(interrupt): implement robust trap frame and state preservation

This commit is contained in:
Liam Kerr 2026-02-11 22:56:25 +00:00
parent 43a26abe74
commit b48da838ec
3 changed files with 72 additions and 11 deletions

View file

@ -24,6 +24,7 @@ void interrupt_init()
void kpanic(const char *reason, ...)
{
asm volatile("csrci mstatus, 8"); // Disable MIE (Machine Interrupt Enable)
va_list args;
va_start(args, reason);
kputs("\n!!! PANIC !!!\n");
@ -50,7 +51,7 @@ void kpanic_force()
}
}
void handle_trap()
void handle_trap(trap_frame_t *registers)
{
// Read the 'mcause' register to see WHY we trapped
unsigned long cause;
@ -60,9 +61,10 @@ void handle_trap()
// For 64-bit RISC-V, the bit is 63
int is_interrupt = (cause >> 63) & 1;
unsigned long code = cause & 0xfff;
if (is_interrupt)
{
unsigned long code = cause & 0xfff;
handle_interrupt(code);
return;
}
@ -71,7 +73,9 @@ void handle_trap()
// fault address (if applicable)
uintptr_t mtval;
asm volatile("csrr %0, mtval" : "=r"(mtval));
kprintf("Faulting Address (if applicable): %x\n", mtval);
kprintf("\n[EXCEPTION] Code: %d | Instruction: %x | Fault Address: %x\n", code, registers->mepc, mtval);
switch (cause)
{
case 0:

View file

@ -1,9 +1,59 @@
#ifndef PANIC_H
#define PANIC_H
// This should match the order of registers in traps.S
typedef struct {
// Return address and pointers
uint64_t ra; // x1
uint64_t gp; // x3
uint64_t tp; // x4
// Temporary registers
uint64_t t0; // x5
uint64_t t1; // x6
uint64_t t2; // x7
// Saved registers
uint64_t s0; // x8 (fp)
uint64_t s1; // x9
// Function arguments / Return values
uint64_t a0; // x10
uint64_t a1; // x11
uint64_t a2; // x12
uint64_t a3; // x13
uint64_t a4; // x14
uint64_t a5; // x15
uint64_t a6; // x16
uint64_t a7; // x17
// More saved registers
uint64_t s2; // x18
uint64_t s3; // x19
uint64_t s4; // x20
uint64_t s5; // x21
uint64_t s6; // x22
uint64_t s7; // x23
uint64_t s8; // x24
uint64_t s9; // x25
uint64_t s10; // x26
uint64_t s11; // x27
// More temporary registers
uint64_t t3; // x28
uint64_t t4; // x29
uint64_t t5; // x30
uint64_t t6; // x31
// Control and Status Register state
uint64_t mepc; // offset 240 (Saved in traps.S)
} trap_frame_t;
void interrupt_init();
void kpanic(const char *, ...);
void kpanic_force();
void handle_trap(trap_frame_t *registers);
void handle_interrupt(unsigned long code);
#define KASSERT(cond, msg) \