[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