Kernel: Add SSE support (enable SSE on boot and save context (user tasks only) on task switch)
This commit is contained in:
parent
d2f9e17c86
commit
1ecd24f5d6
@ -6,7 +6,7 @@ APPS_BIN := $(APPS_DIR)/bin
|
||||
|
||||
REAL_APPS := $(patsubst %, $(APPS_BIN)/%, $(APPS))
|
||||
|
||||
CFLAGS := -Wall -Wextra -Werror -mgeneral-regs-only -Os
|
||||
CFLAGS := -Wall -Wextra -Werror -Os
|
||||
|
||||
$(APPS_BIN)/%: $(APPS_SRC)/%.c
|
||||
@mkdir -p $(@D)
|
||||
|
@ -25,7 +25,15 @@ struct Task
|
||||
TaskState state;
|
||||
|
||||
uint64_t cpu_time = 0;
|
||||
|
||||
char floating_region[512] __attribute__((aligned(16)));
|
||||
bool floating_saved = false;
|
||||
|
||||
bool is_user_task();
|
||||
};
|
||||
|
||||
void set_context_from_task(Task& task, Context* ctx);
|
||||
void get_context_to_task(Task& task, Context* ctx);
|
||||
void get_context_to_task(Task& task, Context* ctx);
|
||||
|
||||
void task_save_floating(Task& task);
|
||||
void task_restore_floating(Task& task);
|
@ -32,11 +32,15 @@ void Init::disable_smp()
|
||||
return;
|
||||
}
|
||||
|
||||
extern "C" void asm_enable_sse();
|
||||
|
||||
void Init::early_init()
|
||||
{
|
||||
Interrupts::disable();
|
||||
asm volatile("cld");
|
||||
|
||||
asm_enable_sse();
|
||||
|
||||
framebuffer0.init((void*)bootboot.fb_ptr, bootboot.fb_type, bootboot.fb_scanline, bootboot.fb_width,
|
||||
bootboot.fb_height);
|
||||
|
||||
|
@ -14,4 +14,15 @@ idle_task_function:
|
||||
sti
|
||||
.idle:
|
||||
hlt
|
||||
jmp .idle
|
||||
jmp .idle
|
||||
|
||||
global asm_enable_sse
|
||||
asm_enable_sse:
|
||||
mov rax, cr0
|
||||
and ax, 0xFFFB
|
||||
or ax, 0x2
|
||||
mov cr0, rax
|
||||
mov rax, cr4
|
||||
or ax, 3 << 9
|
||||
mov cr4, rax
|
||||
ret
|
@ -272,16 +272,20 @@ void Scheduler::task_yield(Context* context)
|
||||
sched_current_task = sched_current_task->next_task;
|
||||
if (sched_current_task->state == sched_current_task->Running)
|
||||
{
|
||||
if (sched_current_task->id != original_task->id)
|
||||
{
|
||||
if (!was_idle && original_task->is_user_task()) { task_save_floating(*original_task); }
|
||||
if (sched_current_task->is_user_task()) { task_restore_floating(*sched_current_task); }
|
||||
}
|
||||
sched_current_task->task_time = 20;
|
||||
set_context_from_task(*sched_current_task, context);
|
||||
Interrupts::enable();
|
||||
return;
|
||||
}
|
||||
} while (sched_current_task != original_task);
|
||||
if (!was_idle && original_task->is_user_task()) task_save_floating(*original_task);
|
||||
sched_current_task = &idle_task;
|
||||
sched_current_task->task_time = frequency;
|
||||
if (!was_idle) { set_context_from_task(*sched_current_task, context); }
|
||||
Interrupts::enable();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -9,4 +9,21 @@ void set_context_from_task(Task& task, Context* ctx)
|
||||
void get_context_to_task(Task& task, Context* ctx)
|
||||
{
|
||||
memcpy(&task.regs, ctx, sizeof(Context));
|
||||
}
|
||||
|
||||
void task_save_floating(Task& task)
|
||||
{
|
||||
task.floating_saved = true;
|
||||
asm volatile("fxsave (%0)" : : "r"(&task.floating_region));
|
||||
}
|
||||
|
||||
void task_restore_floating(Task& task)
|
||||
{
|
||||
if (!task.floating_saved) return;
|
||||
asm volatile("fxrstor (%0)" : : "r"(&task.floating_region));
|
||||
}
|
||||
|
||||
bool Task::is_user_task()
|
||||
{
|
||||
return (regs.cs & 3) > 0;
|
||||
}
|
@ -5,7 +5,7 @@ LIBC_BIN := $(LIBC_DIR)/bin
|
||||
|
||||
DESTDIR ?= $(LUNA_BASE)/usr/lib
|
||||
|
||||
CFLAGS := -Wall -Wextra -Werror -Os -nostdlib -fno-omit-frame-pointer -mno-mmx -mno-sse -mno-sse2
|
||||
CFLAGS := -Wall -Wextra -Werror -Os -nostdlib -fno-omit-frame-pointer
|
||||
CXXFLAGS := -fno-rtti -fno-exceptions
|
||||
ASMFLAGS := -felf64
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user