- 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.
76 lines
1.8 KiB
C
76 lines
1.8 KiB
C
#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 (;;) ;
|
|
}
|
|
}
|