/*
 * Copyright (c) 2026, Chloe M.
 * Provided under the BSD-3 clause.
 *
 * Description: AMD64 interrupt gate management
 * Author:      Chloe M.
 */

#include <machine/idt.h>
#include <machine/gdt.h>
#include <ptdef.h>

static IDT_GATE Idt[256];
ALIGN(8) IDTR Idtr = {
    .Limit = sizeof(Idt) - 1,
    .Offset = (UPTR)&Idt[0]
};

VOID
MdIdtSetGate(UCHAR Vector, UPTR Offset, UCHAR Type, UCHAR Ist)
{
    IDT_GATE *Gate;

    Gate = &Idt[Vector];
    Gate->OffsetLow16 = Offset & 0xFFFF;
    Gate->OffsetMid16 = (Offset >> 16) & 0xFFFF;
    Gate->OffsetHigh32 = (Offset >> 32) & 0xFFFFFFFF;
    Gate->Reserved = 0;
    Gate->Zero = 0;
    Gate->Zero1 = 0;
    Gate->Type = Type;
    Gate->Dpl = (Type == IDT_USER_GATE) ? 3 : 0;
    Gate->Present = 1;
    Gate->Ist = Ist;
    Gate->SegmentSel = GDT_KCODE;
}

VOID
MdIdtLoad(VOID)
{
    ASMV(
        "lidt %0"
        :
        : "m" (Idtr)
        : "memory"
    );
}
