#include #include #include #include #include #include "idt.h" #include "pic.h" #include "../term.h" #include "../panic.h" #include "../drivers/ps2kb.h" #include "../drivers/ps2ctrl.h" static int timer = 0; void idt_pic_generic(uint8_t exception) { pic_eoi(exception - PIC_REMAP_OFFSET); } void idt_pic_timer(void) { uint32_t state = term_save(); term_setcol(0x0a); term_setpos(60, 0); puts(" "); term_setpos(60, 0); printf("%d", timer); term_flush(); timer += 1; term_load(state); } void idt_pic_keyboard(void) { ps2kb_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) { 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)); }