From a8d11e5a35d4694cabcdf001ef659d3dd090a9e6 Mon Sep 17 00:00:00 2001 From: "Pierre-Emmanuel Gob." Date: Fri, 18 Sep 2026 12:01:24 +0200 Subject: [PATCH] Wrote Nadir interrupt IDT + CPU exception entry points --- include/idt.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 include/idt.h diff --git a/include/idt.h b/include/idt.h new file mode 100644 index 0000000..5b31dd7 --- /dev/null +++ b/include/idt.h @@ -0,0 +1,66 @@ +/* Nadir interrupt IDT + CPU exception entry points. + * + * Runs in 64-bit long mode at Ring 0 (CPL 0) with the stage-2 GDT. + * Privileged primitive: `lidt` in idt_init(). Fault behavior: before + * idt_init() any exception triple-faults (no IDT); after, CPU vectors + * 0-31 land in the assembly stubs (isr.asm) and then in + * exception_handler(), which prints and halts. Vectors 32-255 are left + * zero (not present) on purpose because PIC remap + IRQ handling is a later step. + * Interrupts stay disabled throughout (IF=0); exceptions still fire. + */ + +#ifndef NADIR_IDT_H +#define NADIR_IDT_H + +#include + +/* Number of CPU exception vectors this base installs (0-31). */ +#define IDT_EXCEPTION_COUNT 32 + +/* Stack layout on entry to exception_handler(). + * + * Built by the CPU (RIP/CS/RFLAGS, plus an error code on vectors + * 8, 10-14, 17, 21) plus isr.asm: the stub normalizes the stack to + * [vector, error] and isr_common pushes the 15 general-purpose + * registers. RDI points at this struct (System V first argument). + * Field order matches the push order in isr_common — keep in sync. + */ +struct interrupt_frame { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rbp; + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t rbx; + uint64_t rax; + /* Pushed by the stub: exception vector 0-31. */ + uint64_t vector; + /* CPU-pushed error code, or 0 inserted by the stub. */ + uint64_t error; + /* Pushed by the CPU. */ + uint64_t rip; + uint64_t cs; + uint64_t rflags; + /* Pushed by the CPU only on a privilege change; garbage for + * kernel-mode faults */ + uint64_t rsp; + uint64_t ss; +}; + +/* Build the IDT (vectors 0-31 -> isr stubs) and load it with `lidt`. + * Ring 0 only. Leaves IF cleared; returns with exceptions catchable. */ +void idt_init(void); + +/* C entry point for vectors 0-31, called from isr_common with the + * frame above. Prints vector/error/RIP and halts; never returns. */ +void exception_handler(struct interrupt_frame *frame); + +#endif /* NADIR_IDT_H */