#include <stdint.h>
#include "module.h"
#include "idt.h"
extern void vga_write(const char*);
struct idt_entry idt[IDT_ENTRIES];
struct idt_ptr idt_descriptor;
static inline void lidt(struct idt_ptr* p) {
asm volatile ("lidt (%0)" : : "r"(p));
}
static void (*irq_handlers[IDT_ENTRIES])(void) = {0};
void register_irq(int irq, void (*handler)(void)) {
if (irq >= 0 && irq < IDT_ENTRIES) {
irq_handlers[irq] = handler;
}
}
void idt_init(void) {
for (int i = 0; i < IDT_ENTRIES; ++i) {
uint64_t addr = (uint64_t)isr_handler_common;
idt[i].offset_low = addr & 0xFFFF;
idt[i].selector = 0x08;
idt[i].ist = 0;
idt[i].type_attr = 0x8E;
idt[i].offset_mid = (addr >> 16) & 0xFFFF;
idt[i].offset_high = (addr >> 32) & 0xFFFFFFFF;
idt[i].zero = 0;
}
idt_descriptor.limit = sizeof(idt) - 1;
idt_descriptor.base = (uint64_t)&idt;
lidt(&idt_descriptor);
vga_write("IDT initialized\n");
}
extern void isr_handler_common(void);
void isr_c_handler(uint64_t int_no) {
char buf[32];
int len = 0;
uint64_t n = int_no;
if (n == 0) {
buf[len++] = '0';
} else {
char rev[32];
int rev_len = 0;
while (n > 0 && rev_len < 32) {
rev[rev_len++] = '0' + (n % 10);
n /= 10;
}
while (rev_len > 0) {
buf[len++] = rev[--rev_len];
}
}
buf[len++] = '\n';
buf[len] = 0;
vga_write(buf);
if (int_no < IDT_ENTRIES && irq_handlers[int_no]) {
irq_handlers[int_no]();
}
}
void irq_enable(void) { asm volatile ("sti"); }