target/arm: Implement SME2 support in gdbstub

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>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20251017153027.969016-2-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell
2025-10-17 16:30:25 +01:00
parent 0af7ba53fe
commit 841bb7d96f
8 changed files with 78 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-sme2.xml
TARGET_LONG_BITS=64

View File

@@ -1,6 +1,6 @@
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-mte.xml
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-mte.xml gdb-xml/aarch64-sme2.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y

View File

@@ -1,7 +1,7 @@
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
TARGET_KVM_HAVE_GUEST_DEBUG=y
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml gdb-xml/aarch64-pauth.xml
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/arm-core.xml gdb-xml/arm-vfp.xml gdb-xml/arm-vfp3.xml gdb-xml/arm-vfp-sysregs.xml gdb-xml/arm-neon.xml gdb-xml/arm-m-profile.xml gdb-xml/arm-m-profile-mve.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-sme2.xml
# needed by boot.c
TARGET_NEED_FDT=y
TARGET_LONG_BITS=64

View File

@@ -1,7 +1,7 @@
TARGET_ARCH=aarch64
TARGET_BASE_ARCH=arm
TARGET_BIG_ENDIAN=y
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-mte.xml
TARGET_XML_FILES= gdb-xml/aarch64-core.xml gdb-xml/aarch64-fpu.xml gdb-xml/aarch64-pauth.xml gdb-xml/aarch64-mte.xml gdb-xml/aarch64-sme2.xml
TARGET_HAS_BFLT=y
CONFIG_SEMIHOSTING=y
CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y

14
gdb-xml/aarch64-sme2.xml Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2025 Linaro Ltd.
SPDX-License-Identifier: GPL-2.0-or-later
This is the SME2 ZT0 register. Upstream GDB dynamically generates
the XML for this feature, but because the vector is always 64 bytes
in size we prefer to use static XML for it.
-->
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.aarch64.sme2">
<vector id="sme2_bv" type="uint8" count="64"/>
<reg name="zt0" bitsize="512" type="sme2_bv"/>
</feature>

View File

@@ -554,6 +554,12 @@ 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)) {
gdb_register_coprocessor(cs, aarch64_gdb_get_sme2_reg,
aarch64_gdb_set_sme2_reg,
gdb_find_static_feature("aarch64-sme2.xml"),
0);
}
}
/*
* Note that we report pauth information via the feature name

View File

@@ -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);

View File

@@ -1720,6 +1720,8 @@ 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);