[PATCH 23/48] hw/arm/xlnx-versal: instantiate the GIC ITS in the APU

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 23/48] hw/arm/xlnx-versal: instantiate the GIC ITS in the APU
Posted by Luc Michel 4 months ago
Add the instance of the GIC ITS in the APU.

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

diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 35c32de0159..ba8c69bd435 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -42,10 +42,11 @@
 #include "hw/misc/xlnx-versal-cfu.h"
 #include "hw/misc/xlnx-versal-cframe-reg.h"
 #include "hw/or-irq.h"
 #include "hw/misc/xlnx-versal-crl.h"
 #include "hw/intc/arm_gicv3_common.h"
+#include "hw/intc/arm_gicv3_its_common.h"
 
 #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
 #define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
 #define GEM_REVISION        0x40070106
 
@@ -70,11 +71,13 @@ typedef struct VersalSimplePeriphMap {
 
 typedef struct VersalGicMap {
     int version;
     uint64_t dist;
     uint64_t redist;
+    uint64_t its;
     size_t num_irq;
+    bool has_its;
 } VersalGicMap;
 
 enum StartPoweredOffMode {
     SPO_SECONDARIES,
     SPO_ALL,
@@ -216,10 +219,12 @@ static const VersalMap VERSAL_MAP = {
         .gic = {
             .version = 3,
             .dist = 0xf9000000,
             .redist = 0xf9080000,
             .num_irq = 192,
+            .has_its = true,
+            .its = 0xf9020000,
         },
     },
 
     .uart[0] = { 0xff000000, 18 },
     .uart[1] = { 0xff010000, 19 },
@@ -452,10 +457,52 @@ static MemoryRegion *create_cpu_mr(Versal *s, DeviceState *cluster,
     memory_region_add_subregion(mr, 0, root_alias);
 
     return mr;
 }
 
+static void versal_create_gic_its(Versal *s,
+                                  const VersalCpuClusterMap *map,
+                                  DeviceState *gic,
+                                  MemoryRegion *mr,
+                                  char *gic_node)
+{
+    DeviceState *dev;
+    SysBusDevice *sbd;
+    g_autofree char *node_pat = NULL, *node = NULL;
+    const char compatible[] = "arm,gic-v3-its";
+
+    if (!map->gic.has_its) {
+        return;
+    }
+
+    dev = qdev_new(TYPE_ARM_GICV3_ITS);
+    sbd = SYS_BUS_DEVICE(dev);
+
+    object_property_add_child(OBJECT(gic), "its", OBJECT(dev));
+    object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(gic),
+                             &error_abort);
+
+    sysbus_realize_and_unref(sbd, &error_abort);
+
+    memory_region_add_subregion(mr, map->gic.its,
+                                sysbus_mmio_get_region(sbd, 0));
+
+    if (!map->dtb_expose) {
+        return;
+    }
+
+    qemu_fdt_setprop(s->cfg.fdt, gic_node, "ranges", NULL, 0);
+    qemu_fdt_setprop_cell(s->cfg.fdt, gic_node, "#address-cells", 2);
+    qemu_fdt_setprop_cell(s->cfg.fdt, gic_node, "#size-cells", 2);
+
+    node_pat = g_strdup_printf("%s/its", gic_node);
+    node = versal_fdt_add_simple_subnode(s, node_pat, map->gic.its, 0x20000,
+                                         compatible, sizeof(compatible));
+    qemu_fdt_setprop(s->cfg.fdt, node, "msi-controller", NULL, 0);
+    qemu_fdt_setprop_cell(s->cfg.fdt, node, "#msi-cells", 1);
+}
+
 static DeviceState *versal_create_gic(Versal *s,
                                       const VersalCpuClusterMap *map,
                                       MemoryRegion *mr,
                                       size_t num_cpu)
 {
@@ -477,10 +524,11 @@ static DeviceState *versal_create_gic(Versal *s,
     redist_region_count = qlist_new();
     qlist_append_int(redist_region_count, num_cpu);
     qdev_prop_set_array(dev, "redist-region-count", redist_region_count);
 
     qdev_prop_set_bit(dev, "has-security-extensions", true);
+    qdev_prop_set_bit(dev, "has-lpi", map->gic.has_its);
     object_property_set_link(OBJECT(dev), "sysmem", OBJECT(mr), &error_abort);
 
     sysbus_realize_and_unref(sbd, &error_fatal);
 
     memory_region_add_subregion(mr, map->gic.dist,
@@ -502,10 +550,12 @@ static DeviceState *versal_create_gic(Versal *s,
                                GIC_FDT_IRQ_TYPE_PPI, VERSAL_GIC_MAINT_IRQ,
                                GIC_FDT_IRQ_FLAGS_LEVEL_HI);
         qemu_fdt_setprop(s->cfg.fdt, node, "interrupt-controller", NULL, 0);
     }
 
+    versal_create_gic_its(s, map, dev, mr, node);
+
     return dev;
 }
 
 static void connect_gic_to_cpu(const VersalCpuClusterMap *map,
                                DeviceState *gic, DeviceState *cpu, size_t idx,
-- 
2.50.0
Re: [PATCH 23/48] hw/arm/xlnx-versal: instantiate the GIC ITS in the APU
Posted by Francisco Iglesias 3 months, 2 weeks ago
On Wed, Jul 16, 2025 at 11:54:05AM +0200, Luc Michel wrote:
> Add the instance of the GIC ITS in the APU.
> 
> Signed-off-by: Luc Michel <luc.michel@amd.com>

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

> ---
>  hw/arm/xlnx-versal.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index 35c32de0159..ba8c69bd435 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -42,10 +42,11 @@
>  #include "hw/misc/xlnx-versal-cfu.h"
>  #include "hw/misc/xlnx-versal-cframe-reg.h"
>  #include "hw/or-irq.h"
>  #include "hw/misc/xlnx-versal-crl.h"
>  #include "hw/intc/arm_gicv3_common.h"
> +#include "hw/intc/arm_gicv3_its_common.h"
>  
>  #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
>  #define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
>  #define GEM_REVISION        0x40070106
>  
> @@ -70,11 +71,13 @@ typedef struct VersalSimplePeriphMap {
>  
>  typedef struct VersalGicMap {
>      int version;
>      uint64_t dist;
>      uint64_t redist;
> +    uint64_t its;
>      size_t num_irq;
> +    bool has_its;
>  } VersalGicMap;
>  
>  enum StartPoweredOffMode {
>      SPO_SECONDARIES,
>      SPO_ALL,
> @@ -216,10 +219,12 @@ static const VersalMap VERSAL_MAP = {
>          .gic = {
>              .version = 3,
>              .dist = 0xf9000000,
>              .redist = 0xf9080000,
>              .num_irq = 192,
> +            .has_its = true,
> +            .its = 0xf9020000,
>          },
>      },
>  
>      .uart[0] = { 0xff000000, 18 },
>      .uart[1] = { 0xff010000, 19 },
> @@ -452,10 +457,52 @@ static MemoryRegion *create_cpu_mr(Versal *s, DeviceState *cluster,
>      memory_region_add_subregion(mr, 0, root_alias);
>  
>      return mr;
>  }
>  
> +static void versal_create_gic_its(Versal *s,
> +                                  const VersalCpuClusterMap *map,
> +                                  DeviceState *gic,
> +                                  MemoryRegion *mr,
> +                                  char *gic_node)
> +{
> +    DeviceState *dev;
> +    SysBusDevice *sbd;
> +    g_autofree char *node_pat = NULL, *node = NULL;
> +    const char compatible[] = "arm,gic-v3-its";
> +
> +    if (!map->gic.has_its) {
> +        return;
> +    }
> +
> +    dev = qdev_new(TYPE_ARM_GICV3_ITS);
> +    sbd = SYS_BUS_DEVICE(dev);
> +
> +    object_property_add_child(OBJECT(gic), "its", OBJECT(dev));
> +    object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(gic),
> +                             &error_abort);
> +
> +    sysbus_realize_and_unref(sbd, &error_abort);
> +
> +    memory_region_add_subregion(mr, map->gic.its,
> +                                sysbus_mmio_get_region(sbd, 0));
> +
> +    if (!map->dtb_expose) {
> +        return;
> +    }
> +
> +    qemu_fdt_setprop(s->cfg.fdt, gic_node, "ranges", NULL, 0);
> +    qemu_fdt_setprop_cell(s->cfg.fdt, gic_node, "#address-cells", 2);
> +    qemu_fdt_setprop_cell(s->cfg.fdt, gic_node, "#size-cells", 2);
> +
> +    node_pat = g_strdup_printf("%s/its", gic_node);
> +    node = versal_fdt_add_simple_subnode(s, node_pat, map->gic.its, 0x20000,
> +                                         compatible, sizeof(compatible));
> +    qemu_fdt_setprop(s->cfg.fdt, node, "msi-controller", NULL, 0);
> +    qemu_fdt_setprop_cell(s->cfg.fdt, node, "#msi-cells", 1);
> +}
> +
>  static DeviceState *versal_create_gic(Versal *s,
>                                        const VersalCpuClusterMap *map,
>                                        MemoryRegion *mr,
>                                        size_t num_cpu)
>  {
> @@ -477,10 +524,11 @@ static DeviceState *versal_create_gic(Versal *s,
>      redist_region_count = qlist_new();
>      qlist_append_int(redist_region_count, num_cpu);
>      qdev_prop_set_array(dev, "redist-region-count", redist_region_count);
>  
>      qdev_prop_set_bit(dev, "has-security-extensions", true);
> +    qdev_prop_set_bit(dev, "has-lpi", map->gic.has_its);
>      object_property_set_link(OBJECT(dev), "sysmem", OBJECT(mr), &error_abort);
>  
>      sysbus_realize_and_unref(sbd, &error_fatal);
>  
>      memory_region_add_subregion(mr, map->gic.dist,
> @@ -502,10 +550,12 @@ static DeviceState *versal_create_gic(Versal *s,
>                                 GIC_FDT_IRQ_TYPE_PPI, VERSAL_GIC_MAINT_IRQ,
>                                 GIC_FDT_IRQ_FLAGS_LEVEL_HI);
>          qemu_fdt_setprop(s->cfg.fdt, node, "interrupt-controller", NULL, 0);
>      }
>  
> +    versal_create_gic_its(s, map, dev, mr, node);
> +
>      return dev;
>  }
>  
>  static void connect_gic_to_cpu(const VersalCpuClusterMap *map,
>                                 DeviceState *gic, DeviceState *cpu, size_t idx,
> -- 
> 2.50.0
>