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
>