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.michel@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
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.michel@amd.com>
Reviewed-by: Francisco Iglesias <francisco.iglesias@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
>
© 2016 - 2025 Red Hat, Inc.