Implement ISR stubs and PIC driver for hardware interrupt handling (AI)

- Reworked IDT initialization to register all 32 CPU exception handlers (ISR 0-31)
  and 16 hardware interrupt handlers (IRQ 0-15, mapped to IDT entries 32-47).
- Created assembly stubs in interrupts.S using macros for ISRs with and without
  error codes, plus IRQ stubs. All route through a common stub that saves
  registers, loads kernel data segment, and calls the C handler.
- Added isr.c with a unified interrupt dispatcher that handles both exceptions
  (halts on fault) and hardware IRQs (sends EOI via PIC).
- Implemented PIC (8259) driver in pic.c with full initialization sequence that
  remaps IRQ 0-7 to IDT 32-39 and IRQ 8-15 to IDT 40-47. Includes mask/unmask
  and EOI support.
- Extracted port I/O primitives (inb, outb, io_wait) into port_io.h header for
  reuse across drivers.
- Kernel now initializes PIC after IDT and enables interrupts with STI.
This commit is contained in:
AI
2026-02-23 10:51:45 +00:00
parent 3909a1f581
commit f1923fdbcf
9 changed files with 475 additions and 42 deletions

75
src/isr.c Normal file
View File

@@ -0,0 +1,75 @@
#include "isr.h"
#include "pic.h"
#include <stdint.h>
/* Forward declaration for kernel panic or similar */
void offset_print(const char *str);
void print_hex(uint32_t val);
/* Exception messages */
char *exception_messages[] = {
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Into Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void isr_handler(registers_t *regs)
{
// If it's a hardware interrupt (IRQ), we must acknowledge it
if (regs->int_no >= 32 && regs->int_no < 48) {
// Send EOI to PIC (IRQ number 0-15)
pic_send_eoi(regs->int_no - 32);
// Here we would call the registered handler for this IRQ
// For now, just print something for the timer tick so we know it works,
// but limit it to avoid flooding the log.
if (regs->int_no == 32) {
// Timer tick - do nothing verbose
// offset_print(".");
} else if (regs->int_no == 33) {
// Keyboard
offset_print("Keyboard IRQ!\n");
}
return;
}
offset_print("received interrupt: ");
print_hex(regs->int_no);
offset_print("\n");
if (regs->int_no < 32)
{
offset_print(exception_messages[regs->int_no]);
offset_print(" Exception. System Halted!\n");
for (;;) ;
}
}