Re: [PATCH v17 03/14] target/riscv: Use GDBFeature for dynamic XML

2023-12-17 Thread Alistair Francis
On Wed, Dec 13, 2023 at 4:43 PM Akihiko Odaki  wrote:
>
> In preparation for a change to use GDBFeature as a parameter of
> gdb_register_coprocessor(), convert the internal representation of
> dynamic feature from plain XML to GDBFeature.
>
> Signed-off-by: Akihiko Odaki 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.h |  5 ++--
>  target/riscv/cpu.c |  4 +--
>  target/riscv/gdbstub.c | 79 
> ++
>  3 files changed, 40 insertions(+), 48 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 060b7f69a743..ad7236d75477 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -24,6 +24,7 @@
>  #include "hw/registerfields.h"
>  #include "hw/qdev-properties.h"
>  #include "exec/cpu-defs.h"
> +#include "exec/gdbstub.h"
>  #include "qemu/cpu-float.h"
>  #include "qom/object.h"
>  #include "qemu/int128.h"
> @@ -424,8 +425,8 @@ struct ArchCPU {
>
>  CPURISCVState env;
>
> -char *dyn_csr_xml;
> -char *dyn_vreg_xml;
> +GDBFeature dyn_csr_feature;
> +GDBFeature dyn_vreg_feature;
>
>  /* Configuration Settings */
>  RISCVCPUConfig cfg;
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index b799f1336041..673e937a5d82 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1534,9 +1534,9 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState 
> *cs, const char *xmlname)
>  RISCVCPU *cpu = RISCV_CPU(cs);
>
>  if (strcmp(xmlname, "riscv-csr.xml") == 0) {
> -return cpu->dyn_csr_xml;
> +return cpu->dyn_csr_feature.xml;
>  } else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
> -return cpu->dyn_vreg_xml;
> +return cpu->dyn_vreg_feature.xml;
>  }
>
>  return NULL;
> diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
> index 365040228a12..76b72a959549 100644
> --- a/target/riscv/gdbstub.c
> +++ b/target/riscv/gdbstub.c
> @@ -214,13 +214,14 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs, 
> uint8_t *mem_buf, int n)
>  return 0;
>  }
>
> -static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
> +static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
>  {
>  RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
>  RISCVCPU *cpu = RISCV_CPU(cs);
>  CPURISCVState *env = >env;
> -GString *s = g_string_new(NULL);
> +GDBFeatureBuilder builder;
>  riscv_csr_predicate_fn predicate;
> +const char *name;
>  int bitsize = 16 << mcc->misa_mxl_max;
>  int i;
>
> @@ -233,9 +234,9 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
> base_reg)
>  bitsize = 64;
>  }
>
> -g_string_printf(s, "");
> -g_string_append_printf(s, " \"gdb-target.dtd\">");
> -g_string_append_printf(s, "");
> +gdb_feature_builder_init(, >dyn_csr_feature,
> + "org.gnu.gdb.riscv.csr", "riscv-csr.xml",
> + base_reg);
>
>  for (i = 0; i < CSR_TABLE_SIZE; i++) {
>  if (env->priv_ver < csr_ops[i].min_priv_ver) {
> @@ -243,72 +244,64 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
> base_reg)
>  }
>  predicate = csr_ops[i].predicate;
>  if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
> -if (csr_ops[i].name) {
> -g_string_append_printf(s, " csr_ops[i].name);
> -} else {
> -g_string_append_printf(s, " +g_autofree char *dynamic_name = NULL;
> +name = csr_ops[i].name;
> +if (!name) {
> +dynamic_name = g_strdup_printf("csr%03x", i);
> +name = dynamic_name;
>  }
> -g_string_append_printf(s, " bitsize=\"%d\"", bitsize);
> -g_string_append_printf(s, " regnum=\"%d\"/>", base_reg + i);
> +
> +gdb_feature_builder_append_reg(, name, bitsize, i,
> +   "int", NULL);
>  }
>  }
>
> -g_string_append_printf(s, "");
> -
> -cpu->dyn_csr_xml = g_string_free(s, false);
> +gdb_feature_builder_end();
>
>  #if !defined(CONFIG_USER_ONLY)
>  env->debugger = false;
>  #endif
>
> -return CSR_TABLE_SIZE;
> +return >dyn_csr_feature;
>  }
>
> -static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
> +static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int 
> base_reg)
>  {
>  RISCVCPU *cpu = RISCV_CPU(cs);
> -GString *s = g_string_new(NULL);
> -g_autoptr(GString) ts = g_string_new("");
> +GDBFeatureBuilder builder;
>  int reg_width = cpu->cfg.vlen;
> -int num_regs = 0;
>  int i;
>
> -g_string_printf(s, "");
> -g_string_append_printf(s, "");
> -g_string_append_printf(s, "");
> +gdb_feature_builder_init(, >dyn_vreg_feature,
> + "org.gnu.gdb.riscv.vector", "riscv-vector.xml",
> + base_reg);
>
>  /* First 

[PATCH v17 03/14] target/riscv: Use GDBFeature for dynamic XML

2023-12-12 Thread Akihiko Odaki
In preparation for a change to use GDBFeature as a parameter of
gdb_register_coprocessor(), convert the internal representation of
dynamic feature from plain XML to GDBFeature.

Signed-off-by: Akihiko Odaki 
---
 target/riscv/cpu.h |  5 ++--
 target/riscv/cpu.c |  4 +--
 target/riscv/gdbstub.c | 79 ++
 3 files changed, 40 insertions(+), 48 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 060b7f69a743..ad7236d75477 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -24,6 +24,7 @@
 #include "hw/registerfields.h"
 #include "hw/qdev-properties.h"
 #include "exec/cpu-defs.h"
+#include "exec/gdbstub.h"
 #include "qemu/cpu-float.h"
 #include "qom/object.h"
 #include "qemu/int128.h"
@@ -424,8 +425,8 @@ struct ArchCPU {
 
 CPURISCVState env;
 
-char *dyn_csr_xml;
-char *dyn_vreg_xml;
+GDBFeature dyn_csr_feature;
+GDBFeature dyn_vreg_feature;
 
 /* Configuration Settings */
 RISCVCPUConfig cfg;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b799f1336041..673e937a5d82 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1534,9 +1534,9 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState 
*cs, const char *xmlname)
 RISCVCPU *cpu = RISCV_CPU(cs);
 
 if (strcmp(xmlname, "riscv-csr.xml") == 0) {
-return cpu->dyn_csr_xml;
+return cpu->dyn_csr_feature.xml;
 } else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
-return cpu->dyn_vreg_xml;
+return cpu->dyn_vreg_feature.xml;
 }
 
 return NULL;
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 365040228a12..76b72a959549 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -214,13 +214,14 @@ static int riscv_gdb_set_virtual(CPURISCVState *cs, 
uint8_t *mem_buf, int n)
 return 0;
 }
 
-static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
+static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
 {
 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = >env;
-GString *s = g_string_new(NULL);
+GDBFeatureBuilder builder;
 riscv_csr_predicate_fn predicate;
+const char *name;
 int bitsize = 16 << mcc->misa_mxl_max;
 int i;
 
@@ -233,9 +234,9 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 bitsize = 64;
 }
 
-g_string_printf(s, "");
-g_string_append_printf(s, "");
-g_string_append_printf(s, "");
+gdb_feature_builder_init(, >dyn_csr_feature,
+ "org.gnu.gdb.riscv.csr", "riscv-csr.xml",
+ base_reg);
 
 for (i = 0; i < CSR_TABLE_SIZE; i++) {
 if (env->priv_ver < csr_ops[i].min_priv_ver) {
@@ -243,72 +244,64 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 }
 predicate = csr_ops[i].predicate;
 if (predicate && (predicate(env, i) == RISCV_EXCP_NONE)) {
-if (csr_ops[i].name) {
-g_string_append_printf(s, "", base_reg + i);
+
+gdb_feature_builder_append_reg(, name, bitsize, i,
+   "int", NULL);
 }
 }
 
-g_string_append_printf(s, "");
-
-cpu->dyn_csr_xml = g_string_free(s, false);
+gdb_feature_builder_end();
 
 #if !defined(CONFIG_USER_ONLY)
 env->debugger = false;
 #endif
 
-return CSR_TABLE_SIZE;
+return >dyn_csr_feature;
 }
 
-static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
+static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
-GString *s = g_string_new(NULL);
-g_autoptr(GString) ts = g_string_new("");
+GDBFeatureBuilder builder;
 int reg_width = cpu->cfg.vlen;
-int num_regs = 0;
 int i;
 
-g_string_printf(s, "");
-g_string_append_printf(s, "");
-g_string_append_printf(s, "");
+gdb_feature_builder_init(, >dyn_vreg_feature,
+ "org.gnu.gdb.riscv.vector", "riscv-vector.xml",
+ base_reg);
 
 /* First define types and totals in a whole VL */
 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
 int count = reg_width / vec_lanes[i].size;
-g_string_printf(ts, "%s", vec_lanes[i].id);
-g_string_append_printf(s,
-   "",
-   ts->str, vec_lanes[i].gdb_type, count);
+gdb_feature_builder_append_tag(
+, "",
+vec_lanes[i].id, vec_lanes[i].gdb_type, count);
 }
 
 /* Define unions */
-g_string_append_printf(s, "");
+gdb_feature_builder_append_tag(, "");
 for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
-g_string_append_printf(s, "",
-   vec_lanes[i].suffix,
-   vec_lanes[i].id);
+gdb_feature_builder_append_tag(,
+