diff options
Diffstat (limited to 'src/idt.c')
-rw-r--r-- | src/idt.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/idt.c b/src/idt.c new file mode 100644 index 0000000..a78847d --- /dev/null +++ b/src/idt.c @@ -0,0 +1,110 @@ +#include <stdbool.h> +#include <idt.h> +#include <vga.h> +#include <mem.h> + +extern void idt_load(); + +struct idt_entry { + uint16_t offset_low; + uint16_t sel; + uint8_t ist; + uint8_t flags; + uint16_t offset_middle; + uint32_t offset_high; + uint32_t reserved; +} __attribute__((packed)); + +struct idt { + uint16_t limit; + uint64_t base; +} __attribute__((packed)); + +struct idt_entry idt[256]; +struct idt idt_ptr; +static void (*handlers[256])(uint64_t, uint64_t) = { 0 }; +static const char *exception_msg[] = { + "Division By Zero Exception", + "Debug Exception", + "Non Maskable Interrupt Exception", + "Breakpoint Exception", + "Into Detected Overflow Exception", + "Out of Bounds Exception", + "Invalid Opcode Exception", + "No Coprocessor Exception", + "Double Fault Exception", + "Coprocessor Segment Overrun Exception", + "Bad TSS Exception", + "Segment Not Present Exception", + "Stack Fault Exception", + "General Protection Fault Exception", + "Page Fault Exception", + "Unknown Interrupt Exception", + "Coprocessor Fault Exception", + "Alignment Check Exception (486+)", + "Machine Check Exception (Pentium/586+)", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", + "Reserved Exceptions", +}; + + +void exception_handler(uint64_t num, uint64_t error) { + vga_puts("\n\neto bleh: "); + vga_puts(exception_msg[num]); + vga_puts("\nerror info: "); + vga_putx(error); + while (1); +} + +void interrupt_handler(uint64_t num, uint64_t data) { + handlers[num](num, data); +} + +void idt_set_isr(uint8_t num, uint64_t offset, uint16_t sel, uint8_t flags) { + idt[num] = (struct idt_entry) { + .offset_low = offset & 0xFFFF, + .offset_middle = (offset >> 16) & 0xFFFF, + .offset_high = (offset >> 32) & 0xFFFFFFFF, + .sel = sel, + .ist = 0, + .flags = flags, + .reserved = 0, + }; +} + +void idt_init() { + idt_ptr.limit = (sizeof(struct idt_entry) * 256) - 1; + idt_ptr.base = (uint64_t) &idt; + memset(idt, 0, (sizeof(struct idt_entry) * 256)); + idt_load(); + + for (size_t i = 0; i < 32; i++) { + idt_set_isr(i, isr_table[i], 0x08, 0x8E); + handlers[i] = exception_handler; + } +} + +bool idt_register_isr(size_t num, void (*func)(uint64_t, uint64_t)) { + if (handlers[num]) + return false; + handlers[num] = func; + return true; +} + +bool idt_remove_isr(size_t num, void (*func)(uint64_t, uint64_t)) { + if (handlers[num] != func) + return false; + handlers[num] = NULL; + return true; +} |