traps/interrupts: Refactor trap handling and align CSR access

This commit is contained in:
Liam Kerr 2026-05-01 22:34:27 +01:00
parent 0176b636c5
commit f76ca1ee31
3 changed files with 15 additions and 12 deletions

View file

@ -39,9 +39,13 @@ trap_entry:
sd t5, 224(sp)
sd t6, 232(sp)
# --- Save mepc ---
# --- Save mepc/mcause/mstatus ---
csrr t0, mepc
sd t0, 240(sp)
csrr t0, mcause
sd t0, 248(sp)
csrr t0, mstatus
sd t0, 256(sp)
# --- Check FPU Status (mstatus.FS) ---
csrr t1, mstatus

View file

@ -54,15 +54,11 @@ void kpanic_force()
void handle_trap(trap_frame_t *registers)
{
// Read the 'mcause' register to see WHY we trapped
unsigned long cause;
__asm__ volatile("csrr %0, mcause" : "=r"(cause));
// Check if the top bit is 1 (Interrupt) or 0 (Exception)
// For 64-bit RISC-V, the bit is 63
int is_interrupt = (cause >> 63) & 1;
int is_interrupt = (registers->mcause >> 63) & 1;
unsigned long code = cause & 0xfff;
unsigned long code = registers->mcause & 0xfff;
if (is_interrupt)
{
@ -77,7 +73,7 @@ void handle_trap(trap_frame_t *registers)
kprintf("\n[EXCEPTION] Code: %d | Instruction: %x | Fault Address: %x\n", code, registers->mepc, mtval);
switch (cause)
switch (registers->mcause)
{
case 0:
kpanic("Reason: Instruction Address Misaligned\n");
@ -104,7 +100,7 @@ void handle_trap(trap_frame_t *registers)
kpanic("Reason: Store/AMO Access Fault\n");
break;
default:
kpanic("Reason: Unknown Exception Code %d\n", cause);
kpanic("Reason: Unknown Exception Code %d\n", registers->mcause);
break;
}
}
@ -118,7 +114,6 @@ void handle_interrupt(unsigned long code)
static volatile uint64_t *mtime = (uint64_t *)CLINT_MTIME;
static volatile uint64_t *mtimecmp = (uint64_t *)CLINT_MTIMECMP(0);
*mtimecmp = *mtime + 100000;
break;
case 11:
volatile uint32_t *claim_reg = (uint32_t *)PLIC_CLAIM(0);

View file

@ -3,6 +3,8 @@
#define MSTATUS 0x300
#define MIE 0x304
#define MCAUSE 0x342
#define MEPC 0x341
#define MSTATUS_BIT_MIE 3
#define MIE_BIT_MTIE 7
#define MIE_BIT_MEIE 11
@ -56,8 +58,10 @@ typedef struct {
uint64_t t5; // x30
uint64_t t6; // x31
// Control and Status Register state
uint64_t mepc; // offset 240 (Saved in traps.S)
// Control and Status Register state (Saved in traps.S)
uint64_t mepc; // offset 240
uint64_t mcause; // offset 248
uint64_t mstatus; // offset 256
} trap_frame_t;
void interrupt_init();