stos/amd64: cpu: Add exception handling groundwork
Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Chloe M.
|
||||
* Provided under the BSD-3 clause.
|
||||
*
|
||||
* Description: Interrupt descriptor table
|
||||
* Author: Chloe M.
|
||||
*/
|
||||
|
||||
#include <machine/idt.h>
|
||||
#include <machine/gdt.h>
|
||||
|
||||
#define IDT_VECTOR_SHIFT 4
|
||||
|
||||
.text
|
||||
.globl MdIdtSetEntry
|
||||
MdIdtSetEntry:
|
||||
/*
|
||||
* Set an IDT entry
|
||||
*
|
||||
* @[RDI]: Interrupt vector of entry to set
|
||||
* @[RSI]: Interrupt service routine base
|
||||
* @[RDX]: Interrupt gate type
|
||||
* @[RCX]: Interrupt stack table index
|
||||
*/
|
||||
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
push %rbx
|
||||
|
||||
shl $IDT_VECTOR_SHIFT, %rdi /* Scale the vector by IDT size */
|
||||
lea IdtTable(%rip), %rbx /* IDT base -> RBX */
|
||||
add %rdi, %rbx /* Obtain the entry */
|
||||
|
||||
mov %rsi, %rax /* ISR base -> RAX */
|
||||
and $0xFFFF, %rax /* Obtain ISR[15:0] */
|
||||
mov %ax, 0(%rbx) /* Set the ISR base */
|
||||
|
||||
movw $GDT_KCODE, 2(%rbx) /* Set the code selector */
|
||||
xor %rax, %rax /* Clear out RAX */
|
||||
and $0x3, %cl /* Ensure we only have 3 bits */
|
||||
or %cl, %al /* Merge it with RAX */
|
||||
|
||||
and $0xF, %rdx /* Ensure we only get 4 bits */
|
||||
shl $8, %rdx /* Prepare to merge it */
|
||||
or %rdx, %rax /* Merge it */
|
||||
or $1<<15, %rax /* Mark as present */
|
||||
|
||||
cmpb $IDT_USER_GATE, %dl /* Is this DPL3? */
|
||||
jne 1f /* No, skip .Dpl3 */
|
||||
|
||||
.Dpl3:
|
||||
or $3<<13, %rax /* Set DPL 3 */
|
||||
1: mov %rsi, %r12 /* Copy ISR base to R12 */
|
||||
shr $16, %r12 /* Obtain the middle 16-bits */
|
||||
and $0xFFFF, %r12 /* Isolate it */
|
||||
shl $16, %r12 /* Shift it back up */
|
||||
or %r12, %rax /* Merge it */
|
||||
|
||||
mov %rax, 4(%rbx) /* Set the second dword */
|
||||
mov %rsi, %r12 /* Copy ISR base to R12 */
|
||||
shr $32, %r12 /* Isolate the upper dword */
|
||||
mov %r12, 8(%rbx) /* Write it */
|
||||
|
||||
pop %rbx
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
pop %r12
|
||||
retq
|
||||
|
||||
.globl MdIdtLoad
|
||||
MdIdtLoad:
|
||||
lea Idtr(%rip), %rax
|
||||
lidt (%rax)
|
||||
retq
|
||||
|
||||
.section .data
|
||||
Idtr:
|
||||
.word 4095
|
||||
.quad IdtTable
|
||||
|
||||
.section .bss
|
||||
.align 8
|
||||
IdtTable:
|
||||
.skip 4096, 0
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <hal/kpcr.h>
|
||||
#include <ex/trace.h>
|
||||
#include <machine/cpuid.h>
|
||||
#include <machine/idt.h>
|
||||
#include <stdef.h>
|
||||
|
||||
#define DTRACE(Fmt, ...) \
|
||||
@@ -31,6 +32,9 @@ static const CHAR *ProcessorType[] = {
|
||||
[PROCESSOR_DUAL] = "Intel P5 dual processor"
|
||||
};
|
||||
|
||||
/* From cpu/vector.S */
|
||||
extern VOID MdVectorInit(VOID);
|
||||
|
||||
/*
|
||||
* Called by ProcessorIdentify()
|
||||
*/
|
||||
@@ -113,4 +117,9 @@ HalKpcrP1Init(KPCR *Kpcr)
|
||||
|
||||
Mcb = &Kpcr->Mcb;
|
||||
ProcessorIdentify(Mcb);
|
||||
|
||||
/* Load the IDT */
|
||||
MdVectorInit();
|
||||
MdIdtLoad();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Chloe M.
|
||||
* Provided under the BSD-3 clause.
|
||||
*
|
||||
* Description: Trap handling
|
||||
* Author: Chloe M.
|
||||
*/
|
||||
|
||||
#include <machine/trap.h>
|
||||
#include <ke/knot.h>
|
||||
#include <stdef.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
|
||||
MdTrapDispatch(TRAP_FRAME *Frame)
|
||||
{
|
||||
if (Frame == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Frame->Vector >= NELEM(TrapTab)) {
|
||||
KeKnot(
|
||||
KNOT_EXCEPTION,
|
||||
"Fatal unknown vector %x\n",
|
||||
Frame->Vector
|
||||
);
|
||||
}
|
||||
|
||||
KeKnot(KNOT_EXCEPTION, "Fatal %s\n", TrapTab[Frame->Vector]);
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2026, Chloe M.
|
||||
* Provided under the BSD-3 clause.
|
||||
*
|
||||
* Description: Interrupt Vector entries
|
||||
* Author: Chloe M.
|
||||
*/
|
||||
|
||||
#include <machine/idt.h>
|
||||
#include <machine/kfence.h>
|
||||
#include <machine/frame.h>
|
||||
|
||||
.macro SetTrap, Vector, Isr, Ist
|
||||
mov $\Vector, %rdi
|
||||
lea \Isr(%rip), %rsi
|
||||
mov $IDT_TRAP_GATE, %rdx
|
||||
mov $\Ist, %rcx
|
||||
call MdIdtSetEntry
|
||||
.endm
|
||||
|
||||
.text
|
||||
.globl MdVectorInit
|
||||
MdVectorInit:
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
push %rbx
|
||||
push %rbp
|
||||
|
||||
SetTrap 0x00, DivErr, 0
|
||||
SetTrap 0x01, DebugExcept, 0
|
||||
SetTrap 0x02, Nmi, 0
|
||||
SetTrap 0x03, Breakpoint, 0
|
||||
SetTrap 0x04, Overflow, 0
|
||||
SetTrap 0x05, BoundRange, 0
|
||||
SetTrap 0x06, InvalidOpcode, 0
|
||||
SetTrap 0x07, NoCoproc, 0
|
||||
SetTrap 0x08, DoubleFault, 0
|
||||
SetTrap 0x0A, InvalidTss, 0
|
||||
SetTrap 0x0B, SegNp, 0
|
||||
SetTrap 0x0C, StackSegFault, 0
|
||||
SetTrap 0x0D, Gpf, 0
|
||||
SetTrap 0x0E, PageFault, 0
|
||||
|
||||
pop %rbp
|
||||
pop %rbx
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
pop %r12
|
||||
retq
|
||||
|
||||
.text
|
||||
.extern MdTrapDispatch
|
||||
.align 8
|
||||
DivErr:
|
||||
KFENCE
|
||||
PushFrame 0x00
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
DebugExcept:
|
||||
KFENCE
|
||||
PushFrame 0x1
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
Nmi:
|
||||
KFENCE
|
||||
PushFrame 0x2
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
Breakpoint:
|
||||
KFENCE
|
||||
PushFrame 0x3
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
Overflow:
|
||||
KFENCE
|
||||
PushFrame 0x4
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
BoundRange:
|
||||
KFENCE
|
||||
PushFrame 0x5
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
InvalidOpcode:
|
||||
KFENCE
|
||||
PushFrame 0x6
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
NoCoproc:
|
||||
KFENCE
|
||||
PushFrame 0x7
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
DoubleFault:
|
||||
KFENCE_EC
|
||||
PushFrame 0x8
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE_EC
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
InvalidTss:
|
||||
KFENCE_EC
|
||||
PushFrame 0xA
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE_EC
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
SegNp:
|
||||
KFENCE_EC
|
||||
PushFrame 0xB
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE_EC
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
StackSegFault:
|
||||
KFENCE_EC
|
||||
PushFrame 0xC
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE_EC
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
Gpf:
|
||||
KFENCE_EC
|
||||
PushFrame 0xD
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE_EC
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
PageFault:
|
||||
KFENCE_EC
|
||||
PushFrame 0xE
|
||||
mov %rsp, %rdi
|
||||
call MdTrapDispatch
|
||||
KFENCE_EC
|
||||
1: cli
|
||||
hlt
|
||||
jmp 1b
|
||||
hlt
|
||||
Reference in New Issue
Block a user