KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET
[section .text]
+
+[global NewTaskHeader]
+NewTaskHeader:
+ mov eax, [esp]
+ mov dr0, eax
+
+ mov eax, [esp+4]
+ add esp, 12 ; Thread, Function, Arg Count
+ call eax
+
+ push eax ; Ret val
+ push 0 ; 0 = This Thread
+ call Threads_Exit
+
+[extern MM_Clone]
+[global Proc_CloneInt]
+Proc_CloneInt:
+ pusha
+ ; Save RSP
+ mov eax, [esp+0x20+4]
+ mov [eax], esp
+ call MM_Clone
+ ; Save CR3
+ mov esi, [esp+0x20+8]
+ mov [esi], eax
+ ; Undo the pusha
+ add esp, 0x20
+ mov eax, .newTask
+ ret
+.newTask:
+ popa
+ xor eax, eax
+ ret
+
+[global SwitchTasks]
+; + 4 = New RSP
+; + 8 = Old RSP save loc
+; +12 = New RIP
+; +16 = Old RIP save loc
+; +20 = CR3
+SwitchTasks:
+ pusha
+
+ ; Old IP
+ mov eax, [esp+0x20+16]
+ mov DWORD [eax], .restore
+ ; Old SP
+ mov eax, [esp+0x20+8]
+ mov [eax], esp
+
+ mov ecx, [esp+0x20+12] ; New IP
+ mov eax, [esp+0x20+20] ; New CR3
+ mov esp, [esp+0x20+ 4] ; New SP
+ test eax, eax
+ jz .setState
+ mov cr3, eax
+ invlpg [esp]
+ invlpg [esp+0x1000]
+.setState:
+; xchg bx, bx
+ jmp ecx
+
+.restore:
+ popa
+ xor eax, eax
+ ret
+
+
%if USE_MP
[extern giMP_TimerCount]
[extern gpMP_LocalAPIC]
push fs
push gs
+ pushf
+ and BYTE [esp+1], 0xFE ; Clear Trap Flag
+ popf
+
mov eax, dr0
push eax ; Debug Register 0, Current Thread
pop ds
popa
- add esp, 4 ; CPU ID
+ add esp, 4*2 ; CPU ID + Dummy error code
; No Error code / int num
iret
SpawnTask:
; Call Proc_Clone with Flags=0
xor eax, eax
- push eax
+; push eax
push eax
call Proc_Clone
add esp, 8 ; Remove arguments from stack
; In child, so now set up stack frame
mov ebx, [esp+4] ; Child Function
mov edx, [esp+8] ; Argument
- ; Child
+ ; Child Function
push edx ; Argument
call ebx ; Function
+ ; Kill thread once done
push eax ; Exit Code
push 0 ; Kill this thread
call Threads_Exit ; Kill Thread
; Validate user ESP
; - Page Table
mov edx, [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
- %if USE_PAE
- %error PAE Support
- %else
mov ecx, edx
shr ecx, 22
test BYTE [0xFC3F0000+ecx*4], 1
jnz .justKillIt
- %endif
; - Page
mov ecx, edx
shr ecx, 12
; Adjust
sub edx, 8
; - Page Table
- %if USE_PAE
- %else
mov ecx, edx
shr ecx, 22
test BYTE [0xFC3F0000+ecx*4], 1
jnz .justKillIt
- %endif
; - Page
mov ecx, edx
shr ecx, 12
.justKillIt:
xor eax, eax
xor ebx, ebx
- dec ebx
+ dec ebx ; EBX = -1
int 0xAC
[global GetCPUNum]
mov eax, dr1
ret
+[extern GetEIP]
+[global GetEIP_Sched]
+[global GetEIP_Sched_ret]
+GetEIP_Sched_ret equ GetEIP_Sched.ret
+GetEIP_Sched:
+ call GetEIP
+GetEIP_Sched.ret:
+ ret
+
; Usermode code exported by the kernel
[section .usertext]
; Export a place for the user to jump to to call a syscall