[bits 32]
+%define SAVEFLAG_FPU 0x1
+
KERNEL_BASE equ 0xC0000000
KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET
NewTaskHeader:
mov eax, [esp]
mov dr0, eax
- xchg bx, bx
- sti
- ; TODO: SMP
- mov al, 0x20
- out 0x20, al
-
mov eax, [esp+4]
- add esp, 12 ; Thread, Function, Args
+ 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]
+ test eax, eax
+ jz .nosave
+ mov DWORD [eax], .restore
+ ; Old SP
+ mov eax, [esp+0x20+8]
+ mov [eax], esp
+
+.nosave:
+ 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:
+ jmp ecx
+
+.restore:
+ popa
+ xor eax, eax
+ ret
+
+[global Proc_InitialiseSSE]
+Proc_InitialiseSSE:
+ mov eax, cr4
+ or eax, (1 << 9)|(1 << 10) ; Set OSFXSR and OSXMMEXCPT
+ mov cr4, eax
+ mov eax, cr0
+ and ax, ~(1 << 2) ; Clear EM
+ or eax, (1 << 1) ; Set MP
+ mov eax, cr0
+ ret
+[global Proc_DisableSSE]
+Proc_DisableSSE:
+ mov eax, cr0
+ or ax, 1 << 3 ; Set TS
+ mov cr0, eax
+ ret
+[global Proc_EnableSSE]
+Proc_EnableSSE:
+ mov eax, cr0
+ and ax, ~(1 << 3) ; Clear TS
+ mov cr0, eax
+ ret
+
+[global Proc_SaveSSE]
+Proc_SaveSSE:
+ mov eax, [esp+4]
+ fxsave [eax]
+ ret
+[global Proc_RestoreSSE]
+Proc_RestoreSSE:
+ mov eax, [esp+4]
+ fxrstor [eax]
+ ret
+
%if USE_MP
[extern giMP_TimerCount]
[extern gpMP_LocalAPIC]
pop es
pop ds
popa
- add esp, 4 ; CPU ID
- ; No Error code / int num
+ add esp, 8 ; CPU ID / Error Code
iret
%endif
; --------------
.parent:
ret
-; void Proc_ReturnToUser(void *Method, Uint Parameter)
+; void Proc_ReturnToUser(void *Method, Uint Parameter, tVAddr KernelStack)
; Calls a user fault handler
;
[global Proc_ReturnToUser]
; [EBP+12]: parameter
; [EBP+16]: kernel stack top
- ;call Proc_GetCurThread
-
- ; EAX is the current thread
- ;mov ebx, eax
- ;mov eax, [ebx+12*4] ; Get Kernel Stack
- mov eax, [ebp+16] ; Get Kernel Stack
+ ; Get kernel stack
+ mov eax, [ebp+16]
sub eax, KSTACK_USERSTATE_SIZE
;
[global GetCPUNum]
GetCPUNum: ; TODO: Store in debug registers
-; xor eax, eax
-; str ax
-; sub ax, 0x30
-; shr ax, 3 ; ax /= 8
mov eax, dr1
ret
xor eax, eax
mov ebx, [esp+4]
int 0xAC
+
+; vim: ft=nasm ts=8