#include #include #include static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance static idtr_t idtr; isr_t interrupt_handlers[256]; void isr_handler(registers_t regs) { if (interrupt_handlers[regs.int_no] != 0) { isr_t handler = interrupt_handlers[regs.int_no]; handler(regs); } else { kprintf("Unhandled interrupt: %d\n", regs.int_no); } } void irq_handler(registers_t regs) { if (regs.int_no >= 40) { outb(0xA0, 0x20); } outb(0x20, 0x20); if (interrupt_handlers[regs.int_no] != 0) { isr_t handler = interrupt_handlers[regs.int_no]; handler(regs); } else { kprintf("Unhandled IRQ interrupt: %d\n", regs.int_no); } } void register_interrupt_handler(uint8_t n, isr_t handler) { interrupt_handlers[n] = handler; } void idt_set_gate(uint8_t num, uint32_t base, uint8_t flags) { idt[num].isr_low = base & 0xFFFF; idt[num].isr_high = (base >> 16) & 0xFFFF; idt[num].kernel_cs = 0x08; idt[num].reserved = 0; idt[num].attributes = flags; } extern void* isr_stub_table[]; extern void* irq_stub_table[]; void idt_init() { idtr.base = (uintptr_t)&idt; idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; for (uint8_t vector = 0; vector < 32; vector++) { idt_set_gate(vector, (uint32_t)isr_stub_table[vector], 0x8E); } extern void idt_flush(uint32_t); idt_flush((uint32_t)&idtr); // Remap the irq table. outb(0x20, 0x11); outb(0xA0, 0x11); outb(0x21, 0x20); outb(0xA1, 0x28); outb(0x21, 0x04); outb(0xA1, 0x02); outb(0x21, 0x01); outb(0xA1, 0x01); outb(0x21, 0x0); outb(0xA1, 0x0); for (uint8_t vector = 32; vector < 48; vector++) { idt_set_gate(vector, (uint32_t)irq_stub_table[vector], 0x8E); } outb(0x21,0xfc); outb(0xa1,0xff); __asm__("sti"); }