diff options
Diffstat (limited to '')
-rw-r--r-- | kernel/src/interrupt/idt.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/kernel/src/interrupt/idt.c b/kernel/src/interrupt/idt.c new file mode 100644 index 0000000..6df3793 --- /dev/null +++ b/kernel/src/interrupt/idt.c @@ -0,0 +1,108 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> +#include <sys.h> +#include <print.h> +#include <panic.h> + +#include "acpi/acpi.h" +#include "drivers/ps2kb.h" +#include "drivers/ps2mouse.h" +#include "tty/color.h" +#include "idt.h" +#include "pic.h" +#include "tty/term.h" + +static int timer = 0; + +void idt_pic_eoi(uint8_t exception) { + pic_eoi(exception - PIC_REMAP_OFFSET); +} + +void idt_pic_timer(void) { + uint32_t state = term_save(); + term_setfg(VGA_LIGHT_GREEN); + term_setpos(60, 0); + puts(" "); + term_setpos(60, 0); + printk("%d", timer); + timer += 1; + term_load(state); +} + +void idt_pic_keyboard(void) { + ps2kb_recv(); +} + +void idt_pic_mouse(void) { + ps2mouse_recv(); +} + +void idt_exception_handler(uint8_t exception) { + char* msg; + switch(exception) { + case 0x00: + msg = "Division by zero"; + break; + case 0x02: + msg = "NMI"; + break; + case 0x04: + msg = "Overflow"; + break; + case 0x06: + msg = "invalid opcode"; + break; + case 0x08: + msg = "double fault"; + break; + case 0x0A: + msg = "invalid task state segment"; + break; + case 0x0C: + msg = "stack segment fault"; + break; + case 0x0D: + msg = "general protection fault"; + break; + case 0x0E: + msg = "page fault"; + break; + default: + msg = "unknown exception"; + break; + } + panic("E%u: %s", exception, msg); +} + +__attribute__((aligned(0x10))) +static struct IdtEntry idt[256]; +static struct Idtr idtr; +extern void* isr_stub_table[]; + +static void set_descriptor(uint8_t vector, void* isr, uint8_t flags) { + struct IdtEntry* entry = &idt[vector]; + entry->isr_low = (size_t)isr & 0xffff; + entry->kernel_cs = 0x08; + entry->attributes = flags; + entry->isr_high = (size_t)isr >> 16; + entry->_reserved = 0; +} + +void idt_init(void) { + + debugk("Loading IDT"); + + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(struct IdtEntry) * IDT_SIZE - 1; + + for(int i = 0; i < IDT_INTERRUPTS; i++) { + set_descriptor(i, isr_stub_table[i], 0x8e); + } + + __asm__ volatile ("lidt %0" : : "m"(idtr)); + + succek("IDT has been loaded"); +} + |