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 >