From 43599293d347be1b30d8feb22c4a8c0091ad80b9 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 6 Feb 2014 03:06:06 -0800 Subject: Improve trap entry code --- v/entry.S | 32 ++++++-------------------------- v/riscv_test.h | 13 +++++++++---- v/vm.c | 13 ++++++++----- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/v/entry.S b/v/entry.S index 6933771..662c92f 100644 --- a/v/entry.S +++ b/v/entry.S @@ -10,10 +10,12 @@ # define REGBYTES 4 #endif +#define STACK_TOP (_end + 131072) + .text .global _start _start: - la sp, stack_top + la sp, STACK_TOP li a1, 1337 la a0, userstart j vm_boot @@ -66,22 +68,6 @@ save_tf: # write the trap frame onto the stack csrr x3,cause # cause STORE x3,35*REGBYTES(x2) - # get faulting insn, if it wasn't a fetch-related trap - li x5, CAUSE_MISALIGNED_FETCH - li x6, CAUSE_FAULT_FETCH - beq x3, x5, 1f - beq x3, x6, 1f - lh x5,0(x4) - lh x6,2(x4) - sh x5, 36*REGBYTES(x2) - sh x6,2+36*REGBYTES(x2) -1: - - bge x3, x0, 1f - vxcptcause x3 - STORE x3,37*REGBYTES(x2) -1: - ret .globl pop_tf @@ -143,7 +129,7 @@ trap_entry: bnez ra, 1f # no, so start at the top of the stack - la x2,stack_top-SIZEOF_TRAPFRAME_T + la x2,STACK_TOP-SIZEOF_TRAPFRAME_T jal save_tf move sp,x2 csrs status,SR_EI @@ -151,7 +137,7 @@ trap_entry: csrr ra,status and ra,ra,SR_EA beqz ra, 2f - addi x2,x2,38*REGBYTES + addi x2,x2,36*REGBYTES # rocket currently doesn't support vxcptsave/vxcptrestore natively csrr x3,impl @@ -177,10 +163,4 @@ trap_entry: csrs status,SR_EI move a0,x2 jal handle_trap - - .bss - .global stack_bot - .global stack_top -stack_bot: - .skip 32768 -stack_top: + unimp diff --git a/v/riscv_test.h b/v/riscv_test.h index e8a9015..26c44f2 100644 --- a/v/riscv_test.h +++ b/v/riscv_test.h @@ -79,7 +79,7 @@ userstart: \ #define PGSHIFT 13 #define PGSIZE (1 << PGSHIFT) -#define SIZEOF_TRAPFRAME_T 20784 +#define SIZEOF_TRAPFRAME_T 20768 #ifndef __ASSEMBLER__ @@ -109,11 +109,18 @@ static inline long vgetvl() static inline long vxcptaux() { - int aux; + long aux; asm volatile ("vxcptaux %0" : "=r"(aux) :); return aux; } +static inline long vxcptcause() +{ + long cause; + asm volatile ("vxcptcause %0" : "=r"(cause) :); + return cause; +} + static inline void vxcptrestore(long* mem) { asm volatile("vxcptrestore %0" : : "r"(mem) : "memory"); @@ -138,8 +145,6 @@ typedef struct long epc; long badvaddr; long cause; - long insn; - long hwacha_cause; long evac[2560]; } trapframe_t; #endif diff --git a/v/vm.c b/v/vm.c index e28dd45..a081422 100644 --- a/v/vm.c +++ b/v/vm.c @@ -170,10 +170,12 @@ void handle_trap(trapframe_t* tf) handle_fault(tf->epc); else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION) { + assert(tf->epc % 4 == 0); + int fssr; asm ("la %0, 1f; lw %0, 0(%0); b 2f; 1: fssr x0; 2:" : "=r"(fssr)); - if (tf->insn == fssr) + if (*(int*)tf->epc == fssr) terminate(1); // FP test on non-FP hardware. "succeed." else assert(0); @@ -181,11 +183,12 @@ void handle_trap(trapframe_t* tf) } else if (tf->cause == CAUSE_FAULT_LOAD || tf->cause == CAUSE_FAULT_STORE) handle_fault(tf->badvaddr); - else if ((tf->cause << 1) == (IRQ_COP << 1)) + else if ((long)tf->cause < 0 && (uint8_t)tf->cause == IRQ_COP) { - if (tf->hwacha_cause == HWACHA_CAUSE_VF_FAULT_FETCH || - tf->hwacha_cause == HWACHA_CAUSE_FAULT_LOAD || - tf->hwacha_cause == HWACHA_CAUSE_FAULT_STORE) + long hwacha_cause = vxcptcause(); + if (hwacha_cause == HWACHA_CAUSE_VF_FAULT_FETCH || + hwacha_cause == HWACHA_CAUSE_FAULT_LOAD || + hwacha_cause == HWACHA_CAUSE_FAULT_STORE) { long badvaddr = vxcptaux(); handle_fault(badvaddr); -- cgit v1.1