Re: [PATCH v6 06/12] target/riscv: Add support for hpmcounters/hpmevents
On Tue, Mar 15, 2022 at 12:41 AM Frank Chang wrote: > > Atish Patra 於 2022年3月4日 週五 上午8:06寫道: >> >> 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. >> >> Reviewed-by: Alistair Francis >> Reviewed-by: Bin Meng >> Signed-off-by: Atish Patra >> Signed-off-by: Atish Patra >> --- >> target/riscv/cpu.h | 11 + >> target/riscv/csr.c | 466 +++-- >> target/riscv/machine.c | 3 + >> 3 files changed, 328 insertions(+), 152 deletions(-) >> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h >> index 6667ec963707..3eedd7a5888a 100644 >> --- a/target/riscv/cpu.h >> +++ b/target/riscv/cpu.h >> @@ -109,6 +109,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) >> @@ -261,6 +263,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 9cfbd60aaeb4..10b6e498f059 100644 >> --- a/target/riscv/csr.c >> +++ b/target/riscv/csr.c >> @@ -86,6 +86,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) >> @@ -568,6 +577,72 @@ static RISCVException read_instreth(CPURISCVState *env, >> int csrno, >> 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) >> @@ -3531,157 +3606,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 }, >> -
Re: [PATCH v6 06/12] target/riscv: Add support for hpmcounters/hpmevents
Atish Patra 於 2022年3月4日 週五 上午8:06寫道: > 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. > > Reviewed-by: Alistair Francis > Reviewed-by: Bin Meng > Signed-off-by: Atish Patra > Signed-off-by: Atish Patra > --- > target/riscv/cpu.h | 11 + > target/riscv/csr.c | 466 +++-- > target/riscv/machine.c | 3 + > 3 files changed, 328 insertions(+), 152 deletions(-) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index 6667ec963707..3eedd7a5888a 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -109,6 +109,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) > @@ -261,6 +263,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 9cfbd60aaeb4..10b6e498f059 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -86,6 +86,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) > @@ -568,6 +577,72 @@ static RISCVException read_instreth(CPURISCVState > *env, int csrno, > 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) > @@ -3531,157 +3606,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 }, > -
[PATCH v6 06/12] 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. Reviewed-by: Alistair Francis Reviewed-by: Bin Meng Signed-off-by: Atish Patra Signed-off-by: Atish Patra --- target/riscv/cpu.h | 11 + target/riscv/csr.c | 466 +++-- target/riscv/machine.c | 3 + 3 files changed, 328 insertions(+), 152 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6667ec963707..3eedd7a5888a 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -109,6 +109,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) @@ -261,6 +263,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 9cfbd60aaeb4..10b6e498f059 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -86,6 +86,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) @@ -568,6 +577,72 @@ static RISCVException read_instreth(CPURISCVState *env, int csrno, 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) @@ -3531,157 +3606,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] = { "hpmcounter17", ctr,read_zero }, -[CSR_HPMCOUNTER18] = { "hpmcounter18", ctr,read_zero }, -[CSR_HPMCOUNTER19] = { "hpmcounter19", ctr,read_zero }, -