diff options
Diffstat (limited to 'target/riscv/pmp.c')
-rw-r--r-- | target/riscv/pmp.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index a1b36664..a185c24 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -575,6 +575,13 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index) void mseccfg_csr_write(CPURISCVState *env, target_ulong val) { int i; + uint64_t mask = MSECCFG_MMWP | MSECCFG_MML; + /* Update PMM field only if the value is valid according to Zjpm v1.0 */ + if (riscv_cpu_cfg(env)->ext_smmpm && + riscv_cpu_mxl(env) == MXL_RV64 && + get_field(val, MSECCFG_PMM) != PMM_FIELD_RESERVED) { + mask |= MSECCFG_PMM; + } trace_mseccfg_csr_write(env->mhartid, val); @@ -590,12 +597,13 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) if (riscv_cpu_cfg(env)->ext_smepmp) { /* Sticky bits */ - val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML)); - if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) { + val |= (env->mseccfg & mask); + if ((val ^ env->mseccfg) & mask) { tlb_flush(env_cpu(env)); } } else { - val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB); + mask |= MSECCFG_RLB; + val &= ~(mask); } /* M-mode forward cfi to be enabled if cfi extension is implemented */ |