;
[BITS 64]
+[extern Log]
+[extern gGDTPtr]
+[extern gGDT]
+
%define NUM_IRQ_CALLBACKS 4
MM_LOCALAPIC equ 0xFFFFFD0000000000
[section .text]
[global Desctab_Init]
-Desctab_Init:
- ; Install IDT
- mov rax, gIDTPtr
- lidt [rax]
-
+Desctab_Init:
; Save to make following instructions smaller
mov rdi, gIDT
; 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
+ 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
%endrep
; Install IRQs
- %macro SETIRQ 2
- SETIDT %2, Irq%1
- %endmacro
+ 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 al, 0xF0
+ out dx, al ; Offset (Start of IDT Range)
+ mov al, 0x04
+ out dx, al ; IRQ connected to Slave (00000100b) = IRQ2
+ mov al, 0x01
+ out dx, al ; Set Mode
+ mov al, 0x00
+ out dx, al ; Set Mode
- %assign i 0
- %rep 16
- SETIRQ i, 0xF0+i
- %assign i i+1
- %endrep
+ mov dx, 0xA0
+ mov al, 0x11
+ out dx, al ; Init Command
+ mov dx, 0xA1
+ mov al, 0xF8
+ out dx, al ; Offset (Start of IDT Range)
+ mov al, 0x02
+ out dx, al ; IRQ Line connected to master
+ mov al, 0x01
+ out dx, al ; Set Mode
+ mov dl, 0x00
+ out dx, al ; Set Mode
+ pop rdx
- ; Remap PIC
+
+ ; Install IDT
+ 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
ret
; 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
+
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
ISR_NOERRNO 30; 30: Reserved
ISR_NOERRNO 31; 31: Reserved
+[extern Error_Handler]
+[global ErrorCommon]
ErrorCommon:
+ PUSH_GPR
+ push gs
+ push fs
+ ;PUSH_FPU
+ ;PUSH_XMM
+
+ mov rdi, rsp
+ xchg bx, bx
+ call Error_Handler
+
+ ;POP_XMM
+ ;POP_FPU
+ pop fs
+ pop gs
+ POP_GPR
add rsp, 2*8
- iret
+ iretq
%macro DEFIRQ 1
Irq%1:
%assign i i+1
%endrep
+[global IrqCommon]
IrqCommon:
PUSH_GPR
mov rax, gaIRQ_Handlers
add rbx, rax
+ ; Check all callbacks
%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*8] ; Get IRQ number
+ call rax ; Call
.skip.%[i]:
- add rbx, 8
+ add rbx, 8 ; Next!
%assign i i+1
%endrep
+ ; ACK
mov rdi, [rsp+16*8] ; Get IRQ number
cmp rdi, 8
mov al, 0x20
out dx, al
POP_GPR
- add rsp, 16
- iret
+ add rsp, 8*2
+ ;xchg bx, bx
+ iretq
[extern Proc_Scheduler]
+[global SchedulerIRQ]
SchedulerIRQ:
- ; TODO: Find Current CPU
PUSH_GPR
;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_GPR
- iret
+ iretq
[section .data]
gIDT:
- times 256 dd 0x00080000, 0x00008E00, 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