aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-08-17 14:00:58 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-08-17 15:27:42 -0700
commit5e1d0059353a4756740df709f85c35ee86138ad6 (patch)
tree5d7b128e83b1123bb8204d0136c748c1b78af327
parenteb19d1c1deabf9c8ca7d0f3958b2b6d797f100a9 (diff)
downloadspike-5e1d0059353a4756740df709f85c35ee86138ad6.zip
spike-5e1d0059353a4756740df709f85c35ee86138ad6.tar.gz
spike-5e1d0059353a4756740df709f85c35ee86138ad6.tar.bz2
Allow mstatus.MPP to store bad values; instead, validate on MRET
Either approach is legal, but this more closely matches Rocket.
-rw-r--r--riscv/insns/dret.h5
-rw-r--r--riscv/processor.cc13
-rw-r--r--riscv/processor.h1
3 files changed, 5 insertions, 14 deletions
diff --git a/riscv/insns/dret.h b/riscv/insns/dret.h
index bef9ef2..35c19cb 100644
--- a/riscv/insns/dret.h
+++ b/riscv/insns/dret.h
@@ -1,9 +1,6 @@
require_privilege(PRV_M);
set_pc_and_serialize(STATE.dpc);
-/* The debug spec says we can't crash when prv is set to an invalid value. */
-if (p->validate_priv(STATE.dcsr.prv)) {
- p->set_privilege(STATE.dcsr.prv);
-}
+p->set_privilege(STATE.dcsr.prv);
/* We're not in Debug Mode anymore. */
STATE.dcsr.cause = 0;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 3576af3..0a7912b 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -179,14 +179,11 @@ void processor_t::take_interrupt()
raise_interrupt(ctz(enabled_interrupts));
}
-bool processor_t::validate_priv(reg_t priv)
-{
- return priv == PRV_U || priv == PRV_S || priv == PRV_M;
-}
-
void processor_t::set_privilege(reg_t prv)
{
- assert(validate_priv(prv));
+ assert(prv <= PRV_M);
+ if (prv == PRV_H)
+ prv = PRV_U;
mmu->flush_tlb();
state.prv = prv;
}
@@ -311,12 +308,10 @@ void processor_t::set_csr(int which, reg_t val)
reg_t mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE
| MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_PUM
- | MSTATUS_MXR | (ext ? MSTATUS_XS : 0);
+ | MSTATUS_MPP | MSTATUS_MXR | (ext ? MSTATUS_XS : 0);
if (validate_vm(max_xlen, get_field(val, MSTATUS_VM)))
mask |= MSTATUS_VM;
- if (validate_priv(get_field(val, MSTATUS_MPP)))
- mask |= MSTATUS_MPP;
state.mstatus = (state.mstatus & ~mask) | (val & mask);
diff --git a/riscv/processor.h b/riscv/processor.h
index 4d0d5ab..090ebe7 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -118,7 +118,6 @@ public:
if (ext >= 'a' && ext <= 'z') ext += 'A' - 'a';
return ext >= 'A' && ext <= 'Z' && ((isa >> (ext - 'A')) & 1);
}
- bool validate_priv(reg_t priv);
void set_privilege(reg_t);
void yield_load_reservation() { state.load_reservation = (reg_t)-1; }
void update_histogram(reg_t pc);