aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Bradford <rbradford@rivosinc.com>2023-08-02 13:49:06 +0100
committerAlistair Francis <alistair.francis@wdc.com>2023-09-11 11:45:55 +1000
commitebe16b90395c70a8edbb7a0e855a8de2d3cfb4f9 (patch)
treea8fa8e24ee224ae1862eddc39d30300e40b6e0a8
parent8b045ff45420d12bdbd9868e83559ffaaf059144 (diff)
downloadqemu-ebe16b90395c70a8edbb7a0e855a8de2d3cfb4f9.zip
qemu-ebe16b90395c70a8edbb7a0e855a8de2d3cfb4f9.tar.gz
qemu-ebe16b90395c70a8edbb7a0e855a8de2d3cfb4f9.tar.bz2
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
These are WARL fields - zero out the bits for unavailable counters and special case the TM bit in mcountinhibit which is hardwired to zero. This patch achieves this by modifying the value written so that any use of the field will see the correctly masked bits. Tested by modifying OpenSBI to write max value to these CSRs and upon subsequent read the appropriate number of bits for number of PMUs is enabled and the TM bit is zero in mcountinhibit. Signed-off-by: Rob Bradford <rbradford@rivosinc.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Atish Patra <atishp@rivosinc.com> Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
-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 ca95ae1..661744e 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;
}