summaryrefslogtreecommitdiff
path: root/src/idt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idt.c')
-rw-r--r--src/idt.c110
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;
+}