diff options
-rw-r--r-- | target/riscv/csr.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c index ca95ae1527..661744e6d4 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1833,8 +1833,11 @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno, { int cidx; PMUCTRState *counter; + RISCVCPU *cpu = env_archcpu(env); - env->mcountinhibit = val; + /* WARL register - disable unavailable counters; TM bit is always 0 */ + env->mcountinhibit = + val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR); /* Check if any other counter is also monitoring cycles/instructions */ for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) { @@ -1857,7 +1860,11 @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno, static RISCVException write_mcounteren(CPURISCVState *env, int csrno, target_ulong val) { - env->mcounteren = val; + RISCVCPU *cpu = env_archcpu(env); + + /* WARL register - disable unavailable counters */ + env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM | + COUNTEREN_IR); return RISCV_EXCP_NONE; } |