diff --git a/service/ptos/arch/amd64/cpu/idt.c b/service/ptos/arch/amd64/cpu/idt.c new file mode 100644 index 0000000..c56f2e0 --- /dev/null +++ b/service/ptos/arch/amd64/cpu/idt.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: AMD64 interrupt gate management + * Author: Chloe M. + */ + +#include +#include +#include + +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" + ); +} diff --git a/service/ptos/head/arch/amd64/idt.h b/service/ptos/head/arch/amd64/idt.h index 72b9cb0..1b0a515 100644 --- a/service/ptos/head/arch/amd64/idt.h +++ b/service/ptos/head/arch/amd64/idt.h @@ -16,4 +16,51 @@ #define IDT_TRAP_GATE 0x8F #define IDT_USER_GATE 0xEE +/* + * Represents an interupt gate descriptor + * + * Refer to section 6.14.1 of the Intel SDM + */ +typedef struct { + USHORT OffsetLow16; + USHORT SegmentSel; + UCHAR Ist : 3; + UCHAR Zero : 5; + UCHAR Type : 4; + UCHAR Zero1 : 1; + UCHAR Dpl : 2; + UCHAR Present : 1; + USHORT OffsetMid16; + ULONG OffsetHigh32; + ULONG Reserved; +} IDT_GATE; + +/* + * Refers to the base and limit of the interrupt + * descriptor table. + * + * Refer to section 6.10 of the Intel SDM + */ +typedef struct PACKED { + USHORT Limit; + UQUAD Offset; +} IDTR; + +/* + * Set an interrupt descriptor table gate + * + * @Vector: Interrupt vector to set + * @Offset: Offset of interrupt service routine + * @Type: Interrupt gate type + * @Ist: Interrupt stack table index + */ +VOID MdIdtSetGate(UCHAR Vector, UPTR Offset, UCHAR Type, UCHAR Ist); + +/* + * Load the interrupt descriptor table + * + * XXX: This must be called once per processor + */ +VOID MdIdtLoad(VOID); + #endif /* !_MACHINE_IDT_H_ */