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]
49 ; + 8 = Old RSP save loc
51 ; +16 = Old RIP save loc
57 mov eax, [esp+0x20+16]
60 mov DWORD [eax], .restore
66 mov ecx, [esp+0x20+12] ; New IP
67 mov eax, [esp+0x20+20] ; New CR3
68 mov esp, [esp+0x20+ 4] ; New SP
83 [global Proc_InitialiseSSE]
86 or eax, (1 << 9)|(1 << 10) ; Set OSFXSR and OSXMMEXCPT
89 and ax, ~(1 << 2) ; Clear EM
90 or eax, (1 << 1) ; Set MP
93 [global Proc_DisableSSE]
96 or ax, 1 << 3 ; Set TS
99 [global Proc_EnableSSE]
102 and ax, ~(1 << 3) ; Clear TS
106 [global Proc_SaveSSE]
111 [global Proc_RestoreSSE]
118 [extern giMP_TimerCount]
119 [extern gpMP_LocalAPIC]
121 [global SetAPICTimerCount]
135 mov eax, [gpMP_LocalAPIC]
139 mov DWORD [eax+0x380], 0xFFFFFFFF ; Set Initial Count
140 mov DWORD [eax+0x320], 0x000000F0 ; Enable the timer on IVT#0xEF (One Shot)
147 mov DWORD [giMP_TimerCount], ecx
149 mov DWORD [eax+0x320], 0x000100EF
150 mov DWORD [eax+0x380], 0
152 ; Update Timer IRQ to the IRQ code
153 mov eax, SchedulerBase
154 sub eax, Isr240.jmp+5
155 mov DWORD [Isr240.jmp+1], eax
157 ;xchg bx, bx ; MAGIC BREAK
167 add esp, 8 ; CPU ID / Error Code
173 [extern Proc_Scheduler]
174 [global SchedulerBase]
183 and BYTE [esp+1], 0xFE ; Clear Trap Flag
187 push eax ; Debug Register 0, Current Thread
198 push eax ; Push as argument
204 [global scheduler_return]
205 scheduler_return: ; Used by some hackery in Proc_DumpThreadCPUState
207 add esp, 4 ; Remove CPU Number (thread is poped later)
215 out 0x20, al ; ACK IRQ
220 mov eax, DWORD [gpMP_LocalAPIC]
221 mov DWORD [eax+0x0B0], 0
224 pop eax ; Debug Register 0, Current Thread
233 add esp, 4*2 ; CPU ID + Dummy error code
234 ; No Error code / int num
238 [extern Threads_Exit]
241 ; Call Proc_Clone with Flags=0
246 add esp, 8 ; Remove arguments from stack
251 ; In child, so now set up stack frame
252 mov ebx, [esp+4] ; Child Function
253 mov edx, [esp+8] ; Argument
257 ; Kill thread once done
259 push 0 ; Kill this thread
260 call Threads_Exit ; Kill Thread
265 ; void Proc_ReturnToUser(void *Method, Uint Parameter)
266 ; Calls a user fault handler
268 [global Proc_ReturnToUser]
269 [extern Proc_GetCurThread]
273 ; [EBP+8]: handler to use
274 ; [EBP+12]: parameter
275 ; [EBP+16]: kernel stack top
277 ;call Proc_GetCurThread
279 ; EAX is the current thread
281 ;mov eax, [ebx+12*4] ; Get Kernel Stack
282 mov eax, [ebp+16] ; Get Kernel Stack
283 sub eax, KSTACK_USERSTATE_SIZE
286 ; NOTE: This can cause corruption if the signal happens while the user
287 ; has called a kernel operation.
288 ; Good thing this can only be called on a user fault.
293 mov edx, [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
296 test BYTE [0xFC3F0000+ecx*4], 1
301 test BYTE [0xFC000000+ecx*4], 1
308 test BYTE [0xFC3F0000+ecx*4], 1
313 test BYTE [0xFC000000+ecx*4], 1
316 ; Get and alter User SP
318 mov edx, [ebp+12] ; Get parameter
319 mov [edi+4], edx ; save to user stack
320 mov [edi], DWORD User_Syscall_RetAndExit ; Return Address
322 ; Restore Segment Registers
331 push 0x202 ; EFLAGS (IP and Rsvd)
333 mov eax, [ebp+8] ; Method to call
338 ; Just kill the bleeding thing
339 ; (I know it calls int 0xAC in kernel mode, but meh)
347 GetCPUNum: ; TODO: Store in debug registers
351 ; shr ax, 3 ; ax /= 8
356 [global GetEIP_Sched]
357 [global GetEIP_Sched_ret]
358 GetEIP_Sched_ret equ GetEIP_Sched.ret
364 ; Usermode code exported by the kernel
366 ; Export a place for the user to jump to to call a syscall
367 ; - Allows the kernel to change the method easily
369 xchg bx, bx ; MAGIC BREAKPOINT
372 ; A place to return to and exit
373 User_Syscall_RetAndExit:
375 call User_Syscall_Exit