Implement mstatus.TW, mstatus.TVM, and mstatus.TSR
authorAndrew Waterman <andrew@sifive.com>
Mon, 13 Mar 2017 21:48:52 +0000 (14:48 -0700)
committerAndrew Waterman <andrew@sifive.com>
Mon, 13 Mar 2017 21:48:52 +0000 (14:48 -0700)
riscv/encoding.h
riscv/insns/sfence_vma.h
riscv/insns/sret.h
riscv/insns/wfi.h
riscv/processor.cc

index 13930e855e7cae3994526d5a1d12b1ddba63ac02..0af9132f4c5efdc57e882e79aca84f9f507564c9 100644 (file)
@@ -19,6 +19,9 @@
 #define MSTATUS_MPRV        0x00020000
 #define MSTATUS_PUM         0x00040000
 #define MSTATUS_MXR         0x00080000
+#define MSTATUS_TVM         0x00100000
+#define MSTATUS_TW          0x00200000
+#define MSTATUS_TSR         0x00400000
 #define MSTATUS32_SD        0x80000000
 #define MSTATUS64_SD        0x8000000000000000
 
index 35ff5dd8e525b1a94446544c98795b17a4e7b1cd..fc4625f0bfe033ca3070bcac8892805514368876 100644 (file)
@@ -1,2 +1,2 @@
-require_privilege(PRV_S);
+require_privilege(get_field(STATE.mstatus, MSTATUS_TVM) ? PRV_M : PRV_S);
 MMU.flush_tlb();
index b593198514115bbec7d1b3684f9a69d0edd81106..e4d05023b6d4c83ab80c09157a4ec2fa4e4c30a3 100644 (file)
@@ -1,4 +1,4 @@
-require_privilege(PRV_S);
+require_privilege(get_field(STATE.mstatus, MSTATUS_TSR) ? PRV_M : PRV_S);
 set_pc_and_serialize(p->get_state()->sepc);
 reg_t s = STATE.mstatus;
 reg_t prev_prv = get_field(s, MSTATUS_SPP);
index 643c3747cda991997651b8294d96021abeda159b..16de594408522bc52c89589bb899b6ac1a6e8a43 100644 (file)
@@ -1 +1,2 @@
+require_privilege(get_field(STATE.mstatus, MSTATUS_TW) ? PRV_M : PRV_S);
 set_pc_and_serialize(npc);
index 0f86f25fabe6fc4058d5a58f44b4b9e6bd600cc8..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);
 
@@ -527,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;