[MODERN FEATURES] SSE
This commit is contained in:
parent
253cd84a1f
commit
0b27ddca2c
45
kernel/arch/sse.S
Normal file
45
kernel/arch/sse.S
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include <registers.h>
|
||||||
|
|
||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.global sse_init
|
||||||
|
sse_init:
|
||||||
|
mov rax, cr0
|
||||||
|
and ax, 0xFFFF-CR0_EM
|
||||||
|
or ax, CR0_MP
|
||||||
|
mov cr0, rax
|
||||||
|
|
||||||
|
mov rax, cr4
|
||||||
|
or ax, CR4_OSFXSR
|
||||||
|
or ax, CR4_OSXMMEXCPT
|
||||||
|
mov cr4, rax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global sse_save
|
||||||
|
sse_save:
|
||||||
|
movabs rax, offset _sse_buffer
|
||||||
|
fxsave [rax]
|
||||||
|
movabs rsi, offset _sse_buffer
|
||||||
|
mov rdx, 512
|
||||||
|
call memcpy
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global sse_restore
|
||||||
|
sse_restore:
|
||||||
|
mov rsi, rdi
|
||||||
|
movabs rdi, offset _sse_buffer
|
||||||
|
mov rdx, 512
|
||||||
|
call memcpy
|
||||||
|
movabs rax, offset _sse_buffer
|
||||||
|
fxrstor [rax]
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
.align 16
|
||||||
|
_sse_buffer:
|
||||||
|
.rept 512
|
||||||
|
.byte 0
|
||||||
|
.endr
|
||||||
|
|
@ -9,6 +9,7 @@
|
|||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
#include <acpi.h>
|
#include <acpi.h>
|
||||||
#include <apic.h>
|
#include <apic.h>
|
||||||
|
#include <sse.h>
|
||||||
|
|
||||||
void thread_function()
|
void thread_function()
|
||||||
{
|
{
|
||||||
@ -36,6 +37,7 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data)
|
|||||||
acpi_init();
|
acpi_init();
|
||||||
apic_init();
|
apic_init();
|
||||||
ioapic_init();
|
ioapic_init();
|
||||||
|
sse_init();
|
||||||
|
|
||||||
|
|
||||||
process_t *p1 = process_spawn(0);
|
process_t *p1 = process_spawn(0);
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
void load_idt(void *);
|
void load_idt(void *);
|
||||||
uint64_t read_cr0();
|
uint64_t read_cr0();
|
||||||
uint64_t read_cr2();
|
uint64_t read_cr2();
|
||||||
uint64_t read_cr3();
|
uint64_t read_cr3();
|
||||||
void write_cr3(uint64_t);
|
void write_cr3(uint64_t);
|
||||||
uint64_t read_cr4();
|
uint64_t read_cr4();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CR0_MP (1<<1)
|
||||||
|
#define CR0_EM (1<<2)
|
||||||
|
|
||||||
|
#define CR4_OSFXSR (1<<9)
|
||||||
|
#define CR4_OSXMMEXCPT (1<<10)
|
||||||
|
6
kernel/include/sse.h
Normal file
6
kernel/include/sse.h
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void sse_init();
|
||||||
|
|
||||||
|
void sse_save(uint8_t *addr);
|
||||||
|
void sse_restore(uint8_t *addr);
|
@ -11,6 +11,7 @@ typedef struct thread_st
|
|||||||
uint64_t stack_pointer; // Top of the kernel stack for thread
|
uint64_t stack_pointer; // Top of the kernel stack for thread
|
||||||
uint64_t tid;
|
uint64_t tid;
|
||||||
uint64_t state;
|
uint64_t state;
|
||||||
|
uint8_t sse_registers[512];
|
||||||
process_t *process;
|
process_t *process;
|
||||||
LIST(struct thread_st, process_threads);
|
LIST(struct thread_st, process_threads);
|
||||||
LIST(struct thread_st, ready_queue);
|
LIST(struct thread_st, ready_queue);
|
||||||
|
@ -86,6 +86,4 @@ void ioapic_init()
|
|||||||
vmm_set_page(0, (uintptr_t)P2V(IOAPIC_BASE), IOAPIC_BASE, PAGE_PRESENT | PAGE_WRITE);
|
vmm_set_page(0, (uintptr_t)P2V(IOAPIC_BASE), IOAPIC_BASE, PAGE_PRESENT | PAGE_WRITE);
|
||||||
for(int i = 0; i < 24; i++)
|
for(int i = 0; i < 24; i++)
|
||||||
ioapic_route(i, IOAPIC_DEST_LOGICAL | IOAPIC_DELIVERY_LOWEST, 0xFF, INT_IRQ0+i);
|
ioapic_route(i, IOAPIC_DEST_LOGICAL | IOAPIC_DELIVERY_LOWEST, 0xFF, INT_IRQ0+i);
|
||||||
|
|
||||||
IRQ_UNMASK(IRQ_KEYBOARD);
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <scheduler.h>
|
#include <scheduler.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <sse.h>
|
||||||
|
|
||||||
LIST(thread_t, ready_queue);
|
LIST(thread_t, ready_queue);
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ void scheduler()
|
|||||||
new->state = THREAD_STATE_RUNNING;
|
new->state = THREAD_STATE_RUNNING;
|
||||||
set_last_thread(new);
|
set_last_thread(new);
|
||||||
switch_process(new->process);
|
switch_process(new->process);
|
||||||
|
sse_restore(new->sse_registers);
|
||||||
switch_thread(scheduler_th, new);
|
switch_thread(scheduler_th, new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,6 +72,11 @@ void schedule()
|
|||||||
|
|
||||||
thread_t *old = get_current_thread();
|
thread_t *old = get_current_thread();
|
||||||
|
|
||||||
|
if(old)
|
||||||
|
{
|
||||||
|
sse_save(old->sse_registers);
|
||||||
|
}
|
||||||
|
|
||||||
switch_process(0);
|
switch_process(0);
|
||||||
switch_thread(old, scheduler_th);
|
switch_thread(old, scheduler_th);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user