aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2019-07-11 13:50:45 -0700
committerAndrew Waterman <andrew@sifive.com>2019-07-11 13:50:45 -0700
commit0c2fe4ad849a970c4b456580dabb0e12f3fe9702 (patch)
treef80b3f4ca32f89fe8a2cba385e881691cd3d1fa2 /riscv
parentdb067bbe5b8c23e0ab08fbd01a0f2779cd664a59 (diff)
downloadspike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.zip
spike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.tar.gz
spike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.tar.bz2
Support S-mode vectored interrupts
Diffstat (limited to 'riscv')
-rw-r--r--riscv/processor.cc5
1 files changed, 3 insertions, 2 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index a7d2810..d182f7a 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -369,7 +369,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
deleg = state.mideleg, bit &= ~((reg_t)1 << (max_xlen-1));
if (state.prv <= PRV_S && bit < max_xlen && ((deleg >> bit) & 1)) {
// handle the trap in S-mode
- state.pc = state.stvec;
+ reg_t vector = (state.stvec & 1) && interrupt ? 4*bit : 0;
+ state.pc = (state.stvec & ~(reg_t)1) + vector;
state.scause = t.cause();
state.sepc = epc;
state.stval = t.get_tval();
@@ -564,7 +565,7 @@ void processor_t::set_csr(int which, reg_t val)
break;
}
case CSR_SEPC: state.sepc = val & ~(reg_t)1; break;
- case CSR_STVEC: state.stvec = val >> 2 << 2; break;
+ case CSR_STVEC: state.stvec = val & ~(reg_t)2; break;
case CSR_SSCRATCH: state.sscratch = val; break;
case CSR_SCAUSE: state.scause = val; break;
case CSR_STVAL: state.stval = val; break;