KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET
[section .text]
+%if USE_MP
+[extern giMP_TimerCount]
+[extern gpMP_LocalAPIC]
+[extern Isr240.jmp]
+[global SetAPICTimerCount]
+SetAPICTimerCount:
+ pusha
+ push ds
+ push es
+ push fs
+ push gs
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ mov eax, [gpMP_LocalAPIC]
+ mov ecx, [eax+0x320]
+ test ecx, 0x00010000
+ jz .setTime
+ mov DWORD [eax+0x380], 0xFFFFFFFF ; Set Initial Count
+ mov DWORD [eax+0x320], 0x000000F0 ; Enable the timer on IVT#0xEF (One Shot)
+ jmp .ret
+
+.setTime:
+ ; Get Timer Count
+ mov ecx, 0xFFFFFFFF
+ sub ecx, [eax+0x390]
+ mov DWORD [giMP_TimerCount], ecx
+ ; Disable APIC Timer
+ mov DWORD [eax+0x320], 0x000100EF
+ mov DWORD [eax+0x380], 0
+
+ ; Update Timer IRQ to the IRQ code
+ mov eax, SchedulerBase
+ sub eax, Isr240.jmp+5
+ mov DWORD [Isr240.jmp+1], eax
+
+ ;xchg bx, bx ; MAGIC BREAK
+.ret:
+ mov dx, 0x20
+ mov al, 0x20
+ out dx, al ; ACK IRQ
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ popa
+ add esp, 4 ; CPU ID
+ ; No Error code / int num
+ iret
+%endif
; --------------
; Task Scheduler
; --------------
mov fs, ax
mov gs, ax
- mov eax, [esp+12*4] ; CPU Number
- push eax ; Pus as argument
+ %if USE_MP
+ call GetCPUNum
+ mov ebx, eax
+ push eax ; Push as argument
+ %else
+ push 0
+ %endif
call Proc_Scheduler
add esp, 4 ; Remove Argument
+
+ %if USE_MP
+ test ebx, ebx
+ jnz .sendEOI
+ %endif
+ mov al, 0x20
+ out 0x20, al ; ACK IRQ
+ %if USE_MP
+ jmp .ret
+
+.sendEOI:
+ mov eax, DWORD [gpMP_LocalAPIC]
+ mov DWORD [eax+0x0B0], 0
+ %endif
+.ret:
pop gs
pop fs
pop es
pop ds
-
- mov dx, 0x20
- mov al, 0x20
- out dx, al ; ACK IRQ
+
popa
add esp, 4 ; CPU ID
; No Error code / int num
; Child
push edx ; Argument
call ebx ; Function
+ push eax ; Exit Code
+ push 0 ; Kill this thread
call Threads_Exit ; Kill Thread
.parent:
[global GetCPUNum]
GetCPUNum:
xor eax, eax
- ltr ax
+ str ax
sub ax, 0x30
shr ax, 3 ; ax /= 8
ret
; Usermode code exported by the kernel
[section .usertext]
+; Export a place for the user to jump to to call a syscall
+; - Allows the kernel to change the method easily
+User_Syscall:
+ xchg bx, bx
+ int 0xAC
+
+; A place to return to and exit
User_Syscall_RetAndExit:
push eax
call User_Syscall_Exit