Kernel - Bugfixing x86_64 port
[tpg/acess2.git] / Kernel / arch / x86_64 / desctab.asm
index d49dbc4..8212773 100644 (file)
@@ -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,7 +82,7 @@ Desctab_Init:
        %endrep
        
        ; Install IRQs
-       SETIDT  0xF0, Irq0
+       SETIDT  0xF0, SchedulerIRQ
        SETIDT  0xF1, Irq1
        SETIDT  0xF2, Irq2
        SETIDT  0xF3, Irq3
@@ -100,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
        
@@ -129,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
        
@@ -144,6 +154,7 @@ IRQ_AddHandler:
        ; RDI - IRQ Number
        ; RSI - Callback
        
+       ; Check for RDI >= 16
        cmp rdi, 16
        jb .numOK
        xor rax, rax
@@ -151,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
@@ -171,11 +182,32 @@ 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:
@@ -259,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
@@ -273,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
@@ -291,28 +328,63 @@ IrqCommon:
        mov dx, 0x0020
        out dx, al
        
+       pop fs
+       pop gs
        POP_GPR
        add rsp, 8*2
-       xchg bx, bx
+       ;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
-       add rsp, 8*2
+       add rsp, 2*8    ; Dummy error code and IRQ num
        iretq
 
 [section .data]

UCC git Repository :: git.ucc.asn.au