6 global getrflags:function
13 global switch_task:function
15 ; this needs to be in sync with the definition in process.h
37 .kernel_stack resq 1 ;
51 ; first arg rdi is old register pointer, second arg is new register pointer
54 mov [rdi + reg.rax], rax
55 mov [rdi + reg.rbx], rbx
56 mov [rdi + reg.rcx], rcx
57 mov [rdi + reg.rdx], rdx
58 mov [rdi + reg.rdi], rdi ; a pointer to the current task
59 mov [rdi + reg.rsi], rsi ; though rsi is just a pointer to the new task...
60 mov [rdi + reg.rbp], rbp
61 mov [rdi + reg.r8], r8
62 mov [rdi + reg.r9], r9
63 mov [rdi + reg.r10], r10
64 mov [rdi + reg.r11], r11
65 mov [rdi + reg.r12], r12
66 mov [rdi + reg.r13], r13
67 mov [rdi + reg.r14], r14
68 mov [rdi + reg.r15], r15
69 ; save rip for return from stack
70 ; mov? we're going to switch the stack anyway
72 mov [rdi + reg.rip], rax
76 ; mov rdi, qword printrrip
82 mov [rdi + reg.rsp], rsp
87 mov [rdi + reg.rflags], rax
88 ; and the address space
89 ; TODO skip, shouldn't change
91 mov [rdi + reg.cr3], rax
94 ; Ok. now load up the new registers
95 ; we're going to use rax and rbx, and rsi needs
97 mov rcx, [rsi + reg.rcx]
98 mov rdx, [rsi + reg.rdx]
99 mov rdi, [rsi + reg.rdi]
100 mov rbp, [rsi + reg.rbp]
101 mov r8, [rsi + reg.r8]
102 mov r9, [rsi + reg.r9]
103 mov r10, [rsi + reg.r10]
104 mov r11, [rsi + reg.r11]
105 mov r12, [rsi + reg.r12]
106 mov r13, [rsi + reg.r13]
107 mov r14, [rsi + reg.r14]
108 mov r15, [rsi + reg.r15]
112 ; mov rdi, qword printsp
113 ; mov rsi, [rsi + reg.rsp]
119 ; and the address space
120 ; rsi should be pointing into the kernel
121 ; memory, so we can still load from that
124 mov rbx, [rsi + reg.cr3]
133 ; switch to new stack, has to be after the address space switch, otherwise the
138 mov rsp, [rsi + reg.rsp]
141 mov rax, [rsi + reg.rflags]
146 ; push rip for return from stack
147 ; must be done after we switch address space
148 mov rax, [rsi + reg.rip]
153 ; mov rdi, qword printrip
154 ; ;mov rsi, [rsi + reg.rip]
160 ; restore registers we used for the switch
161 mov rbx, [rsi + reg.rbx]
162 mov rax, [rsi + reg.rax]
163 mov rsi, [rsi + reg.rsi] ; have to do this one last
167 global usermodetrampoline:function
170 ; sysret wants return rip in rcx
173 ; user mode function in rdi (i.e. first argument)
185 ; TODO clear out all the other registers to not leak anything
189 mov r11, 0x202 ; make sure interrupts will be enabled
192 db 0x48 ; need rex prefix for 64 bit mode returns
196 printcr3: db 'cr3 = %llx', 0xA, 0
197 printsp: db 'setting rsp %llx', 0xA, 0
198 printrip: db 'returning to %llx', 0xA, 0
199 printrrip: db 'saving return to %llx', 0xA, 0
201 printcr3s: db 'old cr3 = %llx, new cr3 = %llx', 0xA, 0
210 mov rdi, qword printcr3s
225 mov rdi, qword raxprintf
237 mov rdi, qword raxprintf
245 global printistack:function
249 mov rdi, qword ssprintf
252 mov rdi, qword rspprintf
255 mov rdi, qword rfprintf
258 mov rdi, qword csprintf
261 mov rdi, qword ripprintf
268 rfprintf: db 'rflags : %llx', 10, 0
269 csprintf: db 'cs : %hx', 10, 0
270 ripprintf: db 'rip : %llx', 10, 0
271 raxprintf: db 'rax : %llx', 10, 0
272 rspprintf: db 'rsp : %llx', 10, 0
273 ssprintf: db 'ss : %hx', 10, 0
274 csvprintf: db 'gdt : %016llx', 10, 0