[PATCH 5/7] board: xilinx: Add FWU boot index support

Padmarao Begari padmarao.begari at amd.com
Thu May 14 12:22:22 CEST 2026


Add fwu_plat_get_alt_num() and fwu_plat_get_bootidx() platform
callbacks required for FWU multi-bank update on Versal and Versal
Gen 2. The boot index is read from the PMC Global PGGS4 register
which is populated by PLM with a magic number and boot partition
index. Uses firmware IOCTL when CONFIG_ZYNQMP_FIRMWARE is enabled,
otherwise falls back to direct MMIO read.

Signed-off-by: Padmarao Begari <padmarao.begari at amd.com>
---
 board/xilinx/common/board.c | 73 +++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 89562ef77fc..52a2e8767d8 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -14,8 +14,12 @@
 #include <init.h>
 #include <jffs2/load_kernel.h>
 #include <log.h>
+#include <asm/io.h>
 #include <asm/global_data.h>
 #include <asm/sections.h>
+#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2)
+#include <asm/arch/hardware.h>
+#endif
 #include <dm/uclass.h>
 #include <i2c.h>
 #include <linux/sizes.h>
@@ -30,6 +34,8 @@
 #include <rng.h>
 #include <slre.h>
 #include <soc.h>
+#include <zynqmp_firmware.h>
+#include <linux/bitfield.h>
 #include <linux/ctype.h>
 #include <linux/kernel.h>
 #include <u-boot/uuid.h>
@@ -718,7 +724,74 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
 
 	return reg + size;
 }
+#endif
+
+#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
+
+#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2)
+/*
+ * The Versal and Versal Gen 2 PMC Global pggs4 register contains below
+ * information in each byte as:
+ *
+ * Byte[3]: Magic number
+ * Byte[2]: Boot counter value
+ * Byte[1]: Boot partition value - boot index
+ * Byte[0]: Rollback counter value
+ */
+
+#define MAGIC_NUM	0x1D
+#define MAGIC_MASK	GENMASK(31, 24)
+#define BOOTINDEX_MASK	GENMASK(15, 8)
+
+static int plat_get_boot_index(void)
+{
+	u32 val;
+
+	if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
+		val = zynqmp_pm_get_pmc_global_pggs_reg(PMC_GLOBAL_PGGS4_REG);
+	else
+		val = readl(PMC_GLOBAL_PGGS4_REG);
+
+	if (FIELD_GET(MAGIC_MASK, val) != MAGIC_NUM) {
+		log_err("FWU requires PMC magic number 0x%x\n", MAGIC_NUM);
+		return -EINVAL;
+	}
+
+	return FIELD_GET(BOOTINDEX_MASK, val);
+}
+#endif
+
+int fwu_plat_get_alt_num(struct udevice __always_unused *dev,
+			 efi_guid_t *image_id, u8 *alt_num)
+{
+	int ret;
+
+	ret = fwu_mtd_get_alt_num(image_id, alt_num, "nor0");
+	debug("%s: return %d\n", __func__, ret);
+
+	return ret;
+}
 
+void fwu_plat_get_bootidx(uint *boot_idx)
+{
+	int ret;
+	u32 active_idx;
+
+	ret = fwu_get_active_index(&active_idx);
+	if (ret < 0)
+		printf("%s: failed to read active index\n", __func__);
+
+	ret = plat_get_boot_index();
+	if (ret < 0) {
+		*boot_idx = 0;
+		printf("%s: failed and setup boot index to 0\n", __func__);
+	} else {
+		*boot_idx = ret;
+	}
+
+	debug("%s: boot_idx: %d, active_idx: %d\n",
+	      __func__, *boot_idx, active_idx);
+}
 #endif
 
 #if IS_ENABLED(CONFIG_BOARD_RNG_SEED)
-- 
2.34.1



More information about the U-Boot mailing list