X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fproc.asm;h=944b24dd4d5cd16cdd825515b5b8ca365df7a8fd;hb=3764c294f21229bdf700f436fa4884f5e76e0d3a;hp=bcb0f586fefe241eb643482ff7bf124c60acb84d;hpb=43be77083eba1fc5b11b46deddcf499bac054d6e;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/proc.asm b/Kernel/arch/x86/proc.asm index bcb0f586..944b24dd 100644 --- a/Kernel/arch/x86/proc.asm +++ b/Kernel/arch/x86/proc.asm @@ -8,9 +8,10 @@ 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] +[extern Isr240.jmp] [global SetAPICTimerCount] SetAPICTimerCount: pusha @@ -27,7 +28,7 @@ SetAPICTimerCount: mov eax, [gpMP_LocalAPIC] mov ecx, [eax+0x320] - test ecx, 0x0001000 + 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) @@ -39,22 +40,28 @@ SetAPICTimerCount: sub ecx, [eax+0x390] mov DWORD [giMP_TimerCount], ecx ; Disable APIC Timer - mov DWORD [eax+0x320], 0x00010000 + mov DWORD [eax+0x320], 0x000100EF + mov DWORD [eax+0x380], 0 ; Update Timer IRQ to the IRQ code mov eax, SchedulerBase - sub eax, Isr240+5+5+1 - mov DWORD [Isr240+5+5+1], eax + 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 ; -------------- @@ -67,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 + %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 CPU Number (thread is poped later) + + %if USE_MP + test ebx, ebx + jnz .sendEOI + %endif - add esp, 4 ; Remove Argument + 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 @@ -110,9 +146,10 @@ 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 @@ -120,19 +157,24 @@ SpawnTask: .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 ; @@ -174,10 +216,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 @@ -187,10 +229,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 @@ -199,19 +242,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