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 <[email protected]> --- 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

