foo
This commit is contained in:
+27
-29
@@ -25,30 +25,30 @@ struct task_frame {
|
||||
static struct task* perform_switch(uint64_t* old_rsp, uint64_t new_rsp, struct task* prev) {
|
||||
asm volatile(
|
||||
"sub rsp, 0x30\n" // Make room for all regs (except RIP).
|
||||
"mov [rsp + %c0], rbx\n"
|
||||
"mov [rsp + %c1], rbp\n"
|
||||
"mov [rsp + %c2], r12\n"
|
||||
"mov [rsp + %c3], r13\n"
|
||||
"mov [rsp + %c4], r14\n"
|
||||
"mov [rsp + %c5], r15\n"
|
||||
"mov [rsp + %c[rbx]], rbx\n"
|
||||
"mov [rsp + %c[rbp]], rbp\n"
|
||||
"mov [rsp + %c[r12]], r12\n"
|
||||
"mov [rsp + %c[r13]], r13\n"
|
||||
"mov [rsp + %c[r14]], r14\n"
|
||||
"mov [rsp + %c[r15]], r15\n"
|
||||
"mov [rdi], rsp\n" // rdi = old_rsp
|
||||
"mov rsp, rsi\n" // rsi = new_rsp
|
||||
"mov rbx, [rsp + %c0]\n"
|
||||
"mov rbp, [rsp + %c1]\n"
|
||||
"mov r12, [rsp + %c2]\n"
|
||||
"mov r13, [rsp + %c3]\n"
|
||||
"mov r14, [rsp + %c4]\n"
|
||||
"mov r15, [rsp + %c5]\n"
|
||||
"mov rbx, [rsp + %c[rbx]]\n"
|
||||
"mov rbp, [rsp + %c[rbp]]\n"
|
||||
"mov r12, [rsp + %c[r12]]\n"
|
||||
"mov r13, [rsp + %c[r13]]\n"
|
||||
"mov r14, [rsp + %c[r14]]\n"
|
||||
"mov r15, [rsp + %c[r15]]\n"
|
||||
"add rsp, 0x30\n"
|
||||
"mov rax, rdx\n"
|
||||
"ret" // This will conveniently move us to the RIP we put at this stack entry.
|
||||
:
|
||||
: "i"(offsetof(struct task_frame, rbx)),
|
||||
"i"(offsetof(struct task_frame, rbp)),
|
||||
"i"(offsetof(struct task_frame, r12)),
|
||||
"i"(offsetof(struct task_frame, r13)),
|
||||
"i"(offsetof(struct task_frame, r14)),
|
||||
"i"(offsetof(struct task_frame, r15))
|
||||
: [rbx] "i"(offsetof(struct task_frame, rbx)),
|
||||
[rbp] "i"(offsetof(struct task_frame, rbp)),
|
||||
[r12] "i"(offsetof(struct task_frame, r12)),
|
||||
[r13] "i"(offsetof(struct task_frame, r13)),
|
||||
[r14] "i"(offsetof(struct task_frame, r14)),
|
||||
[r15] "i"(offsetof(struct task_frame, r15))
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ struct task* arch_sched_switch(struct task* from, struct task* to) {
|
||||
|
||||
cpu->tss.rsp0 = to->kernel_stack + KERNEL_STACK_SIZE;
|
||||
|
||||
if (from->user_stack) {
|
||||
if (from_ctx->fpu_region != nullptr) {
|
||||
cpu->fpu_save(from_ctx->fpu_region);
|
||||
from_ctx->ds = asm_read_ds();
|
||||
from_ctx->es = asm_read_es();
|
||||
@@ -70,7 +70,7 @@ struct task* arch_sched_switch(struct task* from, struct task* to) {
|
||||
from_ctx->gs_base = asm_rdmsr(MSR_KERNEL_GS_BASE);
|
||||
}
|
||||
|
||||
if (to->user_stack) {
|
||||
if (to_ctx->fpu_region != nullptr) {
|
||||
cpu->fpu_restore(to_ctx->fpu_region);
|
||||
asm_write_ds(to_ctx->ds);
|
||||
asm_write_es(to_ctx->es);
|
||||
@@ -124,16 +124,14 @@ errno_t arch_task_init(
|
||||
uintptr_t fpu_base = vm_alloc(fpu_size);
|
||||
if (!fpu_base)
|
||||
return ENOMEM;
|
||||
for (size_t i = 0; i < fpu_size; i += arch_mem_page_size()) {
|
||||
phys_t page;
|
||||
errno_t s = mem_phys_alloc(1, 0, &page);
|
||||
if (s) {
|
||||
vm_free(fpu_base, fpu_size);
|
||||
return s;
|
||||
}
|
||||
|
||||
pmap_map(&kernel_vma.pmap, (uintptr_t)fpu_base, page, PTE_WRITE | PTE_READ, CACHE_WRITE_BACK);
|
||||
phys_t pages;
|
||||
errno_t s = mem_phys_alloc(ALIGN_UP(fpu_size, arch_mem_page_size()) / arch_mem_page_size(), 0, &pages);
|
||||
if (s) {
|
||||
vm_free(fpu_base, fpu_size);
|
||||
return s;
|
||||
}
|
||||
for (size_t i = 0; i < fpu_size; i += arch_mem_page_size())
|
||||
pmap_map(&kernel_vma.pmap, fpu_base + i, pages + i, PTE_WRITE | PTE_READ, CACHE_WRITE_BACK);
|
||||
context->fpu_region = (void*)fpu_base;
|
||||
|
||||
context->ds = asm_read_ds();
|
||||
|
||||
Reference in New Issue
Block a user