aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/csr.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/riscv/csr.c')
-rw-r--r--target/riscv/csr.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5714147689..390d3a9a56 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -305,7 +305,8 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
}
mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
- MSTATUS_MPP | MSTATUS_MXR;
+ MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
+ MSTATUS_TW;
}
/* silenty discard mstatus.mpp writes for unsupported modes */
@@ -642,7 +643,11 @@ static int read_satp(CPURISCVState *env, int csrno, target_ulong *val)
if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
*val = 0;
} else if (env->priv_ver >= PRIV_VERSION_1_10_0) {
- *val = env->satp;
+ if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+ return -1;
+ } else {
+ *val = env->satp;
+ }
} else {
*val = env->sptbr;
}
@@ -663,8 +668,12 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
validate_vm(env, get_field(val, SATP_MODE)) &&
((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
{
- tlb_flush(CPU(riscv_env_get_cpu(env)));
- env->satp = val;
+ if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+ return -1;
+ } else {
+ tlb_flush(CPU(riscv_env_get_cpu(env)));
+ env->satp = val;
+ }
}
return 0;
}