On Wed, Jul 16, 2025 at 11:53:53AM +0200, Luc Michel wrote:
> Refactore the eFuse devices creation using the VersalMap structure.
>
> Note that the corresponding FDT nodes are removed. They do not
> correspond to any real node in standard Versal DTBs. No matching drivers
> exist for them.
>
> Signed-off-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
> ---
> include/hw/arm/xlnx-versal.h | 5 +--
> hw/arm/xlnx-versal-virt.c | 43 ++------------------
> hw/arm/xlnx-versal.c | 78 +++++++++++++++++++++++-------------
> 3 files changed, 54 insertions(+), 72 deletions(-)
>
> diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> index 5d4b30f0ff9..79ca9b13321 100644
> --- a/include/hw/arm/xlnx-versal.h
> +++ b/include/hw/arm/xlnx-versal.h
> @@ -18,11 +18,10 @@
> #include "hw/or-irq.h"
> #include "hw/intc/arm_gicv3.h"
> #include "hw/rtc/xlnx-zynqmp-rtc.h"
> #include "qom/object.h"
> #include "hw/nvram/xlnx-bbram.h"
> -#include "hw/nvram/xlnx-versal-efuse.h"
> #include "hw/ssi/xlnx-versal-ospi.h"
> #include "hw/dma/xlnx_csu_dma.h"
> #include "hw/misc/xlnx-versal-crl.h"
> #include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
> #include "hw/misc/xlnx-versal-trng.h"
> @@ -100,13 +99,10 @@ struct Versal {
> } iou;
>
> XlnxZynqMPRTC rtc;
> XlnxVersalTRng trng;
> XlnxBBRam bbram;
> - XlnxEFuse efuse;
> - XlnxVersalEFuseCtrl efuse_ctrl;
> - XlnxVersalEFuseCache efuse_cache;
> XlnxVersalCFUAPB cfu_apb;
> XlnxVersalCFUFDRO cfu_fdro;
> XlnxVersalCFUSFR cfu_sfr;
> XlnxVersalCFrameReg cframe[XLNX_VERSAL_NR_CFRAME];
> XlnxVersalCFrameBcastReg cframe_bcast;
> @@ -137,10 +133,11 @@ static inline void versal_set_fdt(Versal *s, void *fdt)
> g_assert(!qdev_is_realized(DEVICE(s)));
> s->cfg.fdt = fdt;
> }
>
> void versal_sdhci_plug_card(Versal *s, int sd_idx, BlockBackend *blk);
> +void versal_efuse_attach_drive(Versal *s, BlockBackend *blk);
>
> int versal_get_num_can(VersalVersion version);
> int versal_get_num_sdhci(VersalVersion version);
>
> /* Memory-map and IRQ definitions. Copied a subset from
> diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> index 36341b825eb..d3c84d1955a 100644
> --- a/hw/arm/xlnx-versal-virt.c
> +++ b/hw/arm/xlnx-versal-virt.c
> @@ -190,45 +190,10 @@ static void fdt_add_bbram_node(VersalVirt *s)
> 2, MM_PMC_BBRAM_CTRL_SIZE);
> qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
> g_free(name);
> }
>
> -static void fdt_add_efuse_ctrl_node(VersalVirt *s)
> -{
> - const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CTRL;
> - const char interrupt_names[] = "pmc_efuse";
> - char *name = g_strdup_printf("/pmc_efuse@%x", MM_PMC_EFUSE_CTRL);
> -
> - qemu_fdt_add_subnode(s->fdt, name);
> -
> - qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> - GIC_FDT_IRQ_TYPE_SPI, VERSAL_EFUSE_IRQ,
> - GIC_FDT_IRQ_FLAGS_LEVEL_HI);
> - qemu_fdt_setprop(s->fdt, name, "interrupt-names",
> - interrupt_names, sizeof(interrupt_names));
> - qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> - 2, MM_PMC_EFUSE_CTRL,
> - 2, MM_PMC_EFUSE_CTRL_SIZE);
> - qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
> - g_free(name);
> -}
> -
> -static void fdt_add_efuse_cache_node(VersalVirt *s)
> -{
> - const char compat[] = TYPE_XLNX_VERSAL_EFUSE_CACHE;
> - char *name = g_strdup_printf("/xlnx_pmc_efuse_cache@%x",
> - MM_PMC_EFUSE_CACHE);
> -
> - qemu_fdt_add_subnode(s->fdt, name);
> -
> - qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> - 2, MM_PMC_EFUSE_CACHE,
> - 2, MM_PMC_EFUSE_CACHE_SIZE);
> - qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
> - g_free(name);
> -}
> -
> static void fdt_nop_memory_nodes(void *fdt, Error **errp)
> {
> Error *err = NULL;
> char **node_path;
> int n = 0;
> @@ -391,19 +356,19 @@ static void bbram_attach_drive(XlnxBBRam *dev)
> if (blk) {
> qdev_prop_set_drive(DEVICE(dev), "drive", blk);
> }
> }
>
> -static void efuse_attach_drive(XlnxEFuse *dev)
> +static void efuse_attach_drive(VersalVirt *s)
> {
> DriveInfo *dinfo;
> BlockBackend *blk;
>
> dinfo = drive_get_by_index(IF_PFLASH, 1);
> blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
> if (blk) {
> - qdev_prop_set_drive(DEVICE(dev), "drive", blk);
> + versal_efuse_attach_drive(&s->soc, blk);
> }
> }
>
> static void sd_plug_card(VersalVirt *s, int idx, DriveInfo *di)
> {
> @@ -478,12 +443,10 @@ static void versal_virt_init(MachineState *machine)
> versal_set_fdt(&s->soc, s->fdt);
> fdt_add_gic_nodes(s);
> fdt_add_timer_nodes(s);
> fdt_add_rtc_node(s);
> fdt_add_bbram_node(s);
> - fdt_add_efuse_ctrl_node(s);
> - fdt_add_efuse_cache_node(s);
> fdt_add_cpu_nodes(s, psci_conduit);
> fdt_add_clk_node(s, "/old-clk125", 125000000, s->phandle.clk_125Mhz);
> fdt_add_clk_node(s, "/old-clk25", 25000000, s->phandle.clk_25Mhz);
>
> sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
> @@ -496,11 +459,11 @@ static void versal_virt_init(MachineState *machine)
>
> /* Attach bbram backend, if given */
> bbram_attach_drive(&s->soc.pmc.bbram);
>
> /* Attach efuse backend, if given */
> - efuse_attach_drive(&s->soc.pmc.efuse);
> + efuse_attach_drive(s);
>
> /* Plug SD cards */
> for (i = 0; i < versal_get_num_sdhci(VERSAL_VER_VERSAL); i++) {
> sd_plug_card(s, i, drive_get(IF_SD, 0, i));
> }
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index 4e4df0851e8..ed202b0fcda 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -31,10 +31,11 @@
> #include "hw/sd/sdhci.h"
> #include "hw/net/cadence_gem.h"
> #include "hw/dma/xlnx-zdma.h"
> #include "hw/misc/xlnx-versal-xramc.h"
> #include "hw/usb/xlnx-usb-subsystem.h"
> +#include "hw/nvram/xlnx-versal-efuse.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
>
> @@ -86,10 +87,16 @@ typedef struct VersalMap {
> uint64_t xhci;
> uint64_t ctrl;
> int irq;
> } usb[2];
> size_t num_usb;
> +
> + struct VersalEfuseMap {
> + uint64_t ctrl;
> + uint64_t cache;
> + int irq;
> + } efuse;
> } VersalMap;
>
> static const VersalMap VERSAL_MAP = {
> .uart[0] = { 0xff000000, 18 },
> .uart[1] = { 0xff010000, 19 },
> @@ -117,10 +124,12 @@ static const VersalMap VERSAL_MAP = {
> .irq = 79,
> },
>
> .usb[0] = { .xhci = 0xfe200000, .ctrl = 0xff9d0000, .irq = 22 },
> .num_usb = 1,
> +
> + .efuse = { .ctrl = 0xf1240000, .cache = 0xf1250000, .irq = 139 },
> };
>
> static const VersalMap *VERSION_TO_MAP[] = {
> [VERSAL_VER_VERSAL] = &VERSAL_MAP,
> };
> @@ -744,46 +753,45 @@ static void versal_create_bbram(Versal *s, qemu_irq *pic)
> sysbus_mmio_get_region(sbd, 0));
> sysbus_connect_irq(sbd, 0,
> qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
> }
>
> -static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
> +static void versal_create_efuse(Versal *s,
> + const struct VersalEfuseMap *map)
> {
> - SysBusDevice *part = SYS_BUS_DEVICE(dev);
> + DeviceState *bits;
> + DeviceState *ctrl;
> + DeviceState *cache;
>
> - object_property_set_link(OBJECT(part), "efuse",
> - OBJECT(&s->pmc.efuse), &error_abort);
> + ctrl = qdev_new(TYPE_XLNX_VERSAL_EFUSE_CTRL);
> + cache = qdev_new(TYPE_XLNX_VERSAL_EFUSE_CACHE);
> + bits = qdev_new(TYPE_XLNX_EFUSE);
>
> - sysbus_realize(part, &error_abort);
> - memory_region_add_subregion(&s->mr_ps, base,
> - sysbus_mmio_get_region(part, 0));
> -}
> + qdev_prop_set_uint32(bits, "efuse-nr", 3);
> + qdev_prop_set_uint32(bits, "efuse-size", 8192);
>
> -static void versal_create_efuse(Versal *s, qemu_irq *pic)
> -{
> - Object *bits = OBJECT(&s->pmc.efuse);
> - Object *ctrl = OBJECT(&s->pmc.efuse_ctrl);
> - Object *cache = OBJECT(&s->pmc.efuse_cache);
> + object_property_add_child(OBJECT(s), "efuse", OBJECT(bits));
> + qdev_realize_and_unref(bits, NULL, &error_abort);
>
> - object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl,
> - TYPE_XLNX_VERSAL_EFUSE_CTRL);
> + object_property_set_link(OBJECT(ctrl), "efuse", OBJECT(bits), &error_abort);
>
> - object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache,
> - TYPE_XLNX_VERSAL_EFUSE_CACHE);
> + object_property_set_link(OBJECT(cache), "efuse", OBJECT(bits),
> + &error_abort);
>
> - object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
> - sizeof(s->pmc.efuse),
> - TYPE_XLNX_EFUSE, &error_abort,
> - "efuse-nr", "3",
> - "efuse-size", "8192",
> - NULL);
> + object_property_add_child(OBJECT(s), "efuse-cache", OBJECT(cache));
> + sysbus_realize_and_unref(SYS_BUS_DEVICE(cache), &error_abort);
>
> - qdev_realize(DEVICE(bits), NULL, &error_abort);
> - versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL);
> - versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE);
> + object_property_add_child(OBJECT(s), "efuse-ctrl", OBJECT(ctrl));
> + sysbus_realize_and_unref(SYS_BUS_DEVICE(ctrl), &error_abort);
>
> - sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
> + memory_region_add_subregion(&s->mr_ps, map->ctrl,
> + sysbus_mmio_get_region(SYS_BUS_DEVICE(ctrl),
> + 0));
> + memory_region_add_subregion(&s->mr_ps, map->cache,
> + sysbus_mmio_get_region(SYS_BUS_DEVICE(cache),
> + 0));
> + versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(ctrl), 0, map->irq);
> }
>
> static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
> {
> SysBusDevice *sbd;
> @@ -1247,15 +1255,16 @@ static void versal_realize(DeviceState *dev, Error **errp)
>
> for (i = 0; i < map->num_usb; i++) {
> versal_create_usb(s, &map->usb[i]);
> }
>
> + versal_create_efuse(s, &map->efuse);
> +
> versal_create_pmc_apb_irq_orgate(s, pic);
> versal_create_rtc(s, pic);
> versal_create_trng(s, pic);
> versal_create_bbram(s, pic);
> - versal_create_efuse(s, pic);
> versal_create_pmc_iou_slcr(s, pic);
> versal_create_ospi(s, pic);
> versal_create_crl(s, pic);
> versal_create_cfu(s, pic);
> versal_map_ddr(s);
> @@ -1286,10 +1295,23 @@ void versal_sdhci_plug_card(Versal *s, int sd_idx, BlockBackend *blk)
> qdev_prop_set_drive_err(card, "drive", blk, &error_fatal);
> qdev_realize_and_unref(card, qdev_get_child_bus(DEVICE(sdhci), "sd-bus"),
> &error_fatal);
> }
>
> +void versal_efuse_attach_drive(Versal *s, BlockBackend *blk)
> +{
> + DeviceState *efuse;
> +
> + efuse = DEVICE(versal_get_child(s, "efuse"));
> +
> + if (efuse == NULL) {
> + return;
> + }
> +
> + qdev_prop_set_drive(efuse, "drive", blk);
> +}
> +
> int versal_get_num_can(VersalVersion version)
> {
> const VersalMap *map = VERSION_TO_MAP[version];
>
> return map->num_canfd;
> --
> 2.50.0
>