#include "idt.h"
#include "util/binary.h"


IDTEntry g_IDT[256];
IDTDescriptor g_IDTDescriptor = { sizeof(g_IDT) - 1, g_IDT };

extern void x86_64_IDT_Load(IDTDescriptor* descriptor);

void x86_64_IDT_SetGate(int interrupt, void* base, uint16_t segmentDescriptor, uint8_t flags)
{
    uintptr_t addr = (uintptr_t)base;
    g_IDT[interrupt].BaseLow        = addr & 0xFFFF;
    g_IDT[interrupt].SegmentSelector = segmentDescriptor;
    g_IDT[interrupt].IST            = 0;
    g_IDT[interrupt].Flags          = flags;
    g_IDT[interrupt].BaseMid        = (addr >> 16) & 0xFFFF;
    g_IDT[interrupt].BaseHigh       = (addr >> 32) & 0xFFFFFFFF;
    g_IDT[interrupt].Reserved       = 0;
}
void x86_64_IDT_EnableGate(int interrupt)
{
    FLAG_SET(g_IDT[interrupt].Flags, IDT_FLAG_PRESENT);
}

void x86_64_IDT_DisableGate(int interrupt)
{
    FLAG_UNSET(g_IDT[interrupt].Flags, IDT_FLAG_PRESENT);
}


void x86_64_IDT_Initialize(void)
{
    x86_64_IDT_Load(&g_IDTDescriptor);
}