#include "proc/scheduler.h" #include "arch/x86_64/hal/gdt.h" #include "arch/x86_64/hal/obj.h" #include "lib/printf.h" #include "lib/string.h" #include "process.h" #include "../hal/smp.h" #include "../proc/process.h" void _scheduler_switch_pcb_arch(pcb_t *target) { processor_t *proc = processor_current(); proc->syscall_page = target->interrupt_page; proc->interrupt_page = target->interrupt_page; proc->tss.rsp[0] = __interrupt_stack + 0xFF8; if(target->iopb) { proc->tss.iopb = sizeof(struct tss); jove_owned_obj_t *iopb_obj = obj_take(target->iopb); if(obj_gettype(iopb_obj) != JOVE_OBJ_IOPB) { memcpy(proc->iopb, obj_deref(iopb_obj), sizeof(proc->iopb)); } obj_release(iopb_obj); }else{ proc->tss.iopb = 0xff; } } __attribute__((naked)) void scheduler_switch(void *this_sp, void *other_sp, void *new_cr3) { __asm__ volatile("\ movq %%rsp, (%%rdi); \ movq %%rsi, %%rsp; \ movq %%cr3, %%rax; \ cmp %%rax, %%rdx; \ je .nocr3swap; \ movq %%rdx, %%cr3; \ .nocr3swap: \ movq %%gs:%c[syscall_page], %%rax; \ movq %%rax, __syscall_stack_mapping; \ movq (__syscall_stack), %%rax; \ invlpg (%%rax); \ movq %%gs:%c[interrupt_page], %%rax; \ movq %%rax, __interrupt_stack_mapping; \ movq (__interrupt_stack), %%rax; \ invlpg (%%rax); \ retq":: [syscall_page] "i"(offsetof(processor_t, syscall_page)), [interrupt_page] "i"(offsetof(processor_t, interrupt_page))); }