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))
|
REAL_APPS := $(patsubst %, $(APPS_BIN)/%, $(APPS))
|
||||||
|
|
||||||
CFLAGS := -Wall -Wextra -Werror -mgeneral-regs-only -Os
|
CFLAGS := -Wall -Wextra -Werror -Os
|
||||||
|
|
||||||
$(APPS_BIN)/%: $(APPS_SRC)/%.c
|
$(APPS_BIN)/%: $(APPS_SRC)/%.c
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
|
@ -25,7 +25,15 @@ struct Task
|
|||||||
TaskState state;
|
TaskState state;
|
||||||
|
|
||||||
uint64_t cpu_time = 0;
|
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 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void asm_enable_sse();
|
||||||
|
|
||||||
void Init::early_init()
|
void Init::early_init()
|
||||||
{
|
{
|
||||||
Interrupts::disable();
|
Interrupts::disable();
|
||||||
asm volatile("cld");
|
asm volatile("cld");
|
||||||
|
|
||||||
|
asm_enable_sse();
|
||||||
|
|
||||||
framebuffer0.init((void*)bootboot.fb_ptr, bootboot.fb_type, bootboot.fb_scanline, bootboot.fb_width,
|
framebuffer0.init((void*)bootboot.fb_ptr, bootboot.fb_type, bootboot.fb_scanline, bootboot.fb_width,
|
||||||
bootboot.fb_height);
|
bootboot.fb_height);
|
||||||
|
|
||||||
|
@ -15,3 +15,14 @@ idle_task_function:
|
|||||||
.idle:
|
.idle:
|
||||||
hlt
|
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;
|
sched_current_task = sched_current_task->next_task;
|
||||||
if (sched_current_task->state == sched_current_task->Running)
|
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;
|
sched_current_task->task_time = 20;
|
||||||
set_context_from_task(*sched_current_task, context);
|
set_context_from_task(*sched_current_task, context);
|
||||||
Interrupts::enable();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} while (sched_current_task != original_task);
|
} 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 = &idle_task;
|
||||||
sched_current_task->task_time = frequency;
|
sched_current_task->task_time = frequency;
|
||||||
if (!was_idle) { set_context_from_task(*sched_current_task, context); }
|
if (!was_idle) { set_context_from_task(*sched_current_task, context); }
|
||||||
Interrupts::enable();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,3 +10,20 @@ void get_context_to_task(Task& task, Context* ctx)
|
|||||||
{
|
{
|
||||||
memcpy(&task.regs, ctx, sizeof(Context));
|
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
|
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
|
CXXFLAGS := -fno-rtti -fno-exceptions
|
||||||
ASMFLAGS := -felf64
|
ASMFLAGS := -felf64
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user