From a9746d4c55a32cb724b51b805cdc166fe579865b Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 17 Apr 2026 22:04:28 -0400 Subject: [PATCH] sp1/amd64: Add processor exception handling Signed-off-by: Ian Moffett --- usr/src/sp1/amd64/cpu/cpu_init.c | 3 + usr/src/sp1/amd64/cpu/cpu_trap.c | 46 ++++++ usr/src/sp1/amd64/cpu/cpu_vector.S | 244 +++++++++++++++++++++++++++++ usr/src/sp1/head/amd64/idt.h | 6 + usr/src/sp1/head/amd64/trap.h | 31 ++++ 5 files changed, 330 insertions(+) create mode 100644 usr/src/sp1/amd64/cpu/cpu_trap.c create mode 100644 usr/src/sp1/amd64/cpu/cpu_vector.S create mode 100644 usr/src/sp1/head/amd64/trap.h diff --git a/usr/src/sp1/amd64/cpu/cpu_init.c b/usr/src/sp1/amd64/cpu/cpu_init.c index a54bf37..8fa6b68 100644 --- a/usr/src/sp1/amd64/cpu/cpu_init.c +++ b/usr/src/sp1/amd64/cpu/cpu_init.c @@ -89,6 +89,9 @@ mu_cpu_preinit(struct cpu_info *ci) /* Log out some information */ cpu_print_info(ci); + /* Set interrupt vectors */ + md_set_vectors(); + /* Load the IDT */ md_idt_load(); } diff --git a/usr/src/sp1/amd64/cpu/cpu_trap.c b/usr/src/sp1/amd64/cpu/cpu_trap.c new file mode 100644 index 0000000..43dc356 --- /dev/null +++ b/usr/src/sp1/amd64/cpu/cpu_trap.c @@ -0,0 +1,46 @@ +/* + * 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 + +/* Used to convert trap codes to strings */ +static const char *traptab[] = { + [TRAP_DIVERR] = "divide error", + [TRAP_DBG] = "debug exception", + [TRAP_NMI] = "non-maskable interrupt", + [TRAP_BP] = "breakpoint", + [TRAP_OF] = "overflow", + [TRAP_BR] = "bound range exceeded", + [TRAP_UD] = "undefined opcode", + [TRAP_NM] = "no math coprocessor", + [TRAP_DF] = "double fault", + [TRAP_CPR] = "reserved exception", + [TRAP_TS] = "invalid TSS", + [TRAP_NP] = "segment not present", + [TRAP_SS] = "stack segment fault", + [TRAP_GP] = "general protection fault", + [TRAP_PF] = "page fault" +}; + +void +trap_dispatch(struct trapframe *tf) +{ + const char *str; + + if (tf->vector >= NELEM(traptab)) { + knot("fatal unknown vector %x\n", tf->vector); + } + + knot("fatal %s\n", traptab[tf->vector]); +} diff --git a/usr/src/sp1/amd64/cpu/cpu_vector.S b/usr/src/sp1/amd64/cpu/cpu_vector.S new file mode 100644 index 0000000..eac423d --- /dev/null +++ b/usr/src/sp1/amd64/cpu/cpu_vector.S @@ -0,0 +1,244 @@ +/* + * 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 + + .macro set_trap vector, isr, ist + mov $\vector, %rdi + lea \isr(%rip), %rsi + mov $IDT_TRAP_GATE, %rdx + mov $\ist, %rcx + call md_idt_set_gate + .endm + + .macro push_trapframe vector + .if \vector == 10 || \vector == 11 || \vector == 12 || \vector == 13 \ + || \vector == 14 + subq $8, %rsp + .endif + + push %rax + push %rbx + push %rcx + push %rdx + push %rsi + push %rdi + push %rbp + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 + push $\vector + .endm + + .macro pop_trapframe vector + .if \vector == 10 || \vector == 11 || \vector == 12 || \vector == 13 \ + || \vector == 14 + addq $8, %rsp + .endif + + add $8, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rbp + pop %rdi + pop %rsi + pop %rdx + pop %rcx + pop %rbx + pop %rax + .endm + + .text + .globl md_set_vectors +md_set_vectors: + push %r12 + push %r13 + push %r14 + push %r15 + push %rbx + push %rbp + + set_trap 0x00, diverr, 0 + set_trap 0x01, debug_except, 0 + set_trap 0x02, nmi, 0 + set_trap 0x03, breakpoint, 0 + set_trap 0x04, overflow, 0 + set_trap 0x05, bound_range, 0 + set_trap 0x06, invalid_tss, 0 + set_trap 0x07, no_coproc, 0 + set_trap 0x08, double_fault, 0 + set_trap 0x0A, invalid_tss, 0 + set_trap 0x0B, seg_np, 0 + set_trap 0x0C, ss_fault, 0 + set_trap 0x0D, gpf, 0 + set_trap 0x0E, page_fault, 0 + + pop %rbp + pop %rbx + pop %r15 + pop %r14 + pop %r13 + pop %r12 + retq + + .align 8 +diverr: + KFENCE + push_trapframe 0x00 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +debug_except: + KFENCE + push_trapframe 0x1 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +nmi: + KFENCE + push_trapframe 0x2 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +breakpoint: + KFENCE + push_trapframe 0x3 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +overflow: + KFENCE + push_trapframe 0x4 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +bound_range: + KFENCE + push_trapframe 0x5 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +invl_opc: + KFENCE + push_trapframe 0x6 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +no_coproc: + KFENCE + push_trapframe 0x7 + mov %rsp, %rdi + call trap_dispatch + KFENCE +1: cli + hlt + jmp 1b + +double_fault: + KFENCE_EC + push_trapframe 0x8 + mov %rsp, %rdi + call trap_dispatch + KFENCE_EC +1: cli + hlt + jmp 1b + +invalid_tss: + KFENCE_EC + push_trapframe 0xA + mov %rsp, %rdi + call trap_dispatch + KFENCE_EC +1: cli + hlt + jmp 1b + +seg_np: + KFENCE_EC + push_trapframe 0xB + mov %rsp, %rdi + call trap_dispatch + KFENCE_EC +1: cli + hlt + jmp 1b + +ss_fault: + KFENCE_EC + push_trapframe 0xC + mov %rsp, %rdi + call trap_dispatch + KFENCE_EC +1: cli + hlt + jmp 1b + +gpf: + KFENCE_EC + push_trapframe 0xD + mov %rsp, %rdi + call trap_dispatch + KFENCE_EC +1: cli + hlt + jmp 1b + +page_fault: + KFENCE_EC + push_trapframe 0xE + mov %rsp, %rdi + call trap_dispatch + KFENCE_EC +1: cli + hlt + jmp 1b + hlt diff --git a/usr/src/sp1/head/amd64/idt.h b/usr/src/sp1/head/amd64/idt.h index 3dba727..51b2683 100644 --- a/usr/src/sp1/head/amd64/idt.h +++ b/usr/src/sp1/head/amd64/idt.h @@ -61,5 +61,11 @@ void md_idt_set_gate(uint8_t vector, uintptr_t isr, uint8_t type, uint8_t ist); */ void md_idt_load(void); + +/* + * Set all interrupt vectors + */ +void md_set_vectors(void); + #endif /* !__ASSEMBLER__ */ #endif /* !_MACHINE_IDT_H_ */ diff --git a/usr/src/sp1/head/amd64/trap.h b/usr/src/sp1/head/amd64/trap.h new file mode 100644 index 0000000..cdd15d8 --- /dev/null +++ b/usr/src/sp1/head/amd64/trap.h @@ -0,0 +1,31 @@ +/* + * 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_TRAP_H_ +#define _MACHINE_TRAP_H_ 1 + +#define TRAP_DIVERR 0x00 /* Divide error */ +#define TRAP_DBG 0x01 /* Debug exception */ +#define TRAP_NMI 0x02 /* Non-maskable interrupt */ +#define TRAP_BP 0x03 /* Breakpoint */ +#define TRAP_OF 0x04 /* Overflow */ +#define TRAP_BR 0x05 /* BOUND range exceeded */ +#define TRAP_UD 0x06 /* Undefined opcode */ +#define TRAP_NM 0x07 /* No math coprocessor */ +#define TRAP_DF 0x08 /* Double fault */ +#define TRAP_CPR 0x09 /* Reserved */ +#define TRAP_TS 0x0A /* Invalid TSS */ +#define TRAP_NP 0x0B /* Segment not present */ +#define TRAP_SS 0x0C /* Stack segment fault */ +#define TRAP_GP 0x0D /* General protection fault */ +#define TRAP_PF 0x0E /* Page fault */ + +#endif /* !_MACHINE_TRAP_H_ */