1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
#include "proc/scheduler.h"
#include "arch/x86_64/hal/gdt.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;
if(target->iopb) {
proc->tss.iopb = sizeof(struct tss);
jove_owned_obj_t *iopb_obj = obj_take(target->iopb);
memcpy(proc->iopb, obj_deref(iopb_obj), sizeof(proc->iopb));
}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)));
}
|