[PATCH v3 00/20] FWU: Add support for FWU metadata version 2

The following patch series adds support for version 2 of the FWU metadata. The version 2 metadata structure is defined in the latest revision of the FWU specification [1].
The earlier versions of these patches were migrating to a version 2 only support in U-Boot, similar to TF-A. However, based on feedback from ST [2], this series has been updated to support both versions. A platform would still be needed to enable one of the two versions of metadata through a config symbol.
TF-A has code which reads the FWU metadata and boots the platform from the active partition. TF-A has decided to migrate the FWU code to a version 2 only support. These changes have been merged in upstream TF-A.
These changes have been tested on the ST DK2 board, which uses the GPT based partitioning scheme. Both V1 and V2 metadata versions have been tested on the DK2 board.
These changes need to be tested on platforms with MTD partitioned storage devices.
@Michal and @Kojima-san, please help in this testing.
Note: The CI is breaking on some sandbox py tests, but the errors look unrelated. I will look into those issues, but the code review can proceed.
[1] - https://developer.arm.com/documentation/den0118/latest/ [2] - https://lists.denx.de/pipermail/u-boot/2024-February/546277.html
Changes since V2: * New patch which retains support for V1 of metadata * Earlier patch was catering to v2 only support. These changes support both versions of metadata. * Earlier patch was migrating to v2 only support. These changes support both versions. * Support both metadata versions instead of only v2. * Added documentation changes. * Make changes to have the test work with v1 metadata. * Make changes to have the test work with updated logic in fwu code. * Changes to indicate support for both v1 and v2 instead of only v2. * Add config symbol for selecting either of the two metadata versions.
Sughosh Ganu (20): configs: fwu: remove FWU configs for metadata V2 support tools: mkfwumdata: fix the size parameter to the fwrite call drivers: fwu: add the size parameter to the metadata access API's drivers: fwu: mtd: allocate buffer for image info dynamically fwu: metadata: add support for version 2 of the structure fwu: metadata: add a version agnostic structure fwu: metadata: add functions for handling version specific metadata fields fwu: make changes to access version agnostic structure fields capsule: fwu: transition the platform state on a successful update fwu: add config symbols for enabling FWU metadata versions fwu: mtd: remove unused argument from function call fwu: mtd: get MTD partition specific info from driver fwu: mtd: obtain image information from version agnostic structure cmd: fwu: make changes for supporting FWU metadata version 2 tools: mkfwumdata: add support for metadata version 2 tools: mkfwumdata: add logic to append vendor data to the FWU metadata test: fwu: make changes to the FWU metadata access test doc: fwu: make changes to reflect support for FWU metadata v2 MAINTAINERS: add entry for FWU multi bank update feature configs: fwu: re-enable FWU configs
MAINTAINERS | 8 + cmd/fwu_mdata.c | 39 ++-- configs/corstone1000_defconfig | 1 + configs/sandbox64_defconfig | 1 + configs/synquacer_developerbox_defconfig | 2 +- doc/board/socionext/developerbox.rst | 7 +- doc/develop/uefi/fwu_updates.rst | 20 +- doc/mkfwumdata.1 | 16 +- drivers/fwu-mdata/fwu-mdata-uclass.c | 10 +- drivers/fwu-mdata/gpt_blk.c | 23 +- drivers/fwu-mdata/raw_mtd.c | 78 ++++--- include/fwu.h | 147 ++++++++++++- include/fwu_mdata.h | 71 ++++++- lib/efi_loader/efi_capsule.c | 14 +- lib/fwu_updates/Kconfig | 14 ++ lib/fwu_updates/Makefile | 2 + lib/fwu_updates/fwu.c | 204 ++++++++++++------ lib/fwu_updates/fwu_mtd.c | 34 +-- lib/fwu_updates/fwu_v1.c | 167 +++++++++++++++ lib/fwu_updates/fwu_v2.c | 260 +++++++++++++++++++++++ test/dm/fwu_mdata.c | 16 +- tools/mkfwumdata.c | 235 ++++++++++++++++---- 22 files changed, 1153 insertions(+), 216 deletions(-) create mode 100644 lib/fwu_updates/fwu_v1.c create mode 100644 lib/fwu_updates/fwu_v2.c

Support is to be added in the following commits for the FWU metadata version 2. Disable the FWU feature on platforms that enable it for the V2 addition work.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: None
configs/corstone1000_defconfig | 2 -- configs/sandbox64_defconfig | 1 - configs/synquacer_developerbox_defconfig | 4 ---- 3 files changed, 7 deletions(-)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig index 8b2f77f648..29d7550afb 100644 --- a/configs/corstone1000_defconfig +++ b/configs/corstone1000_defconfig @@ -24,7 +24,6 @@ CONFIG_LOGLEVEL=7 CONFIG_BOARD_LATE_INIT=y CONFIG_SYS_PROMPT="corstone1000# " # CONFIG_CMD_CONSOLE is not set -CONFIG_CMD_FWU_METADATA=y CONFIG_CMD_BOOTZ=y # CONFIG_CMD_XIMG is not set CONFIG_CMD_GPT=y @@ -67,4 +66,3 @@ CONFIG_FFA_SHARED_MM_BUF_OFFSET=0 CONFIG_FFA_SHARED_MM_BUF_ADDR=0x02000000 CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_IGNORE_OSINDICATIONS=y -CONFIG_FWU_MULTI_BANK_UPDATE=y diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 3be9a00a85..7e8200e70c 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -272,7 +272,6 @@ CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y -CONFIG_FWU_MULTI_BANK_UPDATE=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig index 2a0407de40..616d410074 100644 --- a/configs/synquacer_developerbox_defconfig +++ b/configs/synquacer_developerbox_defconfig @@ -11,14 +11,12 @@ CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="synquacer-sc2a11-developerbox" CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_TARGET_DEVELOPERBOX=y -CONFIG_FWU_NUM_IMAGES_PER_BANK=1 CONFIG_AHCI=y CONFIG_FIT=y CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_BOOTSTAGE_STASH_SIZE=4096 CONFIG_HUSH_PARSER=y CONFIG_SYS_MAXARGS=128 -CONFIG_CMD_FWU_METADATA=y CONFIG_CMD_IMLS=y CONFIG_CMD_ERASEENV=y CONFIG_CMD_NVEDIT_EFI=y @@ -53,7 +51,6 @@ CONFIG_DFU_TFTP=y CONFIG_DFU_MTD=y CONFIG_DFU_RAM=y CONFIG_DFU_SF=y -CONFIG_FWU_MDATA_MTD=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_SYNQUACER=y CONFIG_MMC_SDHCI=y @@ -96,4 +93,3 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_IGNORE_OSINDICATIONS=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y -CONFIG_FWU_MULTI_BANK_UPDATE=y

On Fri, 22 Mar 2024 at 12:58, Sughosh Ganu sughosh.ganu@linaro.org wrote:
Support is to be added in the following commits for the FWU metadata version 2. Disable the FWU feature on platforms that enable it for the V2 addition work.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V2: None
configs/corstone1000_defconfig | 2 -- configs/sandbox64_defconfig | 1 - configs/synquacer_developerbox_defconfig | 4 ---- 3 files changed, 7 deletions(-)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig index 8b2f77f648..29d7550afb 100644 --- a/configs/corstone1000_defconfig +++ b/configs/corstone1000_defconfig @@ -24,7 +24,6 @@ CONFIG_LOGLEVEL=7 CONFIG_BOARD_LATE_INIT=y CONFIG_SYS_PROMPT="corstone1000# " # CONFIG_CMD_CONSOLE is not set -CONFIG_CMD_FWU_METADATA=y CONFIG_CMD_BOOTZ=y # CONFIG_CMD_XIMG is not set CONFIG_CMD_GPT=y @@ -67,4 +66,3 @@ CONFIG_FFA_SHARED_MM_BUF_OFFSET=0 CONFIG_FFA_SHARED_MM_BUF_ADDR=0x02000000 CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_IGNORE_OSINDICATIONS=y -CONFIG_FWU_MULTI_BANK_UPDATE=y diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 3be9a00a85..7e8200e70c 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -272,7 +272,6 @@ CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y -CONFIG_FWU_MULTI_BANK_UPDATE=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig index 2a0407de40..616d410074 100644 --- a/configs/synquacer_developerbox_defconfig +++ b/configs/synquacer_developerbox_defconfig @@ -11,14 +11,12 @@ CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="synquacer-sc2a11-developerbox" CONFIG_SYS_LOAD_ADDR=0x80000000 CONFIG_TARGET_DEVELOPERBOX=y -CONFIG_FWU_NUM_IMAGES_PER_BANK=1 CONFIG_AHCI=y CONFIG_FIT=y CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_BOOTSTAGE_STASH_SIZE=4096 CONFIG_HUSH_PARSER=y CONFIG_SYS_MAXARGS=128 -CONFIG_CMD_FWU_METADATA=y CONFIG_CMD_IMLS=y CONFIG_CMD_ERASEENV=y CONFIG_CMD_NVEDIT_EFI=y @@ -53,7 +51,6 @@ CONFIG_DFU_TFTP=y CONFIG_DFU_MTD=y CONFIG_DFU_RAM=y CONFIG_DFU_SF=y -CONFIG_FWU_MDATA_MTD=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_SYNQUACER=y CONFIG_MMC_SDHCI=y @@ -96,4 +93,3 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_IGNORE_OSINDICATIONS=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
-CONFIG_FWU_MULTI_BANK_UPDATE=y
2.34.1
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org

The fwrite call returns the number of bytes transferred as part of the write only when the size parameter is 1. Pass the size parameter to the library call as 1 so that the correct number of bytes transferred are returned.
Fixes: fdd56bfd3ad ("tools: Add mkfwumdata tool for FWU metadata image") Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: None
tools/mkfwumdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/mkfwumdata.c b/tools/mkfwumdata.c index 9732a8ddc5..b2d90ca7c9 100644 --- a/tools/mkfwumdata.c +++ b/tools/mkfwumdata.c @@ -259,7 +259,7 @@ fwu_make_mdata(size_t images, size_t banks, char *uuids[], char *output) goto done_make; }
- ret = fwrite(mobj->mdata, mobj->size, 1, file); + ret = fwrite(mobj->mdata, 1, mobj->size, file); if (ret != mobj->size) ret = -errno; else

In version 2 of the metadata structure, the size of the structure cannot be determined statically at build time. The structure is now broken into the top level structure which contains a field indicating the total size of the structure.
Add a size parameter to the metadata access API functions to indicate the number of bytes to be accessed. This is then used to either read the entire structure, or only the top level structure.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: None
drivers/fwu-mdata/fwu-mdata-uclass.c | 10 ++++++---- drivers/fwu-mdata/gpt_blk.c | 23 +++++++++++++---------- drivers/fwu-mdata/raw_mtd.c | 10 ++++++---- include/fwu.h | 14 ++++++++++---- 4 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/drivers/fwu-mdata/fwu-mdata-uclass.c b/drivers/fwu-mdata/fwu-mdata-uclass.c index 0a8edaaa41..145479bab0 100644 --- a/drivers/fwu-mdata/fwu-mdata-uclass.c +++ b/drivers/fwu-mdata/fwu-mdata-uclass.c @@ -20,7 +20,8 @@ * * Return: 0 if OK, -ve on error */ -int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary) +int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary, + uint32_t size) { const struct fwu_mdata_ops *ops = device_get_ops(dev);
@@ -29,7 +30,7 @@ int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary) return -ENOSYS; }
- return ops->read_mdata(dev, mdata, primary); + return ops->read_mdata(dev, mdata, primary, size); }
/** @@ -37,7 +38,8 @@ int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary) * * Return: 0 if OK, -ve on error */ -int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary) +int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary, + uint32_t size) { const struct fwu_mdata_ops *ops = device_get_ops(dev);
@@ -46,7 +48,7 @@ int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary) return -ENOSYS; }
- return ops->write_mdata(dev, mdata, primary); + return ops->write_mdata(dev, mdata, primary, size); }
UCLASS_DRIVER(fwu_mdata) = { diff --git a/drivers/fwu-mdata/gpt_blk.c b/drivers/fwu-mdata/gpt_blk.c index c7284916c4..97eac3611f 100644 --- a/drivers/fwu-mdata/gpt_blk.c +++ b/drivers/fwu-mdata/gpt_blk.c @@ -81,15 +81,14 @@ static int gpt_get_mdata_disk_part(struct blk_desc *desc, return -ENOENT; }
-static int gpt_read_write_mdata(struct blk_desc *desc, - struct fwu_mdata *mdata, - u8 access, u32 part_num) +static int gpt_read_write_mdata(struct blk_desc *desc, struct fwu_mdata *mdata, + u8 access, u32 part_num, u32 size) { int ret; u32 len, blk_start, blkcnt; struct disk_partition info;
- ALLOC_CACHE_ALIGN_BUFFER_PAD(struct fwu_mdata, mdata_aligned, 1, + ALLOC_CACHE_ALIGN_BUFFER_PAD(u8, mdata_aligned, size, desc->blksz);
if (!mdata) @@ -101,7 +100,7 @@ static int gpt_read_write_mdata(struct blk_desc *desc, return -ENOENT; }
- len = sizeof(*mdata); + len = size; blkcnt = BLOCK_CNT(len, desc); if (blkcnt > info.size) { log_debug("Block count exceeds FWU metadata partition size\n"); @@ -114,7 +113,7 @@ static int gpt_read_write_mdata(struct blk_desc *desc, log_debug("Error reading FWU metadata from the device\n"); return -EIO; } - memcpy(mdata, mdata_aligned, sizeof(struct fwu_mdata)); + memcpy(mdata, mdata_aligned, size); } else { if (blk_dwrite(desc, blk_start, blkcnt, mdata) != blkcnt) { log_debug("Error writing FWU metadata to the device\n"); @@ -164,7 +163,7 @@ static int fwu_mdata_gpt_blk_probe(struct udevice *dev) }
static int fwu_gpt_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, - bool primary) + bool primary, u32 size) { struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev); struct blk_desc *desc = dev_get_uclass_plat(priv->blk_dev); @@ -177,11 +176,13 @@ static int fwu_gpt_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, }
return gpt_read_write_mdata(desc, mdata, MDATA_READ, - primary ? g_mdata_part[0] : g_mdata_part[1]); + primary ? + g_mdata_part[0] : g_mdata_part[1], + size); }
static int fwu_gpt_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, - bool primary) + bool primary, u32 size) { struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev); struct blk_desc *desc = dev_get_uclass_plat(priv->blk_dev); @@ -194,7 +195,9 @@ static int fwu_gpt_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, }
return gpt_read_write_mdata(desc, mdata, MDATA_WRITE, - primary ? g_mdata_part[0] : g_mdata_part[1]); + primary ? + g_mdata_part[0] : g_mdata_part[1], + size); }
static const struct fwu_mdata_ops fwu_gpt_blk_ops = { diff --git a/drivers/fwu-mdata/raw_mtd.c b/drivers/fwu-mdata/raw_mtd.c index 17e4517973..9f3f1dc213 100644 --- a/drivers/fwu-mdata/raw_mtd.c +++ b/drivers/fwu-mdata/raw_mtd.c @@ -97,22 +97,24 @@ lock: return ret; }
-static int fwu_mtd_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary) +static int fwu_mtd_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, + bool primary, u32 size) { struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev); struct mtd_info *mtd = mtd_priv->mtd; u32 offs = primary ? mtd_priv->pri_offset : mtd_priv->sec_offset;
- return mtd_io_data(mtd, offs, sizeof(struct fwu_mdata), mdata, FWU_MTD_READ); + return mtd_io_data(mtd, offs, size, mdata, FWU_MTD_READ); }
-static int fwu_mtd_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary) +static int fwu_mtd_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, + bool primary, u32 size) { struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev); struct mtd_info *mtd = mtd_priv->mtd; u32 offs = primary ? mtd_priv->pri_offset : mtd_priv->sec_offset;
- return mtd_io_data(mtd, offs, sizeof(struct fwu_mdata), mdata, FWU_MTD_WRITE); + return mtd_io_data(mtd, offs, size, mdata, FWU_MTD_WRITE); }
static int flash_partition_offset(struct udevice *dev, const char *part_name, fdt_addr_t *offset) diff --git a/include/fwu.h b/include/fwu.h index eb5638f4f3..1815bd0064 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -32,20 +32,24 @@ struct fwu_mdata_ops { * @dev: FWU metadata device * @mdata: Output FWU mdata read * @primary: If primary or secondary copy of metadata is to be read + * @size: Size in bytes of the metadata to be read * * Return: 0 if OK, -ve on error */ - int (*read_mdata)(struct udevice *dev, struct fwu_mdata *mdata, bool primary); + int (*read_mdata)(struct udevice *dev, struct fwu_mdata *mdata, + bool primary, uint32_t size);
/** * write_mdata() - Write the given FWU metadata copy * @dev: FWU metadata device * @mdata: Copy of the FWU metadata to write * @primary: If primary or secondary copy of metadata is to be written + * @size: Size in bytes of the metadata to be written * * Return: 0 if OK, -ve on error */ - int (*write_mdata)(struct udevice *dev, struct fwu_mdata *mdata, bool primary); + int (*write_mdata)(struct udevice *dev, struct fwu_mdata *mdata, + bool primary, uint32_t size); };
#define FWU_MDATA_VERSION 0x1 @@ -80,12 +84,14 @@ struct fwu_mdata_ops { /** * fwu_read_mdata() - Wrapper around fwu_mdata_ops.read_mdata() */ -int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary); +int fwu_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, + bool primary, uint32_t size);
/** * fwu_write_mdata() - Wrapper around fwu_mdata_ops.write_mdata() */ -int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary); +int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, + bool primary, uint32_t size);
/** * fwu_get_mdata() - Read, verify and return the FWU metadata

The FWU metadata access driver for MTD partitioned devices currently uses a statically allocated array for storing the updatable image information. This array depends on the number of banks and images per bank. With migration of the FWU metadata to version 2, these parameters are now obtained at runtime from the metadata.
Make changes to the FWU metadata access driver for MTD devices to allocate memory for the image information dynamically in the driver's probe function, after having obtained the number of banks and images per bank by reading the metadata. Move the image information as part of the driver's private structure, instead of using a global variable.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: None
drivers/fwu-mdata/raw_mtd.c | 68 +++++++++++++++++++++++-------------- include/fwu.h | 9 +++++ 2 files changed, 52 insertions(+), 25 deletions(-)
diff --git a/drivers/fwu-mdata/raw_mtd.c b/drivers/fwu-mdata/raw_mtd.c index 9f3f1dc213..78a709f766 100644 --- a/drivers/fwu-mdata/raw_mtd.c +++ b/drivers/fwu-mdata/raw_mtd.c @@ -12,22 +12,11 @@ #include <linux/errno.h> #include <linux/types.h>
-/* Internal helper structure to move data around */ -struct fwu_mdata_mtd_priv { - struct mtd_info *mtd; - char pri_label[50]; - char sec_label[50]; - u32 pri_offset; - u32 sec_offset; -}; - enum fwu_mtd_op { FWU_MTD_READ, FWU_MTD_WRITE, };
-extern struct fwu_mtd_image_info fwu_mtd_images[]; - static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size) { return !do_div(size, mtd->erasesize); @@ -134,7 +123,7 @@ static int flash_partition_offset(struct udevice *dev, const char *part_name, fd return (int)size; }
-static int fwu_mdata_mtd_of_to_plat(struct udevice *dev) +static int get_fwu_mdata_dev(struct udevice *dev) { struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev); const fdt32_t *phandle_p = NULL; @@ -144,8 +133,6 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev) fdt_addr_t offset; int ret, size; u32 phandle; - ofnode bank; - int off_img;
/* Find the FWU mdata storage device */ phandle_p = ofnode_get_property(dev_ofnode(dev), @@ -199,8 +186,28 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev) return ret; mtd_priv->sec_offset = offset;
- off_img = 0; + return 0; +} + +static int fwu_mtd_image_info_populate(struct udevice *dev, u8 nbanks, + u16 nimages) +{ + struct fwu_mtd_image_info *mtd_images; + struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev); + struct udevice *mtd_dev = mtd_priv->mtd->dev; + fdt_addr_t offset; + ofnode bank; + int off_img; + u32 total_images;
+ total_images = nbanks * nimages; + mtd_priv->fwu_mtd_images = malloc(sizeof(struct fwu_mtd_image_info) * + total_images); + if (!mtd_priv->fwu_mtd_images) + return -ENOMEM; + + off_img = 0; + mtd_images = mtd_priv->fwu_mtd_images; ofnode_for_each_subnode(bank, dev_ofnode(dev)) { int bank_num, bank_offset, bank_size; const char *bank_name; @@ -219,8 +226,7 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev) int image_num, image_offset, image_size; const char *uuid;
- if (off_img == CONFIG_FWU_NUM_BANKS * - CONFIG_FWU_NUM_IMAGES_PER_BANK) { + if (off_img == total_images) { log_err("DT provides more images than configured!\n"); break; } @@ -230,11 +236,11 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev) ofnode_read_u32(image, "offset", &image_offset); ofnode_read_u32(image, "size", &image_size);
- fwu_mtd_images[off_img].start = bank_offset + image_offset; - fwu_mtd_images[off_img].size = image_size; - fwu_mtd_images[off_img].bank_num = bank_num; - fwu_mtd_images[off_img].image_num = image_num; - strcpy(fwu_mtd_images[off_img].uuidbuf, uuid); + mtd_images[off_img].start = bank_offset + image_offset; + mtd_images[off_img].size = image_size; + mtd_images[off_img].bank_num = bank_num; + mtd_images[off_img].image_num = image_num; + strcpy(mtd_images[off_img].uuidbuf, uuid); log_debug("\tImage%d: %s @0x%x\n\n", image_num, uuid, bank_offset + image_offset); off_img++; @@ -246,8 +252,21 @@ static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
static int fwu_mdata_mtd_probe(struct udevice *dev) { - /* Ensure the metadata can be read. */ - return fwu_get_mdata(NULL); + u8 nbanks; + u16 nimages; + int ret; + + ret = get_fwu_mdata_dev(dev); + if (ret) + return ret; + + nbanks = CONFIG_FWU_NUM_BANKS; + nimages = CONFIG_FWU_NUM_IMAGES_PER_BANK; + ret = fwu_mtd_image_info_populate(dev, nbanks, nimages); + if (ret) + return ret; + + return 0; }
static struct fwu_mdata_ops fwu_mtd_ops = { @@ -266,6 +285,5 @@ U_BOOT_DRIVER(fwu_mdata_mtd) = { .of_match = fwu_mdata_ids, .ops = &fwu_mtd_ops, .probe = fwu_mdata_mtd_probe, - .of_to_plat = fwu_mdata_mtd_of_to_plat, .priv_auto = sizeof(struct fwu_mdata_mtd_priv), }; diff --git a/include/fwu.h b/include/fwu.h index 1815bd0064..6c4d218e13 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -26,6 +26,15 @@ struct fwu_mtd_image_info { char uuidbuf[UUID_STR_LEN + 1]; };
+struct fwu_mdata_mtd_priv { + struct mtd_info *mtd; + char pri_label[50]; + char sec_label[50]; + u32 pri_offset; + u32 sec_offset; + struct fwu_mtd_image_info *fwu_mtd_images; +}; + struct fwu_mdata_ops { /** * read_mdata() - Populate the asked FWU metadata copy

Add support for version 2 of the FWU metadata structure. The top level structure is kept separate through a config symbol. Most of the fields, primarily used for providing information on updatable images are common across the two versions.
Also change a few existing structure members used for image identification to reflect the fact that these are GUIDs, and not UUIDs.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch which retains support for V1 of metadata
include/fwu_mdata.h | 71 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 6 deletions(-)
diff --git a/include/fwu_mdata.h b/include/fwu_mdata.h index 56189e2f40..d2521f39b4 100644 --- a/include/fwu_mdata.h +++ b/include/fwu_mdata.h @@ -11,7 +11,7 @@
/** * struct fwu_image_bank_info - firmware image information - * @image_uuid: Guid value of the image in this bank + * @image_guid: Guid value of the image in this bank * @accepted: Acceptance status of the image * @reserved: Reserved * @@ -20,15 +20,15 @@ * acceptance status */ struct fwu_image_bank_info { - efi_guid_t image_uuid; + efi_guid_t image_guid; uint32_t accepted; uint32_t reserved; } __packed;
/** * struct fwu_image_entry - information for a particular type of image - * @image_type_uuid: Guid value for identifying the image type - * @location_uuid: Guid of the storage volume where the image is located + * @image_type_guid: Guid value for identifying the image type + * @location_guid: Guid of the storage volume where the image is located * @img_bank_info: Array containing properties of images * * This structure contains information on various types of updatable @@ -36,11 +36,35 @@ struct fwu_image_bank_info { * information per bank. */ struct fwu_image_entry { - efi_guid_t image_type_uuid; - efi_guid_t location_uuid; + efi_guid_t image_type_guid; + efi_guid_t location_guid; struct fwu_image_bank_info img_bank_info[CONFIG_FWU_NUM_BANKS]; } __packed;
+/** + * struct fwu_fw_store_desc - FWU updatable image information + * @num_banks: Number of firmware banks + * @num_images: Number of images per bank + * @img_entry_size: The size of the img_entry array + * @bank_info_entry_size: The size of the img_bank_info array + * @img_entry: Array of image entries each giving information on a image + * + * This image descriptor structure contains information on the number of + * updatable banks and images per bank. It also gives the total sizes of + * the fwu_image_entry and fwu_image_bank_info arrays. This structure is + * only present in version 2 of the metadata structure. + */ +struct fwu_fw_store_desc { + uint8_t num_banks; + uint8_t reserved; + uint16_t num_images; + uint16_t img_entry_size; + uint16_t bank_info_entry_size; + + struct fwu_image_entry img_entry[CONFIG_FWU_NUM_IMAGES_PER_BANK]; +} __packed; + +#if defined(CONFIG_FWU_MDATA_V1) /** * struct fwu_mdata - FWU metadata structure for multi-bank updates * @crc32: crc32 value for the FWU metadata @@ -65,4 +89,39 @@ struct fwu_mdata { struct fwu_image_entry img_entry[CONFIG_FWU_NUM_IMAGES_PER_BANK]; } __packed;
+#else /* CONFIG_FWU_MDATA_V1 */ +/** + * struct fwu_mdata - FWU metadata structure for multi-bank updates + * @crc32: crc32 value for the FWU metadata + * @version: FWU metadata version + * @active_index: Index of the bank currently used for booting images + * @previous_active_inde: Index of the bank used before the current bank + * being used for booting + * @metadata_size: Size of the entire metadata structure, including the + * image descriptors + * @desc_offset: The offset from the start of this structure where the + * image descriptor structure starts. 0 if absent + * @bank_state: State of each bank, valid, invalid or accepted + * @fw_desc: The structure describing the FWU updatable images + * + * This is the top level structure used to store all information for performing + * multi bank updates on the platform. This contains info on the bank being + * used to boot along with the information on state of individual banks. + */ +struct fwu_mdata { + uint32_t crc32; + uint32_t version; + uint32_t active_index; + uint32_t previous_active_index; + uint32_t metadata_size; + uint16_t desc_offset; + uint16_t reserved1; + uint8_t bank_state[4]; + uint32_t reserved2; + + // struct fwu_fw_store_desc fw_desc; +} __packed; + +#endif /* CONFIG_FWU_MDATA_V1 */ + #endif /* _FWU_MDATA_H_ */

The FWU specification now has two versions of the FWU metadata structure, and both are to be supported. Introduce a version agnostic structure for storing information about the FWU updatable images. This allows for a split of common version agnostic FWU code and version specific code.
The version specific code is then responsible for arranging the data as per the corresponding metadata structure before it gets written to the metadata partitions.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
include/fwu.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/include/fwu.h b/include/fwu.h index 6c4d218e13..e681e91027 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -8,6 +8,7 @@
#include <blk.h> #include <efi.h> +#include <fwu_mdata.h> #include <mtd.h> #include <uuid.h>
@@ -35,6 +36,23 @@ struct fwu_mdata_mtd_priv { struct fwu_mtd_image_info *fwu_mtd_images; };
+struct fwu_data { + uint32_t crc32; + uint32_t version; + uint32_t active_index; + uint32_t previous_active_index; + uint32_t metadata_size; + uint32_t boot_index; + uint32_t num_banks; + uint32_t num_images; + uint8_t bank_state[4]; + bool trial_state; + + struct fwu_mdata *fwu_mdata; + + struct fwu_image_entry fwu_images[CONFIG_FWU_NUM_IMAGES_PER_BANK]; +}; + struct fwu_mdata_ops { /** * read_mdata() - Populate the asked FWU metadata copy

Support is being added in U-Boot for version 2 of the FWU metadata. Support for this version is to co-exist with version 1 support. To achieve this, a common, version agnostic structure has been added to keep information provided by the FWU metadata structure.
Add API's to handle the version specific FWU metadata fields. The version agnostic structure gets initialized at boot by reading the FWU metadata. Updates to the FWU metadata result in the API's getting called to populate the version specific fields of the strucure, before the metadata gets written to the storage media.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
include/fwu.h | 57 +++++++++ lib/fwu_updates/fwu_v1.c | 167 +++++++++++++++++++++++++ lib/fwu_updates/fwu_v2.c | 260 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 484 insertions(+) create mode 100644 lib/fwu_updates/fwu_v1.c create mode 100644 lib/fwu_updates/fwu_v2.c
diff --git a/include/fwu.h b/include/fwu.h index e681e91027..082b5481d1 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -313,4 +313,61 @@ int fwu_gen_alt_info_from_mtd(char *buf, size_t len, struct mtd_info *mtd); */ int fwu_mtd_get_alt_num(efi_guid_t *image_guid, u8 *alt_num, const char *mtd_dev);
+/** + * fwu_populate_mdata_image_info() - Populate the image information + * of the metadata + * @data: Version agnostic FWU metadata information + * + * Populate the image information in the FWU metadata by copying it + * from the version agnostic structure. This is done before the + * metadata gets written to the storage media. + * + * Return: None + */ +void fwu_populate_mdata_image_info(struct fwu_data *data); + +/** + * fwu_get_mdata_size() - Get the FWU metadata size + * @mdata_size: Size of the metadata structure + * + * Get the size of the FWU metadata from the structure. This is later used + * to allocate memory for the structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_get_mdata_size(uint32_t *mdata_size); + +/** + * fwu_state_machine_updates() - Update FWU state of the platform + * @trial_state: Is platform transitioning into Trial State + * @update_index: Bank number to which images have been updated + * + * On successful completion of updates, transition the platform to + * either Trial State or Regular State. + * + * To transition the platform to Trial State, start the + * TrialStateCtr counter, followed by setting the value of bank_state + * field of the metadata to Valid state(applicable only in version 2 + * of metadata). + * + * In case, the platform is to transition directly to Regular State, + * update the bank_state field of the metadata to Accepted + * state(applicable only in version 2 of metadata). + * + * Return: 0 if OK, -ve on error + */ +int fwu_state_machine_updates(bool trial_state, uint32_t update_index); + +/** + * fwu_init() - FWU specific initialisations + * + * Carry out some FWU specific initialisations including allocation + * of memory for the metadata copies, and reading the FWU metadata + * copies into the allocated memory. The metadata fields are then + * copied into a version agnostic structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_init(void); + #endif /* _FWU_H_ */ diff --git a/lib/fwu_updates/fwu_v1.c b/lib/fwu_updates/fwu_v1.c new file mode 100644 index 0000000000..efb8d51500 --- /dev/null +++ b/lib/fwu_updates/fwu_v1.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2024, Linaro Limited + */ + +#include <fwu.h> +#include <fwu_mdata.h> + +#include <linux/types.h> + +#define FWU_MDATA_VERSION 0x1U + +static uint32_t fwu_check_trial_state(struct fwu_mdata *mdata, uint32_t bank) +{ + u32 i; + struct fwu_image_entry *img_entry; + struct fwu_image_bank_info *img_bank_info; + + img_entry = &mdata->img_entry[0]; + for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { + img_bank_info = &img_entry[i].img_bank_info[bank]; + if (!img_bank_info->accepted) { + return 1; + } + } + + return 0; +} + +static void fwu_data_init(void) +{ + size_t image_info_size; + void *dst_img_info, *src_img_info; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + data->crc32 = mdata->crc32; + data->version = mdata->version; + data->active_index = mdata->active_index; + data->previous_active_index = mdata->previous_active_index; + + data->metadata_size = sizeof(struct fwu_mdata); + data->num_banks = CONFIG_FWU_NUM_BANKS; + data->num_images = CONFIG_FWU_NUM_IMAGES_PER_BANK; + fwu_plat_get_bootidx(&data->boot_index); + data->trial_state = fwu_check_trial_state(mdata, data->boot_index); + + src_img_info = &mdata->img_entry[0]; + dst_img_info = &data->fwu_images[0]; + image_info_size = sizeof(data->fwu_images); + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +static int fwu_trial_state_update(bool trial_state) +{ + int ret; + struct fwu_data *data = fwu_get_data(); + + if (trial_state) { + ret = fwu_trial_state_ctr_start(); + if (ret) + return ret; + } + + data->trial_state = trial_state; + + return 0; +} + +/** + * fwu_populate_mdata_image_info() - Populate the image information + * of the metadata + * @data: Version agnostic FWU metadata information + * + * Populate the image information in the FWU metadata by copying it + * from the version agnostic structure. This is done before the + * metadata gets written to the storage media. + * + * Return: None + */ +void fwu_populate_mdata_image_info(struct fwu_data *data) +{ + size_t image_info_size; + void *dst_img_info, *src_img_info; + struct fwu_mdata *mdata = data->fwu_mdata; + + image_info_size = sizeof(data->fwu_images); + dst_img_info = &mdata->img_entry[0]; + src_img_info = &data->fwu_images[0]; + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +/** + * fwu_state_machine_updates() - Update FWU state of the platform + * @trial_state: Is platform transitioning into Trial State + * @update_index: Bank number to which images have been updated + * + * On successful completion of updates, transition the platform to + * either Trial State or Regular State. + * + * To transition the platform to Trial State, start the + * TrialStateCtr counter, followed by setting the value of bank_state + * field of the metadata to Valid state(applicable only in version 2 + * of metadata). + * + * In case, the platform is to transition directly to Regular State, + * update the bank_state field of the metadata to Accepted + * state(applicable only in version 2 of metadata). + * + * Return: 0 if OK, -ve on error + */ +int fwu_state_machine_updates(bool trial_state, + __maybe_unused uint32_t update_index) +{ + return fwu_trial_state_update(trial_state); +} + +/** + * fwu_get_mdata_size() - Get the FWU metadata size + * @mdata_size: Size of the metadata structure + * + * Get the size of the FWU metadata. + * + * Return: 0 if OK, -ve on error + */ +int fwu_get_mdata_size(uint32_t *mdata_size) +{ + *mdata_size = sizeof(struct fwu_mdata); + + return 0; +} + +/** + * fwu_init() - FWU specific initialisations + * + * Carry out some FWU specific initialisations including allocation + * of memory for the metadata copies, and reading the FWU metadata + * copies into the allocated memory. The metadata fields are then + * copied into a version agnostic structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_init(void) +{ + int ret; + uint32_t mdata_size; + + fwu_get_mdata_size(&mdata_size); + + ret = fwu_mdata_copies_allocate(mdata_size); + if (ret) + return ret; + + /* + * Now read the entire structure, both copies, and + * validate that the copies. + */ + ret = fwu_get_mdata(NULL); + if (ret) + return ret; + + fwu_data_init(); + + return 0; +} diff --git a/lib/fwu_updates/fwu_v2.c b/lib/fwu_updates/fwu_v2.c new file mode 100644 index 0000000000..108bc9bb4a --- /dev/null +++ b/lib/fwu_updates/fwu_v2.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2024, Linaro Limited + */ + +#include <fwu.h> +#include <fwu_mdata.h> +#include <log.h> + +#include <linux/types.h> + +#define FWU_MDATA_VERSION 0x2U + +static inline struct fwu_fw_store_desc *fwu_get_fw_desc(struct fwu_mdata *mdata) +{ + return (struct fwu_fw_store_desc *)((u8 *)mdata + sizeof(*mdata)); +} + +static uint32_t fwu_check_trial_state(struct fwu_mdata *mdata, uint32_t bank) +{ + return mdata->bank_state[bank] == FWU_BANK_VALID ? 1 : 0; +} + +static void fwu_data_init(void) +{ + int i; + size_t image_info_size; + void *dst_img_info, *src_img_info; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + data->crc32 = mdata->crc32; + data->version = mdata->version; + data->active_index = mdata->active_index; + data->previous_active_index = mdata->previous_active_index; + data->metadata_size = mdata->metadata_size; + fwu_plat_get_bootidx(&data->boot_index); + data->trial_state = fwu_check_trial_state(mdata, data->boot_index); + + data->num_banks = fwu_get_fw_desc(mdata)->num_banks; + data->num_images = fwu_get_fw_desc(mdata)->num_images; + + for (i = 0; i < 4; i++) { + data->bank_state[i] = mdata->bank_state[i]; + } + + image_info_size = sizeof(data->fwu_images); + src_img_info = &fwu_get_fw_desc(mdata)->img_entry[0]; + dst_img_info = &data->fwu_images[0]; + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +static int fwu_mdata_sanity_checks(void) +{ + uint8_t num_banks; + uint16_t num_images; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + if (mdata->version != FWU_MDATA_VERSION) { + log_err("FWU metadata version %u. Expected value of %u\n", + mdata->version, FWU_MDATA_VERSION); + return -EINVAL; + } + + if (!mdata->desc_offset) { + log_err("No image information provided with the Metadata. "); + log_err("Image information expected in the metadata\n"); + return -EINVAL; + } + + if (mdata->desc_offset != 0x20) { + log_err("Descriptor Offset(0x%x) in the FWU Metadata not equal to 0x20\n", + mdata->desc_offset); + return -EINVAL; + } + + num_banks = fwu_get_fw_desc(mdata)->num_banks; + num_images = fwu_get_fw_desc(mdata)->num_images; + + if (num_banks != CONFIG_FWU_NUM_BANKS) { + log_err("Number of Banks(%u) in FWU Metadata different from the configured value(%d)", + num_banks, CONFIG_FWU_NUM_BANKS); + return -EINVAL; + } + + if (num_images != CONFIG_FWU_NUM_IMAGES_PER_BANK) { + log_err("Number of Images(%u) in FWU Metadata different from the configured value(%d)", + num_images, CONFIG_FWU_NUM_IMAGES_PER_BANK); + return -EINVAL; + } + + return 0; +} + +static int fwu_bank_state_update(bool trial_state, uint32_t bank) +{ + int ret; + struct fwu_data *data = fwu_get_data(); + struct fwu_mdata *mdata = data->fwu_mdata; + + mdata->bank_state[bank] = data->bank_state[bank] = trial_state ? + FWU_BANK_VALID : FWU_BANK_ACCEPTED; + + ret = fwu_sync_mdata(mdata, BOTH_PARTS); + if (ret) + log_err("Unable to set bank_state for bank %u\n", bank); + else + data->trial_state = trial_state; + + return ret; +} + +static int fwu_trial_state_start(uint update_index) +{ + int ret; + + ret = fwu_trial_state_ctr_start(); + if (ret) + return ret; + + ret = fwu_bank_state_update(1, update_index); + if (ret) + return ret; + + return 0; +} + +/** + * fwu_populate_mdata_image_info() - Populate the image information + * of the metadata + * @data: Version agnostic FWU metadata information + * + * Populate the image information in the FWU metadata by copying it + * from the version agnostic structure. This is done before the + * metadata gets written to the storage media. + * + * Return: None + */ +void fwu_populate_mdata_image_info(struct fwu_data *data) +{ + size_t image_info_size; + struct fwu_mdata *mdata = data->fwu_mdata; + void *dst_img_info, *src_img_info; + + image_info_size = sizeof(data->fwu_images); + dst_img_info = &fwu_get_fw_desc(mdata)->img_entry[0]; + src_img_info = &data->fwu_images[0]; + + memcpy(dst_img_info, src_img_info, image_info_size); +} + +/** + * fwu_state_machine_updates() - Update FWU state of the platform + * @trial_state: Is platform transitioning into Trial State + * @update_index: Bank number to which images have been updated + * + * On successful completion of updates, transition the platform to + * either Trial State or Regular State. + * + * To transition the platform to Trial State, start the + * TrialStateCtr counter, followed by setting the value of bank_state + * field of the metadata to Valid state(applicable only in version 2 + * of metadata). + * + * In case, the platform is to transition directly to Regular State, + * update the bank_state field of the metadata to Accepted + * state(applicable only in version 2 of metadata). + * + * Return: 0 if OK, -ve on error + */ +int fwu_state_machine_updates(bool trial_state, uint32_t update_index) +{ + return trial_state ? fwu_trial_state_start(update_index) : + fwu_bank_state_update(0, update_index); +} + +/** + * fwu_get_mdata_size() - Get the FWU metadata size + * @mdata_size: Size of the metadata structure + * + * Get the size of the FWU metadata from the structure. This is later used + * to allocate memory for the structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_get_mdata_size(uint32_t *mdata_size) +{ + int ret = 0; + struct fwu_mdata mdata = { 0 }; + struct fwu_data *data = fwu_get_data(); + struct udevice *fwu_dev = fwu_get_dev(); + + if (data->metadata_size) { + *mdata_size = data->metadata_size; + return 0; + } + + ret = fwu_read_mdata(fwu_dev, &mdata, 1, + sizeof(struct fwu_mdata)); + if (ret) { + log_err("FWU metadata read failed\n"); + return ret; + } + + *mdata_size = mdata.metadata_size; + if (!*mdata_size) + return -EINVAL; + + return 0; +} + +/** + * fwu_init() - FWU specific initialisations + * + * Carry out some FWU specific initialisations including allocation + * of memory for the metadata copies, and reading the FWU metadata + * copies into the allocated memory. The metadata fields are then + * copied into a version agnostic structure. + * + * Return: 0 if OK, -ve on error + */ +int fwu_init(void) +{ + int ret; + struct fwu_mdata mdata = { 0 }; + struct udevice *fwu_dev = fwu_get_dev(); + + /* + * First we read only the top level structure + * and get the size of the complete structure. + */ + ret = fwu_read_mdata(fwu_dev, &mdata, 1, + sizeof(struct fwu_mdata)); + if (ret) { + log_err("FWU metadata read failed\n"); + return ret; + } + + ret = fwu_mdata_copies_allocate(mdata.metadata_size); + if (ret) + return ret; + + /* + * Now read the entire structure, both copies, and + * validate that the copies. + */ + ret = fwu_get_mdata(NULL); + if (ret) + return ret; + + ret = fwu_mdata_sanity_checks(); + if (ret) + return ret; + + fwu_data_init(); + + return 0; +}

With addition of support for version 2 of the FWU metadata structure, the metadata information is collected into a version agnostic structure. Make changes to the FWU functions so that the information that was earlier obtained by reading the metadata structure is now obtained through this version agnostic structure.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
include/fwu.h | 49 +++++++++- lib/fwu_updates/fwu.c | 204 ++++++++++++++++++++++++++++-------------- 2 files changed, 186 insertions(+), 67 deletions(-)
diff --git a/include/fwu.h b/include/fwu.h index 082b5481d1..77ec65e618 100644 --- a/include/fwu.h +++ b/include/fwu.h @@ -79,9 +79,18 @@ struct fwu_mdata_ops { bool primary, uint32_t size); };
-#define FWU_MDATA_VERSION 0x1 #define FWU_IMAGE_ACCEPTED 0x1
+#define FWU_BANK_INVALID (uint8_t)0xFF +#define FWU_BANK_VALID (uint8_t)0xFE +#define FWU_BANK_ACCEPTED (uint8_t)0xFC + +enum { + PRIMARY_PART = 1, + SECONDARY_PART, + BOTH_PARTS, +}; + /* * GUID value defined in the FWU specification for identification * of the FWU metadata partition. @@ -313,6 +322,44 @@ int fwu_gen_alt_info_from_mtd(char *buf, size_t len, struct mtd_info *mtd); */ int fwu_mtd_get_alt_num(efi_guid_t *image_guid, u8 *alt_num, const char *mtd_dev);
+/** + * fwu_mdata_copies_allocate() - Allocate memory for metadata + * @mdata_size: Size of the metadata structure + * + * Allocate memory for storing both the copies of the FWU metadata. The + * copies are then used as a cache for storing FWU metadata contents. + * + * Return: 0 if OK, -ve on error + */ +int fwu_mdata_copies_allocate(u32 mdata_size); + +/** + * fwu_get_dev() - Return the FWU metadata device + * + * Return the pointer to the FWU metadata device. + * + * Return: Pointer to the FWU metadata dev + */ +struct udevice *fwu_get_dev(void); + +/** + * fwu_get_data() - Return the version agnostic FWU structure + * + * Return the pointer to the version agnostic FWU structure. + * + * Return: Pointer to the FWU data structure + */ +struct fwu_data *fwu_get_data(void); + +/** + * fwu_sync_mdata() - Update given meta-data partition(s) with the copy provided + * @data: FWU Data structure + * @part: Bitmask of FWU metadata partitions to be written to + * + * Return: 0 if OK, -ve on error + */ +int fwu_sync_mdata(struct fwu_mdata *mdata, int part); + /** * fwu_populate_mdata_image_info() - Populate the image information * of the metadata diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c index 86518108c2..5dfea2a4d8 100644 --- a/lib/fwu_updates/fwu.c +++ b/lib/fwu_updates/fwu.c @@ -10,6 +10,7 @@ #include <event.h> #include <fwu.h> #include <fwu_mdata.h> +#include <log.h> #include <malloc.h>
#include <linux/errno.h> @@ -17,7 +18,7 @@
#include <u-boot/crc.h>
-static struct fwu_mdata g_mdata; /* = {0} makes uninit crc32 always invalid */ +struct fwu_data g_fwu_data; static struct udevice *g_dev; static u8 in_trial; static u8 boottime_check; @@ -27,12 +28,6 @@ enum { IMAGE_ACCEPT_CLEAR, };
-enum { - PRIMARY_PART = 1, - SECONDARY_PART, - BOTH_PARTS, -}; - static int trial_counter_update(u16 *trial_state_ctr) { bool delete; @@ -106,23 +101,9 @@ out: return ret; }
-static int in_trial_state(struct fwu_mdata *mdata) +static u32 in_trial_state(void) { - u32 i, active_bank; - struct fwu_image_entry *img_entry; - struct fwu_image_bank_info *img_bank_info; - - active_bank = mdata->active_index; - img_entry = &mdata->img_entry[0]; - for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - img_bank_info = &img_entry[i].img_bank_info[active_bank]; - if (!img_bank_info->accepted) { - log_info("System booting in Trial State\n"); - return 1; - } - } - - return 0; + return g_fwu_data.trial_state; }
static int fwu_get_image_type_id(u8 image_index, efi_guid_t *image_type_id) @@ -141,17 +122,70 @@ static int fwu_get_image_type_id(u8 image_index, efi_guid_t *image_type_id) return -ENOENT; }
+static int mdata_crc_check(struct fwu_mdata *mdata) +{ + int ret; + u32 calc_crc32; + uint32_t mdata_size; + void *buf = &mdata->version; + + ret = fwu_get_mdata_size(&mdata_size); + if (ret) + return ret; + + calc_crc32 = crc32(0, buf, mdata_size - sizeof(u32)); + return calc_crc32 == mdata->crc32 ? 0 : -EINVAL; +} + +static void fwu_data_crc_update(uint32_t crc32) +{ + g_fwu_data.crc32 = crc32; +} + +/** + * fwu_get_data() - Return the version agnostic FWU structure + * + * Return the pointer to the version agnostic FWU structure. + * + * Return: Pointer to the FWU data structure + */ +struct fwu_data *fwu_get_data(void) +{ + return &g_fwu_data; +} + +static void fwu_populate_mdata_bank_index(struct fwu_data *fwu_data) +{ + struct fwu_mdata *mdata = fwu_data->fwu_mdata; + + mdata->active_index = fwu_data->active_index; + mdata->previous_active_index = fwu_data->previous_active_index; +} + +/** + * fwu_get_dev() - Return the FWU metadata device + * + * Return the pointer to the FWU metadata device. + * + * Return: Pointer to the FWU metadata dev + */ +struct udevice *fwu_get_dev(void) +{ + return g_dev; +} + /** * fwu_sync_mdata() - Update given meta-data partition(s) with the copy provided - * @mdata: FWU metadata structure + * @data: FWU Data structure * @part: Bitmask of FWU metadata partitions to be written to * * Return: 0 if OK, -ve on error */ -static int fwu_sync_mdata(struct fwu_mdata *mdata, int part) +int fwu_sync_mdata(struct fwu_mdata *mdata, int part) { - void *buf = &mdata->version; int err; + uint mdata_size; + void *buf = &mdata->version;
if (part == BOTH_PARTS) { err = fwu_sync_mdata(mdata, SECONDARY_PART); @@ -160,32 +194,53 @@ static int fwu_sync_mdata(struct fwu_mdata *mdata, int part) part = PRIMARY_PART; }
+ err = fwu_get_mdata_size(&mdata_size); + if (err) + return err; + /* * Calculate the crc32 for the updated FWU metadata * and put the updated value in the FWU metadata crc32 * field */ - mdata->crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32)); + mdata->crc32 = crc32(0, buf, mdata_size - sizeof(u32)); + fwu_data_crc_update(mdata->crc32);
- err = fwu_write_mdata(g_dev, mdata, part == PRIMARY_PART); + err = fwu_write_mdata(g_dev, mdata, part == PRIMARY_PART, mdata_size); if (err) { log_err("Unable to write %s mdata\n", part == PRIMARY_PART ? "primary" : "secondary"); return err; }
- /* update the cached copy of meta-data */ - memcpy(&g_mdata, mdata, sizeof(struct fwu_mdata)); - return 0; }
-static inline int mdata_crc_check(struct fwu_mdata *mdata) +/** + * fwu_mdata_copies_allocate() - Allocate memory for metadata + * @mdata_size: Size of the metadata structure + * + * Allocate memory for storing both the copies of the FWU metadata. The + * copies are then used as a cache for storing FWU metadata contents. + * + * Return: 0 if OK, -ve on error + */ +int fwu_mdata_copies_allocate(u32 mdata_size) { - void *buf = &mdata->version; - u32 calc_crc32 = crc32(0, buf, sizeof(*mdata) - sizeof(u32)); + if (g_fwu_data.fwu_mdata) + return 0;
- return calc_crc32 == mdata->crc32 ? 0 : -EINVAL; + /* + * Allocate the total memory that would be needed for both + * the copies. + */ + g_fwu_data.fwu_mdata = calloc(2, mdata_size); + if (!g_fwu_data.fwu_mdata) { + log_err("Unable to allocate space for FWU metadata\n"); + return -ENOMEM; + } + + return 0; }
/** @@ -201,21 +256,33 @@ static inline int mdata_crc_check(struct fwu_mdata *mdata) int fwu_get_mdata(struct fwu_mdata *mdata) { int err; + uint32_t mdata_size; bool parts_ok[2] = { false }; - struct fwu_mdata s, *parts_mdata[2]; + struct fwu_mdata *parts_mdata[2];
- parts_mdata[0] = &g_mdata; - parts_mdata[1] = &s; + err = fwu_get_mdata_size(&mdata_size); + if (err) + return err; + + parts_mdata[0] = g_fwu_data.fwu_mdata; + if (!parts_mdata[0]) { + log_err("Memory not allocated for the FWU Metadata copies\n"); + return -ENOMEM; + } + + parts_mdata[1] = (struct fwu_mdata *)((char *)parts_mdata[0] + + mdata_size);
/* if mdata already read and ready */ err = mdata_crc_check(parts_mdata[0]); if (!err) goto ret_mdata; - /* else read, verify and, if needed, fix mdata */
+ + /* else read, verify and, if needed, fix mdata */ for (int i = 0; i < 2; i++) { parts_ok[i] = false; - err = fwu_read_mdata(g_dev, parts_mdata[i], !i); + err = fwu_read_mdata(g_dev, parts_mdata[i], !i, mdata_size); if (!err) { err = mdata_crc_check(parts_mdata[i]); if (!err) @@ -230,7 +297,7 @@ int fwu_get_mdata(struct fwu_mdata *mdata) * Before returning, check that both the * FWU metadata copies are the same. */ - err = memcmp(parts_mdata[0], parts_mdata[1], sizeof(struct fwu_mdata)); + err = memcmp(parts_mdata[0], parts_mdata[1], mdata_size); if (!err) goto ret_mdata;
@@ -247,7 +314,7 @@ int fwu_get_mdata(struct fwu_mdata *mdata) if (parts_ok[i]) continue;
- memcpy(parts_mdata[i], parts_mdata[1 - i], sizeof(struct fwu_mdata)); + memcpy(parts_mdata[i], parts_mdata[1 - i], mdata_size); err = fwu_sync_mdata(parts_mdata[i], i ? SECONDARY_PART : PRIMARY_PART); if (err) { log_debug("mdata : %s write failed\n", i ? "secondary" : "primary"); @@ -257,7 +324,7 @@ int fwu_get_mdata(struct fwu_mdata *mdata)
ret_mdata: if (!err && mdata) - memcpy(mdata, parts_mdata[0], sizeof(struct fwu_mdata)); + memcpy(mdata, parts_mdata[0], mdata_size);
return err; } @@ -275,13 +342,13 @@ ret_mdata: int fwu_get_active_index(uint *active_idx) { int ret = 0; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data;
/* * Found the FWU metadata partition, now read the active_index * value */ - *active_idx = mdata->active_index; + *active_idx = data->active_index; if (*active_idx >= CONFIG_FWU_NUM_BANKS) { log_debug("Active index value read is incorrect\n"); ret = -EINVAL; @@ -302,7 +369,7 @@ int fwu_get_active_index(uint *active_idx) int fwu_set_active_index(uint active_idx) { int ret; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data;
if (active_idx >= CONFIG_FWU_NUM_BANKS) { log_debug("Invalid active index value\n"); @@ -313,14 +380,16 @@ int fwu_set_active_index(uint active_idx) * Update the active index and previous_active_index fields * in the FWU metadata */ - mdata->previous_active_index = mdata->active_index; - mdata->active_index = active_idx; + data->previous_active_index = data->active_index; + data->active_index = active_idx; + + fwu_populate_mdata_bank_index(data);
/* * Now write this updated FWU metadata to both the * FWU metadata partitions */ - ret = fwu_sync_mdata(mdata, BOTH_PARTS); + ret = fwu_sync_mdata(data->fwu_mdata, BOTH_PARTS); if (ret) { log_debug("Failed to update FWU metadata partitions\n"); ret = -EIO; @@ -346,7 +415,7 @@ int fwu_get_dfu_alt_num(u8 image_index, u8 *alt_num) int ret, i; uint update_bank; efi_guid_t *image_guid, image_type_id; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data; struct fwu_image_entry *img_entry; struct fwu_image_bank_info *img_bank_info;
@@ -365,15 +434,15 @@ int fwu_get_dfu_alt_num(u8 image_index, u8 *alt_num)
ret = -EINVAL; /* - * The FWU metadata has been read. Now get the image_uuid for the + * The FWU metadata has been read. Now get the image_guid for the * image with the update_bank. */ for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { if (!guidcmp(&image_type_id, - &mdata->img_entry[i].image_type_uuid)) { - img_entry = &mdata->img_entry[i]; + &data->fwu_images[i].image_type_guid)) { + img_entry = &data->fwu_images[i]; img_bank_info = &img_entry->img_bank_info[update_bank]; - image_guid = &img_bank_info->image_uuid; + image_guid = &img_bank_info->image_guid; ret = fwu_plat_get_alt_num(g_dev, image_guid, alt_num); if (ret) log_debug("alt_num not found for partition with GUID %pUs\n", @@ -407,21 +476,23 @@ int fwu_revert_boot_index(void) { int ret; u32 cur_active_index; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data;
/* * Swap the active index and previous_active_index fields * in the FWU metadata */ - cur_active_index = mdata->active_index; - mdata->active_index = mdata->previous_active_index; - mdata->previous_active_index = cur_active_index; + cur_active_index = data->active_index; + data->active_index = data->previous_active_index; + data->previous_active_index = cur_active_index; + + fwu_populate_mdata_bank_index(data);
/* * Now write this updated FWU metadata to both the * FWU metadata partitions */ - ret = fwu_sync_mdata(mdata, BOTH_PARTS); + ret = fwu_sync_mdata(data->fwu_mdata, BOTH_PARTS); if (ret) { log_debug("Failed to update FWU metadata partitions\n"); ret = -EIO; @@ -448,20 +519,21 @@ int fwu_revert_boot_index(void) static int fwu_clrset_image_accept(efi_guid_t *img_type_id, u32 bank, u8 action) { int ret, i; - struct fwu_mdata *mdata = &g_mdata; + struct fwu_data *data = &g_fwu_data; struct fwu_image_entry *img_entry; struct fwu_image_bank_info *img_bank_info;
- img_entry = &mdata->img_entry[0]; + img_entry = &data->fwu_images[0]; for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - if (!guidcmp(&img_entry[i].image_type_uuid, img_type_id)) { + if (!guidcmp(&img_entry[i].image_type_guid, img_type_id)) { img_bank_info = &img_entry[i].img_bank_info[bank]; if (action == IMAGE_ACCEPT_SET) img_bank_info->accepted |= FWU_IMAGE_ACCEPTED; else img_bank_info->accepted = 0;
- ret = fwu_sync_mdata(mdata, BOTH_PARTS); + fwu_populate_mdata_image_info(data); + ret = fwu_sync_mdata(data->fwu_mdata, BOTH_PARTS); goto out; } } @@ -627,9 +699,9 @@ static int fwu_boottime_checks(void) return 0; }
- ret = fwu_get_mdata(NULL); + ret = fwu_init(); if (ret) { - log_debug("Unable to read meta-data\n"); + log_debug("fwu_init() failed\n"); return ret; }
@@ -665,7 +737,7 @@ static int fwu_boottime_checks(void) if (efi_init_obj_list() != EFI_SUCCESS) return 0;
- in_trial = in_trial_state(&g_mdata); + in_trial = in_trial_state(); if (!in_trial || (ret = fwu_trial_count_update()) > 0) ret = trial_counter_update(NULL);

Transition the platform to either Trial State or Regular State on a successful update. Do this by calling the fwu_state_machine_updates() API function.
For version 1 of the FWU metadata, the transition to Trial State is done by starting the Trial State counter, while for version 2, in addition to the counter, the bank_state field of the FWU metadata is also updated to Valid.
For transitioning the platform to Regular State, no action is needed with version 1 of the FWU metadata structure, while for version 2, the bank_state field is set to Accepted.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * Earlier patch was catering to v2 only support. These changes support both versions of metadata.
lib/efi_loader/efi_capsule.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index de0d49ebeb..0937800e58 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -480,6 +480,11 @@ static __maybe_unused efi_status_t fwu_empty_capsule_process( if (ret != EFI_SUCCESS) log_err("Unable to set the Accept bit for the image %pUs\n", image_guid); + + status = fwu_state_machine_updates(0, active_idx); + if (status < 0) + ret = EFI_DEVICE_ERROR; + }
return ret; @@ -521,11 +526,10 @@ static __maybe_unused efi_status_t fwu_post_update_process(bool fw_accept_os) log_err("Failed to update FWU metadata index values\n"); } else { log_debug("Successfully updated the active_index\n"); - if (fw_accept_os) { - status = fwu_trial_state_ctr_start(); - if (status < 0) - ret = EFI_DEVICE_ERROR; - } + status = fwu_state_machine_updates(fw_accept_os ? 1 : 0, + update_index); + if (status < 0) + ret = EFI_DEVICE_ERROR; }
return ret;

Support has been added for version 2 of the FWU metadata structure. Add config symbols to enable either of the two versions.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
lib/fwu_updates/Kconfig | 14 ++++++++++++++ lib/fwu_updates/Makefile | 2 ++ 2 files changed, 16 insertions(+)
diff --git a/lib/fwu_updates/Kconfig b/lib/fwu_updates/Kconfig index d35247d0e5..51b7fbbefd 100644 --- a/lib/fwu_updates/Kconfig +++ b/lib/fwu_updates/Kconfig @@ -31,4 +31,18 @@ config FWU_TRIAL_STATE_CNT the platform is allowed to boot in Trial State after an update.
+config FWU_MDATA_V1 + bool "Enable support FWU Metadata version 1" + help + The FWU specification supports two versions of the + metadata structure. This option enables support for FWU + Metadata version 1 access. + +config FWU_MDATA_V2 + bool "Enable support FWU Metadata version 2" + help + The FWU specification supports two versions of the + metadata structure. This option enables support for FWU + Metadata version 2 access. + endif diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile index c9e3c06b48..3681bef46c 100644 --- a/lib/fwu_updates/Makefile +++ b/lib/fwu_updates/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu.o obj-$(CONFIG_FWU_MDATA_GPT_BLK) += fwu_gpt.o obj-$(CONFIG_FWU_MDATA_MTD) += fwu_mtd.o +obj-$(CONFIG_FWU_MDATA_V1) += fwu_v1.o +obj-$(CONFIG_FWU_MDATA_V2) += fwu_v2.o

The third argument passed to the function gen_image_alt_info() is not used and is superfluous. Remove this unused argument from the function call.
Fixes: 4898679e190 (FWU: Add FWU metadata access driver for MTD storage regions) Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
lib/fwu_updates/fwu_mtd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lib/fwu_updates/fwu_mtd.c b/lib/fwu_updates/fwu_mtd.c index 69cd3d7001..d48de19009 100644 --- a/lib/fwu_updates/fwu_mtd.c +++ b/lib/fwu_updates/fwu_mtd.c @@ -107,7 +107,7 @@ __weak int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_id, return fwu_mtd_get_alt_num(image_id, alt_num, "nor1"); }
-static int gen_image_alt_info(char *buf, size_t len, int sidx, +static int gen_image_alt_info(char *buf, size_t len, struct fwu_image_entry *img, struct mtd_info *mtd) { char *p = buf, *end = buf + len; @@ -168,8 +168,7 @@ int fwu_gen_alt_info_from_mtd(char *buf, size_t len, struct mtd_info *mtd) }
for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - ret = gen_image_alt_info(buf, len, i * CONFIG_FWU_NUM_BANKS, - &mdata.img_entry[i], mtd); + ret = gen_image_alt_info(buf, len, &mdata.img_entry[i], mtd); if (ret) break;

Information about FWU images on MTD partitions is now stored with the corresponding driver instead of a global variable. Get this information from the driver.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
lib/fwu_updates/fwu_mtd.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/lib/fwu_updates/fwu_mtd.c b/lib/fwu_updates/fwu_mtd.c index d48de19009..f4e0e3107b 100644 --- a/lib/fwu_updates/fwu_mtd.c +++ b/lib/fwu_updates/fwu_mtd.c @@ -15,16 +15,21 @@
#include <dm/ofnode.h>
-struct fwu_mtd_image_info -fwu_mtd_images[CONFIG_FWU_NUM_BANKS * CONFIG_FWU_NUM_IMAGES_PER_BANK]; - static struct fwu_mtd_image_info *mtd_img_by_uuid(const char *uuidbuf) { - int num_images = ARRAY_SIZE(fwu_mtd_images); + int num_images; + struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(fwu_get_dev()); + struct fwu_mtd_image_info *image_info = mtd_priv->fwu_mtd_images; + + if (!image_info) + return NULL; + + num_images = CONFIG_FWU_NUM_BANKS * + CONFIG_FWU_NUM_IMAGES_PER_BANK;
for (int i = 0; i < num_images; i++) - if (!strcmp(uuidbuf, fwu_mtd_images[i].uuidbuf)) - return &fwu_mtd_images[i]; + if (!strcmp(uuidbuf, image_info[i].uuidbuf)) + return &image_info[i];
return NULL; }

Make changes to the functions used for generating the DFU's alt variable so that the FWU image information is obtained from the common version agnostic structure instead of reading the metadata.
While here, also update the name of the field used for storing the image GUID in the FWU metadata.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
lib/fwu_updates/fwu_mtd.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/lib/fwu_updates/fwu_mtd.c b/lib/fwu_updates/fwu_mtd.c index f4e0e3107b..e8211dd5ba 100644 --- a/lib/fwu_updates/fwu_mtd.c +++ b/lib/fwu_updates/fwu_mtd.c @@ -136,7 +136,7 @@ static int gen_image_alt_info(char *buf, size_t len,
/* Query a partition by image UUID */ bank = &img->img_bank_info[i]; - uuid_bin_to_str(bank->image_uuid.b, uuidbuf, UUID_STR_FORMAT_STD); + uuid_bin_to_str(bank->image_guid.b, uuidbuf, UUID_STR_FORMAT_STD);
mtd_img_info = mtd_img_by_uuid(uuidbuf); if (!mtd_img_info) { @@ -163,17 +163,13 @@ static int gen_image_alt_info(char *buf, size_t len,
int fwu_gen_alt_info_from_mtd(char *buf, size_t len, struct mtd_info *mtd) { - struct fwu_mdata mdata; int i, l, ret; - - ret = fwu_get_mdata(&mdata); - if (ret < 0) { - log_err("Failed to get the FWU mdata.\n"); - return ret; - } + struct fwu_data *data = fwu_get_data(); + struct fwu_image_entry *img_entry;
for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - ret = gen_image_alt_info(buf, len, &mdata.img_entry[i], mtd); + img_entry = &data->fwu_images[i]; + ret = gen_image_alt_info(buf, len, img_entry, mtd); if (ret) break;

Add support for displaying data specific to FWU metadata version 2. Because the size of the v2 metadata structure is read from the structure itself, allocate memory for the metadata structure by first getting the size of the structure.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * Earlier patch was migrating to v2 only support. These changes support both versions.
cmd/fwu_mdata.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/cmd/fwu_mdata.c b/cmd/fwu_mdata.c index 5ecda455df..3c8be576ac 100644 --- a/cmd/fwu_mdata.c +++ b/cmd/fwu_mdata.c @@ -13,27 +13,33 @@
#include <linux/types.h>
-static void print_mdata(struct fwu_mdata *mdata) +static void print_mdata(struct fwu_data *data) { int i, j; struct fwu_image_entry *img_entry; struct fwu_image_bank_info *img_info;
printf("\tFWU Metadata\n"); - printf("crc32: %#x\n", mdata->crc32); - printf("version: %#x\n", mdata->version); - printf("active_index: %#x\n", mdata->active_index); - printf("previous_active_index: %#x\n", mdata->previous_active_index); + printf("crc32: %#x\n", data->crc32); + printf("version: %#x\n", data->version); + printf("active_index: %#x\n", data->active_index); + printf("previous_active_index: %#x\n", data->previous_active_index); + + if (data->version == 2) { + for (i = 0; i < 4; i++) + printf("bank_state[%d]: %#x\n", + i, data->bank_state[i]); + }
printf("\tImage Info\n"); for (i = 0; i < CONFIG_FWU_NUM_IMAGES_PER_BANK; i++) { - img_entry = &mdata->img_entry[i]; + img_entry = &data->fwu_images[i]; printf("\nImage Type Guid: %pUL\n", - &img_entry->image_type_uuid); - printf("Location Guid: %pUL\n", &img_entry->location_uuid); + &img_entry->image_type_guid); + printf("Location Guid: %pUL\n", &img_entry->location_guid); for (j = 0; j < CONFIG_FWU_NUM_BANKS; j++) { img_info = &img_entry->img_bank_info[j]; - printf("Image Guid: %pUL\n", &img_info->image_uuid); + printf("Image Guid: %pUL\n", &img_info->image_guid); printf("Image Acceptance: %s\n", img_info->accepted == 0x1 ? "yes" : "no"); } @@ -43,20 +49,11 @@ static void print_mdata(struct fwu_mdata *mdata) int do_fwu_mdata_read(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { - int ret = CMD_RET_SUCCESS, res; - struct fwu_mdata mdata; - - res = fwu_get_mdata(&mdata); - if (res < 0) { - log_err("Unable to get valid FWU metadata\n"); - ret = CMD_RET_FAILURE; - goto out; - } + struct fwu_data *data = fwu_get_data();
- print_mdata(&mdata); + print_mdata(data);
-out: - return ret; + return CMD_RET_SUCCESS; }
U_BOOT_CMD(

Add support for generating the FWU metadata version 2. The tool now requires the version to be provided as a command-line option. Make corresponding changes to the tool's manpage.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * Support both metadata versions instead of only v2.
doc/mkfwumdata.1 | 9 ++- tools/mkfwumdata.c | 148 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 127 insertions(+), 30 deletions(-)
diff --git a/doc/mkfwumdata.1 b/doc/mkfwumdata.1 index 7dd718b26e..5e61c615ea 100644 --- a/doc/mkfwumdata.1 +++ b/doc/mkfwumdata.1 @@ -6,6 +6,7 @@ mkfwumdata - create FWU metadata image . .SH SYNOPSIS .SY mkfwumdata +.OP -v version .OP -a activeidx .OP -p previousidx .OP -g @@ -28,6 +29,12 @@ creates metadata info to be used with FWU. Print usage information and exit. . .TP +.B -v +Set +.IR version +as the metadata version to generate. Valid values 1 or 2. +. +.TP .B -a Set .IR activeidx @@ -81,7 +88,7 @@ Create a metadata image with 2 banks and 1 image/bank, BankAct=0, BankPrev=1: .EX .in +4 $ \c -.B mkfwumdata -a 0 -p 1 -b 2 -i 1 \\& +.B mkfwumdata -v 2 -a 0 -p 1 -b 2 -i 1 \\& .in +6 .B 17e86d77-41f9-4fd7-87ec-a55df9842de5,\\& .B 10c36d7d-ca52-b843-b7b9-f9d6c501d108,\\& diff --git a/tools/mkfwumdata.c b/tools/mkfwumdata.c index b2d90ca7c9..634453d421 100644 --- a/tools/mkfwumdata.c +++ b/tools/mkfwumdata.c @@ -10,28 +10,35 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> -#include <u-boot/crc.h> #include <unistd.h> +#include <generated/autoconf.h> +#include <u-boot/crc.h> #include <uuid/uuid.h>
-/* This will dynamically allocate the fwu_mdata */ -#define CONFIG_FWU_NUM_BANKS 0 -#define CONFIG_FWU_NUM_IMAGES_PER_BANK 0 - -/* Since we can not include fwu.h, redefine version here. */ -#define FWU_MDATA_VERSION 1 - typedef uint8_t u8; typedef int16_t s16; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64;
+#undef CONFIG_FWU_NUM_BANKS +#undef CONFIG_FWU_NUM_IMAGES_PER_BANK + +/* This will dynamically allocate the fwu_mdata */ +#define CONFIG_FWU_NUM_BANKS 0 +#define CONFIG_FWU_NUM_IMAGES_PER_BANK 0 + +/* version 2 supports maximum of 4 banks */ +#define MAX_BANKS_V2 4 + +#define BANK_INVALID (u8)0xFF +#define BANK_ACCEPTED (u8)0xFC + #include <fwu_mdata.h>
/* TODO: Endianness conversion may be required for some arch. */
-static const char *opts_short = "b:i:a:p:gh"; +static const char *opts_short = "b:i:a:p:v:gh";
static struct option options[] = { {"banks", required_argument, NULL, 'b'}, @@ -39,6 +46,7 @@ static struct option options[] = { {"guid", required_argument, NULL, 'g'}, {"active-bank", required_argument, NULL, 'a'}, {"previous-bank", required_argument, NULL, 'p'}, + {"version", required_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; @@ -49,6 +57,7 @@ static void print_usage(void) fprintf(stderr, "Options:\n" "\t-i, --images <num> Number of images (mandatory)\n" "\t-b, --banks <num> Number of banks (mandatory)\n" + "\t-v, --version Metadata version (mandatory)\n" "\t-a, --active-bank <num> Active bank (default=0)\n" "\t-p, --previous-bank <num> Previous active bank (default=active_bank - 1)\n" "\t-g, --guid Use GUID instead of UUID\n" @@ -70,13 +79,26 @@ struct fwu_mdata_object { size_t images; size_t banks; size_t size; + u8 version; struct fwu_mdata *mdata; };
static int previous_bank, active_bank; static bool __use_guid;
-static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks) +static bool supported_mdata_version(unsigned long version) +{ + switch (version) { + case 1: + case 2: + return true; + default: + return false; + } +} + +static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks, + u8 version) { struct fwu_mdata_object *mobj;
@@ -84,11 +106,20 @@ static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks) if (!mobj) return NULL;
- mobj->size = sizeof(struct fwu_mdata) + - (sizeof(struct fwu_image_entry) + - sizeof(struct fwu_image_bank_info) * banks) * images; + if (version == 1) { + mobj->size = sizeof(struct fwu_mdata) + + (sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * banks) * images; + } else { + mobj->size = sizeof(struct fwu_mdata) + + sizeof(struct fwu_fw_store_desc) + + (sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * banks) * images; + } + mobj->images = images; mobj->banks = banks; + mobj->version = version;
mobj->mdata = calloc(1, mobj->size); if (!mobj->mdata) { @@ -104,9 +135,18 @@ fwu_get_image(struct fwu_mdata_object *mobj, size_t idx) { size_t offset;
- offset = sizeof(struct fwu_mdata) + - (sizeof(struct fwu_image_entry) + - sizeof(struct fwu_image_bank_info) * mobj->banks) * idx; + if (mobj->version == 1) { + offset = sizeof(struct fwu_mdata) + + (sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * mobj->banks) * + idx; + } else { + offset = sizeof(struct fwu_mdata) + + sizeof(struct fwu_fw_store_desc) + + (sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * mobj->banks) * + idx; + }
return (struct fwu_image_entry *)((char *)mobj->mdata + offset); } @@ -116,11 +156,20 @@ fwu_get_bank(struct fwu_mdata_object *mobj, size_t img_idx, size_t bnk_idx) { size_t offset;
- offset = sizeof(struct fwu_mdata) + - (sizeof(struct fwu_image_entry) + - sizeof(struct fwu_image_bank_info) * mobj->banks) * img_idx + - sizeof(struct fwu_image_entry) + - sizeof(struct fwu_image_bank_info) * bnk_idx; + if (mobj->version == 1) { + offset = sizeof(struct fwu_mdata) + + (sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * mobj->banks) * + img_idx + sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * bnk_idx; + } else { + offset = sizeof(struct fwu_mdata) + + sizeof(struct fwu_fw_store_desc) + + (sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * mobj->banks) * + img_idx + sizeof(struct fwu_image_entry) + + sizeof(struct fwu_image_bank_info) * bnk_idx; + }
return (struct fwu_image_bank_info *)((char *)mobj->mdata + offset); } @@ -188,7 +237,7 @@ fwu_parse_fill_image_uuid(struct fwu_mdata_object *mobj, return -EINVAL;
if (strcmp(uuid, "0") && - uuid_guid_parse(uuid, (unsigned char *)&image->location_uuid) < 0) + uuid_guid_parse(uuid, (unsigned char *)&image->location_guid) < 0) return -EINVAL;
/* Image type UUID */ @@ -196,7 +245,7 @@ fwu_parse_fill_image_uuid(struct fwu_mdata_object *mobj, if (!uuid) return -EINVAL;
- if (uuid_guid_parse(uuid, (unsigned char *)&image->image_type_uuid) < 0) + if (uuid_guid_parse(uuid, (unsigned char *)&image->image_type_guid) < 0) return -EINVAL;
/* Fill bank image-UUID */ @@ -210,22 +259,52 @@ fwu_parse_fill_image_uuid(struct fwu_mdata_object *mobj, return -EINVAL;
if (strcmp(uuid, "0") && - uuid_guid_parse(uuid, (unsigned char *)&bank->image_uuid) < 0) + uuid_guid_parse(uuid, (unsigned char *)&bank->image_guid) < 0) return -EINVAL; } return 0; }
+#if defined(CONFIG_FWU_MDATA_V1) +static void fwu_fill_version_specific_mdata(struct fwu_mdata_object *mobj) +{ +} +#else +static void fwu_fill_version_specific_mdata(struct fwu_mdata_object *mobj) +{ + int i; + struct fwu_fw_store_desc *fw_desc; + struct fwu_mdata *mdata = mobj->mdata; + + mdata->metadata_size = mobj->size; + mdata->desc_offset = sizeof(struct fwu_mdata); + + for (i = 0; i < MAX_BANKS_V2; i++) + mdata->bank_state[i] = i < mobj->banks ? + BANK_ACCEPTED : BANK_INVALID; + + fw_desc = (struct fwu_fw_store_desc *)((u8 *)mdata + sizeof(*mdata)); + fw_desc->num_banks = mobj->banks; + fw_desc->num_images = mobj->images; + fw_desc->img_entry_size = sizeof(struct fwu_image_entry) + + (sizeof(struct fwu_image_bank_info) * mobj->banks); + fw_desc->bank_info_entry_size = + sizeof(struct fwu_image_bank_info); +} +#endif /* CONFIG_FWU_MDATA_V1 */ + /* Caller must ensure that @uuids[] has @mobj->images entries. */ static int fwu_parse_fill_uuids(struct fwu_mdata_object *mobj, char *uuids[]) { struct fwu_mdata *mdata = mobj->mdata; int i, ret;
- mdata->version = FWU_MDATA_VERSION; + mdata->version = mobj->version; mdata->active_index = active_bank; mdata->previous_active_index = previous_bank;
+ fwu_fill_version_specific_mdata(mobj); + for (i = 0; i < mobj->images; i++) { ret = fwu_parse_fill_image_uuid(mobj, i, uuids[i]); if (ret < 0) @@ -239,13 +318,14 @@ static int fwu_parse_fill_uuids(struct fwu_mdata_object *mobj, char *uuids[]) }
static int -fwu_make_mdata(size_t images, size_t banks, char *uuids[], char *output) +fwu_make_mdata(size_t images, size_t banks, u8 version, char *uuids[], + char *output) { struct fwu_mdata_object *mobj; FILE *file; int ret;
- mobj = fwu_alloc_mdata(images, banks); + mobj = fwu_alloc_mdata(images, banks, version); if (!mobj) return -ENOMEM;
@@ -276,7 +356,7 @@ done_make:
int main(int argc, char *argv[]) { - unsigned long banks = 0, images = 0; + unsigned long banks = 0, images = 0, version = 0; int c, ret;
/* Explicitly initialize defaults */ @@ -305,6 +385,9 @@ int main(int argc, char *argv[]) case 'a': active_bank = strtoul(optarg, NULL, 0); break; + case 'v': + version = strtoul(optarg, NULL, 0); + break; } } while (c != -1);
@@ -313,6 +396,12 @@ int main(int argc, char *argv[]) return -EINVAL; }
+ if (!version || !supported_mdata_version(version)) { + fprintf(stderr, "Error: Version value can only be either 1 or 2, not %ld.\n", + version); + return -EINVAL; + } + /* This command takes UUIDs * images and output file. */ if (optind + images + 1 != argc) { fprintf(stderr, "Error: UUID list or output file is not specified or too much.\n"); @@ -325,7 +414,8 @@ int main(int argc, char *argv[]) previous_bank = active_bank > 0 ? active_bank - 1 : banks - 1; }
- ret = fwu_make_mdata(images, banks, argv + optind, argv[argc - 1]); + ret = fwu_make_mdata(images, banks, (u8)version, argv + optind, + argv[argc - 1]); if (ret < 0) fprintf(stderr, "Error: Failed to parse and write image: %s\n", strerror(-ret));

The version 2 of the FWU metadata allows for appending opaque vendor specific data to the metadata structure. Add support for appending this data to the metadata. The vendor specific data needs to be provided through a file, passed through a command-line parameter. Make corresponding changes to the tool's manpage.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * Added documentation changes.
doc/mkfwumdata.1 | 7 ++++ tools/mkfwumdata.c | 99 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 91 insertions(+), 15 deletions(-)
diff --git a/doc/mkfwumdata.1 b/doc/mkfwumdata.1 index 5e61c615ea..2ed0fb100b 100644 --- a/doc/mkfwumdata.1 +++ b/doc/mkfwumdata.1 @@ -10,6 +10,7 @@ mkfwumdata - create FWU metadata image .OP -a activeidx .OP -p previousidx .OP -g +.OP -V vendor-file .BI -i~ imagecount .BI -b~ bankcount .I UUIDs @@ -57,6 +58,12 @@ Convert the as GUIDs before use. . .TP +.B -V +Pass +.IR vendor-file +for appending vendor data to the metadata. Supported only with version 2. +. +.TP .B -i Specify there are .IR imagecount diff --git a/tools/mkfwumdata.c b/tools/mkfwumdata.c index 634453d421..fbc2067bc1 100644 --- a/tools/mkfwumdata.c +++ b/tools/mkfwumdata.c @@ -12,6 +12,8 @@ #include <string.h> #include <unistd.h> #include <generated/autoconf.h> +#include <sys/types.h> +#include <sys/stat.h> #include <u-boot/crc.h> #include <uuid/uuid.h>
@@ -36,9 +38,7 @@ typedef uint64_t u64;
#include <fwu_mdata.h>
-/* TODO: Endianness conversion may be required for some arch. */ - -static const char *opts_short = "b:i:a:p:v:gh"; +static const char *opts_short = "b:i:a:p:v:V:gh";
static struct option options[] = { {"banks", required_argument, NULL, 'b'}, @@ -47,6 +47,7 @@ static struct option options[] = { {"active-bank", required_argument, NULL, 'a'}, {"previous-bank", required_argument, NULL, 'p'}, {"version", required_argument, NULL, 'v'}, + {"vendor-file", required_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; @@ -61,6 +62,7 @@ static void print_usage(void) "\t-a, --active-bank <num> Active bank (default=0)\n" "\t-p, --previous-bank <num> Previous active bank (default=active_bank - 1)\n" "\t-g, --guid Use GUID instead of UUID\n" + "\t-V, --vendor-file Vendor data file to append to the metadata\n" "\t-h, --help print a help message\n" ); fprintf(stderr, " UUIDs list syntax:\n" @@ -80,6 +82,8 @@ struct fwu_mdata_object { size_t banks; size_t size; u8 version; + size_t vsize; + void *vbuf; struct fwu_mdata *mdata; };
@@ -98,7 +102,7 @@ static bool supported_mdata_version(unsigned long version) }
static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks, - u8 version) + u8 version, size_t vendor_size) { struct fwu_mdata_object *mobj;
@@ -115,6 +119,9 @@ static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks, sizeof(struct fwu_fw_store_desc) + (sizeof(struct fwu_image_entry) + sizeof(struct fwu_image_bank_info) * banks) * images; + + mobj->size += vendor_size; + mobj->vsize = vendor_size; }
mobj->images = images; @@ -122,12 +129,21 @@ static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks, mobj->version = version;
mobj->mdata = calloc(1, mobj->size); - if (!mobj->mdata) { - free(mobj); - return NULL; + if (!mobj->mdata) + goto alloc_err; + + if (vendor_size) { + mobj->vbuf = calloc(1, mobj->vsize); + if (!mobj->vbuf) + goto alloc_err; }
return mobj; + +alloc_err: + free(mobj->mdata); + free(mobj); + return NULL; }
static struct fwu_image_entry * @@ -297,6 +313,7 @@ static void fwu_fill_version_specific_mdata(struct fwu_mdata_object *mobj) static int fwu_parse_fill_uuids(struct fwu_mdata_object *mobj, char *uuids[]) { struct fwu_mdata *mdata = mobj->mdata; + char *vdata; int i, ret;
mdata->version = mobj->version; @@ -311,24 +328,65 @@ static int fwu_parse_fill_uuids(struct fwu_mdata_object *mobj, char *uuids[]) return ret; }
+ if (mobj->vsize) { + vdata = (char *)mobj->mdata + (mobj->size - mobj->vsize); + memcpy(vdata, mobj->vbuf, mobj->vsize); + } + mdata->crc32 = crc32(0, (const unsigned char *)&mdata->version, mobj->size - sizeof(uint32_t));
return 0; }
-static int -fwu_make_mdata(size_t images, size_t banks, u8 version, char *uuids[], - char *output) +static int fwu_read_vendor_data(struct fwu_mdata_object *mobj, + const char *vendor_file) +{ + int ret = 0; + FILE *vfile = NULL; + + vfile = fopen(vendor_file, "r"); + if (!vfile) { + ret = -1; + goto out; + } + + if (fread(mobj->vbuf, 1, mobj->vsize, vfile) != mobj->vsize) + ret = -1; + +out: + fclose(vfile); + return ret; +} + +static int fwu_make_mdata(size_t images, size_t banks, u8 version, + const char *vendor_file, char *uuids[], + char *output) { - struct fwu_mdata_object *mobj; - FILE *file; int ret; + FILE *file; + struct stat sbuf; + size_t vendor_size = 0; + struct fwu_mdata_object *mobj;
- mobj = fwu_alloc_mdata(images, banks, version); + if (vendor_file) { + ret = stat(vendor_file, &sbuf); + if (ret) + return -errno; + + vendor_size = sbuf.st_size; + } + + mobj = fwu_alloc_mdata(images, banks, version, vendor_size); if (!mobj) return -ENOMEM;
+ if (vendor_file) { + ret = fwu_read_vendor_data(mobj, vendor_file); + if (ret) + goto done_make; + } + ret = fwu_parse_fill_uuids(mobj, uuids); if (ret < 0) goto done_make; @@ -349,6 +407,7 @@ fwu_make_mdata(size_t images, size_t banks, u8 version, char *uuids[],
done_make: free(mobj->mdata); + free(mobj->vbuf); free(mobj);
return ret; @@ -358,11 +417,13 @@ int main(int argc, char *argv[]) { unsigned long banks = 0, images = 0, version = 0; int c, ret; + const char *vendor_file;
/* Explicitly initialize defaults */ active_bank = 0; __use_guid = false; previous_bank = INT_MAX; + vendor_file = NULL;
do { c = getopt_long(argc, argv, opts_short, options, NULL); @@ -388,6 +449,9 @@ int main(int argc, char *argv[]) case 'v': version = strtoul(optarg, NULL, 0); break; + case 'V': + vendor_file = optarg; + break; } } while (c != -1);
@@ -402,6 +466,11 @@ int main(int argc, char *argv[]) return -EINVAL; }
+ if (version == 1 && vendor_file) { + fprintf(stderr, "Error: Vendor Data can only be appended in version 2 of FWU Metadata.\n"); + return -EINVAL; + } + /* This command takes UUIDs * images and output file. */ if (optind + images + 1 != argc) { fprintf(stderr, "Error: UUID list or output file is not specified or too much.\n"); @@ -414,8 +483,8 @@ int main(int argc, char *argv[]) previous_bank = active_bank > 0 ? active_bank - 1 : banks - 1; }
- ret = fwu_make_mdata(images, banks, (u8)version, argv + optind, - argv[argc - 1]); + ret = fwu_make_mdata(images, banks, (u8)version, vendor_file, + argv + optind, argv[argc - 1]); if (ret < 0) fprintf(stderr, "Error: Failed to parse and write image: %s\n", strerror(-ret));

Make changes to the FWU metadata access tests corresponding to the changes in the FWU metadata access code.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * Make changes to have the test work with v1 metadata. * Make changes to have the test work with updated logic in fwu code.
test/dm/fwu_mdata.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/test/dm/fwu_mdata.c b/test/dm/fwu_mdata.c index 52018f610f..621ba647d9 100644 --- a/test/dm/fwu_mdata.c +++ b/test/dm/fwu_mdata.c @@ -93,6 +93,10 @@ static int dm_test_fwu_mdata_read(struct unit_test_state *uts) struct udevice *dev; struct fwu_mdata mdata = { 0 };
+ ut_assertok(setup_blk_device(uts)); + ut_assertok(populate_mmc_disk_image(uts)); + ut_assertok(write_mmc_blk_device(uts)); + /* * Trigger lib/fwu_updates/fwu.c fwu_boottime_checks() * to populate g_dev global pointer in that library. @@ -100,9 +104,7 @@ static int dm_test_fwu_mdata_read(struct unit_test_state *uts) event_notify_null(EVT_MAIN_LOOP);
ut_assertok(uclass_first_device_err(UCLASS_FWU_MDATA, &dev)); - ut_assertok(setup_blk_device(uts)); - ut_assertok(populate_mmc_disk_image(uts)); - ut_assertok(write_mmc_blk_device(uts)); + ut_assertok(fwu_init());
ut_assertok(fwu_get_mdata(&mdata));
@@ -118,18 +120,20 @@ static int dm_test_fwu_mdata_write(struct unit_test_state *uts) struct udevice *dev; struct fwu_mdata mdata = { 0 };
+ ut_assertok(setup_blk_device(uts)); + ut_assertok(populate_mmc_disk_image(uts)); + ut_assertok(write_mmc_blk_device(uts)); + /* * Trigger lib/fwu_updates/fwu.c fwu_boottime_checks() * to populate g_dev global pointer in that library. */ event_notify_null(EVT_MAIN_LOOP);
- ut_assertok(setup_blk_device(uts)); - ut_assertok(populate_mmc_disk_image(uts)); - ut_assertok(write_mmc_blk_device(uts));
ut_assertok(uclass_first_device_err(UCLASS_FWU_MDATA, &dev));
+ ut_assertok(fwu_init()); ut_assertok(fwu_get_mdata(&mdata));
active_idx = (mdata.active_index + 1) % CONFIG_FWU_NUM_BANKS;

The FWU Update Agent in U-Boot supports both versions of the FWU metadata. Make changes in the documentation to reflect this.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * Changes to indicate support for both v1 and v2 instead of only v2.
doc/board/socionext/developerbox.rst | 7 +++++-- doc/develop/uefi/fwu_updates.rst | 20 +++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/doc/board/socionext/developerbox.rst b/doc/board/socionext/developerbox.rst index 46712c379b..863761c6e2 100644 --- a/doc/board/socionext/developerbox.rst +++ b/doc/board/socionext/developerbox.rst @@ -116,6 +116,7 @@ configs/synquacer_developerbox_defconfig enables default FWU configuration :: CONFIG_FWU_NUM_BANKS=2 CONFIG_FWU_NUM_IMAGES_PER_BANK=1 CONFIG_CMD_FWU_METADATA=y + CONFIG_FWU_MDATA_V2=y
And build it::
@@ -129,7 +130,9 @@ And build it:: By default, the CONFIG_FWU_NUM_BANKS and CONFIG_FWU_NUM_IMAGES_PER_BANKS are set to 2 and 1 respectively. This uses FIP (Firmware Image Package) type image which contains TF-A, U-Boot and OP-TEE (the OP-TEE is optional). -You can use fiptool to compose the FIP image from those firmware images. +You can use fiptool to compose the FIP image from those firmware +images. There are two versions of the FWU metadata, of which the +platform enables version 2 by default.
Rebuild SCP firmware -------------------- @@ -194,7 +197,7 @@ following UUIDs.
These UUIDs are used for making a FWU metadata image.
-u-boot$ ./tools/mkfwumdata -i 1 -b 2 \ +u-boot$ ./tools/mkfwumdata -v 2 -i 1 -b 2 \ 17e86d77-41f9-4fd7-87ec-a55df9842de5,10c36d7d-ca52-b843-b7b9-f9d6c501d108,5a66a702-99fd-4fef-a392-c26e261a2828,a8f868a1-6e5c-4757-878d-ce63375ef2c0 \ ../devbox-fwu-mdata.img
diff --git a/doc/develop/uefi/fwu_updates.rst b/doc/develop/uefi/fwu_updates.rst index e4709d82b4..51e8a28efe 100644 --- a/doc/develop/uefi/fwu_updates.rst +++ b/doc/develop/uefi/fwu_updates.rst @@ -46,6 +46,8 @@ The feature can be enabled by specifying the following configs:: CONFIG_FWU_NUM_BANKS=<val> CONFIG_FWU_NUM_IMAGES_PER_BANK=<val>
+ CONFIG_FWU_MDATA_V1=y or CONFIG_FWU_MDATA_V2=y + in the .config file
By enabling the CONFIG_CMD_FWU_METADATA config option, the @@ -58,6 +60,14 @@ enable the FWU Multi Bank Update functionality. Please refer to the section :ref:`uefi_capsule_update_ref` for more details on generation of the UEFI capsule.
+FWU Metadata +------------ + +U-Boot supports both versions(1 and 2) of the FWU metadata defined in +the two revisions of the specification. Support can be enabled for +either of the two versions through a config flag. The mkfwumdata tool +can generate metadata for both the supported versions. + Setting up the device for GPT partitioned storage -------------------------------------------------
@@ -94,12 +104,12 @@ of. Each GPT partition entry in the GPT header has two GUIDs:: * UniquePartitionGUID
The PartitionTypeGUID value should correspond to the -``image_type_uuid`` field of the FWU metadata. This field is used to +``image_type_guid`` field of the FWU metadata. This field is used to identify a given type of updatable firmware image, e.g. U-Boot, OP-TEE, FIP etc. This GUID should also be used for specifying the `--guid` parameter when generating the capsule.
-The UniquePartitionGUID value should correspond to the ``image_uuid`` +The UniquePartitionGUID value should correspond to the ``image_guid`` field in the FWU metadata. This GUID is used to identify images of a given image type in different banks.
@@ -108,8 +118,8 @@ metadata partitions. This would be the PartitionTypeGUID for the metadata partitions. Similarly, the UEFI specification defines the ESP GUID to be be used.
-When generating the metadata, the ``image_type_uuid`` and the -``image_uuid`` values should match the *PartitionTypeGUID* and the +When generating the metadata, the ``image_type_guid`` and the +``image_guid`` values should match the *PartitionTypeGUID* and the *UniquePartitionGUID* values respectively.
Performing the Update @@ -181,5 +191,5 @@ empty capsule would be:: Links -----
-* [1] https://developer.arm.com/documentation/den0118/a/ - FWU Specification +* [1] https://developer.arm.com/documentation/den0118/ - FWU Specification * [2] https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e... - Dependable Boot Specification

Add an entry for the FWU Multi Bank Update feature.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * New patch
MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS index cd9b2d42e8..5409b1d78a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1147,6 +1147,14 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-fsl-qoriq.git F: drivers/watchdog/sp805_wdt.c F: drivers/watchdog/sbsa_gwdt.c
+FWU Multi Bank Update +M: Sughosh Ganu sughosh.ganu@linaro.org +S: Maintained +T: git https://source.denx.de/u-boot/custodians/u-boot-efi.git +F: lib/fwu_updates/* +F: drivers/fwu-mdata/* +F: tools/mkfwumdata.c + GATEWORKS_SC M: Tim Harvey tharvey@gateworks.com S: Maintained

On Fri, 22 Mar 2024 at 12:59, Sughosh Ganu sughosh.ganu@linaro.org wrote:
Add an entry for the FWU Multi Bank Update feature.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
Changes since V2:
- New patch
MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS index cd9b2d42e8..5409b1d78a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1147,6 +1147,14 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-fsl-qoriq.git F: drivers/watchdog/sp805_wdt.c F: drivers/watchdog/sbsa_gwdt.c
+FWU Multi Bank Update +M: Sughosh Ganu sughosh.ganu@linaro.org +S: Maintained +T: git https://source.denx.de/u-boot/custodians/u-boot-efi.git +F: lib/fwu_updates/* +F: drivers/fwu-mdata/* +F: tools/mkfwumdata.c
GATEWORKS_SC M: Tim Harvey tharvey@gateworks.com S: Maintained -- 2.34.1
Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org

Now that support for FWU metadata version 2 has been added, the feature can be enabled on platforms which had enabled it. A new config symbol for selecting the metadata version for the platform is also being added.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Changes since V2: * Add config symbol for selecting either of the two metadata versions.
configs/corstone1000_defconfig | 3 +++ configs/sandbox64_defconfig | 2 ++ configs/synquacer_developerbox_defconfig | 4 ++++ 3 files changed, 9 insertions(+)
diff --git a/configs/corstone1000_defconfig b/configs/corstone1000_defconfig index 29d7550afb..ab4e0fefc9 100644 --- a/configs/corstone1000_defconfig +++ b/configs/corstone1000_defconfig @@ -24,6 +24,7 @@ CONFIG_LOGLEVEL=7 CONFIG_BOARD_LATE_INIT=y CONFIG_SYS_PROMPT="corstone1000# " # CONFIG_CMD_CONSOLE is not set +CONFIG_CMD_FWU_METADATA=y CONFIG_CMD_BOOTZ=y # CONFIG_CMD_XIMG is not set CONFIG_CMD_GPT=y @@ -66,3 +67,5 @@ CONFIG_FFA_SHARED_MM_BUF_OFFSET=0 CONFIG_FFA_SHARED_MM_BUF_ADDR=0x02000000 CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_IGNORE_OSINDICATIONS=y +CONFIG_FWU_MULTI_BANK_UPDATE=y +CONFIG_FWU_MDATA_V1=y diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 7e8200e70c..7b316f0d80 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -272,6 +272,8 @@ CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y +CONFIG_FWU_MULTI_BANK_UPDATE=y +CONFIG_FWU_MDATA_V1=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig index 616d410074..7e1aeac217 100644 --- a/configs/synquacer_developerbox_defconfig +++ b/configs/synquacer_developerbox_defconfig @@ -17,6 +17,7 @@ CONFIG_SYS_BOOTM_LEN=0x800000 CONFIG_BOOTSTAGE_STASH_SIZE=4096 CONFIG_HUSH_PARSER=y CONFIG_SYS_MAXARGS=128 +CONFIG_CMD_FWU_METADATA=y CONFIG_CMD_IMLS=y CONFIG_CMD_ERASEENV=y CONFIG_CMD_NVEDIT_EFI=y @@ -51,6 +52,7 @@ CONFIG_DFU_TFTP=y CONFIG_DFU_MTD=y CONFIG_DFU_RAM=y CONFIG_DFU_SF=y +CONFIG_FWU_MDATA_MTD=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_SYNQUACER=y CONFIG_MMC_SDHCI=y @@ -93,3 +95,5 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_IGNORE_OSINDICATIONS=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y +CONFIG_FWU_MULTI_BANK_UPDATE=y +CONFIG_FWU_MDATA_V2=y

Hi Sughosh,
-----Original Message----- From: Sughosh Ganu sughosh.ganu@linaro.org Sent: Friday, March 22, 2024 7:57 PM To: u-boot@lists.denx.de Cc: Heinrich Schuchardt xypron.glpk@gmx.de; Ilias Apalodimas ilias.apalodimas@linaro.org; Yann GAUTIER yann.gautier@st.com; Etienne Carriere etienne.carriere@foss.st.com; Patrick DELAUNAY - foss patrick.delaunay@foss.st.com; Michal Simek michal.simek@amd.com; Kojima, Masahisa/小島 雅久 kojima.masahisa@socionext.com; Michal Simek monstr@monstr.eu Subject: [PATCH v3 00/20] FWU: Add support for FWU metadata version 2
The following patch series adds support for version 2 of the FWU metadata. The version 2 metadata structure is defined in the latest revision of the FWU specification [1].
The earlier versions of these patches were migrating to a version 2 only support in U-Boot, similar to TF-A. However, based on feedback from ST [2], this series has been updated to support both versions. A platform would still be needed to enable one of the two versions of metadata through a config symbol.
TF-A has code which reads the FWU metadata and boots the platform from the active partition. TF-A has decided to migrate the FWU code to a version 2 only support. These changes have been merged in upstream TF-A.
These changes have been tested on the ST DK2 board, which uses the GPT based partitioning scheme. Both V1 and V2 metadata versions have been tested on the DK2 board.
These changes need to be tested on platforms with MTD partitioned storage devices.
@Michal and @Kojima-san, please help in this testing.
I have tested this series on the Developerbox that implements the MTD-based metadata access, multi bank update works fine.
Thanks, Masahisa Kojima
Note: The CI is breaking on some sandbox py tests, but the errors look unrelated. I will look into those issues, but the code review can proceed.
[1] - https://developer.arm.com/documentation/den0118/latest/ [2] - https://lists.denx.de/pipermail/u-boot/2024-February/546277.html
Changes since V2:
- New patch which retains support for V1 of metadata
- Earlier patch was catering to v2 only support. These changes support both versions of metadata.
- Earlier patch was migrating to v2 only support. These changes support both versions.
- Support both metadata versions instead of only v2.
- Added documentation changes.
- Make changes to have the test work with v1 metadata.
- Make changes to have the test work with updated logic in fwu code.
- Changes to indicate support for both v1 and v2 instead of only v2.
- Add config symbol for selecting either of the two metadata versions.
Sughosh Ganu (20): configs: fwu: remove FWU configs for metadata V2 support tools: mkfwumdata: fix the size parameter to the fwrite call drivers: fwu: add the size parameter to the metadata access API's drivers: fwu: mtd: allocate buffer for image info dynamically fwu: metadata: add support for version 2 of the structure fwu: metadata: add a version agnostic structure fwu: metadata: add functions for handling version specific metadata fields fwu: make changes to access version agnostic structure fields capsule: fwu: transition the platform state on a successful update fwu: add config symbols for enabling FWU metadata versions fwu: mtd: remove unused argument from function call fwu: mtd: get MTD partition specific info from driver fwu: mtd: obtain image information from version agnostic structure cmd: fwu: make changes for supporting FWU metadata version 2 tools: mkfwumdata: add support for metadata version 2 tools: mkfwumdata: add logic to append vendor data to the FWU metadata test: fwu: make changes to the FWU metadata access test doc: fwu: make changes to reflect support for FWU metadata v2 MAINTAINERS: add entry for FWU multi bank update feature configs: fwu: re-enable FWU configs
MAINTAINERS | 8 + cmd/fwu_mdata.c | 39 ++-- configs/corstone1000_defconfig | 1 + configs/sandbox64_defconfig | 1 + configs/synquacer_developerbox_defconfig | 2 +- doc/board/socionext/developerbox.rst | 7 +- doc/develop/uefi/fwu_updates.rst | 20 +- doc/mkfwumdata.1 | 16 +- drivers/fwu-mdata/fwu-mdata-uclass.c | 10 +- drivers/fwu-mdata/gpt_blk.c | 23 +- drivers/fwu-mdata/raw_mtd.c | 78 ++++--- include/fwu.h | 147 ++++++++++++- include/fwu_mdata.h | 71 ++++++- lib/efi_loader/efi_capsule.c | 14 +- lib/fwu_updates/Kconfig | 14 ++ lib/fwu_updates/Makefile | 2 + lib/fwu_updates/fwu.c | 204 ++++++++++++------ lib/fwu_updates/fwu_mtd.c | 34 +-- lib/fwu_updates/fwu_v1.c | 167 +++++++++++++++ lib/fwu_updates/fwu_v2.c | 260 +++++++++++++++++++++++ test/dm/fwu_mdata.c | 16 +- tools/mkfwumdata.c | 235 ++++++++++++++++---- 22 files changed, 1153 insertions(+), 216 deletions(-) create mode 100644 lib/fwu_updates/fwu_v1.c create mode 100644 lib/fwu_updates/fwu_v2.c
-- 2.34.1

On 3/22/24 11:57, Sughosh Ganu wrote:
The following patch series adds support for version 2 of the FWU metadata. The version 2 metadata structure is defined in the latest revision of the FWU specification [1].
The earlier versions of these patches were migrating to a version 2 only support in U-Boot, similar to TF-A. However, based on feedback from ST [2], this series has been updated to support both versions. A platform would still be needed to enable one of the two versions of metadata through a config symbol.
TF-A has code which reads the FWU metadata and boots the platform from the active partition. TF-A has decided to migrate the FWU code to a version 2 only support. These changes have been merged in upstream TF-A.
These changes have been tested on the ST DK2 board, which uses the GPT based partitioning scheme. Both V1 and V2 metadata versions have been tested on the DK2 board.
These changes need to be tested on platforms with MTD partitioned storage devices.
@Michal and @Kojima-san, please help in this testing.
Note: The CI is breaking on some sandbox py tests, but the errors look unrelated. I will look into those issues, but the code review can proceed.
[1] - https://developer.arm.com/documentation/den0118/latest/ [2] - https://lists.denx.de/pipermail/u-boot/2024-February/546277.html
Changes since V2:
- New patch which retains support for V1 of metadata
- Earlier patch was catering to v2 only support. These changes support both versions of metadata.
- Earlier patch was migrating to v2 only support. These changes support both versions.
- Support both metadata versions instead of only v2.
- Added documentation changes.
- Make changes to have the test work with v1 metadata.
- Make changes to have the test work with updated logic in fwu code.
- Changes to indicate support for both v1 and v2 instead of only v2.
- Add config symbol for selecting either of the two metadata versions.
Sughosh Ganu (20): configs: fwu: remove FWU configs for metadata V2 support tools: mkfwumdata: fix the size parameter to the fwrite call drivers: fwu: add the size parameter to the metadata access API's drivers: fwu: mtd: allocate buffer for image info dynamically fwu: metadata: add support for version 2 of the structure fwu: metadata: add a version agnostic structure fwu: metadata: add functions for handling version specific metadata fields fwu: make changes to access version agnostic structure fields capsule: fwu: transition the platform state on a successful update fwu: add config symbols for enabling FWU metadata versions fwu: mtd: remove unused argument from function call fwu: mtd: get MTD partition specific info from driver fwu: mtd: obtain image information from version agnostic structure cmd: fwu: make changes for supporting FWU metadata version 2 tools: mkfwumdata: add support for metadata version 2 tools: mkfwumdata: add logic to append vendor data to the FWU metadata test: fwu: make changes to the FWU metadata access test doc: fwu: make changes to reflect support for FWU metadata v2 MAINTAINERS: add entry for FWU multi bank update feature configs: fwu: re-enable FWU configs
MAINTAINERS | 8 + cmd/fwu_mdata.c | 39 ++-- configs/corstone1000_defconfig | 1 + configs/sandbox64_defconfig | 1 + configs/synquacer_developerbox_defconfig | 2 +- doc/board/socionext/developerbox.rst | 7 +- doc/develop/uefi/fwu_updates.rst | 20 +- doc/mkfwumdata.1 | 16 +- drivers/fwu-mdata/fwu-mdata-uclass.c | 10 +- drivers/fwu-mdata/gpt_blk.c | 23 +- drivers/fwu-mdata/raw_mtd.c | 78 ++++--- include/fwu.h | 147 ++++++++++++- include/fwu_mdata.h | 71 ++++++- lib/efi_loader/efi_capsule.c | 14 +- lib/fwu_updates/Kconfig | 14 ++ lib/fwu_updates/Makefile | 2 + lib/fwu_updates/fwu.c | 204 ++++++++++++------ lib/fwu_updates/fwu_mtd.c | 34 +-- lib/fwu_updates/fwu_v1.c | 167 +++++++++++++++ lib/fwu_updates/fwu_v2.c | 260 +++++++++++++++++++++++ test/dm/fwu_mdata.c | 16 +- tools/mkfwumdata.c | 235 ++++++++++++++++---- 22 files changed, 1153 insertions(+), 216 deletions(-) create mode 100644 lib/fwu_updates/fwu_v1.c create mode 100644 lib/fwu_updates/fwu_v2.c
FYI: We are working on changes in early firmware (img selector) to test this code on Kria platforms.
Thanks, Michal

Hi Sughosh,
On 3/22/24 11:57, Sughosh Ganu wrote:
The following patch series adds support for version 2 of the FWU metadata. The version 2 metadata structure is defined in the latest revision of the FWU specification [1].
The earlier versions of these patches were migrating to a version 2 only support in U-Boot, similar to TF-A. However, based on feedback from ST [2], this series has been updated to support both versions. A platform would still be needed to enable one of the two versions of metadata through a config symbol.
TF-A has code which reads the FWU metadata and boots the platform from the active partition. TF-A has decided to migrate the FWU code to a version 2 only support. These changes have been merged in upstream TF-A.
These changes have been tested on the ST DK2 board, which uses the GPT based partitioning scheme. Both V1 and V2 metadata versions have been tested on the DK2 board.
These changes need to be tested on platforms with MTD partitioned storage devices.
@Michal and @Kojima-san, please help in this testing.
Note: The CI is breaking on some sandbox py tests, but the errors look unrelated. I will look into those issues, but the code review can proceed.
[1] - https://developer.arm.com/documentation/den0118/latest/ [2] - https://lists.denx.de/pipermail/u-boot/2024-February/546277.html
Changes since V2:
- New patch which retains support for V1 of metadata
- Earlier patch was catering to v2 only support. These changes support both versions of metadata.
- Earlier patch was migrating to v2 only support. These changes support both versions.
- Support both metadata versions instead of only v2.
- Added documentation changes.
- Make changes to have the test work with v1 metadata.
- Make changes to have the test work with updated logic in fwu code.
- Changes to indicate support for both v1 and v2 instead of only v2.
- Add config symbol for selecting either of the two metadata versions.
Sughosh Ganu (20): configs: fwu: remove FWU configs for metadata V2 support tools: mkfwumdata: fix the size parameter to the fwrite call drivers: fwu: add the size parameter to the metadata access API's drivers: fwu: mtd: allocate buffer for image info dynamically fwu: metadata: add support for version 2 of the structure fwu: metadata: add a version agnostic structure fwu: metadata: add functions for handling version specific metadata fields fwu: make changes to access version agnostic structure fields capsule: fwu: transition the platform state on a successful update fwu: add config symbols for enabling FWU metadata versions fwu: mtd: remove unused argument from function call fwu: mtd: get MTD partition specific info from driver fwu: mtd: obtain image information from version agnostic structure cmd: fwu: make changes for supporting FWU metadata version 2 tools: mkfwumdata: add support for metadata version 2 tools: mkfwumdata: add logic to append vendor data to the FWU metadata test: fwu: make changes to the FWU metadata access test doc: fwu: make changes to reflect support for FWU metadata v2 MAINTAINERS: add entry for FWU multi bank update feature configs: fwu: re-enable FWU configs
MAINTAINERS | 8 + cmd/fwu_mdata.c | 39 ++-- configs/corstone1000_defconfig | 1 + configs/sandbox64_defconfig | 1 + configs/synquacer_developerbox_defconfig | 2 +- doc/board/socionext/developerbox.rst | 7 +- doc/develop/uefi/fwu_updates.rst | 20 +- doc/mkfwumdata.1 | 16 +- drivers/fwu-mdata/fwu-mdata-uclass.c | 10 +- drivers/fwu-mdata/gpt_blk.c | 23 +- drivers/fwu-mdata/raw_mtd.c | 78 ++++--- include/fwu.h | 147 ++++++++++++- include/fwu_mdata.h | 71 ++++++- lib/efi_loader/efi_capsule.c | 14 +- lib/fwu_updates/Kconfig | 14 ++ lib/fwu_updates/Makefile | 2 + lib/fwu_updates/fwu.c | 204 ++++++++++++------ lib/fwu_updates/fwu_mtd.c | 34 +-- lib/fwu_updates/fwu_v1.c | 167 +++++++++++++++ lib/fwu_updates/fwu_v2.c | 260 +++++++++++++++++++++++ test/dm/fwu_mdata.c | 16 +- tools/mkfwumdata.c | 235 ++++++++++++++++---- 22 files changed, 1153 insertions(+), 216 deletions(-) create mode 100644 lib/fwu_updates/fwu_v1.c create mode 100644 lib/fwu_updates/fwu_v2.c
I tested it on Kria and I can't see any issue that's why
Tested-by: Michal Simek michal.simek@amd.com
Thanks, Michal

On Fri, 22 Mar 2024 16:27:13 +0530, Sughosh Ganu wrote:
The following patch series adds support for version 2 of the FWU metadata. The version 2 metadata structure is defined in the latest revision of the FWU specification [1].
The earlier versions of these patches were migrating to a version 2 only support in U-Boot, similar to TF-A. However, based on feedback from ST [2], this series has been updated to support both versions. A platform would still be needed to enable one of the two versions of metadata through a config symbol.
[...]
Applied to u-boot/next, thanks!
participants (5)
-
Ilias Apalodimas
-
kojima.masahisa@socionext.com
-
Michal Simek
-
Sughosh Ganu
-
Tom Rini