#include "idt.h" #include "stddef.h" static struct idtEntry idt[IDT_NUM]; int idtSetup() { struct idtRegister idtr; for (int i = 0; i < IDT_NUM; i++) { struct idtEntry *idte = idt + i; /* Setup an empty IDTE interrupt gate, see figure 5-2 in Intel x86 doc, vol 3 */ idte->seg_sel = BUILD_SEGMENT_SELECTOR(RING_0, 0, SEGMENT_IDX_CODE); idte->reserved = 0; idte->flags = 0; idte->type = 0x6; /* Interrupt gate (110b) */ idte->op_size = 1; /* 32bits instructions */ /* Disabled it for now */ idte->zero = 0; idte->offset_low = 0; idte->offset_high = 0; idte->dpl = 0; idte->present = 0; } /* * Setup the IDT register, see Intel x86 doc vol 3, section 5.8. */ /* Address of the IDT */ idtr.base_addr = (uint32_t)idt; /* The limit is the maximum offset in bytes from the base address of the IDT */ idtr.limit = sizeof(idt) - 1; /* Commit the IDT into the CPU */ asm volatile("lidt %0\n" ::"m"(idtr) : "memory"); return 0; } int idt_set_handler(int index, unsigned int addr, int priviledge) { struct idtEntry *idte; if (index < 0 || index >= IDT_NUM) return -1; if ((priviledge < 0) || priviledge > 3) return -1; idte = idt + index; if (addr != (unsigned int)NULL) { idte->offset_low = addr & 0xffff; idte->offset_high = (addr >> 16) & 0xffff; idte->dpl = priviledge; idte->present = 1; } else { idte->offset_low = 0; idte->offset_high = 0; idte->dpl = 0; idte->present = 0; } return 0; }