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 <[email protected]> Reviewed-by: Alexei Filippov <[email protected]> --- 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
