On Wed, Jul 16, 2025 at 11:54:00AM +0200, Luc Michel wrote:
> Refactor the CFU device creation using the VersalMap structure. All
> users of the APB IRQ OR gate have now been converted. The OR gate device
> can be dropped.
> 
> Signed-off-by: Luc Michel <luc.mic...@amd.com>

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

> ---
>  include/hw/arm/xlnx-versal.h |  14 --
>  hw/arm/xlnx-versal.c         | 258 ++++++++++++++++-------------------
>  2 files changed, 115 insertions(+), 157 deletions(-)
> 
> diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> index abdbed15689..5a685aea6d4 100644
> --- a/include/hw/arm/xlnx-versal.h
> +++ b/include/hw/arm/xlnx-versal.h
> @@ -13,17 +13,14 @@
>  #ifndef XLNX_VERSAL_H
>  #define XLNX_VERSAL_H
>  
>  #include "hw/sysbus.h"
>  #include "hw/cpu/cluster.h"
> -#include "hw/or-irq.h"
>  #include "hw/intc/arm_gicv3.h"
>  #include "qom/object.h"
>  #include "hw/misc/xlnx-versal-crl.h"
>  #include "net/can_emu.h"
> -#include "hw/misc/xlnx-versal-cfu.h"
> -#include "hw/misc/xlnx-versal-cframe-reg.h"
>  #include "target/arm/cpu.h"
>  #include "hw/arm/xlnx-versal-version.h"
>  
>  #define TYPE_XLNX_VERSAL_BASE "xlnx-versal-base"
>  OBJECT_DECLARE_TYPE(Versal, VersalClass, XLNX_VERSAL_BASE)
> @@ -76,21 +73,10 @@ struct Versal {
>          } rpu;
>  
>          XlnxVersalCRL crl;
>      } lpd;
>  
> -    /* The Platform Management Controller subsystem.  */
> -    struct {
> -        XlnxVersalCFUAPB cfu_apb;
> -        XlnxVersalCFUFDRO cfu_fdro;
> -        XlnxVersalCFUSFR cfu_sfr;
> -        XlnxVersalCFrameReg cframe[XLNX_VERSAL_NR_CFRAME];
> -        XlnxVersalCFrameBcastReg cframe_bcast;
> -
> -        OrIRQState apb_irq_orgate;
> -    } pmc;
> -
>      struct {
>          uint32_t clk_25mhz;
>          uint32_t clk_125mhz;
>      } phandle;
>  
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index 41965531f8d..2128dbbad92 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -37,10 +37,13 @@
>  #include "hw/ssi/xlnx-versal-ospi.h"
>  #include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
>  #include "hw/nvram/xlnx-bbram.h"
>  #include "hw/misc/xlnx-versal-trng.h"
>  #include "hw/rtc/xlnx-zynqmp-rtc.h"
> +#include "hw/misc/xlnx-versal-cfu.h"
> +#include "hw/misc/xlnx-versal-cframe-reg.h"
> +#include "hw/or-irq.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
>  
> @@ -128,10 +131,28 @@ typedef struct VersalMap {
>      struct VersalRtcMap {
>          VersalSimplePeriphMap map;
>          int alarm_irq;
>          int second_irq;
>      } rtc;
> +
> +    struct VersalCfuMap {
> +        uint64_t cframe_base;
> +        uint64_t cframe_stride;
> +        uint64_t cfu_fdro;
> +        uint64_t cframe_bcast_reg;
> +        uint64_t cframe_bcast_fdri;
> +        uint64_t cfu_apb;
> +        uint64_t cfu_stream;
> +        uint64_t cfu_stream_2;
> +        uint64_t cfu_sfr;
> +        int cfu_apb_irq;
> +        int cframe_irq;
> +        size_t num_cframe;
> +        struct VersalCfuCframeCfg {
> +            uint32_t blktype_frames[7];
> +        } cframe_cfg[15];
> +    } cfu;
>  } VersalMap;
>  
>  static const VersalMap VERSAL_MAP = {
>      .uart[0] = { 0xff000000, 18 },
>      .uart[1] = { 0xff010000, 19 },
> @@ -176,10 +197,26 @@ static const VersalMap VERSAL_MAP = {
>      .trng = { 0xf1230000, 141 },
>      .rtc = {
>          { 0xf12a0000, OR_IRQ(121, 2) },
>          .alarm_irq = 142, .second_irq = 143
>      },
> +
> +    .cfu = {
> +        .cframe_base = 0xf12d0000, .cframe_stride = 0x1000,
> +        .cframe_bcast_reg = 0xf12ee000, .cframe_bcast_fdri = 0xf12ef000,
> +        .cfu_apb = 0xf12b0000, .cfu_sfr = 0xf12c1000,
> +        .cfu_stream = 0xf12c0000, .cfu_stream_2 = 0xf1f80000,
> +        .cfu_fdro = 0xf12c2000,
> +        .cfu_apb_irq = 120, .cframe_irq = OR_IRQ(121, 3),
> +        .num_cframe = 15,
> +        .cframe_cfg = {
> +            { { 34111, 3528, 12800, 11, 5, 1, 1 } },
> +            { { 38498, 3841, 15361, 13, 7, 3, 1 } },
> +            { { 38498, 3841, 15361, 13, 7, 3, 1 } },
> +            { { 38498, 3841, 15361, 13, 7, 3, 1 } },
> +        },
> +    },
>  };
>  
>  static const VersalMap *VERSION_TO_MAP[] = {
>      [VERSAL_VER_VERSAL] = &VERSAL_MAP,
>  };
> @@ -743,31 +780,10 @@ static void versal_create_sdhci(Versal *s,
>      qemu_fdt_setprop_cells(s->cfg.fdt, node, "interrupts",
>                             GIC_FDT_IRQ_TYPE_SPI, map->irq,
>                             GIC_FDT_IRQ_FLAGS_LEVEL_HI);
>  }
>  
> -static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
> -{
> -    DeviceState *orgate;
> -
> -    /*
> -     * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
> -     * models:
> -     *  - RTC
> -     *  - BBRAM
> -     *  - PMC SLCR
> -     *  - CFRAME regs (input 3 - 17 to the orgate)
> -     */
> -    object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
> -                            &s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
> -    orgate = DEVICE(&s->pmc.apb_irq_orgate);
> -    object_property_set_int(OBJECT(orgate),
> -                            "num-lines", VERSAL_NUM_PMC_APB_IRQS, 
> &error_fatal);
> -    qdev_realize(orgate, NULL, &error_fatal);
> -    qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
> -}
> -
>  static void versal_create_rtc(Versal *s, const struct VersalRtcMap *map)
>  {
>      SysBusDevice *sbd;
>      MemoryRegion *mr;
>      g_autofree char *node;
> @@ -982,158 +998,115 @@ static DeviceState *versal_create_ospi(Versal *s,
>      sysbus_connect_irq(SYS_BUS_DEVICE(dma_dst), 0, qdev_get_gpio_in(orgate, 
> 2));
>  
>      return dev;
>  }
>  
> -static void versal_create_cfu(Versal *s, qemu_irq *pic)
> +static void versal_create_cfu(Versal *s, const struct VersalCfuMap *map)
>  {
>      SysBusDevice *sbd;
> -    DeviceState *dev;
> +    Object *container;
> +    DeviceState *cfu_fdro, *cfu_apb, *cfu_sfr, *cframe_bcast;
> +    DeviceState *cframe_irq_or;
>      int i;
> -    const struct {
> +
> +    container = object_new(TYPE_CONTAINER);
> +    object_property_add_child(OBJECT(s), "cfu", container);
> +    object_unref(container);
> +
> +    /* CFU FDRO */
> +    cfu_fdro = qdev_new(TYPE_XLNX_VERSAL_CFU_FDRO);
> +    object_property_add_child(container, "cfu-fdro", OBJECT(cfu_fdro));
> +    sbd = SYS_BUS_DEVICE(cfu_fdro);
> +
> +    sysbus_realize_and_unref(sbd, &error_fatal);
> +    memory_region_add_subregion(&s->mr_ps, map->cfu_fdro,
> +                                sysbus_mmio_get_region(sbd, 0));
> +
> +    /* cframe bcast */
> +    cframe_bcast = qdev_new(TYPE_XLNX_VERSAL_CFRAME_BCAST_REG);
> +    object_property_add_child(container, "cframe-bcast", 
> OBJECT(cframe_bcast));
> +
> +    /* CFU APB */
> +    cfu_apb = qdev_new(TYPE_XLNX_VERSAL_CFU_APB);
> +    object_property_add_child(container, "cfu-apb", OBJECT(cfu_apb));
> +
> +    /* IRQ or gate for cframes */
> +    cframe_irq_or = qdev_new(TYPE_OR_IRQ);
> +    object_property_add_child(container, "cframe-irq-or-gate",
> +                              OBJECT(cframe_irq_or));
> +    qdev_prop_set_uint16(cframe_irq_or, "num-lines", map->num_cframe);
> +    qdev_realize_and_unref(cframe_irq_or, NULL, &error_abort);
> +    versal_qdev_connect_gpio_out(s, cframe_irq_or, 0, map->cframe_irq);
> +
> +    /* cframe reg */
> +    for (i = 0; i < map->num_cframe; i++) {
>          uint64_t reg_base;
>          uint64_t fdri_base;
> -    } cframe_addr[] = {
> -        { MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI },
> -        { MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI },
> -        { MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI },
> -        { MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI },
> -        { MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI },
> -        { MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI },
> -        { MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI },
> -        { MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI },
> -        { MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI },
> -        { MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI },
> -        { MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI },
> -        { MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI },
> -        { MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI },
> -        { MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI },
> -        { MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI },
> -    };
> -    const struct {
> -        uint32_t blktype0_frames;
> -        uint32_t blktype1_frames;
> -        uint32_t blktype2_frames;
> -        uint32_t blktype3_frames;
> -        uint32_t blktype4_frames;
> -        uint32_t blktype5_frames;
> -        uint32_t blktype6_frames;
> -    } cframe_cfg[] = {
> -        [0] = { 34111, 3528, 12800, 11, 5, 1, 1 },
> -        [1] = { 38498, 3841, 15361, 13, 7, 3, 1 },
> -        [2] = { 38498, 3841, 15361, 13, 7, 3, 1 },
> -        [3] = { 38498, 3841, 15361, 13, 7, 3, 1 },
> -    };
> +        DeviceState *dev;
> +        g_autofree char *prop_name;
> +        size_t j;
>  
> -    /* CFU FDRO */
> -    object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro,
> -                            TYPE_XLNX_VERSAL_CFU_FDRO);
> -    sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro);
> +        dev = qdev_new(TYPE_XLNX_VERSAL_CFRAME_REG);
> +        object_property_add_child(container, "cframe[*]", OBJECT(dev));
>  
> -    sysbus_realize(sbd, &error_fatal);
> -    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO,
> -                                sysbus_mmio_get_region(sbd, 0));
> +        sbd = SYS_BUS_DEVICE(dev);
>  
> -    /* CFRAME REG */
> -    for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
> -        g_autofree char *name = g_strdup_printf("cframe%d", i);
> +        for (j = 0; j < ARRAY_SIZE(map->cframe_cfg[i].blktype_frames); j++) {
> +            g_autofree char *blktype_prop_name;
>  
> -        object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i],
> -                                TYPE_XLNX_VERSAL_CFRAME_REG);
> -
> -        sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]);
> -        dev = DEVICE(&s->pmc.cframe[i]);
> -
> -        if (i < ARRAY_SIZE(cframe_cfg)) {
> -            object_property_set_int(OBJECT(dev), "blktype0-frames",
> -                                    cframe_cfg[i].blktype0_frames,
> -                                    &error_abort);
> -            object_property_set_int(OBJECT(dev), "blktype1-frames",
> -                                    cframe_cfg[i].blktype1_frames,
> -                                    &error_abort);
> -            object_property_set_int(OBJECT(dev), "blktype2-frames",
> -                                    cframe_cfg[i].blktype2_frames,
> -                                    &error_abort);
> -            object_property_set_int(OBJECT(dev), "blktype3-frames",
> -                                    cframe_cfg[i].blktype3_frames,
> -                                    &error_abort);
> -            object_property_set_int(OBJECT(dev), "blktype4-frames",
> -                                    cframe_cfg[i].blktype4_frames,
> -                                    &error_abort);
> -            object_property_set_int(OBJECT(dev), "blktype5-frames",
> -                                    cframe_cfg[i].blktype5_frames,
> -                                    &error_abort);
> -            object_property_set_int(OBJECT(dev), "blktype6-frames",
> -                                    cframe_cfg[i].blktype6_frames,
> +            blktype_prop_name = g_strdup_printf("blktype%zu-frames", j);
> +            object_property_set_int(OBJECT(dev), blktype_prop_name,
> +                                    map->cframe_cfg[i].blktype_frames[j],
>                                      &error_abort);
>          }
> +
>          object_property_set_link(OBJECT(dev), "cfu-fdro",
> -                                 OBJECT(&s->pmc.cfu_fdro), &error_fatal);
> +                                 OBJECT(cfu_fdro), &error_abort);
>  
> -        sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
> +        sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_abort);
>  
> -        memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base,
> +        reg_base = map->cframe_base + i * map->cframe_stride * 2;
> +        fdri_base = reg_base + map->cframe_stride;
> +        memory_region_add_subregion(&s->mr_ps, reg_base,
>                                      sysbus_mmio_get_region(sbd, 0));
> -        memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base,
> +        memory_region_add_subregion(&s->mr_ps, fdri_base,
>                                      sysbus_mmio_get_region(sbd, 1));
> -        sysbus_connect_irq(sbd, 0,
> -                           qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate),
> -                                            3 + i));
> -    }
> -
> -    /* CFRAME BCAST */
> -    object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast,
> -                            TYPE_XLNX_VERSAL_CFRAME_BCAST_REG);
> +        sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(cframe_irq_or, i));
>  
> -    sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast);
> -    dev = DEVICE(&s->pmc.cframe_bcast);
> -
> -    for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
> -        g_autofree char *propname = g_strdup_printf("cframe%d", i);
> -        object_property_set_link(OBJECT(dev), propname,
> -                                 OBJECT(&s->pmc.cframe[i]), &error_fatal);
> +        prop_name = g_strdup_printf("cframe%d", i);
> +        object_property_set_link(OBJECT(cframe_bcast), prop_name,
> +                                 OBJECT(dev), &error_abort);
> +        object_property_set_link(OBJECT(cfu_apb), prop_name,
> +                                 OBJECT(dev), &error_abort);
>      }
>  
> -    sysbus_realize(sbd, &error_fatal);
> -
> -    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG,
> +    sbd = SYS_BUS_DEVICE(cframe_bcast);
> +    sysbus_realize_and_unref(sbd, &error_abort);
> +    memory_region_add_subregion(&s->mr_ps, map->cframe_bcast_reg,
>                                  sysbus_mmio_get_region(sbd, 0));
> -    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI,
> +    memory_region_add_subregion(&s->mr_ps, map->cframe_bcast_fdri,
>                                  sysbus_mmio_get_region(sbd, 1));
>  
> -    /* CFU APB */
> -    object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb,
> -                            TYPE_XLNX_VERSAL_CFU_APB);
> -    sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb);
> -    dev = DEVICE(&s->pmc.cfu_apb);
> -
> -    for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
> -        g_autofree char *propname = g_strdup_printf("cframe%d", i);
> -        object_property_set_link(OBJECT(dev), propname,
> -                                 OBJECT(&s->pmc.cframe[i]), &error_fatal);
> -    }
> -
> -    sysbus_realize(sbd, &error_fatal);
> -    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB,
> +    sbd = SYS_BUS_DEVICE(cfu_apb);
> +    sysbus_realize_and_unref(sbd, &error_fatal);
> +    memory_region_add_subregion(&s->mr_ps, map->cfu_apb,
>                                  sysbus_mmio_get_region(sbd, 0));
> -    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM,
> +    memory_region_add_subregion(&s->mr_ps, map->cfu_stream,
>                                  sysbus_mmio_get_region(sbd, 1));
> -    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2,
> +    memory_region_add_subregion(&s->mr_ps, map->cfu_stream_2,
>                                  sysbus_mmio_get_region(sbd, 2));
> -    sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]);
> +    versal_sysbus_connect_irq(s, sbd, 0, map->cfu_apb_irq);
>  
>      /* CFU SFR */
> -    object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr,
> -                            TYPE_XLNX_VERSAL_CFU_SFR);
> +    cfu_sfr = qdev_new(TYPE_XLNX_VERSAL_CFU_SFR);
> +    object_property_add_child(container, "cfu-sfr", OBJECT(cfu_sfr));
> +    sbd = SYS_BUS_DEVICE(cfu_sfr);
>  
> -    sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr);
> -
> -    object_property_set_link(OBJECT(&s->pmc.cfu_sfr),
> -                            "cfu", OBJECT(&s->pmc.cfu_apb), &error_abort);
> -
> -    sysbus_realize(sbd, &error_fatal);
> -    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR,
> +    object_property_set_link(OBJECT(cfu_sfr),
> +                            "cfu", OBJECT(cfu_apb), &error_abort);
> +    sysbus_realize_and_unref(sbd, &error_fatal);
> +    memory_region_add_subregion(&s->mr_ps, map->cfu_sfr,
>                                  sysbus_mmio_get_region(sbd, 0));
>  }
>  
>  static void versal_create_crl(Versal *s, qemu_irq *pic)
>  {
> @@ -1353,14 +1326,13 @@ static void versal_realize(DeviceState *dev, Error 
> **errp)
>                                                         "ospi-mux-sel", 0));
>  
>      versal_create_bbram(s, &map->bbram);
>      versal_create_trng(s, &map->trng);
>      versal_create_rtc(s, &map->rtc);
> +    versal_create_cfu(s, &map->cfu);
>  
> -    versal_create_pmc_apb_irq_orgate(s, pic);
>      versal_create_crl(s, pic);
> -    versal_create_cfu(s, pic);
>      versal_map_ddr(s);
>      versal_unimp(s);
>  
>      /* Create the On Chip Memory (OCM).  */
>      memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm",
> -- 
> 2.50.0
> 

Reply via email to