; ; ; %include "arch/x86_64/include/common.inc.asm" [BITS 64] [section .text] [extern Threads_Exit] [global GetRIP] GetRIP: mov rax, [rsp] ret [global NewTaskHeader] NewTaskHeader: ; [rsp+0x00]: Thread ; [rsp+0x08]: Function ; [rsp+0x10]: Argument mov rdi, [rsp+0x10] mov rax, [rsp+0x8] add rsp, 0x10 ; Reclaim stack space (thread/fcn) xchg bx, bx call rax ; Quit thread with RAX as the return code xor rdi, rdi mov rsi, rax call Threads_Exit .hlt: jmp .hlt [extern MM_Clone] [extern MM_DumpTables] [global Proc_CloneInt] Proc_CloneInt: PUSH_GPR ; Save RSP mov [rdi], rsp call MM_Clone ; Save CR3 mov rsi, [rsp+0x30] ; Saved version of RSI mov [rsi], rax ; Undo the PUSH_GPR add rsp, 0x80 mov rax, .newTask ret .newTask: ; mov rdi, 0 ; mov rsi, 0x800000000000 ; call MM_DumpTables POP_GPR xor eax, eax ret [global SaveState] SaveState: ; Save regs to RSI add rsi, 0x80 SAVE_GPR rsi ; Save return addr mov rax, [rsp] mov [rsi], rax ; Return RSI as the RSP value sub rsi, 0x80 mov [rdi], rsi ; Check for mov rax, .restore ret .restore: ; RSP = RSI now POP_GPR mov rax, [rsp] mov rsp, [rsp-0x60] ; Restore RSP from the saved value mov [rsp], rax ; Restore return address xor eax, eax ret [global SwitchTasks] ; rdi = New RSP ; rsi = Old RSP save loc ; rdx = New RIP ; rcx = Old RIP save loc ; r8 = CR3 SwitchTasks: PUSH_GPR ; Save state RIP and RSP lea rax, [rel .restore] mov [rcx], rax mov [rsi], rsp ; Change CR3 if requested test r8, r8 jz .setState mov cr3, r8 ; Make sure the stack is valid before jumping invlpg [rdi-0x1000] invlpg [rdi] invlpg [rdi+0x1000] ; Go to new state .setState: mov rsp, rdi jmp rdx ; Restore point for saved state .restore: POP_GPR xor eax, eax ; Return zero ret [global Proc_InitialiseSSE] Proc_InitialiseSSE: mov rax, cr4 or ax, (1 << 9)|(1 << 10) ; Set OSFXSR and OSXMMEXCPT mov cr4, rax mov rax, cr0 and ax, ~(1 << 2) ; Clear EM or rax, (1 << 1) ; Set MP mov rax, cr0 ret [global Proc_DisableSSE] Proc_DisableSSE: mov rax, cr0 or ax, 1 << 3 ; Set TS mov cr0, rax ret [global Proc_EnableSSE] Proc_EnableSSE: mov rax, cr0 and ax, ~(1 << 3) ; Clear TS mov cr0, rax ret [global Proc_SaveSSE] Proc_SaveSSE: fxsave [rdi] ret [global Proc_RestoreSSE] Proc_RestoreSSE: fxrstor [rdi] ret ; vim: ft=nasm