summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2014-02-06 03:06:06 -0800
committerAndrew Waterman <waterman@eecs.berkeley.edu>2014-02-06 03:06:06 -0800
commit43599293d347be1b30d8feb22c4a8c0091ad80b9 (patch)
tree71e8be119c3428d87c278a66d304a945df6f7066
parent35d0a989a24fc0b9913760dcbead775eb8c0f29e (diff)
downloadenv-43599293d347be1b30d8feb22c4a8c0091ad80b9.zip
env-43599293d347be1b30d8feb22c4a8c0091ad80b9.tar.gz
env-43599293d347be1b30d8feb22c4a8c0091ad80b9.tar.bz2
Improve trap entry code
-rw-r--r--v/entry.S32
-rw-r--r--v/riscv_test.h13
-rw-r--r--v/vm.c13
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);