55 lines
1.3 KiB
C++

#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));
}