[PATCH 04/18] arm64: versal: Decouple multiboot register access from firmware

Michal Simek michal.simek at amd.com
Tue Jun 23 14:53:29 CEST 2026


versal_multi_boot() in board code selected between the firmware call
zynqmp_pm_get_pmc_multi_boot_reg() and a direct readl() based on an
IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) check. Generic board code should not
carry firmware-specific ifdefs, and this becomes harder to maintain once
SCMI introduces yet another access method.

Introduce an overridable accessor versal_pmc_multi_boot(). The weak
default lives in arch/arm/mach-versal and performs the plain MMIO read
(used at EL3 and when no firmware is present). When CONFIG_ZYNQMP_FIRMWARE
is enabled, firmware-zynqmp.c provides a strong definition that issues the
firmware call, falling back to the direct read at EL3 where the SMC path
to firmware is unavailable. The shared MMIO read is factored into
versal_multi_boot_reg() so the firmware override does not duplicate it.

versal_multi_boot() keeps the generic JTAG/QEMU workaround and simply
calls the accessor, so board code no longer references the firmware
interface for the multiboot register. The firmware-vs-MMIO decision is
selected at link time, and adding SCMI later only requires a third strong
definition with no board-code changes.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/mach-versal/cpu.c                    | 10 ++++++++++
 arch/arm/mach-versal/include/mach/sys_proto.h |  5 +++++
 board/xilinx/versal/board.c                   |  8 +-------
 drivers/firmware/firmware-zynqmp.c            | 11 +++++++++++
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-versal/cpu.c b/arch/arm/mach-versal/cpu.c
index 62f8a87ce321..1ef4e3435c22 100644
--- a/arch/arm/mach-versal/cpu.c
+++ b/arch/arm/mach-versal/cpu.c
@@ -110,6 +110,16 @@ int arm_reserve_mmu(void)
 }
 #endif
 
+u32 versal_multi_boot_reg(void)
+{
+	return readl(PMC_MULTI_BOOT_REG) & PMC_MULTI_BOOT_MASK;
+}
+
+u32 __weak versal_pmc_multi_boot(void)
+{
+	return versal_multi_boot_reg();
+}
+
 U_BOOT_DRVINFO(soc_xilinx_versal) = {
 	.name = "soc_xilinx_versal",
 };
diff --git a/arch/arm/mach-versal/include/mach/sys_proto.h b/arch/arm/mach-versal/include/mach/sys_proto.h
index b53e616e47be..d7ab25496583 100644
--- a/arch/arm/mach-versal/include/mach/sys_proto.h
+++ b/arch/arm/mach-versal/include/mach/sys_proto.h
@@ -17,4 +17,9 @@ void initialize_tcm(enum tcm_mode mode);
 void tcm_init(enum tcm_mode mode);
 void mem_map_fill(void);
 
+/* Overridable PMC multiboot accessor: weak MMIO default, firmware override */
+u32 versal_pmc_multi_boot(void);
+/* Direct MMIO read of the multiboot register (EL3 / no-firmware path) */
+u32 versal_multi_boot_reg(void);
+
 #endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 8666f2ceff4e..110490b96729 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -62,18 +62,12 @@ static u8 versal_get_bootmode(void)
 static u32 versal_multi_boot(void)
 {
 	u8 bootmode = versal_get_bootmode();
-	u32 reg = 0;
 
 	/* Mostly workaround for QEMU CI pipeline */
 	if (bootmode == JTAG_MODE)
 		return 0;
 
-	if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) && current_el() != 3)
-		reg = zynqmp_pm_get_pmc_multi_boot_reg();
-	else
-		reg = readl(PMC_MULTI_BOOT_REG);
-
-	return reg & PMC_MULTI_BOOT_MASK;
+	return versal_pmc_multi_boot();
 }
 
 int board_init(void)
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 70d205ff3ef9..c8943b8d23a3 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -328,6 +328,17 @@ u32 zynqmp_pm_get_pmc_multi_boot_reg(void)
 }
 #endif
 
+#if defined(CONFIG_ARCH_VERSAL)
+u32 versal_pmc_multi_boot(void)
+{
+	/* At EL3 the SMC path to firmware is unavailable, read directly */
+	if (current_el() == 3)
+		return versal_multi_boot_reg();
+
+	return zynqmp_pm_get_pmc_multi_boot_reg() & PMC_MULTI_BOOT_MASK;
+}
+#endif
+
 #if defined(CONFIG_ARCH_VERSAL2)
 u32 versal2_pmc_multi_boot(void)
 {
-- 
2.43.0



More information about the U-Boot mailing list