summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mos/sys/arch/x86_64/cpu/idt.c38
-rw-r--r--mos/sys/inc/arch/x86_64/idt.h64
2 files changed, 102 insertions, 0 deletions
diff --git a/mos/sys/arch/x86_64/cpu/idt.c b/mos/sys/arch/x86_64/cpu/idt.c
new file mode 100644
index 0000000..569fe71
--- /dev/null
+++ b/mos/sys/arch/x86_64/cpu/idt.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2025, Ian Moffett.
+ * Provided under the BSD-3 clause.
+ */
+
+#include <sdk/defs.h>
+#include <md/idt.h>
+#include <md/gdt.h>
+
+ALIGN(8) static IDT_GATE idt[256];
+static IDT_DESCRIPTOR idtr = {
+ .limit = sizeof(idt) - 1,
+ .offset = (UPTR)&idt[0]
+};
+
+void
+md_idt_set_entry(UBYTE vector, UPTR isr, UBYTE type, UBYTE ist)
+{
+ IDT_GATE *gate = &idt[vector];
+
+ gate->offset_low = isr & 0xFFFF;
+ gate->offset_mid = (isr >> 16) & 0xFFFF;
+ gate->offset_high = (isr >> 32) & 0xFFFFFFFF;
+ gate->p = 1;
+ gate->dpl = (type == IDT_USER_GATE) ? 3 : 0;
+ gate->zero = 0;
+ gate->zero1 = 0;
+ gate->reserved = 0;
+ gate->ist = ist;
+ gate->target_cs = GDT_KCODE;
+ gate->type = type;
+}
+
+void
+md_idt_load(void)
+{
+ ASM("lidt %0" :: "m" (idtr) : "memory");
+}
diff --git a/mos/sys/inc/arch/x86_64/idt.h b/mos/sys/inc/arch/x86_64/idt.h
new file mode 100644
index 0000000..b696a89
--- /dev/null
+++ b/mos/sys/inc/arch/x86_64/idt.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2025, Ian Moffett.
+ * Provided under the BSD-3 clause.
+ */
+
+#ifndef _MACHINE_IDT_H_
+#define _MACHINE_IDT_H_ 1
+
+#include <sdk/types.h>
+#include <sdk/defs.h>
+
+#define IDT_INT_GATE 0x8E
+#define IDT_TRAP_GATE 0x8F
+#define IDT_USER_GATE 0xEE
+
+/*
+ * Represents a 64-bit interrupt gate descriptor
+ * for the x86_64 architecture. See section 6.14.1
+ * for more information.
+ */
+typedef struct {
+ USHORT offset_low;
+ USHORT target_cs;
+ UBYTE ist : 3;
+ UBYTE zero : 5;
+ UBYTE type : 4;
+ UBYTE zero1 : 1;
+ UBYTE dpl : 2;
+ UBYTE p : 1;
+ USHORT offset_mid;
+ ULONG offset_high;
+ ULONG reserved;
+} IDT_GATE;
+
+/*
+ * This descriptor is loaded into the processor core
+ * for when it needs to reference a gate descriptor.
+ *
+ * @limit: IDT limit
+ * @offset: Base address of IDT
+ */
+typedef struct {
+ USHORT limit;
+ UPTR offset;
+} PACKED IDT_DESCRIPTOR;
+
+/*
+ * Set an interrupt gate descriptor within the
+ * interrupt descriptor table.
+ *
+ * @vector: Interrupt vector to set
+ * @isr: Interrupt service routine
+ * @type: Gate descriptor type
+ * @ist: Interrupt stack table index to use
+ */
+void md_idt_set_entry(UBYTE vector, UPTR isr, UBYTE type, UBYTE ist);
+
+/*
+ * Load the interrupt descriptor table into the current
+ * processor core.
+ */
+void md_idt_load(void);
+
+#endif /* !_MACHINE_IDT_H_ */