nadir-kernel/kernel/arch/x86_64/isr.asm

107 lines
2.5 KiB
NASM

; Nadir exception stubs: vectors 0-31 -> exception_handler.
;
; Runs in 64-bit long mode at Ring 0 (CPL 0). Entered by the CPU with
; IF cleared (interrupt gate); no privilege change, so the CPU pushed
; RIP/CS/RFLAGS plus an error code only on vectors 8, 10-14, 17, 21.
; Fault behavior: a fault here (before the IDT is loaded, or inside the
; handler) triple-faults. Never returns: the C handler halts.
;
; Contract with include/idt.h `struct interrupt_frame`: each stub leaves
; [vector, error] on the stack (pushing a dummy 0 where the CPU did not),
; then isr_common pushes the 15 GPRs and calls the C handler with RDI
; pointing at the frame. Field order must stay in sync. Interrupts stay
; disabled; -mno-red-zone makes the pushes safe.
bits 64
section .text
global isr_stub_table
extern exception_handler
; Vectors without a CPU error code: normalize with a dummy 0.
%macro ISR_NOERR 1
global isr_stub_%1
isr_stub_%1:
push 0
push %1
jmp isr_common
%endmacro
; Vectors where the CPU already pushed an error code: only push the vector.
%macro ISR_ERR 1
global isr_stub_%1
isr_stub_%1:
push %1
jmp isr_common
%endmacro
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
ISR_NOERR 3
ISR_NOERR 4
ISR_NOERR 5
ISR_NOERR 6
ISR_NOERR 7
ISR_ERR 8
ISR_NOERR 9
ISR_ERR 10
ISR_ERR 11
ISR_ERR 12
ISR_ERR 13
ISR_ERR 14
ISR_NOERR 15
ISR_NOERR 16
ISR_ERR 17
ISR_NOERR 18
ISR_NOERR 19
ISR_NOERR 20
ISR_ERR 21
ISR_NOERR 22
ISR_NOERR 23
ISR_NOERR 24
ISR_NOERR 25
ISR_NOERR 26
ISR_NOERR 27
ISR_NOERR 28
ISR_NOERR 29
ISR_NOERR 30
ISR_NOERR 31
; Common entry: save GPRs, call void exception_handler(frame in RDI), halt
; if it ever returns (it must not).
isr_common:
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
mov rdi, rsp
call exception_handler
; Unreachable in practice; park the CPU if the handler returns.
cli
.hang:
hlt
jmp .hang
section .rodata
align 8
isr_stub_table:
dq isr_stub_0, isr_stub_1, isr_stub_2, isr_stub_3
dq isr_stub_4, isr_stub_5, isr_stub_6, isr_stub_7
dq isr_stub_8, isr_stub_9, isr_stub_10, isr_stub_11
dq isr_stub_12, isr_stub_13, isr_stub_14, isr_stub_15
dq isr_stub_16, isr_stub_17, isr_stub_18, isr_stub_19
dq isr_stub_20, isr_stub_21, isr_stub_22, isr_stub_23
dq isr_stub_24, isr_stub_25, isr_stub_26, isr_stub_27
dq isr_stub_28, isr_stub_29, isr_stub_30, isr_stub_31