Re: [PATCH 1/9] target/riscv: debug: Determine the trigger type from tdata1.type

2022-06-14 Thread Bin Meng
On Fri, Jun 10, 2022 at 1:20 PM  wrote:
>
> From: Frank Chang 
>
> Current RISC-V debug assumes that only type 2 trigger is supported.
> To allow more types of triggers to be supported in the future
> (e.g. type 6 trigger, which is similar to type 2 trigger with additional
>  functionality), we should determine the trigger type from tdata1.type.
>
> RV_MAX_TRIGGERS is also introduced in replacement of TRIGGER_TYPE2_NUM.
>
> Signed-off-by: Frank Chang 
> ---
>  target/riscv/cpu.h |   2 +-
>  target/riscv/csr.c |   2 +-
>  target/riscv/debug.c   | 183 -
>  target/riscv/debug.h   |  15 ++--
>  target/riscv/machine.c |   2 +-
>  5 files changed, 137 insertions(+), 67 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 7d6397acdf..535123a989 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -289,7 +289,7 @@ struct CPUArchState {
>
>  /* trigger module */
>  target_ulong trigger_cur;
> -type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM];
> +type2_trigger_t type2_trig[RV_MAX_TRIGGERS];
>
>  /* machine specific rdtime callback */
>  uint64_t (*rdtime_fn)(void *);
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 6dbe9b541f..005ae31a01 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -2776,7 +2776,7 @@ static RISCVException read_tdata(CPURISCVState *env, 
> int csrno,
>   target_ulong *val)
>  {
>  /* return 0 in tdata1 to end the trigger enumeration */
> -if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
> +if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
>  *val = 0;
>  return RISCV_EXCP_NONE;
>  }
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index fc6e13222f..abbcd38a17 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -52,8 +52,15 @@
>  /* tdata availability of a trigger */
>  typedef bool tdata_avail[TDATA_NUM];
>
> -static tdata_avail tdata_mapping[TRIGGER_NUM] = {
> -[TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false },
> +static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = {
> +[TRIGGER_TYPE_NO_EXIST] = { false, false, false },
> +[TRIGGER_TYPE_AD_MATCH] = { true, true, true },
> +[TRIGGER_TYPE_INST_CNT] = { true, false, true },
> +[TRIGGER_TYPE_INT] = { true, true, true },
> +[TRIGGER_TYPE_EXCP] = { true, true, true },
> +[TRIGGER_TYPE_AD_MATCH6] = { true, true, true },
> +[TRIGGER_TYPE_EXT_SRC] = { true, false, false },
> +[TRIGGER_TYPE_UNAVAIL] = { true, true, true }
>  };
>
>  /* only breakpoint size 1/2/4/8 supported */
> @@ -67,6 +74,26 @@ static int access_size[SIZE_NUM] = {
>  [6 ... 15] = -1,
>  };
>
> +static inline target_ulong extract_trigger_type(CPURISCVState *env,
> +target_ulong tdata1)
> +{
> +switch (riscv_cpu_mxl(env)) {
> +case MXL_RV32:
> +return extract32(tdata1, 28, 4);
> +case MXL_RV64:
> +return extract64(tdata1, 60, 4);

I guess we should add a "case MXL_RV128" here so that it won't break rv128.
See commit d1d8541217ce8a23e9e751cd868c7d618817134a

> +default:
> +g_assert_not_reached();
> +}
> +}
> +
> +static inline target_ulong get_trigger_type(CPURISCVState *env,
> +target_ulong trigger_index)
> +{
> +target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol;
> +return extract_trigger_type(env, tdata1);
> +}
> +
>  static inline target_ulong trigger_type(CPURISCVState *env,
>  trigger_type_t type)
>  {
> @@ -89,15 +116,17 @@ static inline target_ulong trigger_type(CPURISCVState 
> *env,
>
>  bool tdata_available(CPURISCVState *env, int tdata_index)
>  {
> +int trigger_type = get_trigger_type(env, env->trigger_cur);
> +
>  if (unlikely(tdata_index >= TDATA_NUM)) {
>  return false;
>  }
>
> -if (unlikely(env->trigger_cur >= TRIGGER_NUM)) {
> +if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) {
>  return false;
>  }
>
> -return tdata_mapping[env->trigger_cur][tdata_index];
> +return tdata_mapping[trigger_type][tdata_index];
>  }
>
>  target_ulong tselect_csr_read(CPURISCVState *env)
> @@ -137,6 +166,7 @@ static target_ulong tdata1_validate(CPURISCVState *env, 
> target_ulong val,
>  qemu_log_mask(LOG_GUEST_ERROR,
>"ignoring type write to tdata1 register\n");
>  }
> +
>  if (dmode != 0) {
>  qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n");
>  }
> @@ -261,9 +291,8 @@ static void type2_breakpoint_remove(CPURISCVState *env, 
> target_ulong index)
>  }
>
>  static target_ulong type2_reg_read(CPURISCVState *env,
> -   target_ulong trigger_index, int 
> tdata_index)
> +   target_ulong index, int tdata_index)
>  {

Re: [PATCH 1/9] target/riscv: debug: Determine the trigger type from tdata1.type

2022-06-14 Thread Bin Meng
On Fri, Jun 10, 2022 at 1:20 PM  wrote:
>
> From: Frank Chang 
>
> Current RISC-V debug assumes that only type 2 trigger is supported.
> To allow more types of triggers to be supported in the future
> (e.g. type 6 trigger, which is similar to type 2 trigger with additional
>  functionality), we should determine the trigger type from tdata1.type.
>
> RV_MAX_TRIGGERS is also introduced in replacement of TRIGGER_TYPE2_NUM.
>
> Signed-off-by: Frank Chang 
> ---
>  target/riscv/cpu.h |   2 +-
>  target/riscv/csr.c |   2 +-
>  target/riscv/debug.c   | 183 -
>  target/riscv/debug.h   |  15 ++--
>  target/riscv/machine.c |   2 +-
>  5 files changed, 137 insertions(+), 67 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 7d6397acdf..535123a989 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -289,7 +289,7 @@ struct CPUArchState {
>
>  /* trigger module */
>  target_ulong trigger_cur;
> -type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM];
> +type2_trigger_t type2_trig[RV_MAX_TRIGGERS];
>
>  /* machine specific rdtime callback */
>  uint64_t (*rdtime_fn)(void *);
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 6dbe9b541f..005ae31a01 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -2776,7 +2776,7 @@ static RISCVException read_tdata(CPURISCVState *env, 
> int csrno,
>   target_ulong *val)
>  {
>  /* return 0 in tdata1 to end the trigger enumeration */
> -if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
> +if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
>  *val = 0;
>  return RISCV_EXCP_NONE;
>  }
> diff --git a/target/riscv/debug.c b/target/riscv/debug.c
> index fc6e13222f..abbcd38a17 100644
> --- a/target/riscv/debug.c
> +++ b/target/riscv/debug.c
> @@ -52,8 +52,15 @@
>  /* tdata availability of a trigger */
>  typedef bool tdata_avail[TDATA_NUM];
>
> -static tdata_avail tdata_mapping[TRIGGER_NUM] = {
> -[TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false },
> +static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = {
> +[TRIGGER_TYPE_NO_EXIST] = { false, false, false },
> +[TRIGGER_TYPE_AD_MATCH] = { true, true, true },
> +[TRIGGER_TYPE_INST_CNT] = { true, false, true },
> +[TRIGGER_TYPE_INT] = { true, true, true },
> +[TRIGGER_TYPE_EXCP] = { true, true, true },
> +[TRIGGER_TYPE_AD_MATCH6] = { true, true, true },
> +[TRIGGER_TYPE_EXT_SRC] = { true, false, false },
> +[TRIGGER_TYPE_UNAVAIL] = { true, true, true }
>  };
>
>  /* only breakpoint size 1/2/4/8 supported */
> @@ -67,6 +74,26 @@ static int access_size[SIZE_NUM] = {
>  [6 ... 15] = -1,
>  };
>
> +static inline target_ulong extract_trigger_type(CPURISCVState *env,
> +target_ulong tdata1)
> +{
> +switch (riscv_cpu_mxl(env)) {
> +case MXL_RV32:
> +return extract32(tdata1, 28, 4);
> +case MXL_RV64:
> +return extract64(tdata1, 60, 4);
> +default:
> +g_assert_not_reached();
> +}
> +}
> +
> +static inline target_ulong get_trigger_type(CPURISCVState *env,
> +target_ulong trigger_index)
> +{
> +target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol;
> +return extract_trigger_type(env, tdata1);
> +}
> +
>  static inline target_ulong trigger_type(CPURISCVState *env,
>  trigger_type_t type)
>  {
> @@ -89,15 +116,17 @@ static inline target_ulong trigger_type(CPURISCVState 
> *env,
>
>  bool tdata_available(CPURISCVState *env, int tdata_index)
>  {
> +int trigger_type = get_trigger_type(env, env->trigger_cur);
> +
>  if (unlikely(tdata_index >= TDATA_NUM)) {
>  return false;
>  }
>
> -if (unlikely(env->trigger_cur >= TRIGGER_NUM)) {
> +if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) {
>  return false;
>  }
>
> -return tdata_mapping[env->trigger_cur][tdata_index];
> +return tdata_mapping[trigger_type][tdata_index];
>  }
>
>  target_ulong tselect_csr_read(CPURISCVState *env)
> @@ -137,6 +166,7 @@ static target_ulong tdata1_validate(CPURISCVState *env, 
> target_ulong val,
>  qemu_log_mask(LOG_GUEST_ERROR,
>"ignoring type write to tdata1 register\n");
>  }
> +
>  if (dmode != 0) {
>  qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n");
>  }
> @@ -261,9 +291,8 @@ static void type2_breakpoint_remove(CPURISCVState *env, 
> target_ulong index)
>  }
>
>  static target_ulong type2_reg_read(CPURISCVState *env,
> -   target_ulong trigger_index, int 
> tdata_index)
> +   target_ulong index, int tdata_index)
>  {
> -uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0;
>  target_ulong tdata;
>
>  switch (tdata_index) {
> @@ 

[PATCH 1/9] target/riscv: debug: Determine the trigger type from tdata1.type

2022-06-09 Thread frank . chang
From: Frank Chang 

Current RISC-V debug assumes that only type 2 trigger is supported.
To allow more types of triggers to be supported in the future
(e.g. type 6 trigger, which is similar to type 2 trigger with additional
 functionality), we should determine the trigger type from tdata1.type.

RV_MAX_TRIGGERS is also introduced in replacement of TRIGGER_TYPE2_NUM.

Signed-off-by: Frank Chang 
---
 target/riscv/cpu.h |   2 +-
 target/riscv/csr.c |   2 +-
 target/riscv/debug.c   | 183 -
 target/riscv/debug.h   |  15 ++--
 target/riscv/machine.c |   2 +-
 5 files changed, 137 insertions(+), 67 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7d6397acdf..535123a989 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -289,7 +289,7 @@ struct CPUArchState {
 
 /* trigger module */
 target_ulong trigger_cur;
-type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM];
+type2_trigger_t type2_trig[RV_MAX_TRIGGERS];
 
 /* machine specific rdtime callback */
 uint64_t (*rdtime_fn)(void *);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 6dbe9b541f..005ae31a01 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2776,7 +2776,7 @@ static RISCVException read_tdata(CPURISCVState *env, int 
csrno,
  target_ulong *val)
 {
 /* return 0 in tdata1 to end the trigger enumeration */
-if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
+if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
 *val = 0;
 return RISCV_EXCP_NONE;
 }
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index fc6e13222f..abbcd38a17 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -52,8 +52,15 @@
 /* tdata availability of a trigger */
 typedef bool tdata_avail[TDATA_NUM];
 
-static tdata_avail tdata_mapping[TRIGGER_NUM] = {
-[TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false },
+static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = {
+[TRIGGER_TYPE_NO_EXIST] = { false, false, false },
+[TRIGGER_TYPE_AD_MATCH] = { true, true, true },
+[TRIGGER_TYPE_INST_CNT] = { true, false, true },
+[TRIGGER_TYPE_INT] = { true, true, true },
+[TRIGGER_TYPE_EXCP] = { true, true, true },
+[TRIGGER_TYPE_AD_MATCH6] = { true, true, true },
+[TRIGGER_TYPE_EXT_SRC] = { true, false, false },
+[TRIGGER_TYPE_UNAVAIL] = { true, true, true }
 };
 
 /* only breakpoint size 1/2/4/8 supported */
@@ -67,6 +74,26 @@ static int access_size[SIZE_NUM] = {
 [6 ... 15] = -1,
 };
 
+static inline target_ulong extract_trigger_type(CPURISCVState *env,
+target_ulong tdata1)
+{
+switch (riscv_cpu_mxl(env)) {
+case MXL_RV32:
+return extract32(tdata1, 28, 4);
+case MXL_RV64:
+return extract64(tdata1, 60, 4);
+default:
+g_assert_not_reached();
+}
+}
+
+static inline target_ulong get_trigger_type(CPURISCVState *env,
+target_ulong trigger_index)
+{
+target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol;
+return extract_trigger_type(env, tdata1);
+}
+
 static inline target_ulong trigger_type(CPURISCVState *env,
 trigger_type_t type)
 {
@@ -89,15 +116,17 @@ static inline target_ulong trigger_type(CPURISCVState *env,
 
 bool tdata_available(CPURISCVState *env, int tdata_index)
 {
+int trigger_type = get_trigger_type(env, env->trigger_cur);
+
 if (unlikely(tdata_index >= TDATA_NUM)) {
 return false;
 }
 
-if (unlikely(env->trigger_cur >= TRIGGER_NUM)) {
+if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) {
 return false;
 }
 
-return tdata_mapping[env->trigger_cur][tdata_index];
+return tdata_mapping[trigger_type][tdata_index];
 }
 
 target_ulong tselect_csr_read(CPURISCVState *env)
@@ -137,6 +166,7 @@ static target_ulong tdata1_validate(CPURISCVState *env, 
target_ulong val,
 qemu_log_mask(LOG_GUEST_ERROR,
   "ignoring type write to tdata1 register\n");
 }
+
 if (dmode != 0) {
 qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n");
 }
@@ -261,9 +291,8 @@ static void type2_breakpoint_remove(CPURISCVState *env, 
target_ulong index)
 }
 
 static target_ulong type2_reg_read(CPURISCVState *env,
-   target_ulong trigger_index, int tdata_index)
+   target_ulong index, int tdata_index)
 {
-uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0;
 target_ulong tdata;
 
 switch (tdata_index) {
@@ -280,10 +309,9 @@ static target_ulong type2_reg_read(CPURISCVState *env,
 return tdata;
 }
 
-static void type2_reg_write(CPURISCVState *env, target_ulong trigger_index,
+static void type2_reg_write(CPURISCVState *env, target_ulong index,
 int tdata_index,