Message ID | 20220107004846.378859-5-atishp@rivosinc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Improve PMU support | expand |
On Fri, Jan 7, 2022 at 10:18 AM Atish Patra <atishp@rivosinc.com> wrote: > > The RISC-V privilege specification provides flexibility to implement > any number of counters from 29 programmable counters. However, the QEMU > implements all the counters. > > Make it configurable through pmu config parameter which now will indicate > how many programmable counters should be implemented by the cpu. > > Signed-off-by: Atish Patra <atish.patra@wdc.com> > Signed-off-by: Atish Patra <atishp@rivosinc.com> > --- > target/riscv/cpu.c | 2 +- > target/riscv/cpu.h | 2 +- > target/riscv/csr.c | 96 ++++++++++++++++++++++++++++++---------------- > 3 files changed, 65 insertions(+), 35 deletions(-) > Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
On Fri, Jan 7, 2022 at 12:19 PM Atish Patra <atishp@rivosinc.com> wrote: > > The RISC-V privilege specification provides flexibility to implement > any number of counters from 29 programmable counters. However, the QEMU > implements all the counters. > > Make it configurable through pmu config parameter which now will indicate > how many programmable counters should be implemented by the cpu. > > Signed-off-by: Atish Patra <atish.patra@wdc.com> > Signed-off-by: Atish Patra <atishp@rivosinc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > target/riscv/cpu.c | 2 +- > target/riscv/cpu.h | 2 +- > target/riscv/csr.c | 96 ++++++++++++++++++++++++++++++---------------- > 3 files changed, 65 insertions(+), 35 deletions(-) > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c > index df87489f6d87..9448c4335347 100644 > --- a/target/riscv/cpu.c > +++ b/target/riscv/cpu.c > @@ -627,7 +627,7 @@ static Property riscv_cpu_properties[] = { > DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true), > DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true), > DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false), > - DEFINE_PROP_BOOL("pmu", RISCVCPU, cfg.ext_pmu, true), > + DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), > DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), > DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), > DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false), > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 16d0b4f139ee..b353770596e8 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -312,12 +312,12 @@ struct RISCVCPU { > bool ext_zbb; > bool ext_zbc; > bool ext_zbs; > - bool ext_pmu; > bool ext_ifencei; > bool ext_icsr; > bool ext_zfh; > bool ext_zfhmin; > > + uint8_t pmu_num; > char *priv_spec; > char *user_spec; > char *bext_spec; > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index a6e856b896a9..e31c27e270a2 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -58,15 +58,45 @@ static RISCVException vs(CPURISCVState *env, int csrno) > return RISCV_EXCP_ILLEGAL_INST; > } > > +static RISCVException mctr(CPURISCVState *env, int csrno) > +{ > +#if !defined(CONFIG_USER_ONLY) > + CPUState *cs = env_cpu(env); > + RISCVCPU *cpu = RISCV_CPU(cs); > + int ctr_index; > + int base_csrno = CSR_MHPMCOUNTER3; > + > + if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) { > + /* Offset for RV32 mhpmcounternh counters */ > + base_csrno += 0x80; > + } > + ctr_index = csrno - base_csrno; > + if (!cpu->cfg.pmu_num || ctr_index >= cpu->cfg.pmu_num) { > + /* The PMU is not enabled or counter is out of range*/ > + return RISCV_EXCP_ILLEGAL_INST; > + } > + > +#endif > + return RISCV_EXCP_NONE; > +} > + > static RISCVException ctr(CPURISCVState *env, int csrno) > { > #if !defined(CONFIG_USER_ONLY) > CPUState *cs = env_cpu(env); > RISCVCPU *cpu = RISCV_CPU(cs); > int ctr_index; > + int base_csrno = CSR_HPMCOUNTER3; > + 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; > > - if (!cpu->cfg.ext_pmu) { > - /* The PMU extension is not enabled */ > + if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) { > + /* No counter is enabled in PMU or the counter is out of range */ > return RISCV_EXCP_ILLEGAL_INST; > } > > @@ -94,7 +124,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno) > } > break; > } > - if (riscv_cpu_is_32bit(env)) { > + if (rv32) { > switch (csrno) { > case CSR_CYCLEH: > if (!get_field(env->mcounteren, COUNTEREN_CY)) { > @@ -149,7 +179,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno) > } > break; > } > - if (riscv_cpu_mxl(env) == MXL_RV32) { > + if (rv32) { > switch (csrno) { > case CSR_CYCLEH: > if (!get_field(env->hcounteren, COUNTEREN_CY) && > @@ -2060,35 +2090,35 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { > [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero }, > [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero }, > > - [CSR_MHPMCOUNTER3] = { "mhpmcounter3", any, read_zero }, > - [CSR_MHPMCOUNTER4] = { "mhpmcounter4", any, read_zero }, > - [CSR_MHPMCOUNTER5] = { "mhpmcounter5", any, read_zero }, > - [CSR_MHPMCOUNTER6] = { "mhpmcounter6", any, read_zero }, > - [CSR_MHPMCOUNTER7] = { "mhpmcounter7", any, read_zero }, > - [CSR_MHPMCOUNTER8] = { "mhpmcounter8", any, read_zero }, > - [CSR_MHPMCOUNTER9] = { "mhpmcounter9", any, read_zero }, > - [CSR_MHPMCOUNTER10] = { "mhpmcounter10", any, read_zero }, > - [CSR_MHPMCOUNTER11] = { "mhpmcounter11", any, read_zero }, > - [CSR_MHPMCOUNTER12] = { "mhpmcounter12", any, read_zero }, > - [CSR_MHPMCOUNTER13] = { "mhpmcounter13", any, read_zero }, > - [CSR_MHPMCOUNTER14] = { "mhpmcounter14", any, read_zero }, > - [CSR_MHPMCOUNTER15] = { "mhpmcounter15", any, read_zero }, > - [CSR_MHPMCOUNTER16] = { "mhpmcounter16", any, read_zero }, > - [CSR_MHPMCOUNTER17] = { "mhpmcounter17", any, read_zero }, > - [CSR_MHPMCOUNTER18] = { "mhpmcounter18", any, read_zero }, > - [CSR_MHPMCOUNTER19] = { "mhpmcounter19", any, read_zero }, > - [CSR_MHPMCOUNTER20] = { "mhpmcounter20", any, read_zero }, > - [CSR_MHPMCOUNTER21] = { "mhpmcounter21", any, read_zero }, > - [CSR_MHPMCOUNTER22] = { "mhpmcounter22", any, read_zero }, > - [CSR_MHPMCOUNTER23] = { "mhpmcounter23", any, read_zero }, > - [CSR_MHPMCOUNTER24] = { "mhpmcounter24", any, read_zero }, > - [CSR_MHPMCOUNTER25] = { "mhpmcounter25", any, read_zero }, > - [CSR_MHPMCOUNTER26] = { "mhpmcounter26", any, read_zero }, > - [CSR_MHPMCOUNTER27] = { "mhpmcounter27", any, read_zero }, > - [CSR_MHPMCOUNTER28] = { "mhpmcounter28", any, read_zero }, > - [CSR_MHPMCOUNTER29] = { "mhpmcounter29", any, read_zero }, > - [CSR_MHPMCOUNTER30] = { "mhpmcounter30", any, read_zero }, > - [CSR_MHPMCOUNTER31] = { "mhpmcounter31", any, read_zero }, > + [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_zero }, > + [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_zero }, > + [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_zero }, > + [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_zero }, > + [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_zero }, > + [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_zero }, > + [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_zero }, > + [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_zero }, > + [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_zero }, > + [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_zero }, > + [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_zero }, > + [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_zero }, > + [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_zero }, > + [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_zero }, > + [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_zero }, > + [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_zero }, > + [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_zero }, > + [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_zero }, > + [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_zero }, > + [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_zero }, > + [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_zero }, > + [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_zero }, > + [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_zero }, > + [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_zero }, > + [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_zero }, > + [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_zero }, > + [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_zero }, > + [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_zero }, > + [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_zero }, > > [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero }, > [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero }, > -- > 2.30.2 > >
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index df87489f6d87..9448c4335347 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -627,7 +627,7 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true), DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true), DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false), - DEFINE_PROP_BOOL("pmu", RISCVCPU, cfg.ext_pmu, true), + DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16), DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true), DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true), DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 16d0b4f139ee..b353770596e8 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -312,12 +312,12 @@ struct RISCVCPU { bool ext_zbb; bool ext_zbc; bool ext_zbs; - bool ext_pmu; bool ext_ifencei; bool ext_icsr; bool ext_zfh; bool ext_zfhmin; + uint8_t pmu_num; char *priv_spec; char *user_spec; char *bext_spec; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a6e856b896a9..e31c27e270a2 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -58,15 +58,45 @@ static RISCVException vs(CPURISCVState *env, int csrno) return RISCV_EXCP_ILLEGAL_INST; } +static RISCVException mctr(CPURISCVState *env, int csrno) +{ +#if !defined(CONFIG_USER_ONLY) + CPUState *cs = env_cpu(env); + RISCVCPU *cpu = RISCV_CPU(cs); + int ctr_index; + int base_csrno = CSR_MHPMCOUNTER3; + + if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) { + /* Offset for RV32 mhpmcounternh counters */ + base_csrno += 0x80; + } + ctr_index = csrno - base_csrno; + if (!cpu->cfg.pmu_num || ctr_index >= cpu->cfg.pmu_num) { + /* The PMU is not enabled or counter is out of range*/ + return RISCV_EXCP_ILLEGAL_INST; + } + +#endif + return RISCV_EXCP_NONE; +} + static RISCVException ctr(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) CPUState *cs = env_cpu(env); RISCVCPU *cpu = RISCV_CPU(cs); int ctr_index; + int base_csrno = CSR_HPMCOUNTER3; + 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; - if (!cpu->cfg.ext_pmu) { - /* The PMU extension is not enabled */ + if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) { + /* No counter is enabled in PMU or the counter is out of range */ return RISCV_EXCP_ILLEGAL_INST; } @@ -94,7 +124,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno) } break; } - if (riscv_cpu_is_32bit(env)) { + if (rv32) { switch (csrno) { case CSR_CYCLEH: if (!get_field(env->mcounteren, COUNTEREN_CY)) { @@ -149,7 +179,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno) } break; } - if (riscv_cpu_mxl(env) == MXL_RV32) { + if (rv32) { switch (csrno) { case CSR_CYCLEH: if (!get_field(env->hcounteren, COUNTEREN_CY) && @@ -2060,35 +2090,35 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero }, [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero }, - [CSR_MHPMCOUNTER3] = { "mhpmcounter3", any, read_zero }, - [CSR_MHPMCOUNTER4] = { "mhpmcounter4", any, read_zero }, - [CSR_MHPMCOUNTER5] = { "mhpmcounter5", any, read_zero }, - [CSR_MHPMCOUNTER6] = { "mhpmcounter6", any, read_zero }, - [CSR_MHPMCOUNTER7] = { "mhpmcounter7", any, read_zero }, - [CSR_MHPMCOUNTER8] = { "mhpmcounter8", any, read_zero }, - [CSR_MHPMCOUNTER9] = { "mhpmcounter9", any, read_zero }, - [CSR_MHPMCOUNTER10] = { "mhpmcounter10", any, read_zero }, - [CSR_MHPMCOUNTER11] = { "mhpmcounter11", any, read_zero }, - [CSR_MHPMCOUNTER12] = { "mhpmcounter12", any, read_zero }, - [CSR_MHPMCOUNTER13] = { "mhpmcounter13", any, read_zero }, - [CSR_MHPMCOUNTER14] = { "mhpmcounter14", any, read_zero }, - [CSR_MHPMCOUNTER15] = { "mhpmcounter15", any, read_zero }, - [CSR_MHPMCOUNTER16] = { "mhpmcounter16", any, read_zero }, - [CSR_MHPMCOUNTER17] = { "mhpmcounter17", any, read_zero }, - [CSR_MHPMCOUNTER18] = { "mhpmcounter18", any, read_zero }, - [CSR_MHPMCOUNTER19] = { "mhpmcounter19", any, read_zero }, - [CSR_MHPMCOUNTER20] = { "mhpmcounter20", any, read_zero }, - [CSR_MHPMCOUNTER21] = { "mhpmcounter21", any, read_zero }, - [CSR_MHPMCOUNTER22] = { "mhpmcounter22", any, read_zero }, - [CSR_MHPMCOUNTER23] = { "mhpmcounter23", any, read_zero }, - [CSR_MHPMCOUNTER24] = { "mhpmcounter24", any, read_zero }, - [CSR_MHPMCOUNTER25] = { "mhpmcounter25", any, read_zero }, - [CSR_MHPMCOUNTER26] = { "mhpmcounter26", any, read_zero }, - [CSR_MHPMCOUNTER27] = { "mhpmcounter27", any, read_zero }, - [CSR_MHPMCOUNTER28] = { "mhpmcounter28", any, read_zero }, - [CSR_MHPMCOUNTER29] = { "mhpmcounter29", any, read_zero }, - [CSR_MHPMCOUNTER30] = { "mhpmcounter30", any, read_zero }, - [CSR_MHPMCOUNTER31] = { "mhpmcounter31", any, read_zero }, + [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_zero }, + [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_zero }, + [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_zero }, + [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_zero }, + [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_zero }, + [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_zero }, + [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_zero }, + [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_zero }, + [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_zero }, + [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_zero }, + [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_zero }, + [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_zero }, + [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_zero }, + [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_zero }, + [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_zero }, + [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_zero }, + [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_zero }, + [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_zero }, + [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_zero }, + [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_zero }, + [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_zero }, + [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_zero }, + [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_zero }, + [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_zero }, + [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_zero }, + [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_zero }, + [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_zero }, + [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_zero }, + [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_zero }, [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero }, [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero },