aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2017-04-07 17:57:59 -0700
committerAndrew Waterman <andrew@sifive.com>2017-04-07 17:57:59 -0700
commit5f494a22db29d69893db4b39f488cf67c0ac6437 (patch)
treeb33e3d42376719e4a5ad38a33abe104ed487c209
parent1132fdf4f07dfbfba237af7b0cfac3cae543a79b (diff)
downloadriscv-isa-sim-5f494a22db29d69893db4b39f488cf67c0ac6437.zip
riscv-isa-sim-5f494a22db29d69893db4b39f488cf67c0ac6437.tar.gz
riscv-isa-sim-5f494a22db29d69893db4b39f488cf67c0ac6437.tar.bz2
Implement vectored interrupt proposal
https://github.com/riscv/riscv-isa-manual/commit/4dcaa944ba40e074d25516a157fc37f7491b71cc
-rw-r--r--riscv/processor.cc8
1 files changed, 5 insertions, 3 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 3830b1e..ab5640e 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -223,7 +223,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
// by default, trap to M-mode, unless delegated to S-mode
reg_t bit = t.cause();
reg_t deleg = state.medeleg;
- if (bit & ((reg_t)1 << (max_xlen-1)))
+ bool interrupt = (bit & ((reg_t)1 << (max_xlen-1))) != 0;
+ if (interrupt)
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
@@ -240,7 +241,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
set_csr(CSR_MSTATUS, s);
set_privilege(PRV_S);
} else {
- state.pc = state.mtvec;
+ reg_t vector = (state.mtvec & 1) && interrupt ? 4*bit : 0;
+ state.pc = (state.mtvec & ~(reg_t)1) + vector;
state.mepc = epc;
state.mcause = t.cause();
if (t.has_badaddr())
@@ -378,7 +380,7 @@ void processor_t::set_csr(int which, reg_t val)
case CSR_SCAUSE: state.scause = val; break;
case CSR_SBADADDR: state.sbadaddr = val; break;
case CSR_MEPC: state.mepc = val; break;
- case CSR_MTVEC: state.mtvec = val >> 2 << 2; break;
+ case CSR_MTVEC: state.mtvec = val & ~(reg_t)2; break;
case CSR_MSCRATCH: state.mscratch = val; break;
case CSR_MCAUSE: state.mcause = val; break;
case CSR_MBADADDR: state.mbadaddr = val; break;