2024-07-11 08:56:52 +02:00
|
|
|
#include <kernel/tty.h>
|
2024-07-16 22:51:41 +02:00
|
|
|
#include <debugging.h>
|
2024-07-11 08:56:52 +02:00
|
|
|
#include <stdint.h>
|
2024-07-16 22:51:41 +02:00
|
|
|
#include <stddef.h>
|
2024-07-11 08:56:52 +02:00
|
|
|
|
2024-07-16 22:51:41 +02:00
|
|
|
#define NUM_ENTRIES 0
|
2024-07-11 08:56:52 +02:00
|
|
|
|
2024-07-16 22:51:41 +02:00
|
|
|
struct InterruptDescriptor {
|
|
|
|
uint32_t offset;
|
|
|
|
uint32_t selector;
|
|
|
|
uint8_t gate_type;
|
|
|
|
uint8_t ring;
|
|
|
|
bool present;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct IDT {
|
|
|
|
uint16_t size;
|
|
|
|
uint64_t* base;
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
|
|
|
static uint64_t entries[NUM_ENTRIES];
|
|
|
|
static size_t current_entry = 0;
|
|
|
|
struct IDT idt;
|
|
|
|
|
|
|
|
static void encodeIdtEntry(uint8_t *target, struct InterruptDescriptor source)
|
|
|
|
{
|
|
|
|
// Encode the present bit
|
|
|
|
if (source.present) {
|
|
|
|
target[5] |= 0xF0;
|
|
|
|
} else {
|
|
|
|
// Not present, return
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Encode the offset
|
|
|
|
target[0] = (source.offset >> 0x00) & 0xFF;
|
|
|
|
target[1] = (source.offset >> 0x08) & 0xFF;
|
|
|
|
target[6] = (source.offset >> 0x10) & 0xFF;
|
|
|
|
target[7] = (source.offset >> 0x18) & 0xFF;
|
|
|
|
|
|
|
|
// Encode the base
|
|
|
|
target[2] = (source.selector >> 0x00) & 0xFF;
|
|
|
|
target[3] = (source.selector >> 0x08) & 0xFF;
|
|
|
|
|
|
|
|
// Encode the gate type
|
|
|
|
target[5] |= source.gate_type;
|
|
|
|
|
|
|
|
// Encode the DPL
|
|
|
|
target[5] |= (source.ring >> 5);
|
|
|
|
|
|
|
|
print_hex_bytes(target, 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void add_entry(struct InterruptDescriptor entry)
|
|
|
|
{
|
|
|
|
if (current_entry == NUM_ENTRIES) {
|
|
|
|
terminal_writestring("WARNING: More IDT entries than NUM_ENTRIES.\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t descriptor = 0;
|
|
|
|
encodeIdtEntry((uint8_t*) &descriptor, entry);
|
|
|
|
|
|
|
|
entries[current_entry] = descriptor;
|
|
|
|
|
|
|
|
current_entry++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void load_idt()
|
2024-07-11 08:56:52 +02:00
|
|
|
{
|
2024-07-16 22:51:41 +02:00
|
|
|
idt.size = NUM_ENTRIES * 8 - 1;
|
|
|
|
idt.base = entries;
|
|
|
|
|
|
|
|
for (int i = 0; i < NUM_ENTRIES; i++) {
|
|
|
|
print_hex_bytes(idt.base + i, 8);
|
|
|
|
terminal_putchar('\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
asm ( "lidt %0" : : "m"(idt) );
|
2024-07-11 08:56:52 +02:00
|
|
|
}
|
|
|
|
|
2024-07-16 22:51:41 +02:00
|
|
|
void idt_init()
|
2024-07-11 08:56:52 +02:00
|
|
|
{
|
2024-07-16 22:51:41 +02:00
|
|
|
terminal_writestring("TODO: Add interrupts");
|
|
|
|
terminal_putchar('\n');
|
|
|
|
|
|
|
|
// load_idt();
|
2024-07-11 08:56:52 +02:00
|
|
|
}
|