From: "Alex Bennée" <alex.bennee@linaro.org>
To: Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com>
Cc: qemu-devel@nongnu.org, Peter Maydell <peter.maydell@linaro.org>,
qemu-arm@nongnu.org
Subject: Re: [PATCH v4 2/2] target/arm: Added support for SME register exposure to GDB
Date: Mon, 04 Aug 2025 16:35:19 +0100 [thread overview]
Message-ID: <87zfcf5cco.fsf@draig.linaro.org> (raw)
In-Reply-To: <20250722201404.2368507-3-vacha.bhavsar@oss.qualcomm.com> (Vacha Bhavsar's message of "Tue, 22 Jul 2025 20:14:04 +0000")
Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com> writes:
> The QEMU GDB stub does not expose the ZA storage SME register to GDB via
> the remote serial protocol, which can be a useful functionality to debug SME
> code. To provide this functionality in Aarch64 target, this patch registers the
> SME register set with the GDB stub. To do so, this patch implements the
> aarch64_gdb_get_sme_reg() and aarch64_gdb_set_sme_reg() functions to
> specify how to get and set the SME registers, and the
> arm_gen_dynamic_smereg_feature() function to generate the target
> description in XML format to indicate the target architecture supports SME.
> Finally, this patch includes a dyn_smereg_feature structure to hold this
> GDB XML description of the SME registers for each CPU.
>
> Signed-off-by: Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com>
> ---
> Changes since v3:
> - added changes to aarch64_gdb_set_sme_reg() to address the concerns
> brought up in review regarding endianness
>
> target/arm/cpu.h | 1 +
> target/arm/gdbstub.c | 6 ++
> target/arm/gdbstub64.c | 122 +++++++++++++++++++++++++++++++++++++++++
> target/arm/internals.h | 3 +
> 4 files changed, 132 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index dc9b6dce4c..8bd66d7049 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -933,6 +933,7 @@ struct ArchCPU {
>
> DynamicGDBFeatureInfo dyn_sysreg_feature;
> DynamicGDBFeatureInfo dyn_svereg_feature;
> + DynamicGDBFeatureInfo dyn_smereg_feature;
> DynamicGDBFeatureInfo dyn_m_systemreg_feature;
> DynamicGDBFeatureInfo dyn_m_secextreg_feature;
>
> diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
> index ce4497ad7c..9c942c77cc 100644
> --- a/target/arm/gdbstub.c
> +++ b/target/arm/gdbstub.c
> @@ -531,6 +531,12 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
> GDBFeature *feature = arm_gen_dynamic_svereg_feature(cs, cs->gdb_num_regs);
> gdb_register_coprocessor(cs, aarch64_gdb_get_sve_reg,
> aarch64_gdb_set_sve_reg, feature, 0);
> + if (isar_feature_aa64_sme(&cpu->isar)) {
> + GDBFeature *sme_feature = 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);
> + }
> } else {
> gdb_register_coprocessor(cs, aarch64_gdb_get_fpu_reg,
> aarch64_gdb_set_fpu_reg,
> diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
> index 64ee9b3b56..3d86980bc9 100644
> --- a/target/arm/gdbstub64.c
> +++ b/target/arm/gdbstub64.c
> @@ -228,6 +228,91 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
> return 0;
> }
>
> +int aarch64_gdb_get_sme_reg(CPUState *cs, GByteArray *buf, int reg)
> +{
> + ARMCPU *cpu = ARM_CPU(cs);
> + CPUARMState *env = &cpu->env;
> +
> + switch (reg) {
> + /* Svg register */
> + case 0:
> + {
> + int vq = 0;
> + if (FIELD_EX64(env->svcr, SVCR, SM)) {
> + vq = sve_vqm1_for_el_sm(env, arm_current_el(env),
> + FIELD_EX64(env->svcr, SVCR, SM)) + 1;
> + }
> + /* svg = vector granules (2 * vector quardwords) in streaming mode */
> + return gdb_get_reg64(buf, vq * 2);
> + }
> + case 1:
> + return gdb_get_reg64(buf, env->svcr);
> + case 2:
> + {
> + int len = 0;
> + int vq = cpu->sme_max_vq;
> + int svl = vq * 16;
> + for (int i = 0; i < svl; i++) {
> + for (int q = 0; q < vq; q++) {
> + len += gdb_get_reg128(buf,
> + env->za_state.za[i].d[q * 2 + 1],
> + env->za_state.za[i].d[q * 2]);
> + }
> + }
> + 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_sme_reg(CPUState *cs, uint8_t *buf, int reg)
> +{
> + ARMCPU *cpu = ARM_CPU(cs);
> + CPUARMState *env = &cpu->env;
> +
> + switch (reg) {
> + case 0:
> + {
> + /* cannot set svg via gdbstub */
> + return 8;
> + }
> + case 1:
> + aarch64_set_svcr(env, ldq_le_p(buf),
> + R_SVCR_SM_MASK | R_SVCR_ZA_MASK);
> + return 8;
> + case 2:
> + int len = 0;
> + int vq = cpu->sme_max_vq;
> + int svl = vq * 16;
> + for (int i = 0; i < svl; i++) {
> + for (int q = 0; q < vq; q++) {
> + if (target_big_endian()){
> + env->za_state.za[i].d[q * 2 + 1] = ldq_p(buf);
> + buf += 8;
> + env->za_state.za[i].d[q * 2] = ldq_p(buf);
> + } else{
> + env->za_state.za[i].d[q * 2] = ldq_p(buf);
> + buf += 8;
> + env->za_state.za[i].d[q * 2 + 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);
> @@ -392,6 +477,43 @@ GDBFeature *arm_gen_dynamic_svereg_feature(CPUState *cs, int base_reg)
> return &cpu->dyn_svereg_feature.desc;
> }
>
> +GDBFeature *arm_gen_dynamic_smereg_feature(CPUState *cs, int base_reg)
> +{
> + ARMCPU *cpu = ARM_CPU(cs);
> + int vq = cpu->sme_max_vq;
> + int svl = vq * 16;
> + GDBFeatureBuilder builder;
> + int reg = 0;
> +
> + gdb_feature_builder_init(&builder, &cpu->dyn_smereg_feature.desc,
> + "org.gnu.gdb.aarch64.sme", "sme-registers.xml", base_reg);
> +
> +
> + /* Create the sme_bv vector type. */
> + gdb_feature_builder_append_tag(&builder,
> + "<vector id=\"sme_bv\" type=\"uint8\" count=\"%d\"/>",
> + svl);
> +
> + /* Create the sme_bvv vector type. */
> + gdb_feature_builder_append_tag(
> + &builder, "<vector id=\"sme_bvv\" type=\"sme_bv\" count=\"%d\"/>",
> + svl);
> +
> + /* Define the svg, svcr, and za registers. */
> +
> + /* fpscr & status registers */
> + gdb_feature_builder_append_reg(&builder, "svg", 64, reg++,
> + "int", NULL);
> + gdb_feature_builder_append_reg(&builder, "svcr", 64, reg++,
> + "int", NULL);
> + gdb_feature_builder_append_reg(&builder, "za", svl * svl * 8, reg++,
> + "sme_bvv", NULL);
> +
> + gdb_feature_builder_end(&builder);
> +
> + return &cpu->dyn_smereg_feature.desc;
> +}
> +
> #ifdef CONFIG_USER_ONLY
> int aarch64_gdb_get_tag_ctl_reg(CPUState *cs, GByteArray *buf, int reg)
> {
> diff --git a/target/arm/internals.h b/target/arm/internals.h
> index c4765e4489..760e1c6490 100644
> --- a/target/arm/internals.h
> +++ b/target/arm/internals.h
> @@ -1808,8 +1808,11 @@ 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);
> 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_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);
It would also be nice to add a test for this, see tests/tcg/aarch64/gdbstub/test-sve.py
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2025-08-04 17:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-22 20:14 [PATCH v4 0/2] target/arm: Added support for SME register exposure to GDB Vacha Bhavsar
2025-07-22 20:14 ` [PATCH v4 1/2] target/arm: Increase MAX_PACKET_LENGTH for SME ZA remote gdb debugging Vacha Bhavsar
2025-08-04 15:34 ` Alex Bennée
2025-08-04 16:49 ` Peter Maydell
2025-08-04 18:32 ` Alex Bennée
2025-08-04 18:38 ` Peter Maydell
2025-08-05 21:21 ` Vacha Bhavsar
2025-08-06 21:18 ` Vacha Bhavsar
2025-08-07 9:42 ` Peter Maydell
2025-08-11 19:37 ` Vacha Bhavsar
2025-07-22 20:14 ` [PATCH v4 2/2] target/arm: Added support for SME register exposure to GDB Vacha Bhavsar
2025-08-04 15:35 ` Alex Bennée [this message]
2025-08-08 13:54 ` Vacha Bhavsar
2025-08-11 7:58 ` Alex Bennée
2025-08-11 19:37 ` Vacha Bhavsar
2025-07-23 11:54 ` [PATCH v4 0/2] " Philippe Mathieu-Daudé
-- strict thread matches above, loose matches on Subject: below --
2025-07-22 20:20 [PATCH v4 2/2] " Vacha Bhavsar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87zfcf5cco.fsf@draig.linaro.org \
--to=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=vacha.bhavsar@oss.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.