#define MODULE "idt" #include "interrupts/IDT.h" #include "assert.h" #include "log/Log.h" struct IDTEntry { uint16_t offset0; uint16_t selector; uint8_t ist; uint8_t type_attr; uint16_t offset1; uint32_t offset2; uint32_t ignore; void set_offset(uint64_t offset); uint64_t get_offset(); }; static IDTEntry entries[256]; void IDTEntry::set_offset(uint64_t offset) { offset0 = (uint16_t)(offset & 0x000000000000ffff); offset1 = (uint16_t)((offset & 0x00000000ffff0000) >> 16); offset2 = (uint32_t)((offset & 0xffffffff00000000) >> 32); } uint64_t IDTEntry::get_offset() { uint64_t offset = 0; offset |= (uint64_t)offset0; offset |= (uint64_t)offset1 << 16; offset |= (uint64_t)offset2 << 32; return offset; } void IDT::add_handler(short interrupt_number, void* handler, uint8_t type_attr) { ASSERT(handler != nullptr); ASSERT(interrupt_number < 256); IDTEntry* entry_for_handler = &entries[interrupt_number]; entry_for_handler->selector = 0x08; entry_for_handler->type_attr = type_attr; entry_for_handler->set_offset((uint64_t)handler); } IDTR idtr; void IDT::load() { idtr.limit = 0x0FFF; idtr.offset = (uint64_t)entries; kdbgln("Loading IDT at offset %lx, limit %d", idtr.offset, idtr.limit); asm("lidt %0" : : "m"(idtr)); }