diff options
author | Andrew Waterman <andrew@sifive.com> | 2019-07-11 13:50:45 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2019-07-11 13:50:45 -0700 |
commit | 0c2fe4ad849a970c4b456580dabb0e12f3fe9702 (patch) | |
tree | f80b3f4ca32f89fe8a2cba385e881691cd3d1fa2 /riscv | |
parent | db067bbe5b8c23e0ab08fbd01a0f2779cd664a59 (diff) | |
download | spike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.zip spike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.tar.gz spike-0c2fe4ad849a970c4b456580dabb0e12f3fe9702.tar.bz2 |
Support S-mode vectored interrupts
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/processor.cc | 5 |
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; |