You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
36 lines
1.1 KiB
C++
36 lines
1.1 KiB
C++
#include "idt.h"
|
|
|
|
#include "core_interrupt.h"
|
|
|
|
namespace IDT {
|
|
|
|
// Interrupt Descriptor Table, 8 Byte aligned
|
|
constinit struct InterruptDescriptor idt[256] = {};
|
|
|
|
// Struct used for loading (the address of) the Interrupt Descriptor Table into
|
|
// the IDT-Register
|
|
struct Register {
|
|
uint16_t limit; // Address of the last valid byte (relative to base)
|
|
struct InterruptDescriptor* base;
|
|
explicit Register(uint8_t max = 255) {
|
|
limit = (max + static_cast<uint16_t>(1)) * sizeof(InterruptDescriptor) - 1;
|
|
base = idt;
|
|
}
|
|
} __attribute__((packed));
|
|
|
|
static_assert(sizeof(InterruptDescriptor) == 16,
|
|
"IDT::InterruptDescriptor has wrong size");
|
|
static_assert(sizeof(Register) == 10, "IDT::Register has wrong size");
|
|
static_assert(alignof(decltype(idt)) % 8 == 0, "IDT must be 8 byte aligned!");
|
|
|
|
void load() {
|
|
// Create structure required for writing to idtr and load via lidt
|
|
Register idtr(Core::Interrupt::VECTORS - 1);
|
|
asm volatile("lidt %0\n\t" ::"m"(idtr));
|
|
}
|
|
|
|
void set(Core::Interrupt::Vector vector, InterruptDescriptor descriptor) {
|
|
idt[(uint8_t)vector] = descriptor;
|
|
}
|
|
} // namespace IDT
|