80 lines
1.8 KiB
C
80 lines
1.8 KiB
C
#include <idt.h>
|
|
#include <asm.h>
|
|
#include <stdio.h>
|
|
|
|
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");
|
|
}
|