X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86_64%2Fdesctab.asm;h=411cea3e83079fb85321e6d3dc11a0f53032ea0c;hb=cfcbb03e9b8d5f24069a212330075540161c8be0;hp=838f67e6f783ba0f5e9291220d59819456fe89f9;hpb=eecce4b7a55315f6c385ad8be35c25dbb12d43d8;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm index 838f67e6..411cea3e 100644 --- a/Kernel/arch/x86_64/desctab.asm +++ b/Kernel/arch/x86_64/desctab.asm @@ -3,6 +3,10 @@ ; [BITS 64] +[extern Log] +[extern gGDTPtr] +[extern gGDT] + %define NUM_IRQ_CALLBACKS 4 MM_LOCALAPIC equ 0xFFFFFD0000000000 @@ -55,15 +59,15 @@ Desctab_Init: ; Set an IDT entry to a callback %macro SETIDT 2 mov rax, %2 - mov WORD [rdi + %1*16], ax + mov WORD [rdi + %1*16], ax shr rax, 16 - mov WORD [rdi + %1*16 + 6], ax + mov WORD [rdi + %1*16 + 6], ax shr rax, 16 mov DWORD [rdi + %1*16 + 8], eax ; Enable - mov ax, WORD [rdi + %1*16 + 4] - or ax, 0x8000 - mov WORD [rdi + %1*16 + 4], ax + mov ax, WORD [rdi + %1*16 + 4] + or ax, 0x8000 + mov WORD [rdi + %1*16 + 4], ax %endmacro ; Install error handlers @@ -78,42 +82,49 @@ Desctab_Init: %endrep ; Install IRQs - %macro SETIRQ 1 - SETIDT 0xF0+%1, Irq%1 - %endmacro - - %assign i 0 - %rep 16 - SETIRQ i - %assign i i+1 - %endrep + SETIDT 0xF0, SchedulerIRQ + SETIDT 0xF1, Irq1 + SETIDT 0xF2, Irq2 + SETIDT 0xF3, Irq3 + SETIDT 0xF4, Irq4 + SETIDT 0xF5, Irq5 + SETIDT 0xF6, Irq6 + SETIDT 0xF7, Irq7 + SETIDT 0xF8, Irq8 + SETIDT 0xF9, Irq9 + SETIDT 0xFA, Irq10 + SETIDT 0xFB, Irq11 + SETIDT 0xFC, Irq12 + SETIDT 0xFD, Irq13 + SETIDT 0xFE, Irq14 + SETIDT 0xFF, Irq15 ; Remap PIC push rdx ; Save RDX mov dx, 0x20 mov al, 0x11 out dx, al ; Init Command - mov dx, 0x21 + mov dx, 0x21 mov al, 0xF0 out dx, al ; Offset (Start of IDT Range) - mov al, 0x04 + mov al, 0x04 out dx, al ; IRQ connected to Slave (00000100b) = IRQ2 - mov al, 0x01 + mov al, 0x01 out dx, al ; Set Mode - mov al, 0x00 + mov al, 0x00 out dx, al ; Set Mode mov dx, 0xA0 mov al, 0x11 out dx, al ; Init Command - mov dx, 0xA1 + mov dx, 0xA1 mov al, 0xF8 out dx, al ; Offset (Start of IDT Range) - mov al, 0x02 + mov al, 0x02 out dx, al ; IRQ Line connected to master - mov al, 0x01 + mov al, 0x01 out dx, al ; Set Mode - mov dl, 0x00 + mov dl, 0x00 out dx, al ; Set Mode pop rdx @@ -122,8 +133,36 @@ Desctab_Init: mov rax, gIDTPtr lidt [rax] + ; Re-install GDT (in higher address space) + mov rax, gGDTPtr + mov rcx, gGDT + mov QWORD [rax+2], rcx + lgdt [rax] + ; Start interrupts sti + + ; Initialise System Calls (SYSCALL/SYSRET) + ; Set IA32_EFER.SCE + mov ecx, 0xC0000080 + rdmsr + or eax, 1 + wrmsr + ; Set IA32_LSTAR (RIP of handler) + mov ecx, 0xC0000082 ; IA32_LSTAR + mov eax, SyscallStub - 0xFFFFFFFF00000000 + mov edx, 0xFFFFFFFF + wrmsr + ; Set IA32_FMASK (flags mask) + mov ecx, 0xC0000084 + rdmsr + mov eax, 0x202 + wrmsr + ; Set IA32_STAR (Kernel/User CS) + mov ecx, 0xC0000081 + rdmsr + mov edx, 0x8 | (0x18 << 16) ; Kernel CS (and Kernel DS/SS - 8), User CS + wrmsr ret @@ -137,6 +176,7 @@ IRQ_AddHandler: ; RDI - IRQ Number ; RSI - Callback + ; Check for RDI >= 16 cmp rdi, 16 jb .numOK xor rax, rax @@ -144,10 +184,10 @@ IRQ_AddHandler: jmp .ret .numOK: - mov rax, rdi - shr rax, 3+2 + ; Get handler base into RAX + lea rax, [rdi*4] mov rcx, gaIRQ_Handlers - add rax, rcx + lea rax, [rcx+rax*8] ; Find a free callback slot %rep NUM_IRQ_CALLBACKS @@ -164,21 +204,42 @@ IRQ_AddHandler: ; Assign the IRQ Callback .assign: + ; A little bit of debug + push rdi + push rsi + push rax + sub rsp, 8 + mov rcx, rdi ; IRQ Number + mov rdx, rsi ; Callback + mov rsi, rax ; Pointer + mov rdi, csIRQ_Assigned + call Log + add rsp, 8 + pop rax + pop rsi + pop rdi + + ; Assign and return mov [rax], rsi xor rax, rax .ret: ret + +[section .rodata] +csIRQ_Assigned: + db "IRQ %p := %p (IRQ %i)",0 +[section .text] %macro ISR_NOERRNO 1 Isr%1: - push 0 - push %1 + push QWORD 0 + push QWORD %1 jmp ErrorCommon %endmacro %macro ISR_ERRNO 1 Isr%1: - push %1 + push QWORD %1 jmp ErrorCommon %endmacro @@ -224,7 +285,8 @@ ErrorCommon: ;PUSH_FPU ;PUSH_XMM - mov rsi, rsp + mov rdi, rsp + xchg bx, bx call Error_Handler ;POP_XMM @@ -233,7 +295,7 @@ ErrorCommon: pop gs POP_GPR add rsp, 2*8 - iret + iretq %macro DEFIRQ 1 Irq%1: @@ -248,29 +310,39 @@ DEFIRQ i %assign i i+1 %endrep +[global IrqCommon] IrqCommon: PUSH_GPR + push gs + push fs - mov rbx, [rsp+16*8] ; Calculate address - shr rbx, 3+2 ; *8*4 + mov rbx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs) +; xchg bx, bx ; Bochs Magic break (NOTE: will clear the high-bits of RBX) + shl rbx, 2 ; *8*4 mov rax, gaIRQ_Handlers - add rbx, rax + lea rbx, [rax+rbx*8] + ; Check all callbacks + sub rsp, 8 ; Shadow of argument %assign i 0 %rep NUM_IRQ_CALLBACKS + ; Get callback address mov rax, [rbx] - test rax, rax - mov rdi, [rsp+16*8] ; Get IRQ number + test rax, rax ; Check if it exists jz .skip.%[i] - call rax ; 2 Bytes (Op and Mod/RM) + ; Set RDI to IRQ number + mov rdi, [rsp+(16+2+1)*8] ; Get IRQ number + call rax ; Call .skip.%[i]: - add rbx, 8 + add rbx, 8 ; Next! %assign i i+1 %endrep + add rsp, 8 + ; ACK + mov al, 0x20 mov rdi, [rsp+16*8] ; Get IRQ number cmp rdi, 8 - mov al, 0x20 jb .skipAckSecondary mov dx, 0x00A0 out dx, al @@ -278,30 +350,111 @@ IrqCommon: mov dx, 0x0020 out dx, al + pop fs + pop gs POP_GPR - add rsp, 16 - iret + add rsp, 8*2 + ;xchg bx, bx + iretq [extern Proc_Scheduler] +[global SchedulerIRQ] +; +; NOTE: Proc_Scheduler makes assumptions about the stack state when called +; SchedulerIRQ: - ; TODO: Find Current CPU + push 0 ; Error code + push 0 ; IRQNum PUSH_GPR + push gs + push fs ;PUSH_FPU ;PUSH_XMM - xor rsi, rsi - mov rdi, MM_LOCALAPIC+0x20 - mov esi, [rdi] + ; Save Thread Pointer + mov rax, dr0 + push rax + + ; Get the CPU Number + mov rdi, dr1 + ; Call the Scheduler call Proc_Scheduler + ; Restore Thread Pointer + pop rax + mov dr0, rax + + ; Send EOI (To either the APIC or the PIC) + %if USE_MP + test ebx, ebx + jnz .sendEOI + %endif + ; PIC + mov al, 0x20 + out 0x20, al ; ACK IRQ + %if USE_MP + jmp .ret + ; APIC +.sendEOI: + mov eax, DWORD [gpMP_LocalAPIC] + mov DWORD [eax+0x0B0], 0 + %endif +.ret: + ;POP_XMM ;POP_FPU + pop fs + pop gs POP_GPR - iret + add rsp, 2*8 ; Dummy error code and IRQ num + iretq + +[extern ci_offsetof_tThread_KernelStack] +[extern SyscallHandler] +[global SyscallStub] +SyscallStub: + mov rbp, dr0 + mov ebx, [rel ci_offsetof_tThread_KernelStack] + mov rbp, [rbp+rbx] ; Get kernel stack + xchg rbp, rsp ; Swap stacks + + push rbp ; Save User RSP + push rcx ; RIP + push r11 ; RFLAGS + + ; RDI + ; RSI + ; RDX + ; R10 (RCX for non syscall) + ; R8 + ; R9 + sub rsp, (6+2)*8 + mov [rsp+0x00], rax ; Number +; mov [rsp+0x08], rax ; Errno (don't care really) + mov [rsp+0x10], rdi ; Arg1 + mov [rsp+0x18], rsi ; Arg2 + mov [rsp+0x20], rdx ; Arg3 + mov [rsp+0x28], r10 ; Arg4 + mov [rsp+0x30], r8 ; Arg5 + mov [rsp+0x38], r9 ; Arg6 + + mov rdi, rsp + sub rsp, 8 + call SyscallHandler + add rsp, 8 + mov ebx, [rsp+8] ; Get errno + mov rax, [rsp+0] ; Get return + add rsp, (6+2)*8 + + pop r11 + pop rcx + pop rsp ; Change back to user stack + sysret [section .data] gIDT: - times 256 dd 0x00080000, 0x00000E00, 0, 0 ; 64-bit Interrupt Gate, CS = 0x8, IST0 + ; 64-bit Interrupt Gate, CS = 0x8, IST0 (Disabled) + times 256 dd 0x00080000, 0x00000E00, 0, 0 gIDTPtr: dw 256*16-1 dq gIDT