When working with hpm registers, we need to calculate counter index
by csr number. By now it was done manually. Let's add a function --
riscv_pmu_csrno_to_ctr_idx(), which incapsulates this action.
Signed-off-by: Aleksandr Sergeev <sergeev0xef@gmail.com>
Reviewed-by: Alexei Filippov <halip0503@gmail.com>
---
target/riscv/cpu_bits.h | 4 +++
target/riscv/csr.c | 73 ++++++++++++++---------------------------
target/riscv/pmu.c | 44 +++++++++++++++++++++++++
target/riscv/pmu.h | 1 +
4 files changed, 73 insertions(+), 49 deletions(-)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index b62dd82fe7..5c3c1af64e 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -1145,6 +1145,10 @@ typedef enum CTRType {
/* RISC-V-specific interrupt pending bits. */
#define CPU_INTERRUPT_RNMI CPU_INTERRUPT_TGT_EXT_0
+#define HPM_MCYCLE_IDX 0
+#define HPM_MTIME_IDX 1
+#define HPM_MINSTRET_IDX 2
+
/* JVT CSR bits */
#define JVT_MODE 0x3F
#define JVT_BASE (~0x3F)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5c91658c3d..8bdbc71160 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -110,17 +110,8 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
RISCVCPU *cpu = env_archcpu(env);
- int ctr_index;
- target_ulong ctr_mask;
- int base_csrno = CSR_CYCLE;
- bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
-
- if (rv32 && csrno >= CSR_CYCLEH) {
- /* Offset for RV32 hpmcounternh counters */
- base_csrno += 0x80;
- }
- ctr_index = csrno - base_csrno;
- ctr_mask = BIT(ctr_index);
+ uint32_t ctr_index = riscv_pmu_csrno_to_ctr_idx(csrno);
+ target_ulong ctr_mask = BIT(ctr_index);
if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
(csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
@@ -1166,9 +1157,9 @@ static RISCVException write_minstretcfgh(CPURISCVState *env, int csrno,
static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
target_ulong *val)
{
- int evt_index = csrno - CSR_MCOUNTINHIBIT;
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
- *val = env->mhpmevent_val[evt_index];
+ *val = env->mhpmevent_val[ctr_idx];
return RISCV_EXCP_NONE;
}
@@ -1176,14 +1167,15 @@ static RISCVException read_mhpmevent(CPURISCVState *env, int csrno,
static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
target_ulong val, uintptr_t ra)
{
- int evt_index = csrno - CSR_MCOUNTINHIBIT;
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
+
uint64_t mhpmevt_val = val;
uint64_t inh_avail_mask;
if (riscv_cpu_mxl(env) == MXL_RV32) {
- env->mhpmevent_val[evt_index] = val;
+ env->mhpmevent_val[ctr_idx] = val;
mhpmevt_val = mhpmevt_val |
- ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
+ ((uint64_t)env->mhpmeventh_val[ctr_idx] << 32);
} else {
inh_avail_mask = ~MHPMEVENT_FILTER_MASK | MHPMEVENT_BIT_MINH;
inh_avail_mask |= riscv_has_ext(env, RVU) ? MHPMEVENT_BIT_UINH : 0;
@@ -1193,10 +1185,10 @@ static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
inh_avail_mask |= (riscv_has_ext(env, RVH) &&
riscv_has_ext(env, RVS)) ? MHPMEVENT_BIT_VSINH : 0;
mhpmevt_val = val & inh_avail_mask;
- env->mhpmevent_val[evt_index] = mhpmevt_val;
+ env->mhpmevent_val[ctr_idx] = mhpmevt_val;
}
- riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
+ riscv_pmu_update_event_map(env, mhpmevt_val, ctr_idx);
return RISCV_EXCP_NONE;
}
@@ -1204,9 +1196,9 @@ static RISCVException write_mhpmevent(CPURISCVState *env, int csrno,
static RISCVException read_mhpmeventh(CPURISCVState *env, int csrno,
target_ulong *val)
{
- int evt_index = csrno - CSR_MHPMEVENT3H + 3;
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
- *val = env->mhpmeventh_val[evt_index];
+ *val = env->mhpmeventh_val[ctr_idx];
return RISCV_EXCP_NONE;
}
@@ -1214,9 +1206,9 @@ static RISCVException read_mhpmeventh(CPURISCVState *env, int csrno,
static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
target_ulong val, uintptr_t ra)
{
- int evt_index = csrno - CSR_MHPMEVENT3H + 3;
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
uint64_t mhpmevth_val;
- uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
+ uint64_t mhpmevt_val = env->mhpmevent_val[ctr_idx];
target_ulong inh_avail_mask = (target_ulong)(~MHPMEVENTH_FILTER_MASK |
MHPMEVENTH_BIT_MINH);
@@ -1229,9 +1221,9 @@ static RISCVException write_mhpmeventh(CPURISCVState *env, int csrno,
mhpmevth_val = val & inh_avail_mask;
mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
- env->mhpmeventh_val[evt_index] = mhpmevth_val;
+ env->mhpmeventh_val[ctr_idx] = mhpmevth_val;
- riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
+ riscv_pmu_update_event_map(env, mhpmevt_val, ctr_idx);
return RISCV_EXCP_NONE;
}
@@ -1357,7 +1349,7 @@ static RISCVException riscv_pmu_write_ctrh(CPURISCVState *env, target_ulong val,
static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
target_ulong val, uintptr_t ra)
{
- int ctr_idx = csrno - CSR_MCYCLE;
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
return riscv_pmu_write_ctr(env, val, ctr_idx);
}
@@ -1365,7 +1357,7 @@ static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
target_ulong val, uintptr_t ra)
{
- int ctr_idx = csrno - CSR_MCYCLEH;
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
return riscv_pmu_write_ctrh(env, val, ctr_idx);
}
@@ -1406,33 +1398,16 @@ RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
target_ulong *val)
{
- uint16_t ctr_index;
-
- if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
- ctr_index = csrno - CSR_MCYCLE;
- } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
- ctr_index = csrno - CSR_CYCLE;
- } else {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- return riscv_pmu_read_ctr(env, val, false, ctr_index);
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
+ return riscv_pmu_read_ctr(env, val, false, ctr_idx);
}
static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
target_ulong *val)
{
- uint16_t ctr_index;
- if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
- ctr_index = csrno - CSR_MCYCLEH;
- } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
- ctr_index = csrno - CSR_CYCLEH;
- } else {
- return RISCV_EXCP_ILLEGAL_INST;
- }
-
- return riscv_pmu_read_ctr(env, val, true, ctr_index);
+ uint32_t ctr_idx = riscv_pmu_csrno_to_ctr_idx(csrno);
+ return riscv_pmu_read_ctr(env, val, true, ctr_idx);
}
static int rmw_cd_mhpmcounter(CPURISCVState *env, int ctr_idx,
@@ -1599,8 +1574,8 @@ static int rmw_cd_ctr_cfgh(CPURISCVState *env, int cfg_index, target_ulong *val,
static RISCVException read_scountovf(CPURISCVState *env, int csrno,
target_ulong *val)
{
- int mhpmevt_start = CSR_MHPMEVENT3 - CSR_MCOUNTINHIBIT;
- int i;
+ uint32_t mhpmevt_start = riscv_pmu_csrno_to_ctr_idx(CSR_MHPMEVENT3);
+ uint32_t i;
*val = 0;
target_ulong *mhpm_evt_val;
uint64_t of_bit_mask;
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index a68809eef3..b983eadd83 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -600,3 +600,47 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
cpu->pmu_avail_ctrs = cpu->cfg.pmu_mask;
}
+
+uint32_t riscv_pmu_csrno_to_ctr_idx(int csrno)
+{
+ #define CASE_RANGE(low, high, offset) { \
+ case (low)...(high): \
+ return csrno - (low) + (offset); \
+ }
+ #define HPMCOUNTER_START (HPM_MINSTRET_IDX + 1)
+
+ switch (csrno) {
+ CASE_RANGE(CSR_MHPMEVENT3, CSR_MHPMEVENT31, HPMCOUNTER_START)
+ CASE_RANGE(CSR_MHPMEVENT3H, CSR_MHPMEVENT31H, HPMCOUNTER_START)
+ CASE_RANGE(CSR_HPMCOUNTER3, CSR_HPMCOUNTER31, HPMCOUNTER_START)
+ CASE_RANGE(CSR_HPMCOUNTER3H, CSR_HPMCOUNTER31H, HPMCOUNTER_START)
+ CASE_RANGE(CSR_MHPMCOUNTER3, CSR_MHPMCOUNTER31, HPMCOUNTER_START)
+ CASE_RANGE(CSR_MHPMCOUNTER3H, CSR_MHPMCOUNTER31H, HPMCOUNTER_START)
+
+ case CSR_MCYCLE:
+ case CSR_MCYCLEH:
+ case CSR_CYCLE:
+ case CSR_CYCLEH:
+ case CSR_MCYCLECFG:
+ case CSR_MCYCLECFGH:
+ return HPM_MCYCLE_IDX;
+
+ case CSR_MINSTRET:
+ case CSR_MINSTRETH:
+ case CSR_INSTRET:
+ case CSR_INSTRETH:
+ case CSR_MINSTRETCFG:
+ case CSR_MINSTRETCFGH:
+ return HPM_MINSTRET_IDX;
+
+ case CSR_TIME:
+ case CSR_TIMEH:
+ return HPM_MTIME_IDX;
+
+ default:
+ g_assert_not_reached();
+ }
+
+ #undef HPMCOUNTER_START
+ #undef CASE_RANGE
+}
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
index 3853d0e262..8f019bea9f 100644
--- a/target/riscv/pmu.h
+++ b/target/riscv/pmu.h
@@ -38,5 +38,6 @@ void riscv_pmu_update_fixed_ctrs(CPURISCVState *env, target_ulong newpriv,
bool new_virt);
RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
bool upper_half, uint32_t ctr_idx);
+uint32_t riscv_pmu_csrno_to_ctr_idx(int csrno);
#endif /* RISCV_PMU_H */
--
2.51.0
© 2016 - 2026 Red Hat, Inc.