Add configure_capsule_updates() supporting MMC, SD and QSPI/OSPI boot modes for DFU string generation. Add set_dfu_alt_info() for FWU multi-bank mode to generate DFU alt info from NOR flash MTD partitions. Add XILINX_BOOT_IMAGE_GUID for the capsule updatable firmware image.
Signed-off-by: Padmarao Begari <[email protected]> --- board/amd/versal2/board.c | 131 +++++++++++++++++++++++++++++++++- include/configs/amd_versal2.h | 5 ++ 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c index d94c1494d53..4e68efc6416 100644 --- a/board/amd/versal2/board.c +++ b/board/amd/versal2/board.c @@ -1,17 +1,24 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2021 - 2022, Xilinx, Inc. - * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc. + * Copyright (C) 2022 - 2026, Advanced Micro Devices, Inc. * * Michal Simek <[email protected]> */ #include <cpu_func.h> +#include <dfu.h> +#include <env.h> +#include <efi_loader.h> #include <fdtdec.h> +#include <fwu.h> #include <init.h> #include <env_internal.h> #include <log.h> #include <malloc.h> +#include <memalign.h> +#include <mmc.h> +#include <mtd.h> #include <time.h> #include <asm/cache.h> #include <asm/global_data.h> @@ -26,6 +33,7 @@ #include "../../xilinx/common/board.h" #include <linux/bitfield.h> +#include <linux/sizes.h> #include <debug_uart.h> #include <generated/dt.h> #include <linux/ioport.h> @@ -347,6 +355,10 @@ int board_late_init(void) int ret; u32 multiboot; + if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && + !IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) + configure_capsule_updates(); + if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { debug("Saved variables - Skipping\n"); return 0; @@ -475,3 +487,120 @@ enum env_location env_get_location(enum env_operation op, int prio) } } #endif + +#define DFU_ALT_BUF_LEN SZ_1K + +#if defined(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) && \ + !defined(CONFIG_FWU_MULTI_BANK_UPDATE) +static void mtd_found_part(u32 *base, u32 *size) +{ + struct mtd_info *part, *mtd; + + mtd_probe_devices(); + + mtd = get_mtd_device_nm("nor0"); + if (!IS_ERR_OR_NULL(mtd)) { + list_for_each_entry(part, &mtd->partitions, node) { + debug("0x%012llx-0x%012llx : \"%s\"\n", + part->offset, part->offset + part->size, + part->name); + + if (*base >= part->offset && + *base < part->offset + part->size) { + debug("Found my partition: %d/%s\n", + part->index, part->name); + *base = part->offset; + *size = part->size; + break; + } + } + } +} + +void configure_capsule_updates(void) +{ + int bootseq = 0, len = 0; + u32 multiboot = versal2_multi_boot(); + u32 bootmode = versal2_get_bootmode(); + + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + + memset(buf, 0, DFU_ALT_BUF_LEN); + + multiboot = env_get_hex("multiboot", multiboot); + + switch (bootmode) { + case EMMC_MODE: + case SD_MODE: + case SD1_LSHFT_MODE: + case SD_MODE1: + bootseq = mmc_get_env_dev(); + + len += snprintf(buf + len, DFU_ALT_BUF_LEN, "mmc %d=boot", + bootseq); + + if (multiboot) + len += snprintf(buf + len, DFU_ALT_BUF_LEN, + "%04d", multiboot); + + len += snprintf(buf + len, DFU_ALT_BUF_LEN, ".bin fat %d 1", + bootseq); + break; + case QSPI_MODE_24BIT: + case QSPI_MODE_32BIT: + case OSPI_MODE: + { + u32 base = multiboot * SZ_32K; + u32 size = 0x1500000; + u32 limit = size; + + mtd_found_part(&base, &limit); + + len += snprintf(buf + len, DFU_ALT_BUF_LEN, + "sf 0:0=boot.bin raw 0x%x 0x%x", + base, limit); + } + break; + default: + return; + } + + update_info.dfu_string = strdup(buf); + debug("Capsule DFU: %s\n", update_info.dfu_string); +} +#endif + +#if defined(CONFIG_FWU_MULTI_BANK_UPDATE) + +/* Generate dfu_alt_info from partitions */ +void set_dfu_alt_info(char *interface, char *devstr) +{ + int ret; + struct mtd_info *mtd; + + /* + * It is called multiple times for every image + * per bank that's why enough to set it up once. + */ + if (env_get("dfu_alt_info")) + return; + + ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); + memset(buf, 0, DFU_ALT_BUF_LEN); + + mtd_probe_devices(); + + mtd = get_mtd_device_nm("nor0"); + if (IS_ERR_OR_NULL(mtd)) + return; + + ret = fwu_gen_alt_info_from_mtd(buf, DFU_ALT_BUF_LEN, mtd); + if (ret < 0) { + log_err("Error: Failed to generate dfu_alt_info. (%d)\n", ret); + return; + } + log_debug("Make dfu_alt_info: '%s'\n", buf); + + env_set("dfu_alt_info", buf); +} +#endif diff --git a/include/configs/amd_versal2.h b/include/configs/amd_versal2.h index fccc786219f..a07e12bd146 100644 --- a/include/configs/amd_versal2.h +++ b/include/configs/amd_versal2.h @@ -23,6 +23,11 @@ #define CFG_SYS_BAUDRATE_TABLE \ { 4800, 9600, 19200, 38400, 57600, 115200 } +/* GUID for capsule updatable firmware image */ +#define XILINX_BOOT_IMAGE_GUID \ + EFI_GUID(0xed9e7fcf, 0x47b3, 0x40cd, 0xb6, 0xe3, \ + 0x56, 0x5f, 0x14, 0x67, 0x6d, 0x82) + #if defined(CONFIG_CMD_DFU) #define DFU_DEFAULT_POLL_TIMEOUT 300 #define DFU_ALT_INFO_RAM \ -- 2.34.1

