diff options
| author | Ian Moffett <ian@osmora.org> | 2025-12-23 18:32:51 -0500 |
|---|---|---|
| committer | Ian Moffett <ian@osmora.org> | 2025-12-23 18:32:51 -0500 |
| commit | 2aa294e12e0d9c183d2a2f4a5176edb636852d62 (patch) | |
| tree | c95d24af431087dcb5be5b5ef727fef6942eaaaa | |
| parent | 5983b741f6cef8de27e401fb277adc8ac62afeca (diff) | |
mos/x86_64: cpu: Add interrupt descriptor table
Signed-off-by: Ian Moffett <ian@osmora.org>
| -rw-r--r-- | mos/sys/arch/x86_64/cpu/idt.c | 38 | ||||
| -rw-r--r-- | mos/sys/inc/arch/x86_64/idt.h | 64 |
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_ */ |
