X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86_64%2Fdesctab.asm;h=8212773b5b81468a9dbe35614ab9ac5bc9371b1f;hb=98d45a155c3ce437d0eddb67b9eb2b203f87ec3b;hp=cf1b0f614540eb94648c26c386200c82c343ab7c;hpb=f5f082502f5aeaa144a6ff60ad331e23957b0bbb;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm index cf1b0f61..8212773b 100644 --- a/Kernel/arch/x86_64/desctab.asm +++ b/Kernel/arch/x86_64/desctab.asm @@ -4,6 +4,8 @@ [BITS 64] [extern Log] +[extern gGDTPtr] +[extern gGDT] %define NUM_IRQ_CALLBACKS 4 @@ -57,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 @@ -80,7 +82,7 @@ Desctab_Init: %endrep ; Install IRQs - SETIDT 0xF0, Irq0 + SETIDT 0xF0, SchedulerIRQ SETIDT 0xF1, Irq1 SETIDT 0xF2, Irq2 SETIDT 0xF3, Irq3 @@ -102,27 +104,27 @@ Desctab_Init: 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 @@ -131,6 +133,12 @@ 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 @@ -146,6 +154,7 @@ IRQ_AddHandler: ; RDI - IRQ Number ; RSI - Callback + ; Check for RDI >= 16 cmp rdi, 16 jb .numOK xor rax, rax @@ -153,10 +162,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 @@ -188,6 +197,7 @@ IRQ_AddHandler: pop rsi pop rdi + ; Assign and return mov [rax], rsi xor rax, rax @@ -281,13 +291,17 @@ DEFIRQ i [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 @@ -295,17 +309,18 @@ IrqCommon: test rax, rax ; Check if it exists jz .skip.%[i] ; Set RDI to IRQ number - mov rdi, [rsp+16*8] ; Get IRQ number + mov rdi, [rsp+(16+2+1)*8] ; Get IRQ number call rax ; Call .skip.%[i]: 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 @@ -313,6 +328,8 @@ IrqCommon: mov dx, 0x0020 out dx, al + pop fs + pop gs POP_GPR add rsp, 8*2 ;xchg bx, bx @@ -320,21 +337,54 @@ IrqCommon: [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 - add rsp, 8*2 + add rsp, 2*8 ; Dummy error code and IRQ num iretq [section .data]