X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fproc.asm;h=1011b53c7624cfe8bde0ec218cebe2f429cd6035;hb=37de13c0c8c88fa6edba679c20becec15547533e;hp=348c31ba4f1f4f58427403f171ccb4334127291d;hpb=ccd6cf2af99fdc050888c70eb4d59f078a15a2da;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/proc.asm b/Kernel/arch/x86/proc.asm index 348c31ba..1011b53c 100644 --- a/Kernel/arch/x86/proc.asm +++ b/Kernel/arch/x86/proc.asm @@ -8,6 +8,60 @@ KERNEL_BASE equ 0xC0000000 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 ; -------------- @@ -20,29 +74,58 @@ SchedulerBase: push fs push gs + pushf + and BYTE [esp+1], 0xFE ; Clear Trap Flag + popf + + mov eax, dr0 + push eax ; Debug Register 0, Current Thread + mov ax, 0x10 mov ds, ax mov es, ax 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 +[global scheduler_return] +scheduler_return: ; Used by some hackery in Proc_DumpThreadCPUState - add esp, 4 ; Remove Argument + add esp, 4 ; Remove CPU Number (thread is poped later) + + %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 eax ; Debug Register 0, Current Thread + mov dr0, eax + 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 + add esp, 4*2 ; CPU ID + Dummy error code ; No Error code / int num iret @@ -52,7 +135,7 @@ SchedulerBase: SpawnTask: ; Call Proc_Clone with Flags=0 xor eax, eax - push eax +; push eax push eax call Proc_Clone add esp, 8 ; Remove arguments from stack @@ -63,27 +146,35 @@ SpawnTask: ; In child, so now set up stack frame mov ebx, [esp+4] ; Child Function mov edx, [esp+8] ; Argument - ; Child + ; Child Function push edx ; Argument call ebx ; Function + ; Kill thread once done + push eax ; Exit Code + push 0 ; Kill this thread call Threads_Exit ; Kill Thread .parent: ret -; +; void Proc_ReturnToUser(void *Method, Uint Parameter) ; Calls a user fault handler ; [global Proc_ReturnToUser] [extern Proc_GetCurThread] Proc_ReturnToUser: - ; EBP is the handler to use + push ebp + mov ebp, esp + ; [EBP+8]: handler to use + ; [EBP+12]: parameter + ; [EBP+16]: kernel stack top - call Proc_GetCurThread + ;call Proc_GetCurThread ; EAX is the current thread - mov ebx, eax - mov eax, [ebx+40] ; Get Kernel Stack + ;mov ebx, eax + ;mov eax, [ebx+12*4] ; Get Kernel Stack + mov eax, [ebp+16] ; Get Kernel Stack sub eax, KSTACK_USERSTATE_SIZE ; @@ -95,14 +186,10 @@ Proc_ReturnToUser: ; Validate user ESP ; - Page Table mov edx, [eax+KSTACK_USERSTATE_SIZE-12] ; User ESP is at top of kstack - 3*4 - %if USE_PAE - %error PAE Support - %else mov ecx, edx shr ecx, 22 test BYTE [0xFC3F0000+ecx*4], 1 jnz .justKillIt - %endif ; - Page mov ecx, edx shr ecx, 12 @@ -111,13 +198,10 @@ Proc_ReturnToUser: ; Adjust sub edx, 8 ; - Page Table - %if USE_PAE - %else mov ecx, edx shr ecx, 22 test BYTE [0xFC3F0000+ecx*4], 1 jnz .justKillIt - %endif ; - Page mov ecx, edx shr ecx, 12 @@ -125,10 +209,10 @@ Proc_ReturnToUser: jnz .justKillIt ; Get and alter User SP - mov ecx, edx - mov edx, [ebx+60] ; Get Signal Number from TCB - mov [ecx+4], edx ; Parameter (Signal/Error Number) - mov [ecx], DWORD User_Syscall_RetAndExit ; Return Address + mov edi, edx + mov edx, [ebp+12] ; Get parameter + mov [edi+4], edx ; save to user stack + mov [edi], DWORD User_Syscall_RetAndExit ; Return Address ; Restore Segment Registers mov ax, 0x23 @@ -138,10 +222,11 @@ Proc_ReturnToUser: mov gs, ax push 0x23 ; SS - push ecx ; ESP + push edi ; ESP push 0x202 ; EFLAGS (IP and Rsvd) push 0x1B ; CS - push ebp ; EIP + mov eax, [ebp+8] ; Method to call + push eax ; EIP iret @@ -150,19 +235,36 @@ Proc_ReturnToUser: .justKillIt: xor eax, eax xor ebx, ebx - dec ebx + dec ebx ; EBX = -1 int 0xAC [global GetCPUNum] -GetCPUNum: - xor eax, eax - str ax - sub ax, 0x30 - shr ax, 3 ; ax /= 8 +GetCPUNum: ; TODO: Store in debug registers +; xor eax, eax +; str ax +; sub ax, 0x30 +; shr ax, 3 ; ax /= 8 + mov eax, dr1 + ret + +[extern GetEIP] +[global GetEIP_Sched] +[global GetEIP_Sched_ret] +GetEIP_Sched_ret equ GetEIP_Sched.ret +GetEIP_Sched: + call GetEIP +GetEIP_Sched.ret: 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 ; MAGIC BREAKPOINT + int 0xAC + +; A place to return to and exit User_Syscall_RetAndExit: push eax call User_Syscall_Exit