Implement mstatus.TW, mstatus.TVM, and mstatus.TSR
[riscv-isa-sim.git] / riscv / processor.cc
index d44f870574d1ccced46717248c78347f51974a87..c2a7d49b85df38549762bddfafb061a760e95c3a 100644 (file)
@@ -298,7 +298,8 @@ 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_MPP | MSTATUS_MXR | (ext ? MSTATUS_XS : 0);
+                 | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TW | MSTATUS_TVM
+                 | MSTATUS_TSR | (ext ? MSTATUS_XS : 0);
 
       state.mstatus = (state.mstatus & ~mask) | (val & mask);
 
@@ -367,7 +368,8 @@ void processor_t::set_csr(int which, reg_t val)
       if (max_xlen == 32)
         state.sptbr = val & (SPTBR32_PPN | SPTBR32_MODE);
       if (max_xlen == 64 && (get_field(val, SPTBR64_MODE) == SPTBR_MODE_OFF ||
-                             get_field(val, SPTBR64_MODE) >= SPTBR_MODE_SV39))
+                             get_field(val, SPTBR64_MODE) == SPTBR_MODE_SV39 ||
+                             get_field(val, SPTBR64_MODE) == SPTBR_MODE_SV48))
         state.sptbr = val & (SPTBR64_PPN | SPTBR64_MODE);
       break;
     }
@@ -526,7 +528,10 @@ reg_t processor_t::get_csr(int which)
       if (max_xlen > xlen)
         return state.scause | ((state.scause >> (max_xlen-1)) << (xlen-1));
       return state.scause;
-    case CSR_SPTBR: return state.sptbr;
+    case CSR_SPTBR:
+      if (get_field(state.mstatus, MSTATUS_TVM))
+        require_privilege(PRV_M);
+      return state.sptbr;
     case CSR_SSCRATCH: return state.sscratch;
     case CSR_MSTATUS: return state.mstatus;
     case CSR_MIP: return state.mip;