#include "idt.h" #define outb(port, value) asm volatile("out %b0,%w1" : : "a" (value), "d" (port)); #define isr_panic(num) void isr_ ## num(); \ asm( \ ".globl isr_" #num "\n" \ "isr_" #num ":\n" \ "push $" #num "\n" \ "call panic\n" \ "iret\n" \ ) char* panic_msg[] = { [0] = "Divide error.", [8] = "Double fault.", [14] = "Page fault." }; isr_panic(0); isr_panic(8); isr_panic(14); void panic(uint32_t num) { char* str = panic_msg[num]; while(*str) { outb(0x3f8, *str++); } outb(0x3f8, '\r'); outb(0x3f8, '\n'); asm volatile( "cli\n" "hlt\n" ); while(1); } idt_entry idt[] = { {.base_low = 1}, // Keep IDT in .data. [1 ... 255] = idt_entry_null }; idt_ptr idtr = { .base = idt, .limit = sizeof(idt) - 1 }; void idt_set_gate(uint8_t num, uint32_t base, uint16_t segment, uint16_t flags) { idt[num].base_low = base & 0xffff; idt[num].base_high = base >> 16 & 0xffff; idt[num].segment = segment; idt[num].flags = flags; } void idt_init() { idt_set_gate(0, (uint32_t)isr_0, 0x08, 0x8e00); idt_set_gate(8, (uint32_t)isr_8, 0x08, 0x8e00); idt_set_gate(14, (uint32_t)isr_14, 0x08, 0x8e00); asm volatile( "lidt (%0)\n" : : "r" (&idtr) ); }