aboutsummaryrefslogtreecommitdiff
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
parentdb067bbe5b8c23e0ab08fbd01a0f2779cd664a59 (diff)
downloadspike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.zip
spike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.tar.gz
spike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.tar.bz2
Support S-mode vectored interrupts
-rw-r--r--ChangeLog.md1
-rw-r--r--riscv/processor.cc5
2 files changed, 4 insertions, 2 deletions
diff --git a/ChangeLog.md b/ChangeLog.md
index e411491..b9fcd7e 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,6 @@
Version 1.0.1-dev
-----------------
+- Support S-mode vectored interrupts (i.e. stvec[0] is now writable).
- Added `hasel` debug feature.
- Added `--dm-no-abstract-csr` command-line option.
- Renamed `--progsize` to `--dm-progsize`.
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;