# Interrupt Subsystem ## Overview The interrupt subsystem handles both CPU exceptions (faults, traps, aborts) and hardware interrupts (IRQs) from external devices. It consists of three cooperating components: 1. **IDT (Interrupt Descriptor Table)** — Maps interrupt vectors 0–255 to handler entry points. 2. **ISR (Interrupt Service Routines)** — Assembly stubs and a C dispatcher that routes interrupts. 3. **PIC (Programmable Interrupt Controller)** — Manages the 8259A PIC chips that multiplex hardware IRQs onto CPU interrupt lines. ## Architecture ### Interrupt Vector Layout | Vector Range | Purpose | |---|---| | 0–31 | CPU exceptions (Division by Zero, Page Fault, GPF, etc.) | | 32–47 | Hardware IRQs (remapped from default 0–15) | | 48–255 | Available for software interrupts / future use | ### Flow of an Interrupt 1. CPU or device raises an interrupt. 2. CPU looks up the vector in the IDT and jumps to the assembly stub. 3. The stub pushes a dummy error code (if the CPU didn't push one), the interrupt number, and all general-purpose registers onto the stack. 4. The stub loads the kernel data segment (0x10) and calls `isr_handler()` in C. 5. For hardware interrupts (vectors 32–47), `isr_handler` sends an End-of-Interrupt (EOI) to the PIC. 6. For CPU exceptions (vectors 0–31), the handler prints the exception name and halts. 7. On return, the stub restores all registers and executes `iret`. ### PIC Remapping The 8259A PIC ships with IRQ 0–7 mapped to vectors 8–15, which collide with CPU exceptions. During initialization, we remap: - **Master PIC** (IRQ 0–7) → vectors 32–39 - **Slave PIC** (IRQ 8–15) → vectors 40–47 The PIC is initialized in cascade mode with ICW4 (8086 mode). Original IRQ masks are saved and restored after remapping. ## Key Files - `src/idt.c` / `src/idt.h` — IDT setup and gate registration. - `src/interrupts.S` — Assembly stubs for ISRs 0–31 and IRQs 0–15. - `src/isr.c` / `src/isr.h` — C interrupt dispatcher and `registers_t` structure. - `src/pic.c` / `src/pic.h` — PIC initialization, EOI, mask/unmask. - `src/port_io.h` — Inline `inb`, `outb`, `io_wait` helpers. ## Register Save Frame When an interrupt fires, the following is pushed onto the stack (from high to low address): ``` ss, useresp (only on privilege change) eflags cs, eip (pushed by CPU) err_code (pushed by CPU or stub as 0) int_no (pushed by stub) eax..edi (pushed by pusha) ds (pushed by stub) ``` This matches the `registers_t` struct in `isr.h`.