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]
24 add esp, 12 ; Thread, Function, Args
28 push 0 ; 0 = This Thread
32 [extern giMP_TimerCount]
33 [extern gpMP_LocalAPIC]
35 [global SetAPICTimerCount]
49 mov eax, [gpMP_LocalAPIC]
53 mov DWORD [eax+0x380], 0xFFFFFFFF ; Set Initial Count
54 mov DWORD [eax+0x320], 0x000000F0 ; Enable the timer on IVT#0xEF (One Shot)
61 mov DWORD [giMP_TimerCount], ecx
63 mov DWORD [eax+0x320], 0x000100EF
64 mov DWORD [eax+0x380], 0
66 ; Update Timer IRQ to the IRQ code
67 mov eax, SchedulerBase
69 mov DWORD [Isr240.jmp+1], eax
71 ;xchg bx, bx ; MAGIC BREAK
82 ; No Error code / int num
88 [extern Proc_Scheduler]
89 [global SchedulerBase]
98 and BYTE [esp+1], 0xFE ; Clear Trap Flag
102 push eax ; Debug Register 0, Current Thread
113 push eax ; Push as argument
119 [global scheduler_return]
120 scheduler_return: ; Used by some hackery in Proc_DumpThreadCPUState
122 add esp, 4 ; Remove CPU Number (thread is poped later)
130 out 0x20, al ; ACK IRQ
135 mov eax, DWORD [gpMP_LocalAPIC]
136 mov DWORD [eax+0x0B0], 0
139 pop eax ; Debug Register 0, Current Thread
148 add esp, 4*2 ; CPU ID + Dummy error code
149 ; No Error code / int num
153 [extern Threads_Exit]
156 ; Call Proc_Clone with Flags=0
161 add esp, 8 ; Remove arguments from stack
166 ; In child, so now set up stack frame
167 mov ebx, [esp+4] ; Child Function
168 mov edx, [esp+8] ; Argument
172 ; Kill thread once done
174 push 0 ; Kill this thread
175 call Threads_Exit ; Kill Thread
180 ; void Proc_ReturnToUser(void *Method, Uint Parameter)
181 ; Calls a user fault handler
183 [global Proc_ReturnToUser]
184 [extern Proc_GetCurThread]
188 ; [EBP+8]: handler to use
189 ; [EBP+12]: parameter
190 ; [EBP+16]: kernel stack top
192 ;call Proc_GetCurThread
194 ; EAX is the current thread
196 ;mov eax, [ebx+12*4] ; Get Kernel Stack
197 mov eax, [ebp+16] ; Get Kernel Stack
198 sub eax, KSTACK_USERSTATE_SIZE
201 ; NOTE: This can cause corruption if the signal happens while the user
202 ; has called a kernel operation.
203 ; Good thing this can only be called on a user fault.
208 mov edx, [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4
211 test BYTE [0xFC3F0000+ecx*4], 1
216 test BYTE [0xFC000000+ecx*4], 1
223 test BYTE [0xFC3F0000+ecx*4], 1
228 test BYTE [0xFC000000+ecx*4], 1
231 ; Get and alter User SP
233 mov edx, [ebp+12] ; Get parameter
234 mov [edi+4], edx ; save to user stack
235 mov [edi], DWORD User_Syscall_RetAndExit ; Return Address
237 ; Restore Segment Registers
246 push 0x202 ; EFLAGS (IP and Rsvd)
248 mov eax, [ebp+8] ; Method to call
253 ; Just kill the bleeding thing
254 ; (I know it calls int 0xAC in kernel mode, but meh)
262 GetCPUNum: ; TODO: Store in debug registers
266 ; shr ax, 3 ; ax /= 8
271 [global GetEIP_Sched]
272 [global GetEIP_Sched_ret]
273 GetEIP_Sched_ret equ GetEIP_Sched.ret
279 ; Usermode code exported by the kernel
281 ; Export a place for the user to jump to to call a syscall
282 ; - Allows the kernel to change the method easily
284 xchg bx, bx ; MAGIC BREAKPOINT
287 ; A place to return to and exit
288 User_Syscall_RetAndExit:
290 call User_Syscall_Exit