Allow mstatus.MPP to store bad values; instead, validate on MRET
authorAndrew Waterman <waterman@cs.berkeley.edu>
Wed, 17 Aug 2016 21:00:58 +0000 (14:00 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Wed, 17 Aug 2016 22:27:42 +0000 (15:27 -0700)
Either approach is legal, but this more closely matches Rocket.

riscv/insns/dret.h
riscv/processor.cc
riscv/processor.h

index bef9ef2e26769c82fd37862cb3023de7e50f1d4b..35c19cb8a29090b774ff8c7a1fa091aa36428e21 100644 (file)
@@ -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;
index 3576af3899a6f23cad5c38638228ca4c99d31bac..0a7912bd791554454813dd071a978e624c4f1f94 100644 (file)
@@ -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);
 
index 4d0d5ab344b40d011ce4b686dc00ea1a36b2e848..090ebe7a155a9157f2cc6c8e0d112d05f120acfc 100644 (file)
@@ -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);