#include <shade/platform/interrupts/idt.h>

void idt_set_gate(uint8_t index, void* isr, uint8_t flags) {
    idt_descriptor_t* descriptor = &idt[index];

    descriptor->isr_low        = (uint64_t)isr & 0xFFFF;
    descriptor->kernel_cs      = KERNEL_CODE;
    descriptor->ist            = 0;
    descriptor->attributes     = flags;
    descriptor->isr_mid        = ((uint64_t)isr >> 16) & 0xFFFF;
    descriptor->isr_high       = ((uint64_t)isr >> 32) & 0xFFFFFFFF;
    descriptor->reserved       = 0;
}

void idt_assemble() {
    idt_ptr.base = (uintptr_t)&idt[0];
    idt_ptr.limit = (uint16_t)sizeof(idt_descriptor_t) * IDT_DESCRIPTORS - 1;

    for (uint8_t vector = 0; vector < 47; vector++) {
        idt_set_gate(vector, isr_stub_table[vector], 0x8E);
        vectors[vector] = true;
    }

    __asm__ __volatile__ ("lidt %0" : : "m"(idt_ptr));
    idt_enable_interrupts();
}

void idt_enable_interrupts() {
    __asm__ __volatile__("sti");
}
void idt_disable_interrupts() {
    __asm__ __volatile__("cli");
}