From: Andrew Waterman Date: Mon, 13 Mar 2017 21:48:52 +0000 (-0700) Subject: Implement mstatus.TW, mstatus.TVM, and mstatus.TSR X-Git-Url: https://git.libre-soc.org/?p=riscv-isa-sim.git;a=commitdiff_plain;h=17e3ef9618fb013abc4a7e78daad01663801cc36 Implement mstatus.TW, mstatus.TVM, and mstatus.TSR --- diff --git a/riscv/encoding.h b/riscv/encoding.h index 13930e8..0af9132 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -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 diff --git a/riscv/insns/sfence_vma.h b/riscv/insns/sfence_vma.h index 35ff5dd..fc4625f 100644 --- a/riscv/insns/sfence_vma.h +++ b/riscv/insns/sfence_vma.h @@ -1,2 +1,2 @@ -require_privilege(PRV_S); +require_privilege(get_field(STATE.mstatus, MSTATUS_TVM) ? PRV_M : PRV_S); MMU.flush_tlb(); diff --git a/riscv/insns/sret.h b/riscv/insns/sret.h index b593198..e4d0502 100644 --- a/riscv/insns/sret.h +++ b/riscv/insns/sret.h @@ -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); diff --git a/riscv/insns/wfi.h b/riscv/insns/wfi.h index 643c374..16de594 100644 --- a/riscv/insns/wfi.h +++ b/riscv/insns/wfi.h @@ -1 +1,2 @@ +require_privilege(get_field(STATE.mstatus, MSTATUS_TW) ? PRV_M : PRV_S); set_pc_and_serialize(npc); diff --git a/riscv/processor.cc b/riscv/processor.cc index 0f86f25..c2a7d49 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -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;