Re: [PATCH v6 06/12] target/riscv: Add support for hpmcounters/hpmevents

2022-03-30 Thread Atish Patra
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

2022-03-15 Thread Frank Chang
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

2022-03-03 Thread Atish Patra
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 },
-