From 7f91fd1fea9cb58d34022561fb799073a538d107 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 17 Apr 2026 14:39:33 -0400 Subject: [PATCH] sp1/amd64: cpu: Add interrupt descriptor table Signed-off-by: Ian Moffett --- usr/src/sp1/amd64/cpu/cpu_idt.c | 47 +++++++++++++++++++++++ usr/src/sp1/amd64/cpu/cpu_init.c | 4 ++ usr/src/sp1/head/amd64/idt.h | 65 ++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 usr/src/sp1/amd64/cpu/cpu_idt.c create mode 100644 usr/src/sp1/head/amd64/idt.h diff --git a/usr/src/sp1/amd64/cpu/cpu_idt.c b/usr/src/sp1/amd64/cpu/cpu_idt.c new file mode 100644 index 0000000..4b2fb3c --- /dev/null +++ b/usr/src/sp1/amd64/cpu/cpu_idt.c @@ -0,0 +1,47 @@ + +/* + * Copyright (c) 2026, Mirocom Laboratories + * All rights reserved. + * + * The following sources are CONFIDENTIAL and PROPRIETARY + * property of Mirocom Laboratories. Unauthorized copying, + * use, distribution or modification of this file, in whole + * and in part, is strictly prohibited without the prior written + * consent from Mirocom Laboratories. + */ + +#include +#include +#include +#include + +__align(8) static struct idt_gate idt[256]; +static struct idtr idtr = { + .limit = sizeof(idt) - 1, + .base = (uintptr_t)&idt[0] +}; + +void +md_idt_set_gate(uint8_t vector, uintptr_t isr, uint8_t type, uint8_t ist) +{ + struct idt_gate *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->type = type; + gate->ist = ist; + gate->segment_sel = GDT_KCODE; +} + +void +md_idt_load(void) +{ + __asmv("lidt %0" :: "m" (idtr) : "memory"); +} diff --git a/usr/src/sp1/amd64/cpu/cpu_init.c b/usr/src/sp1/amd64/cpu/cpu_init.c index 99267f2..a54bf37 100644 --- a/usr/src/sp1/amd64/cpu/cpu_init.c +++ b/usr/src/sp1/amd64/cpu/cpu_init.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #define pr_trace(fmt, ...) \ @@ -87,4 +88,7 @@ mu_cpu_preinit(struct cpu_info *ci) /* Log out some information */ cpu_print_info(ci); + + /* Load the IDT */ + md_idt_load(); } diff --git a/usr/src/sp1/head/amd64/idt.h b/usr/src/sp1/head/amd64/idt.h new file mode 100644 index 0000000..3dba727 --- /dev/null +++ b/usr/src/sp1/head/amd64/idt.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2026, Mirocom Laboratories + * All rights reserved. + * + * The following sources are CONFIDENTIAL and PROPRIETARY + * property of Mirocom Laboratories. Unauthorized copying, + * use, distribution or modification of this file, in whole + * and in part, is strictly prohibited without the prior written + * consent from Mirocom Laboratories. + */ + +#ifndef _MACHINE_IDT_H_ +#define _MACHINE_IDT_H_ 1 + +#ifndef __ASSEMBLER__ +#include +#include +#endif /* !__ASSEMBLER__ */ + +#define IDT_INT_GATE 0x8E +#define IDT_TRAP_GATE 0x8F +#define IDT_USER_GATE 0xEE + +#ifndef __ASSEMBLER__ +/* + * 64-bit interrupt gate descriptor + */ +struct idt_gate { + uint16_t offset_low; + uint16_t segment_sel; + uint8_t ist : 3; + uint8_t zero : 5; + uint8_t type : 4; + uint8_t zero1 : 1; + uint8_t dpl : 2; + uint8_t p : 1; + uint16_t offset_mid; + uint32_t offset_high; + uint32_t reserved; +}; + +/* + * Points to + */ +struct __packed idtr { + uint16_t limit; + uintptr_t base; +}; + +/* + * Set an IDT gate desriptor + * + * @vector: Interrupt vector to set + * @isr: Interrupt service routine base + * @type: Gate descriptor type + * @ist: Interrupt stack table index + */ +void md_idt_set_gate(uint8_t vector, uintptr_t isr, uint8_t type, uint8_t ist); + +/* + * Load the IDT + */ +void md_idt_load(void); + +#endif /* !__ASSEMBLER__ */ +#endif /* !_MACHINE_IDT_H_ */