[PATCH 4/4] hw/arm/xlnx-zynqmp: adapt cluster-id based on the boot cpu

Clément Chigot posted 4 patches 6 months ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>, Alistair Francis <alistair@alistair23.me>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
There is a newer version of this series
[PATCH 4/4] hw/arm/xlnx-zynqmp: adapt cluster-id based on the boot cpu
Posted by Clément Chigot 6 months ago
When gdb is being connected to QEmu, it will be attached to the first
CPU cluster. However, the ZynqMP board has two clusters, those being of
two different architectures.
Therefore, when gdb is connecting to the ZynqMP, it receives the target
descriptor of the first CPU cluster. Up to now, it was always the APU
cluster, which is AARCH64.

When booting on a RPU, gdb will still connect to the APU. If gdb is
supporting only ARM32, it will receive the APU target descriptor,
resulting in:
  | (gdb) target remote :1234
  | warning: while parsing target description (at line 1): Target
  | description specified unknown architecture "aarch64"

Adjust the cluster-id based on the boot cpu will resolve the above
issue; allowing a pure ARM32 toolchain to debug programs running on
RPUs.

Signed-off-by: Clément Chigot <chigot@adacore.com>
---
 hw/arm/xlnx-zynqmp.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index be33669f87..f23ace6446 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -221,7 +221,13 @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s,
 
     object_initialize_child(OBJECT(s), "rpu-cluster", &s->rpu_cluster,
                             TYPE_CPU_CLUSTER);
-    qdev_prop_set_uint32(DEVICE(&s->rpu_cluster), "cluster-id", 1);
+
+    /* In order to connect gdb to the boot cpu, adjust the cluster-id.  */
+    if (!strncmp(boot_cpu, "rpu-cpu", 7)) {
+        qdev_prop_set_uint32(DEVICE(&s->rpu_cluster), "cluster-id", 0);
+    } else {
+        qdev_prop_set_uint32(DEVICE(&s->rpu_cluster), "cluster-id", 1);
+    }
 
     for (i = 0; i < num_rpus; i++) {
         const char *name;
@@ -380,7 +386,6 @@ static void xlnx_zynqmp_init(Object *obj)
 
     object_initialize_child(obj, "apu-cluster", &s->apu_cluster,
                             TYPE_CPU_CLUSTER);
-    qdev_prop_set_uint32(DEVICE(&s->apu_cluster), "cluster-id", 0);
 
     for (i = 0; i < num_apus; i++) {
         object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]",
@@ -475,6 +480,13 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
 
     ram_size = memory_region_size(s->ddr_ram);
 
+    /* In order to connect gdb to the boot cpu, adjust the cluster-id.  */
+    if (!strncmp(boot_cpu, "apu-cpu", 7)) {
+        qdev_prop_set_uint32(DEVICE(&s->apu_cluster), "cluster-id", 0);
+    } else {
+        qdev_prop_set_uint32(DEVICE(&s->apu_cluster), "cluster-id", 1);
+    }
+
     /*
      * Create the DDR Memory Regions. User friendly checks should happen at
      * the board level
-- 
2.34.1


Re: [PATCH 4/4] hw/arm/xlnx-zynqmp: adapt cluster-id based on the boot cpu
Posted by Peter Maydell 6 months ago
On Tue, 13 May 2025 at 15:15, Clément Chigot <chigot@adacore.com> wrote:
>
> When gdb is being connected to QEmu, it will be attached to the first

(QEMU is all-caps, by the way)

> CPU cluster. However, the ZynqMP board has two clusters, those being of
> two different architectures.
> Therefore, when gdb is connecting to the ZynqMP, it receives the target
> descriptor of the first CPU cluster. Up to now, it was always the APU
> cluster, which is AARCH64.
>
> When booting on a RPU, gdb will still connect to the APU. If gdb is
> supporting only ARM32, it will receive the APU target descriptor,
> resulting in:
>   | (gdb) target remote :1234
>   | warning: while parsing target description (at line 1): Target
>   | description specified unknown architecture "aarch64"
>
> Adjust the cluster-id based on the boot cpu will resolve the above
> issue; allowing a pure ARM32 toolchain to debug programs running on
> RPUs.

I'm not really enthusiastic about renumbering the clusters
like this. I think you should be able to get gdb to connect
to the second cluster via the multiple-inferior support:

https://www.qemu.org/docs/master/system/gdb.html#debugging-multicore-machines

thanks
-- PMM
Re: [PATCH 4/4] hw/arm/xlnx-zynqmp: adapt cluster-id based on the boot cpu
Posted by Clément Chigot 5 months, 4 weeks ago
On Mon, May 19, 2025 at 5:38 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Tue, 13 May 2025 at 15:15, Clément Chigot <chigot@adacore.com> wrote:
> >
> > When gdb is being connected to QEmu, it will be attached to the first
>
> (QEMU is all-caps, by the way)
>
> > CPU cluster. However, the ZynqMP board has two clusters, those being of
> > two different architectures.
> > Therefore, when gdb is connecting to the ZynqMP, it receives the target
> > descriptor of the first CPU cluster. Up to now, it was always the APU
> > cluster, which is AARCH64.
> >
> > When booting on a RPU, gdb will still connect to the APU. If gdb is
> > supporting only ARM32, it will receive the APU target descriptor,
> > resulting in:
> >   | (gdb) target remote :1234
> >   | warning: while parsing target description (at line 1): Target
> >   | description specified unknown architecture "aarch64"
> >
> > Adjust the cluster-id based on the boot cpu will resolve the above
> > issue; allowing a pure ARM32 toolchain to debug programs running on
> > RPUs.
>
> I'm not really enthusiastic about renumbering the clusters
> like this. I think you should be able to get gdb to connect
> to the second cluster via the multiple-inferior support:
>
> https://www.qemu.org/docs/master/system/gdb.html#debugging-multicore-machines

Sadly, that doesn't work. `attach 2` requires the connection to be
already established. But it's being aborted as soon as gdb can't
decode the XML provided.
  | $ arm-elf-gdb helloworld
  | (gdb) target extended-remote localhost:1234
  | Remote debugging using localhost:1234
  | warning: while parsing target description (at line 1): Target
description specified unknown architecture "aarch64"
  | warning: Could not load XML target description; ignoring
  | Remote 'g' packet reply is too long (expected 168 bytes, got 268 bytes): ...
  | (gdb) add-inferior
  | [New inferior 2]
  | Added inferior 2
  | (gdb) inferior 2
  | [Switching to inferior 2 [<null>] (<noexec>)]
  | (gdb) attach 2
  | Don't know how to attach.  Try "help target".
  | (gdb) info connection
  | No connections.

FTR, I tried to find a way to adjust gdbstub.c to retrieve the
boot-cpu or have a different "first cpu" according to an option. But
this was far more complex than just that patch.
That being said, I understand that this solution is far from perfect
and I'm fine keeping it as a local patch if you think it would bring
more pain overall. There is a simple workaround/solution: have a gdb
understanding both aarch64 and arm32 when debugging ZynqMP programs
(something we cannot do that on our side for various reasons
though...).

Clément

> thanks
> -- PMM