1 ; AcessOS Microkernel Version
6 %define SAVEFLAG_FPU 0x1
8 KERNEL_BASE equ 0xC0000000
10 KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET
14 [global NewTaskHeader]
20 add esp, 12 ; Thread, Function, Arg Count
24 push 0 ; 0 = This Thread
28 [global Proc_CloneInt]
34 push DWORD [esp+0x20+12]
51 ; + 8 = Old RSP save loc
53 ; +16 = Old RIP save loc
59 mov eax, [esp+0x20+16]
62 mov DWORD [eax], .restore
68 mov ecx, [esp+0x20+12] ; New IP
69 mov eax, [esp+0x20+20] ; New CR3
70 mov esp, [esp+0x20+ 4] ; New SP
85 [global Proc_InitialiseSSE]
88 or eax, (1 << 9)|(1 << 10) ; Set OSFXSR and OSXMMEXCPT
91 and ax, ~(1 << 2) ; Clear EM
92 or eax, (1 << 1) ; Set MP
95 [global Proc_DisableSSE]
98 or ax, 1 << 3 ; Set TS
101 [global Proc_EnableSSE]
104 and ax, ~(1 << 3) ; Clear TS
108 [global Proc_SaveSSE]
113 [global Proc_RestoreSSE]
120 [extern giMP_TimerCount]
121 [extern gpMP_LocalAPIC]
123 [global SetAPICTimerCount]
137 mov eax, [gpMP_LocalAPIC]
141 mov DWORD [eax+0x380], 0xFFFFFFFF ; Set Initial Count
142 mov DWORD [eax+0x320], 0x000000F0 ; Enable the timer on IVT#0xEF (One Shot)
149 mov DWORD [giMP_TimerCount], ecx
151 mov DWORD [eax+0x320], 0x000100EF
152 mov DWORD [eax+0x380], 0
154 ; Update Timer IRQ to the IRQ code
155 mov eax, SchedulerBase
156 sub eax, Isr240.jmp+5
157 mov DWORD [Isr240.jmp+1], eax
159 ;xchg bx, bx ; MAGIC BREAK
169 add esp, 8 ; CPU ID / Error Code
175 [extern Proc_Scheduler]
176 [global SchedulerBase]
185 and BYTE [esp+1], 0xFE ; Clear Trap Flag
189 push eax ; Debug Register 0, Current Thread
200 push eax ; Push as argument
206 [global scheduler_return]
207 scheduler_return: ; Used by some hackery in Proc_DumpThreadCPUState
209 add esp, 4 ; Remove CPU Number (thread is poped later)
217 out 0x20, al ; ACK IRQ
222 mov eax, DWORD [gpMP_LocalAPIC]
223 mov DWORD [eax+0x0B0], 0
226 pop eax ; Debug Register 0, Current Thread
229 jmp ReturnFromInterrupt
232 ; Returns after an interrupt, restoring the user state
233 ; - Also handles signal handlers
235 [global ReturnFromInterrupt]
236 [extern Threads_GetPendingSignal]
237 [extern Threads_GetSignalHandler]
238 [extern Proc_CallUser]
240 ; Check that we're returning to userland
241 test DWORD [esp+(4+8+2+1)*4], 0x07
242 jz .ret ; Kernel interrupted, return
244 call Threads_GetPendingSignal
249 ; There's a signal pending, funtime
251 call Threads_GetSignalHandler
252 ; eax: signal handler
260 push User_RestoreState
264 push (2+4+8+2+2)*4 ; Up to and incl. CS
265 push ecx ; User stack data base
266 push DWORD [ecx+(2+4+8+2+3)*4] ; User SP
269 ; Oh, ... it failed. Default time?
274 ; Fall through to return
281 add esp, 2*4 ; IRQ Num / CPU ID + error code
285 [extern Threads_Exit]
288 ; Call Proc_Clone with Flags=0
293 add esp, 8 ; Remove arguments from stack
298 ; In child, so now set up stack frame
299 mov ebx, [esp+4] ; Child Function
300 mov edx, [esp+8] ; Argument
304 ; Kill thread once done
306 push 0 ; Kill this thread
307 call Threads_Exit ; Kill Thread
312 ; void Proc_ReturnToUser(void *Method, Uint Parameter, tVAddr KernelStack)
313 ; Calls a user fault handler
315 [global Proc_ReturnToUser]
316 [extern Proc_GetCurThread]
320 ; [EBP+8]: handler to use
321 ; [EBP+12]: parameter
322 ; [EBP+16]: kernel stack top
326 sub eax, KSTACK_USERSTATE_SIZE
329 ; NOTE: This can cause corruption if the signal happens while the user
330 ; has called a kernel operation.
331 ; Good thing this can only be called on a user fault.
334 ; Create data to add to user stack
336 push User_Syscall_RetAndExit
342 push DWORD [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
346 ; Just kill the bleeding thing
347 ; (I know it calls int 0xAC in kernel mode, but meh)
355 GetCPUNum: ; TODO: Store in debug registers
360 [global GetEIP_Sched]
361 [global GetEIP_Sched_ret]
362 GetEIP_Sched_ret equ GetEIP_Sched.ret
368 ; Usermode code exported by the kernel
370 ; Export a place for the user to jump to to call a syscall
371 ; - Allows the kernel to change the method easily
373 xchg bx, bx ; MAGIC BREAKPOINT
376 [global User_Signal_Kill]
390 add esp, 2*4 ; Kernel's error code and interrupt number
391 retf ; EFLAGS/SS/ESP were not included in the state
394 ; A place to return to and exit
395 User_Syscall_RetAndExit:
397 call User_Syscall_Exit