[PATCH 38/48] hw/arm/xlnx-versal: add a per_cluster_gic switch to VersalCpuClusterMap

Luc Michel posted 48 patches 4 months ago
Maintainers: Alistair Francis <alistair@alistair23.me>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Peter Maydell <peter.maydell@linaro.org>, Jason Wang <jasowang@redhat.com>
There is a newer version of this series
[PATCH 38/48] hw/arm/xlnx-versal: add a per_cluster_gic switch to VersalCpuClusterMap
Posted by Luc Michel 4 months ago
Add the per_cluster_gic switch to the VersalCpuClusterMap structure.
When set, this indicates that a GIC instance should by created
per-cluster instead of globaly for the whole RPU or APU. This is in
preparation for versal2.

Signed-off-by: Luc Michel <luc.michel@amd.com>
---
 hw/arm/xlnx-versal.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index aef53876f26..9d900fe3127 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -86,10 +86,15 @@ enum StartPoweredOffMode {
     SPO_ALL,
 };
 
 typedef struct VersalCpuClusterMap {
     VersalGicMap gic;
+    /*
+     * true: one GIC per cluster.
+     * false: one GIC for all CPUs
+     */
+    bool per_cluster_gic;
 
     const char *name;
     const char *cpu_model;
     size_t num_core;
     size_t num_cluster;
@@ -828,16 +833,22 @@ static void versal_create_cpu_cluster(Versal *s, const VersalCpuClusterMap *map)
             DeviceState *cpu = versal_create_cpu(s, map, cluster, mr, i, j);
 
             cpus[i * map->num_core + j] = cpu;
         }
 
+        if (map->per_cluster_gic) {
+            versal_create_and_connect_gic(s, map, mr, &cpus[i * map->num_core],
+                                          map->num_core);
+        }
     }
 
     qdev_realize_and_unref(cluster, NULL, &error_fatal);
 
-    versal_create_and_connect_gic(s, map, mr, cpus,
-                                  map->num_cluster * map->num_core);
+    if (!map->per_cluster_gic) {
+        versal_create_and_connect_gic(s, map, mr, cpus,
+                                      map->num_cluster * map->num_core);
+    }
 
     has_gtimer = arm_feature(&ARM_CPU(cpus[0])->env, ARM_FEATURE_GENERIC_TIMER);
     if (map->dtb_expose && has_gtimer) {
         qemu_fdt_add_subnode(s->cfg.fdt, "/timer");
         qemu_fdt_setprop_cells(s->cfg.fdt, "/timer", "interrupts",
-- 
2.50.0
Re: [PATCH 38/48] hw/arm/xlnx-versal: add a per_cluster_gic switch to VersalCpuClusterMap
Posted by Francisco Iglesias 3 months, 2 weeks ago
Hi Luc,

On Wed, Jul 16, 2025 at 11:54:20AM +0200, Luc Michel wrote:
> Add the per_cluster_gic switch to the VersalCpuClusterMap structure.
> When set, this indicates that a GIC instance should by created
> per-cluster instead of globaly for the whole RPU or APU. This is in

s/globaly/globally/

Otherwise:

Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>


> preparation for versal2.
> 
> Signed-off-by: Luc Michel <luc.michel@amd.com>
> ---
>  hw/arm/xlnx-versal.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index aef53876f26..9d900fe3127 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -86,10 +86,15 @@ enum StartPoweredOffMode {
>      SPO_ALL,
>  };
>  
>  typedef struct VersalCpuClusterMap {
>      VersalGicMap gic;
> +    /*
> +     * true: one GIC per cluster.
> +     * false: one GIC for all CPUs
> +     */
> +    bool per_cluster_gic;
>  
>      const char *name;
>      const char *cpu_model;
>      size_t num_core;
>      size_t num_cluster;
> @@ -828,16 +833,22 @@ static void versal_create_cpu_cluster(Versal *s, const VersalCpuClusterMap *map)
>              DeviceState *cpu = versal_create_cpu(s, map, cluster, mr, i, j);
>  
>              cpus[i * map->num_core + j] = cpu;
>          }
>  
> +        if (map->per_cluster_gic) {
> +            versal_create_and_connect_gic(s, map, mr, &cpus[i * map->num_core],
> +                                          map->num_core);
> +        }
>      }
>  
>      qdev_realize_and_unref(cluster, NULL, &error_fatal);
>  
> -    versal_create_and_connect_gic(s, map, mr, cpus,
> -                                  map->num_cluster * map->num_core);
> +    if (!map->per_cluster_gic) {
> +        versal_create_and_connect_gic(s, map, mr, cpus,
> +                                      map->num_cluster * map->num_core);
> +    }
>  
>      has_gtimer = arm_feature(&ARM_CPU(cpus[0])->env, ARM_FEATURE_GENERIC_TIMER);
>      if (map->dtb_expose && has_gtimer) {
>          qemu_fdt_add_subnode(s->cfg.fdt, "/timer");
>          qemu_fdt_setprop_cells(s->cfg.fdt, "/timer", "interrupts",
> -- 
> 2.50.0
>