157 lines
2.7 KiB
NASM
157 lines
2.7 KiB
NASM
section .text
|
|
extern task_exit
|
|
global context_switch
|
|
global first_task_start
|
|
global fpu_save
|
|
global fpu_restore
|
|
global task_trampoline
|
|
global task_trampoline_user
|
|
global task_trampoline_fork
|
|
|
|
TASK_ENTRY_OFFSET equ 120
|
|
TASK_ARG_OFFSET equ 128
|
|
TASK_USER_RSP_OFFSET equ 144
|
|
TASK_CR3_OFFSET equ 24
|
|
TASK_USER_SAVED_RIP_OFFSET equ 272
|
|
TASK_USER_SAVED_RBP_OFFSET equ 280
|
|
TASK_USER_SAVED_RBX_OFFSET equ 288
|
|
TASK_USER_SAVED_R12_OFFSET equ 296
|
|
TASK_USER_SAVED_R13_OFFSET equ 304
|
|
TASK_USER_SAVED_R14_OFFSET equ 312
|
|
TASK_USER_SAVED_R15_OFFSET equ 320
|
|
TASK_USER_SAVED_R11_OFFSET equ 328
|
|
|
|
PERCPU_CURRENT_TASK equ 24
|
|
TASK_ON_CPU_OFFSET equ 0x158
|
|
|
|
context_switch:
|
|
push rbp
|
|
push rbx
|
|
push r12
|
|
push r13
|
|
push r14
|
|
push r15
|
|
|
|
mov [rdi], rsp
|
|
|
|
mov [rdx], rsi
|
|
mov [gs:PERCPU_CURRENT_TASK], rsi
|
|
|
|
mov rsp, [rsi]
|
|
|
|
test rcx, rcx
|
|
jz .skip_cr3
|
|
mov cr3, rcx
|
|
.skip_cr3:
|
|
|
|
lock add dword [rsp], 0
|
|
mov byte [rdi + TASK_ON_CPU_OFFSET], 0
|
|
|
|
pop r15
|
|
pop r14
|
|
pop r13
|
|
pop r12
|
|
pop rbx
|
|
pop rbp
|
|
|
|
ret
|
|
|
|
first_task_start:
|
|
mov [gs:PERCPU_CURRENT_TASK], rdi
|
|
|
|
mov rsi, [rdi + TASK_CR3_OFFSET]
|
|
mov rsp, [rdi]
|
|
|
|
test rsi, rsi
|
|
jz .skip_cr3_fts
|
|
mov cr3, rsi
|
|
.skip_cr3_fts:
|
|
|
|
pop r15
|
|
pop r14
|
|
pop r13
|
|
pop r12
|
|
pop rbx
|
|
pop rbp
|
|
|
|
ret
|
|
|
|
fpu_save:
|
|
fxsave [rdi]
|
|
ret
|
|
|
|
fpu_restore:
|
|
fxrstor [rdi]
|
|
ret
|
|
|
|
task_trampoline:
|
|
mov rdi, [rbp + TASK_ARG_OFFSET]
|
|
mov rax, [rbp + TASK_ENTRY_OFFSET]
|
|
xor rbp, rbp
|
|
sti
|
|
call rax
|
|
call task_exit
|
|
.hang:
|
|
cli
|
|
hlt
|
|
jmp .hang
|
|
|
|
task_trampoline_user:
|
|
mov rax, [rbp + TASK_ENTRY_OFFSET]
|
|
mov rcx, [rbp + TASK_USER_RSP_OFFSET]
|
|
|
|
xor rbp, rbp
|
|
|
|
push qword 0x1B
|
|
push rcx
|
|
pushfq
|
|
pop rdx
|
|
or rdx, (1 << 9)
|
|
and rdx, ~(3 << 12)
|
|
push rdx
|
|
push qword 0x23
|
|
push rax
|
|
|
|
xor rax, rax
|
|
xor rbx, rbx
|
|
xor rcx, rcx
|
|
xor rdx, rdx
|
|
xor rdi, rdi
|
|
xor rsi, rsi
|
|
xor r8, r8
|
|
xor r9, r9
|
|
xor r10, r10
|
|
xor r11, r11
|
|
xor r12, r12
|
|
xor r13, r13
|
|
xor r14, r14
|
|
xor r15, r15
|
|
|
|
swapgs
|
|
iretq
|
|
|
|
task_trampoline_fork:
|
|
cli
|
|
|
|
mov rax, [rbp + TASK_USER_SAVED_RIP_OFFSET]
|
|
mov rcx, [rbp + TASK_USER_RSP_OFFSET]
|
|
mov r11, [rbp + TASK_USER_SAVED_R11_OFFSET]
|
|
mov rbx, [rbp + TASK_USER_SAVED_RBX_OFFSET]
|
|
mov r12, [rbp + TASK_USER_SAVED_R12_OFFSET]
|
|
mov r13, [rbp + TASK_USER_SAVED_R13_OFFSET]
|
|
mov r14, [rbp + TASK_USER_SAVED_R14_OFFSET]
|
|
mov r15, [rbp + TASK_USER_SAVED_R15_OFFSET]
|
|
mov rbp, [rbp + TASK_USER_SAVED_RBP_OFFSET]
|
|
|
|
or r11, (1 << 9)
|
|
|
|
push qword 0x1B
|
|
push rcx
|
|
push r11
|
|
push qword 0x23
|
|
push rax
|
|
|
|
xor rax, rax
|
|
|
|
swapgs
|
|
iretq |