On 10/1/25 12:32 AM, Anton Johansson wrote:
According to version 20250508 of the privileged specification,
mhpmeventn is 64 bits in size and mhpmeventnh is only ever used
when XLEN == 32 and accesses the top 32 bits of the 64-bit
mhpmeventn registers. Combine the two arrays of target_ulong
mhpmeventh[] and mhpmevent[] to a single array of uint64_t.

This also allows for some minor code simplification where branches
handling either mhpmeventh[] or mhpmevent[] could be combined.

Signed-off-by: Anton Johansson <[email protected]>
---
  target/riscv/cpu.h     | 10 +++----
  target/riscv/csr.c     | 67 +++++++++++++++---------------------------
  target/riscv/machine.c |  3 +-
  target/riscv/pmu.c     | 53 ++++++++-------------------------
  4 files changed, 42 insertions(+), 91 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3235108112..64b9964028 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -427,11 +427,11 @@ struct CPUArchState {
      /* PMU counter state */
      PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
- /* PMU event selector configured values. First three are unused */
-    target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
-
-    /* PMU event selector configured values for RV32 */
-    target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
+    /*
+     * PMU event selector configured values. First three are unused.
+     * For RV32 top 32 bits are accessed via the mhpmeventh CSR.
+     */
+    uint64_t mhpmevent_val[RV_MAX_MHPMEVENTS];
PMUFixedCtrState pmu_fixed_ctrs[2]; diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 859f89aedd..2d8916ee40 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1166,8 +1166,9 @@ static RISCVException read_mhpmevent(CPURISCVState *env, 
int csrno,
                                       target_ulong *val)
  {
      int evt_index = csrno - CSR_MCOUNTINHIBIT;
+    bool rv32 = riscv_cpu_mxl(env) == MXL_RV32;
- *val = env->mhpmevent_val[evt_index];
+    *val = extract64(env->mhpmevent_val[evt_index], 0, rv32 ? 32 : 64);
return RISCV_EXCP_NONE;
  }
@@ -1176,13 +1177,11 @@ static RISCVException write_mhpmevent(CPURISCVState 
*env, int csrno,
                                        target_ulong val, uintptr_t ra)
  {
      int evt_index = csrno - CSR_MCOUNTINHIBIT;
-    uint64_t mhpmevt_val = val;
+    uint64_t mhpmevt_val;
      uint64_t inh_avail_mask;
if (riscv_cpu_mxl(env) == MXL_RV32) {
-        env->mhpmevent_val[evt_index] = val;
-        mhpmevt_val = mhpmevt_val |
-                      ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
+        mhpmevt_val = deposit64(env->mhpmevent_val[evt_index], 0, 32, val);

Maybe I missed something, but should it be:
deposit64(env->mhpmevent_val[evt_index], 32, 32, val)
instead?

Reading the rest of the patch, I'm a bit confused about which bits are supposed to be used in 32/64 mode.

Reply via email to