[PATCH 2/2] target/arm: Fix big-endian handling of SVE gdb remote debugging

Vacha Bhavsar posted 2 patches 3 months, 3 weeks ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>
There is a newer version of this series
[PATCH 2/2] target/arm: Fix big-endian handling of SVE gdb remote debugging
Posted by Vacha Bhavsar 3 months, 3 weeks ago
This patch adds big endian support for SVE GDB remote
debugging. It replaces the use of pointer dereferencing with the use of
ldq_p() as explained in the first part of this patch series. Additionally,
the order in which the buffer content is loaded into the CPU struct is
switched depending on target endianness to ensure the most significant bits
are always in second element.

Signed-off-by: Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com>
---
 target/arm/gdbstub64.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
index 8b7f15b920..cd61d946bb 100644
--- a/target/arm/gdbstub64.c
+++ b/target/arm/gdbstub64.c
@@ -200,10 +200,18 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
     case 0 ... 31:
     {
         int vq, len = 0;
-        uint64_t *p = (uint64_t *) buf;
         for (vq = 0; vq < cpu->sve_max_vq; vq++) {
-            env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
-            env->vfp.zregs[reg].d[vq * 2] = *p++;
+            if (target_big_endian()){
+                env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
+                buf += 8;
+                env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
+            }
+            else{
+                env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
+                buf += 8;
+                env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
+            }
+            buf += 8;
             len += 16;
         }
         return len;
@@ -218,9 +226,9 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
     {
         int preg = reg - 34;
         int vq, len = 0;
-        uint64_t *p = (uint64_t *) buf;
         for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
-            env->vfp.pregs[preg].p[vq / 4] = *p++;
+            env->vfp.pregs[preg].p[vq/4] = ldq_p(buf);
+            buf += 8;
             len += 8;
         }
         return len;
-- 
2.34.1
Re: [PATCH 2/2] target/arm: Fix big-endian handling of SVE gdb remote debugging
Posted by Philippe Mathieu-Daudé 3 months, 3 weeks ago
On 21/7/25 23:19, Vacha Bhavsar wrote:
> This patch adds big endian support for SVE GDB remote
> debugging. It replaces the use of pointer dereferencing with the use of
> ldq_p() as explained in the first part of this patch series. Additionally,
> the order in which the buffer content is loaded into the CPU struct is
> switched depending on target endianness to ensure the most significant bits
> are always in second element.
> 
> Signed-off-by: Vacha Bhavsar <vacha.bhavsar@oss.qualcomm.com>
> ---
>   target/arm/gdbstub64.c | 18 +++++++++++++-----
>   1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
> index 8b7f15b920..cd61d946bb 100644
> --- a/target/arm/gdbstub64.c
> +++ b/target/arm/gdbstub64.c
> @@ -200,10 +200,18 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)

Alex,

Why is there a disconnection with gdb_register_coprocessor() and
"gdbstub/helpers.h" APIs? The former is older? Should we unify
using the latter API with GByteArray?

>       case 0 ... 31:
>       {
>           int vq, len = 0;
> -        uint64_t *p = (uint64_t *) buf;
>           for (vq = 0; vq < cpu->sve_max_vq; vq++) {
> -            env->vfp.zregs[reg].d[vq * 2 + 1] = *p++;
> -            env->vfp.zregs[reg].d[vq * 2] = *p++;
> +            if (target_big_endian()){
> +                env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
> +                buf += 8;
> +                env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
> +            }
> +            else{
> +                env->vfp.zregs[reg].d[vq * 2] = ldq_p(buf);
> +                buf += 8;
> +                env->vfp.zregs[reg].d[vq * 2 + 1] = ldq_p(buf);
> +            }
> +            buf += 8;
>               len += 16;
>           }
>           return len;
> @@ -218,9 +226,9 @@ int aarch64_gdb_set_sve_reg(CPUState *cs, uint8_t *buf, int reg)
>       {
>           int preg = reg - 34;
>           int vq, len = 0;
> -        uint64_t *p = (uint64_t *) buf;
>           for (vq = 0; vq < cpu->sve_max_vq; vq = vq + 4) {
> -            env->vfp.pregs[preg].p[vq / 4] = *p++;
> +            env->vfp.pregs[preg].p[vq/4] = ldq_p(buf);
> +            buf += 8;
>               len += 8;
>           }
>           return len;