For SME2, we need to expose the new ZT0 register in the gdbstub XML.
gdb documents that the requirements are:
> The ‘org.gnu.gdb.aarch64.sme2’ feature is optional. If present,
> then the ‘org.gnu.gdb.aarch64.sme’ feature must also be present.
> The ‘org.gnu.gdb.aarch64.sme2’ feature should contain the
> following:
>
> - ZT0 is a register of 512 bits (64 bytes). It is defined as a
> vector of bytes.
Implement this.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/cpu.h | 1 +
target/arm/internals.h | 3 ++
target/arm/gdbstub.c | 7 ++++
target/arm/gdbstub64.c | 76 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 87 insertions(+)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index bf221e6f973..912f7a87e42 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -939,6 +939,7 @@ struct ArchCPU {
DynamicGDBFeatureInfo dyn_sysreg_feature;
DynamicGDBFeatureInfo dyn_svereg_feature;
DynamicGDBFeatureInfo dyn_smereg_feature;
+ DynamicGDBFeatureInfo dyn_sme2reg_feature;
DynamicGDBFeatureInfo dyn_m_systemreg_feature;
DynamicGDBFeatureInfo dyn_m_secextreg_feature;
diff --git a/target/arm/internals.h b/target/arm/internals.h
index f539bbe58e1..c41c1f224a5 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1715,10 +1715,13 @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)
GDBFeature *arm_gen_dynamic_svereg_feature(CPUState *cpu, int base_reg);
GDBFeature *arm_gen_dynamic_smereg_feature(CPUState *cpu, int base_reg);
+GDBFeature *arm_gen_dynamic_sme2reg_feature(CPUState *cpu, int base_reg);
int aarch64_gdb_get_sve_reg(CPUState *cs, GByteArray *buf, int reg);
int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg);
int aarch64_gdb_get_sme_reg(CPUState *cs, GByteArray *buf, int reg);
int aarch64_gdb_set_sme_reg(CPUState *cs, uint8_t *buf, int reg);
+int aarch64_gdb_get_sme2_reg(CPUState *cs, GByteArray *buf, int reg);
+int aarch64_gdb_set_sme2_reg(CPUState *cs, uint8_t *buf, int reg);
int aarch64_gdb_get_fpu_reg(CPUState *cs, GByteArray *buf, int reg);
int aarch64_gdb_set_fpu_reg(CPUState *cs, uint8_t *buf, int reg);
int aarch64_gdb_get_pauth_reg(CPUState *cs, GByteArray *buf, int reg);
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
index 8d2229f5192..7cac2a5965e 100644
--- a/target/arm/gdbstub.c
+++ b/target/arm/gdbstub.c
@@ -554,6 +554,13 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
arm_gen_dynamic_smereg_feature(cs, cs->gdb_num_regs);
gdb_register_coprocessor(cs, aarch64_gdb_get_sme_reg,
aarch64_gdb_set_sme_reg, sme_feature, 0);
+ if (isar_feature_aa64_sme2(&cpu->isar)) {
+ GDBFeature *sme2_feature =
+ arm_gen_dynamic_sme2reg_feature(cs, cs->gdb_num_regs);
+ gdb_register_coprocessor(cs, aarch64_gdb_get_sme2_reg,
+ aarch64_gdb_set_sme2_reg,
+ sme2_feature, 0);
+ }
}
/*
* Note that we report pauth information via the feature name
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
index 65d6bbe65fb..7f7d706324e 100644
--- a/target/arm/gdbstub64.c
+++ b/target/arm/gdbstub64.c
@@ -335,6 +335,58 @@ int aarch64_gdb_set_sme_reg(CPUState *cs, uint8_t *buf, int reg)
return 0;
}
+int aarch64_gdb_get_sme2_reg(CPUState *cs, GByteArray *buf, int reg)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+ int len = 0;
+
+ switch (reg) {
+ case 0: /* ZT0 */
+ for (int i = 0; i < ARRAY_SIZE(env->za_state.zt0); i+= 2) {
+ len += gdb_get_reg128(buf, env->za_state.zt0[i + 1],
+ env->za_state.zt0[i]);
+ }
+ return len;
+ default:
+ /* gdbstub asked for something out of range */
+ qemu_log_mask(LOG_UNIMP, "%s: out of range register %d", __func__, reg);
+ break;
+ }
+
+ return 0;
+}
+
+int aarch64_gdb_set_sme2_reg(CPUState *cs, uint8_t *buf, int reg)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+ int len = 0;
+
+ switch (reg) {
+ case 0: /* ZT0 */
+ for (int i = 0; i < ARRAY_SIZE(env->za_state.zt0); i += 2) {
+ if (target_big_endian()) {
+ env->za_state.zt0[i + 1] = ldq_p(buf);
+ buf += 8;
+ env->za_state.zt0[i] = ldq_p(buf);
+ } else {
+ env->za_state.zt0[i] = ldq_p(buf);
+ buf += 8;
+ env->za_state.zt0[i + 1] = ldq_p(buf);
+ }
+ buf += 8;
+ len += 16;
+ }
+ return len;
+ default:
+ /* gdbstub asked for something out of range */
+ break;
+ }
+
+ return 0;
+}
+
int aarch64_gdb_get_pauth_reg(CPUState *cs, GByteArray *buf, int reg)
{
ARMCPU *cpu = ARM_CPU(cs);
@@ -534,6 +586,30 @@ GDBFeature *arm_gen_dynamic_smereg_feature(CPUState *cs, int base_reg)
return &cpu->dyn_smereg_feature.desc;
}
+GDBFeature *arm_gen_dynamic_sme2reg_feature(CPUState *cs, int base_reg)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ GDBFeatureBuilder builder;
+ int reg = 0;
+
+ gdb_feature_builder_init(&builder, &cpu->dyn_sme2reg_feature.desc,
+ "org.gnu.gdb.aarch64.sme2", "sme2-registers.xml",
+ base_reg);
+
+
+ /* Create the sme2_bv vector type (a 64 byte vector) */
+ gdb_feature_builder_append_tag(
+ &builder, "<vector id=\"sme2_bv\" type=\"uint8\" count=\"64\"/>");
+
+ /* Define the ZT0 register */
+ gdb_feature_builder_append_reg(&builder, "zt0", 64 * 8, reg++,
+ "sme2_bv", NULL);
+
+ gdb_feature_builder_end(&builder);
+
+ return &cpu->dyn_sme2reg_feature.desc;
+}
+
#ifdef CONFIG_USER_ONLY
int aarch64_gdb_get_tag_ctl_reg(CPUState *cs, GByteArray *buf, int reg)
{
--
2.43.0
On 10/16/25 05:21, Peter Maydell wrote: > For SME2, we need to expose the new ZT0 register in the gdbstub XML. > gdb documents that the requirements are: > >> The ‘org.gnu.gdb.aarch64.sme2’ feature is optional. If present, >> then the ‘org.gnu.gdb.aarch64.sme’ feature must also be present. >> The ‘org.gnu.gdb.aarch64.sme2’ feature should contain the >> following: >> >> - ZT0 is a register of 512 bits (64 bytes). It is defined as a >> vector of bytes. > > Implement this. > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> The size of ZT0 is fixed at 512 bits. There's no need for the xml to be dynamically generated. r~
On Thu, 16 Oct 2025 at 22:17, Richard Henderson <richard.henderson@linaro.org> wrote: > > On 10/16/25 05:21, Peter Maydell wrote: > > For SME2, we need to expose the new ZT0 register in the gdbstub XML. > > gdb documents that the requirements are: > > > >> The ‘org.gnu.gdb.aarch64.sme2’ feature is optional. If present, > >> then the ‘org.gnu.gdb.aarch64.sme’ feature must also be present. > >> The ‘org.gnu.gdb.aarch64.sme2’ feature should contain the > >> following: > >> > >> - ZT0 is a register of 512 bits (64 bytes). It is defined as a > >> vector of bytes. > > > > Implement this. > > > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > > The size of ZT0 is fixed at 512 bits. > There's no need for the xml to be dynamically generated. I suppose not. GDB upstream dynamically generates the XML, though, so there's no upstream XML file for us to use. -- PMM
© 2016 - 2025 Red Hat, Inc.