1 ; AcessOS Microkernel Version
6 KERNEL_BASE equ 0xC0000000
8 KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET
12 [global NewTaskHeader]
18 add esp, 12 ; Thread, Function, Arg Count
22 push 0 ; 0 = This Thread
26 [global Proc_CloneInt]
47 ; + 8 = Old RSP save loc
49 ; +16 = Old RIP save loc
55 mov eax, [esp+0x20+16]
56 mov DWORD [eax], .restore
61 mov ecx, [esp+0x20+12] ; New IP
62 mov eax, [esp+0x20+20] ; New CR3
63 mov esp, [esp+0x20+ 4] ; New SP
80 [extern giMP_TimerCount]
81 [extern gpMP_LocalAPIC]
83 [global SetAPICTimerCount]
97 mov eax, [gpMP_LocalAPIC]
101 mov DWORD [eax+0x380], 0xFFFFFFFF ; Set Initial Count
102 mov DWORD [eax+0x320], 0x000000F0 ; Enable the timer on IVT#0xEF (One Shot)
109 mov DWORD [giMP_TimerCount], ecx
111 mov DWORD [eax+0x320], 0x000100EF
112 mov DWORD [eax+0x380], 0
114 ; Update Timer IRQ to the IRQ code
115 mov eax, SchedulerBase
116 sub eax, Isr240.jmp+5
117 mov DWORD [Isr240.jmp+1], eax
119 ;xchg bx, bx ; MAGIC BREAK
130 ; No Error code / int num
136 [extern Proc_Scheduler]
137 [global SchedulerBase]
146 and BYTE [esp+1], 0xFE ; Clear Trap Flag
150 push eax ; Debug Register 0, Current Thread
161 push eax ; Push as argument
167 [global scheduler_return]
168 scheduler_return: ; Used by some hackery in Proc_DumpThreadCPUState
170 add esp, 4 ; Remove CPU Number (thread is poped later)
178 out 0x20, al ; ACK IRQ
183 mov eax, DWORD [gpMP_LocalAPIC]
184 mov DWORD [eax+0x0B0], 0
187 pop eax ; Debug Register 0, Current Thread
196 add esp, 4*2 ; CPU ID + Dummy error code
197 ; No Error code / int num
201 [extern Threads_Exit]
204 ; Call Proc_Clone with Flags=0
209 add esp, 8 ; Remove arguments from stack
214 ; In child, so now set up stack frame
215 mov ebx, [esp+4] ; Child Function
216 mov edx, [esp+8] ; Argument
220 ; Kill thread once done
222 push 0 ; Kill this thread
223 call Threads_Exit ; Kill Thread
228 ; void Proc_ReturnToUser(void *Method, Uint Parameter)
229 ; Calls a user fault handler
231 [global Proc_ReturnToUser]
232 [extern Proc_GetCurThread]
236 ; [EBP+8]: handler to use
237 ; [EBP+12]: parameter
238 ; [EBP+16]: kernel stack top
240 ;call Proc_GetCurThread
242 ; EAX is the current thread
244 ;mov eax, [ebx+12*4] ; Get Kernel Stack
245 mov eax, [ebp+16] ; Get Kernel Stack
246 sub eax, KSTACK_USERSTATE_SIZE
249 ; NOTE: This can cause corruption if the signal happens while the user
250 ; has called a kernel operation.
251 ; Good thing this can only be called on a user fault.
256 mov edx, [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
259 test BYTE [0xFC3F0000+ecx*4], 1
264 test BYTE [0xFC000000+ecx*4], 1
271 test BYTE [0xFC3F0000+ecx*4], 1
276 test BYTE [0xFC000000+ecx*4], 1
279 ; Get and alter User SP
281 mov edx, [ebp+12] ; Get parameter
282 mov [edi+4], edx ; save to user stack
283 mov [edi], DWORD User_Syscall_RetAndExit ; Return Address
285 ; Restore Segment Registers
294 push 0x202 ; EFLAGS (IP and Rsvd)
296 mov eax, [ebp+8] ; Method to call
301 ; Just kill the bleeding thing
302 ; (I know it calls int 0xAC in kernel mode, but meh)
310 GetCPUNum: ; TODO: Store in debug registers
314 ; shr ax, 3 ; ax /= 8
319 [global GetEIP_Sched]
320 [global GetEIP_Sched_ret]
321 GetEIP_Sched_ret equ GetEIP_Sched.ret
327 ; Usermode code exported by the kernel
329 ; Export a place for the user to jump to to call a syscall
330 ; - Allows the kernel to change the method easily
332 xchg bx, bx ; MAGIC BREAKPOINT
335 ; A place to return to and exit
336 User_Syscall_RetAndExit:
338 call User_Syscall_Exit