Re: [PATCH v4 06/11] target/riscv: Add support for hpmcounters/hpmevents
On Fri, Jan 7, 2022 at 10:22 AM Atish Patra wrote: > > From: Atish Patra > > With SBI PMU extension, user can use any of the available hpmcounters to > track any perf events based on the value written to mhpmevent csr. > Add read/write functionality for these csrs. > > Signed-off-by: Atish Patra > Signed-off-by: Atish Patra > --- > target/riscv/cpu.h | 11 + > target/riscv/csr.c | 468 - > target/riscv/machine.c | 3 + > 3 files changed, 330 insertions(+), 152 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 6f2875fd9acd..39edc948d703 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -101,6 +101,8 @@ typedef struct CPURISCVState CPURISCVState; > #endif > > #define RV_VLEN_MAX 1024 > +#define RV_MAX_MHPMEVENTS 29 > +#define RV_MAX_MHPMCOUNTERS 32 > > FIELD(VTYPE, VLMUL, 0, 3) > FIELD(VTYPE, VSEW, 3, 3) > @@ -224,6 +226,15 @@ struct CPURISCVState { > > target_ulong mcountinhibit; > > +/* PMU counter configured values */ > +target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS]; > + > +/* for RV32 */ > +target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS]; > + > +/* PMU event selector configured values */ > +target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS]; > + > target_ulong sscratch; > target_ulong mscratch; > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c > index 89d15b38be7c..58a9550bd898 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -80,6 +80,15 @@ static RISCVException mctr(CPURISCVState *env, int csrno) > return RISCV_EXCP_NONE; > } > > +static RISCVException mctr32(CPURISCVState *env, int csrno) > +{ > +if (riscv_cpu_mxl(env) != MXL_RV32) { > +return RISCV_EXCP_ILLEGAL_INST; > +} > + > +return mctr(env, csrno); > +} > + > static RISCVException ctr(CPURISCVState *env, int csrno) > { > #if !defined(CONFIG_USER_ONLY) > @@ -464,6 +473,7 @@ static RISCVException read_instret(CPURISCVState *env, > int csrno, > #else > *val = cpu_get_host_ticks(); > #endif > + nits: it looks like this change is unnecessary, and is causing a not-so-good git diff here, and below for read_instreth() > return RISCV_EXCP_NONE; > } > > @@ -479,9 +489,76 @@ static RISCVException read_instreth(CPURISCVState *env, > int csrno, > #else > *val = cpu_get_host_ticks() >> 32; > #endif > + > +return RISCV_EXCP_NONE; > +} nits: ditto > + > +static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val) > +{ > +int evt_index = csrno - CSR_MHPMEVENT3; > + > +*val = env->mhpmevent_val[evt_index]; > + > +return RISCV_EXCP_NONE; > +} > + > +static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val) > +{ > +int evt_index = csrno - CSR_MHPMEVENT3; > + > +env->mhpmevent_val[evt_index] = val; > + > +return RISCV_EXCP_NONE; > +} > + > +static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val) > +{ > +int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3; > + > +env->mhpmcounter_val[ctr_index] = val; > + > return RISCV_EXCP_NONE; > } > > +static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong > val) > +{ > +int ctr_index = csrno - CSR_MHPMCOUNTER3H + 3; > + > +env->mhpmcounterh_val[ctr_index] = val; > + > +return RISCV_EXCP_NONE; > +} > + > +static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val) > +{ > +int ctr_index; > + > +if (env->priv == PRV_M) { > +ctr_index = csrno - CSR_MHPMCOUNTER3 + 3; > +} else { > +ctr_index = csrno - CSR_HPMCOUNTER3 + 3; > +} > +*val = env->mhpmcounter_val[ctr_index]; > + > +return RISCV_EXCP_NONE; > +} > + > +static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val) > +{ > +int ctr_index; > + > +if (env->priv == PRV_M) { > +ctr_index = csrno - CSR_MHPMCOUNTER3H + 3; > +} else { > +ctr_index = csrno - CSR_HPMCOUNTER3H + 3; > +} > + > +*val = env->mhpmcounterh_val[ctr_index]; > + > +return RISCV_EXCP_NONE; > +} > + > + > #if defined(CONFIG_USER_ONLY) > static RISCVException read_time(CPURISCVState *env, int csrno, > target_ulong *val) > @@ -2082,157 +2159,244 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { > [CSR_SPMBASE] ={ "spmbase", pointer_masking, read_spmbase, > write_spmbase }, > > /* Performance Counters */ > -[CSR_HPMCOUNTER3]= { "hpmcounter3",ctr,read_zero }, > -[CSR_HPMCOUNTER4]= { "hpmcounter4",ctr,read_zero }, > -[CSR_HPMCOUNTER5]= { "hpmcounter5",ctr,read_zero }, > -[CSR_HPMCOUNTER6]= { "hpmcounter6",ctr,read_zero }, > -[CSR_HPMCOUNTER7]= { "hpmcounter7",ctr,read_zero }, > -[CSR_HPMCOUNTER8]= { "hpmcounter8",ctr,read_zero }, > -[CSR_HPMCOUNTER9]= { "hpmcounter9",ctr,read_zero }, > -[CSR_HPMCOUNTER1
[PATCH v4 06/11] target/riscv: Add support for hpmcounters/hpmevents
From: Atish Patra With SBI PMU extension, user can use any of the available hpmcounters to track any perf events based on the value written to mhpmevent csr. Add read/write functionality for these csrs. Signed-off-by: Atish Patra Signed-off-by: Atish Patra --- target/riscv/cpu.h | 11 + target/riscv/csr.c | 468 - target/riscv/machine.c | 3 + 3 files changed, 330 insertions(+), 152 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6f2875fd9acd..39edc948d703 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -101,6 +101,8 @@ typedef struct CPURISCVState CPURISCVState; #endif #define RV_VLEN_MAX 1024 +#define RV_MAX_MHPMEVENTS 29 +#define RV_MAX_MHPMCOUNTERS 32 FIELD(VTYPE, VLMUL, 0, 3) FIELD(VTYPE, VSEW, 3, 3) @@ -224,6 +226,15 @@ struct CPURISCVState { target_ulong mcountinhibit; +/* PMU counter configured values */ +target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS]; + +/* for RV32 */ +target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS]; + +/* PMU event selector configured values */ +target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS]; + target_ulong sscratch; target_ulong mscratch; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 89d15b38be7c..58a9550bd898 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -80,6 +80,15 @@ static RISCVException mctr(CPURISCVState *env, int csrno) return RISCV_EXCP_NONE; } +static RISCVException mctr32(CPURISCVState *env, int csrno) +{ +if (riscv_cpu_mxl(env) != MXL_RV32) { +return RISCV_EXCP_ILLEGAL_INST; +} + +return mctr(env, csrno); +} + static RISCVException ctr(CPURISCVState *env, int csrno) { #if !defined(CONFIG_USER_ONLY) @@ -464,6 +473,7 @@ static RISCVException read_instret(CPURISCVState *env, int csrno, #else *val = cpu_get_host_ticks(); #endif + return RISCV_EXCP_NONE; } @@ -479,9 +489,76 @@ static RISCVException read_instreth(CPURISCVState *env, int csrno, #else *val = cpu_get_host_ticks() >> 32; #endif + +return RISCV_EXCP_NONE; +} + +static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val) +{ +int evt_index = csrno - CSR_MHPMEVENT3; + +*val = env->mhpmevent_val[evt_index]; + +return RISCV_EXCP_NONE; +} + +static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val) +{ +int evt_index = csrno - CSR_MHPMEVENT3; + +env->mhpmevent_val[evt_index] = val; + +return RISCV_EXCP_NONE; +} + +static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val) +{ +int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3; + +env->mhpmcounter_val[ctr_index] = val; + return RISCV_EXCP_NONE; } +static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val) +{ +int ctr_index = csrno - CSR_MHPMCOUNTER3H + 3; + +env->mhpmcounterh_val[ctr_index] = val; + +return RISCV_EXCP_NONE; +} + +static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val) +{ +int ctr_index; + +if (env->priv == PRV_M) { +ctr_index = csrno - CSR_MHPMCOUNTER3 + 3; +} else { +ctr_index = csrno - CSR_HPMCOUNTER3 + 3; +} +*val = env->mhpmcounter_val[ctr_index]; + +return RISCV_EXCP_NONE; +} + +static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val) +{ +int ctr_index; + +if (env->priv == PRV_M) { +ctr_index = csrno - CSR_MHPMCOUNTER3H + 3; +} else { +ctr_index = csrno - CSR_HPMCOUNTER3H + 3; +} + +*val = env->mhpmcounterh_val[ctr_index]; + +return RISCV_EXCP_NONE; +} + + #if defined(CONFIG_USER_ONLY) static RISCVException read_time(CPURISCVState *env, int csrno, target_ulong *val) @@ -2082,157 +2159,244 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_SPMBASE] ={ "spmbase", pointer_masking, read_spmbase, write_spmbase }, /* Performance Counters */ -[CSR_HPMCOUNTER3]= { "hpmcounter3",ctr,read_zero }, -[CSR_HPMCOUNTER4]= { "hpmcounter4",ctr,read_zero }, -[CSR_HPMCOUNTER5]= { "hpmcounter5",ctr,read_zero }, -[CSR_HPMCOUNTER6]= { "hpmcounter6",ctr,read_zero }, -[CSR_HPMCOUNTER7]= { "hpmcounter7",ctr,read_zero }, -[CSR_HPMCOUNTER8]= { "hpmcounter8",ctr,read_zero }, -[CSR_HPMCOUNTER9]= { "hpmcounter9",ctr,read_zero }, -[CSR_HPMCOUNTER10] = { "hpmcounter10", ctr,read_zero }, -[CSR_HPMCOUNTER11] = { "hpmcounter11", ctr,read_zero }, -[CSR_HPMCOUNTER12] = { "hpmcounter12", ctr,read_zero }, -[CSR_HPMCOUNTER13] = { "hpmcounter13", ctr,read_zero }, -[CSR_HPMCOUNTER14] = { "hpmcounter14", ctr,read_zero }, -[CSR_HPMCOUNTER15] = { "hpmcounter15", ctr,read_zero }, -[CSR_HPMCOUNTER16] = { "hpmcounter16", ctr,read_zero }, -[CSR_HPMCOUNTER17] = { "hpmcoun