1 ; AcessOS Microkernel Version
3 %include "arch/x86/common.inc.asm"
7 %define SAVEFLAG_FPU 0x1
9 KERNEL_BASE equ 0xC0000000
11 KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET
16 [global Proc_CloneInt]
22 push DWORD [esp+0x20+12]
39 ; + 8 = Old RSP save loc
41 ; +16 = Old RIP save loc
47 mov eax, [esp+0x20+16]
50 mov DWORD [eax], .restore
56 mov ecx, [esp+0x20+12] ; New IP
57 mov eax, [esp+0x20+20] ; New CR3
58 mov esp, [esp+0x20+ 4] ; New SP
73 [global Proc_InitialiseSSE]
76 or eax, (1 << 9)|(1 << 10) ; Set OSFXSR and OSXMMEXCPT
79 and ax, ~(1 << 2) ; Clear EM
80 or eax, (1 << 1) ; Set MP
83 [global Proc_DisableSSE]
86 or ax, 1 << 3 ; Set TS
89 [global Proc_EnableSSE]
92 and ax, ~(1 << 3) ; Clear TS
101 [global Proc_RestoreSSE]
108 [extern giMP_TimerCount]
109 [extern gpMP_LocalAPIC]
111 [global SetAPICTimerCount]
116 mov eax, [gpMP_LocalAPIC]
120 mov DWORD [eax+0x380], 0xFFFFFFFF ; Set Initial Count
121 mov DWORD [eax+0x320], 0x000000F0 ; Enable the timer on IVT#0xEF (One Shot)
128 mov DWORD [giMP_TimerCount], ecx
130 mov DWORD [eax+0x320], 0x000100EF
131 mov DWORD [eax+0x380], 0
133 ; Update Timer IRQ to the IRQ code
134 mov eax, Proc_EventTimer_PIT
135 sub eax, Isr240.jmp+5
136 mov DWORD [Isr240.jmp+1], eax
138 ;xchg bx, bx ; MAGIC BREAK
142 out 0x20, al ; ACK IRQ
145 add esp, 8 ; CPU ID / Error Code
150 [global Proc_EventTimer_LAPIC]
151 Proc_EventTimer_LAPIC:
153 mov eax, SS:[gpMP_LocalAPIC]
154 mov DWORD SS:[eax + 0xB0], 0
156 jmp Proc_EventTimer_Common
158 [global Proc_EventTimer_PIT]
162 out 0x20, al ; ACK IRQ
164 jmp Proc_EventTimer_Common
165 [extern Proc_HandleEventTimer]
166 [global Proc_EventTimer_Common]
167 Proc_EventTimer_Common:
171 ; Clear the Trace/Trap flag
173 and BYTE [esp+1], 0xFE ; Clear Trap Flag
175 ; Re-enable interrupts
176 ; - TODO: This is quite likely racy, if we get an interrupt flood
181 push eax ; Push as argument
186 call Proc_HandleEventTimer
187 [global scheduler_return]
188 scheduler_return: ; Used by some hackery in Proc_DumpThreadCPUState
189 add esp, 4 ; Remove CPU Number (thread is poped later)
191 jmp ReturnFromInterrupt
194 ; Returns after an interrupt, restoring the user state
195 ; - Also handles signal handlers
197 [global ReturnFromInterrupt]
198 [extern Threads_GetPendingSignal]
199 [extern Threads_GetSignalHandler]
200 [extern Proc_CallUser]
202 ; Check that we're returning to userland
203 test DWORD [esp+(4+8+2+1)*4], 0x07
204 jz .ret ; Kernel interrupted, return
206 call Threads_GetPendingSignal
211 ; There's a signal pending, funtime
213 call Threads_GetSignalHandler
214 ; eax: signal handler
222 push User_RestoreState
226 push (2+4+8+2+2)*4 ; Up to and incl. CS
227 push ecx ; User stack data base
228 push DWORD [ecx+(2+4+8+2+3)*4] ; User SP
231 ; Oh, ... it failed. Default time?
236 ; Fall through to return
243 add esp, 2*4 ; IRQ Num / CPU ID + error code
247 [extern Threads_Exit]
250 ; Call Proc_Clone with Flags=0
255 add esp, 8 ; Remove arguments from stack
260 ; In child, so now set up stack frame
261 mov ebx, [esp+4] ; Child Function
262 mov edx, [esp+8] ; Argument
266 ; Kill thread once done
268 push 0 ; Kill this thread
269 call Threads_Exit ; Kill Thread
274 ; void Proc_ReturnToUser(void *Method, Uint Parameter, tVAddr KernelStack)
275 ; Calls a user fault handler
277 [global Proc_ReturnToUser]
278 [extern Proc_GetCurThread]
282 ; [EBP+8]: handler to use
283 ; [EBP+12]: parameter
284 ; [EBP+16]: kernel stack top
288 sub eax, KSTACK_USERSTATE_SIZE
291 ; NOTE: This can cause corruption if the signal happens while the user
292 ; has called a kernel operation.
293 ; Good thing this can only be called on a user fault.
296 ; Create data to add to user stack
298 push User_Syscall_RetAndExit
304 push DWORD [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
308 ; Just kill the bleeding thing
309 ; (I know it calls int 0xAC in kernel mode, but meh)
317 GetCPUNum: ; TODO: Store in debug registers
322 [global GetEIP_Sched]
323 [global GetEIP_Sched_ret]
324 GetEIP_Sched_ret equ GetEIP_Sched.ret
330 ; Usermode code exported by the kernel
332 ; Export a place for the user to jump to to call a syscall
333 ; - Allows the kernel to change the method easily
335 xchg bx, bx ; MAGIC BREAKPOINT
338 [global User_Signal_Kill]
352 add esp, 2*4 ; Kernel's error code and interrupt number
353 retf ; EFLAGS/SS/ESP were not included in the state
356 ; A place to return to and exit
357 User_Syscall_RetAndExit:
359 call User_Syscall_Exit