sp1/amd64: Add processor exception handling

Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
2026-04-17 22:04:28 -04:00
parent 9c950525b9
commit a9746d4c55
5 changed files with 330 additions and 0 deletions
+3
View File
@@ -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();
}
+46
View File
@@ -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 <sys/param.h>
#include <os/knot.h>
#include <machine/frame.h>
#include <machine/trap.h>
/* 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]);
}
+244
View File
@@ -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 <machine/idt.h>
#include <machine/kfence.h>
.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
+6
View File
@@ -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_ */
+31
View File
@@ -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_ */