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

Reply via email to