aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target/riscv/csr.c11
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;
}