diff mbox series

[v4,6/6] fwu: DeveloperBox: add support for FWU

Message ID 20230327211640.499001-1-jaswinder.singh@linaro.org
State Superseded
Delegated to: Tom Rini
Headers show
Series FWU: Add support for mtd backed feature on DeveloperBox | expand

Commit Message

Jassi Brar March 27, 2023, 9:16 p.m. UTC
From: Jassi Brar <jaswinder.singh@linaro.org>

Add code to support FWU_MULTI_BANK_UPDATE.
The platform does not have gpt-partition storage for
Banks and MetaData, rather it used SPI-NOR backed
mtd regions for the purpose.

Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
---
 board/socionext/developerbox/Makefile       |   1 +
 board/socionext/developerbox/developerbox.c |   8 +
 board/socionext/developerbox/fwu_plat.c     |  57 +++++++
 configs/synquacer_developerbox_defconfig    |   8 +
 doc/board/socionext/developerbox.rst        | 155 +++++++++++++++++++-
 include/configs/synquacer.h                 |  10 ++
 6 files changed, 233 insertions(+), 6 deletions(-)
 create mode 100644 board/socionext/developerbox/fwu_plat.c

Comments

Michal Simek March 29, 2023, 1:01 p.m. UTC | #1
On 3/27/23 23:16, jassisinghbrar@gmail.com wrote:
> From: Jassi Brar <jaswinder.singh@linaro.org>
> 
> Add code to support FWU_MULTI_BANK_UPDATE.
> The platform does not have gpt-partition storage for
> Banks and MetaData, rather it used SPI-NOR backed
> mtd regions for the purpose.
> 
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> ---
>   board/socionext/developerbox/Makefile       |   1 +
>   board/socionext/developerbox/developerbox.c |   8 +
>   board/socionext/developerbox/fwu_plat.c     |  57 +++++++
>   configs/synquacer_developerbox_defconfig    |   8 +
>   doc/board/socionext/developerbox.rst        | 155 +++++++++++++++++++-
>   include/configs/synquacer.h                 |  10 ++
>   6 files changed, 233 insertions(+), 6 deletions(-)
>   create mode 100644 board/socionext/developerbox/fwu_plat.c
> 
> diff --git a/board/socionext/developerbox/Makefile b/board/socionext/developerbox/Makefile
> index 4a46de995a..1acd067a7e 100644
> --- a/board/socionext/developerbox/Makefile
> +++ b/board/socionext/developerbox/Makefile
> @@ -7,3 +7,4 @@
>   #
>   
>   obj-y	:= developerbox.o
> +obj-$(CONFIG_FWU_MDATA_MTD) += fwu_plat.o
> diff --git a/board/socionext/developerbox/developerbox.c b/board/socionext/developerbox/developerbox.c
> index 16e14d4f7f..ce2cccf4f0 100644
> --- a/board/socionext/developerbox/developerbox.c
> +++ b/board/socionext/developerbox/developerbox.c
> @@ -20,6 +20,13 @@
>   
>   #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
>   struct efi_fw_image fw_images[] = {
> +#if CONFIG_IS_ENABLED(FWU_MULTI_BANK_UPDATE)
> +	{
> +		.image_type_id = DEVELOPERBOX_FIP_IMAGE_GUID,
> +		.fw_name = u"DEVELOPERBOX-FIP",
> +		.image_index = 1,
> +	},
> +#else
>   	{
>   		.image_type_id = DEVELOPERBOX_UBOOT_IMAGE_GUID,
>   		.fw_name = u"DEVELOPERBOX-UBOOT",
> @@ -35,6 +42,7 @@ struct efi_fw_image fw_images[] = {
>   		.fw_name = u"DEVELOPERBOX-OPTEE",
>   		.image_index = 3,
>   	},
> +#endif
>   };
>   
>   struct efi_capsule_update_info update_info = {
> diff --git a/board/socionext/developerbox/fwu_plat.c b/board/socionext/developerbox/fwu_plat.c
> new file mode 100644
> index 0000000000..29b258f86c
> --- /dev/null
> +++ b/board/socionext/developerbox/fwu_plat.c
> @@ -0,0 +1,57 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2023, Linaro Limited
> + */
> +
> +#include <efi_loader.h>
> +#include <fwu.h>
> +#include <fwu_mdata.h>
> +#include <memalign.h>
> +#include <mtd.h>
> +
> +#define DFU_ALT_BUF_LEN 256
> +
> +/* Generate dfu_alt_info from partitions */
> +void set_dfu_alt_info(char *interface, char *devstr)
> +{
> +	int ret;
> +	struct mtd_info *mtd;
> +
> +	ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
> +	memset(buf, 0, sizeof(buf));
> +
> +	mtd_probe_devices();
> +
> +	mtd = get_mtd_device_nm("nor1");
> +	if (IS_ERR_OR_NULL(mtd))
> +		return;
> +
> +	ret = fwu_gen_alt_info_from_mtd(buf, DFU_ALT_BUF_LEN, mtd);
> +	if (ret < 0) {
> +		log_err("Error: Failed to generate dfu_alt_info. (%d)\n", ret);
> +		return;
> +	}
> +	log_debug("Make dfu_alt_info: '%s'\n", buf);
> +
> +	env_set("dfu_alt_info", buf);
> +}
> +
> +int fwu_plat_get_alt_num(struct udevice __always_unused *dev,
> +			 efi_guid_t *image_id, u8 *alt_num)
> +{
> +	return fwu_mtd_get_alt_num(image_id, alt_num, "nor1");
> +}
> +
> +void fwu_plat_get_bootidx(uint *boot_idx)
> +{
> +	int ret;
> +	u32 active_idx;
> +	u32 *bootidx = boot_idx;
> +
> +	ret = fwu_get_active_index(&active_idx);
> +

nit: remove this newline

> +	if (ret < 0)
> +		*bootidx = -1;
> +
> +	*bootidx = active_idx;

Is this logic here right?
If fwu_get_active_index fails you setup bootidx to -1
and right after it you rewrite it to active_idx initialized in 
fwu_get_active_index() to mdata->active_index.

It means why to do *bootidx = -1; at all?

> +}
> diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig
> index 09e12b739b..d09684153a 100644
> --- a/configs/synquacer_developerbox_defconfig
> +++ b/configs/synquacer_developerbox_defconfig
> @@ -97,3 +97,11 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
>   CONFIG_EFI_CAPSULE_ON_DISK=y
>   CONFIG_EFI_IGNORE_OSINDICATIONS=y
>   CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
> +CONFIG_EFI_SECURE_BOOT=y
> +CONFIG_FWU_MULTI_BANK_UPDATE=y
> +CONFIG_FWU_MDATA=y
> +CONFIG_FWU_MDATA_MTD=y
> +CONFIG_FWU_NUM_BANKS=2
> +CONFIG_FWU_NUM_IMAGES_PER_BANK=1
> +CONFIG_CMD_FWU_METADATA=y
> +CONFIG_TOOLS_MKFWUMDATA=y

doesn't look like that it was created via savedefconfig.

> diff --git a/doc/board/socionext/developerbox.rst b/doc/board/socionext/developerbox.rst
> index 2d943c23be..908d3a7e6f 100644
> --- a/doc/board/socionext/developerbox.rst
> +++ b/doc/board/socionext/developerbox.rst
> @@ -57,14 +57,20 @@ Installation
>   
>   You can install the SNI_NOR_UBOOT.fd via NOR flash writer.
>   
> -Flashing the U-Boot image on DeveloperBox requires a 96boards UART mezzanine or other mezzanine which can connect to LS-UART0 port.
> -Connect USB cable from host to the LS-UART0 and set DSW2-7 to ON, and turn the board on again. The flash writer program will be started automatically; don’t forget to turn the DSW2-7 off again after flashing.
> +Flashing the U-Boot image on DeveloperBox requires a 96boards UART mezzanine
> +or other mezzanine which can connect to LS-UART0 port.
> +Connect USB cable from host to the LS-UART0 and set DSW2-7 to ON, and turn the
> +board on again. The flash writer program will be started automatically;
> +don't forget to turn the DSW2-7 off again after flashing.
>   
> -*!!CAUTION!! If you failed to write the U-Boot image on wrong address, the board can be bricked. See below page if you need to recover the bricked board. See the following page for more detail*
> +*!!CAUTION!! If you write the U-Boot image on wrong address, the board can
> +be bricked. See below page if you need to recover the bricked board. See
> +the following page for more detail*
>   
>   https://www.96boards.org/documentation/enterprise/developerbox/installation/board-recovery.md.html
>   
> -When the serial flasher is running correctly is will show the following boot messages shown via LS-UART0::
> +When the serial flasher is running correctly is will show the following boot
> +messages shown via LS-UART0::
>   
>   
>     /*------------------------------------------*/
> @@ -81,7 +87,144 @@ Once the flasher tool is running we are ready flash the UEFI image::
>     flash rawwrite 200000 100000
>     >> Send SPI_NOR_UBOOT.fd via XMODEM (Control-A S in minicom) <<
>   
> -*!!NOTE!! The flasher command parameter is different from the command for board recovery. U-Boot uses the offset 200000 (2-five-0, 2M in hex) and the size 100000 (1-five-0, 1M in hex).*
> +*!!NOTE!! The flasher command parameter is different from the command for
> +board recovery. U-Boot uses the offset 200000 (2-five-0, 2M in hex) and the
> +size 100000 (1-five-0, 1M in hex).*
>   
> -After transferring the SPI_NOR_UBOOT.fd, turn off the DSW2-7 and reset the board.
> +After transferring the SPI_NOR_UBOOT.fd, turn off the DSW2-7 and
> +reset the board.
>   
> +
> +Enable FWU Multi Bank Update
> +============================
> +
> +DeveloperBox supports the FWU Multi Bank Update. You *MUST* update both
> +*SCP firmware* and *TF-A* for this feature. This will change the layout and
> +the boot process but you can switch back to the normal one by changing
> +the DSW 1-4 off.
> +
> +Configure U-Boot
> +----------------
> +
> +To enable the FWU Multi Bank Update on the DeveloperBox, you need to add
> +following configurations to configs/synquacer_developerbox_defconfig ::
> +
> + CONFIG_FWU_MULTI_BANK_UPDATE=y
> + CONFIG_FWU_MDATA=y
> + CONFIG_FWU_MDATA_MTD=y
> + CONFIG_FWU_NUM_BANKS=2
> + CONFIG_FWU_NUM_IMAGES_PER_BANK=1
> + CONFIG_CMD_FWU_METADATA=y
> +
> +And build it::
> +
> +  cd u-boot/
> +  export ARCH=arm64
> +  export CROSS_COMPILE=aarch64-linux-gnu-
> +  make synquacer_developerbox_defconfig
> +  make -j `noproc`
> +  cd ../
> +
> +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.
> +
> +Rebuild SCP firmware
> +--------------------
> +
> +Rebuild SCP firmware which supports FWU Multi Bank Update as below::
> +
> +  cd SCP-firmware/
> +  OUT=./build/product/synquacer
> +  ROMFW_FILE=$OUT/scp_romfw/$SCP_BUILD_MODE/bin/scp_romfw.bin
> +  RAMFW_FILE=$OUT/scp_ramfw/$SCP_BUILD_MODE/bin/scp_ramfw.bin
> +  ROMRAMFW_FILE=scp_romramfw_release.bin
> +
> +  make CC=arm-none-eabi-gcc PRODUCT=synquacer MODE=release
> +  tr "\000" "\377" < /dev/zero | dd of=${ROMRAMFW_FILE} bs=1 count=196608
> +  dd if=${ROMFW_FILE} of=${ROMRAMFW_FILE} bs=1 conv=notrunc seek=0
> +  dd if=${RAMFW_FILE} of=${ROMRAMFW_FILE} bs=1 seek=65536
> +  cd ../
> +
> +And you can get the `scp_romramfw_release.bin` file
> +
> +Rebuild OPTEE firmware
> +----------------------
> +
> +Rebuild OPTEE to use in new-layout fip as below::
> +
> +  cd optee_os/
> +  make -j`nproc` PLATFORM=synquacer ARCH=arm \
> +    CROSS_COMPILE64=aarch64-linux-gnu- CFG_ARM64_core=y \
> +    CFG_CRYPTO_WITH_CE=y CFG_CORE_HEAP_SIZE=524288 CFG_CORE_DYN_SHM=y \
> +    CFG_CORE_ARM64_PA_BITS=48 CFG_TEE_CORE_LOG_LEVEL=1 CFG_TEE_TA_LOG_LEVEL=1
> +  cp out/arm-plat-synquacer/core/tee-pager_v2.bin ../arm-trusted-firmware/
> +
> +The produced `tee-pager_v2.bin` is to be used while building TF-A next.
> +
> +
> +Rebuild TF-A and FIP
> +--------------------
> +
> +Rebuild TF-A which supports FWU Multi Bank Update as below::
> +
> +  cd arm-trusted-firmware/
> +  make CROSS_COMPILE=aarch64-linux-gnu- -j`nproc` PLAT=synquacer \
> +     TRUSTED_BOARD_BOOT=1 SPD=opteed SQ_RESET_TO_BL2=1 GENERATE_COT=1 \
> +     MBEDTLS_DIR=../mbedtls BL32=tee-pager_v2.bin \
> +     BL33=../u-boot/u-boot.bin all fip fiptool
> +
> +And make a FIP image.::
> +
> +  cp build/synquacer/release/fip.bin SPI_NOR_NEWFIP.fd
> +  tools/fiptool/fiptool update --tb-fw build/synquacer/release/bl2.bin SPI_NOR_NEWFIP.fd
> +
> +UUIDs for the FWU Multi Bank Update
> +-----------------------------------
> +
> +FWU multi-bank update requires some UUIDs. The DeveloperBox platform uses
> +following UUIDs.
> +
> + - Location UUID for the FIP image: 17e86d77-41f9-4fd7-87ec-a55df9842de5


In past you have it listed at flash node in DT. I see you have removed it 
between v3 and v4 without any note about it.
Is it still needed? And should it be listed in DT spec again?

Thanks,
Michal
Jassi Brar April 10, 2023, 4:21 a.m. UTC | #2
On Wed, 29 Mar 2023 at 08:02, Michal Simek <michal.simek@amd.com> wrote:
> On 3/27/23 23:16, jassisinghbrar@gmail.com wrote:

.....
> > +
> > +void fwu_plat_get_bootidx(uint *boot_idx)
> > +{
> > +     int ret;
> > +     u32 active_idx;
> > +     u32 *bootidx = boot_idx;
> > +
> > +     ret = fwu_get_active_index(&active_idx);
> > +
>
> nit: remove this newline
>
ok

> > +     if (ret < 0)
> > +             *bootidx = -1;
> > +
> > +     *bootidx = active_idx;
>
> Is this logic here right?
> If fwu_get_active_index fails you setup bootidx to -1
> and right after it you rewrite it to active_idx initialized in
> fwu_get_active_index() to mdata->active_index.
>
> It means why to do *bootidx = -1; at all?
>
yes :) it's a silly remnant of history of changes.
Actually this goes away after implementing the default/weak function.


> > +}
> > diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig
> > index 09e12b739b..d09684153a 100644
> > --- a/configs/synquacer_developerbox_defconfig
> > +++ b/configs/synquacer_developerbox_defconfig
> > @@ -97,3 +97,11 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
> >   CONFIG_EFI_CAPSULE_ON_DISK=y
> >   CONFIG_EFI_IGNORE_OSINDICATIONS=y
> >   CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
> > +CONFIG_EFI_SECURE_BOOT=y
> > +CONFIG_FWU_MULTI_BANK_UPDATE=y
> > +CONFIG_FWU_MDATA=y
> > +CONFIG_FWU_MDATA_MTD=y
> > +CONFIG_FWU_NUM_BANKS=2
> > +CONFIG_FWU_NUM_IMAGES_PER_BANK=1
> > +CONFIG_CMD_FWU_METADATA=y
> > +CONFIG_TOOLS_MKFWUMDATA=y
>
> doesn't look like that it was created via savedefconfig.
>
Yes. I had some other config changes too and picked only the relevant
ones together.


> > +And make a FIP image.::
> > +
> > +  cp build/synquacer/release/fip.bin SPI_NOR_NEWFIP.fd
> > +  tools/fiptool/fiptool update --tb-fw build/synquacer/release/bl2.bin SPI_NOR_NEWFIP.fd
> > +
> > +UUIDs for the FWU Multi Bank Update
> > +-----------------------------------
> > +
> > +FWU multi-bank update requires some UUIDs. The DeveloperBox platform uses
> > +following UUIDs.
> > +
> > + - Location UUID for the FIP image: 17e86d77-41f9-4fd7-87ec-a55df9842de5
>
>
> In past you have it listed at flash node in DT. I see you have removed it
> between v3 and v4 without any note about it.
> Is it still needed? And should it be listed in DT spec again?
>
After the dt change, we no longer require this. But the location_uuid
is a standard member of an fwu_image_entry and cmd/fwu_mdata.c always
print it. So I think this should be seen as just what a platform wants
some unique id to be printed for the image (?).

Thanks Michal for reviewing v4.
cheers.
Michal Simek April 14, 2023, 1:52 p.m. UTC | #3
On 4/10/23 06:21, Jassi Brar wrote:
> On Wed, 29 Mar 2023 at 08:02, Michal Simek <michal.simek@amd.com> wrote:
>> On 3/27/23 23:16, jassisinghbrar@gmail.com wrote:
> 
> .....
>>> +
>>> +void fwu_plat_get_bootidx(uint *boot_idx)
>>> +{
>>> +     int ret;
>>> +     u32 active_idx;
>>> +     u32 *bootidx = boot_idx;
>>> +
>>> +     ret = fwu_get_active_index(&active_idx);
>>> +
>>
>> nit: remove this newline
>>
> ok
> 
>>> +     if (ret < 0)
>>> +             *bootidx = -1;
>>> +
>>> +     *bootidx = active_idx;
>>
>> Is this logic here right?
>> If fwu_get_active_index fails you setup bootidx to -1
>> and right after it you rewrite it to active_idx initialized in
>> fwu_get_active_index() to mdata->active_index.
>>
>> It means why to do *bootidx = -1; at all?
>>
> yes :) it's a silly remnant of history of changes.
> Actually this goes away after implementing the default/weak function.
> 
> 
>>> +}
>>> diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig
>>> index 09e12b739b..d09684153a 100644
>>> --- a/configs/synquacer_developerbox_defconfig
>>> +++ b/configs/synquacer_developerbox_defconfig
>>> @@ -97,3 +97,11 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
>>>    CONFIG_EFI_CAPSULE_ON_DISK=y
>>>    CONFIG_EFI_IGNORE_OSINDICATIONS=y
>>>    CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
>>> +CONFIG_EFI_SECURE_BOOT=y
>>> +CONFIG_FWU_MULTI_BANK_UPDATE=y
>>> +CONFIG_FWU_MDATA=y
>>> +CONFIG_FWU_MDATA_MTD=y
>>> +CONFIG_FWU_NUM_BANKS=2
>>> +CONFIG_FWU_NUM_IMAGES_PER_BANK=1
>>> +CONFIG_CMD_FWU_METADATA=y
>>> +CONFIG_TOOLS_MKFWUMDATA=y
>>
>> doesn't look like that it was created via savedefconfig.
>>
> Yes. I had some other config changes too and picked only the relevant
> ones together.

But this is defconfig not documentation.



> 
> 
>>> +And make a FIP image.::
>>> +
>>> +  cp build/synquacer/release/fip.bin SPI_NOR_NEWFIP.fd
>>> +  tools/fiptool/fiptool update --tb-fw build/synquacer/release/bl2.bin SPI_NOR_NEWFIP.fd
>>> +
>>> +UUIDs for the FWU Multi Bank Update
>>> +-----------------------------------
>>> +
>>> +FWU multi-bank update requires some UUIDs. The DeveloperBox platform uses
>>> +following UUIDs.
>>> +
>>> + - Location UUID for the FIP image: 17e86d77-41f9-4fd7-87ec-a55df9842de5
>>
>>
>> In past you have it listed at flash node in DT. I see you have removed it
>> between v3 and v4 without any note about it.
>> Is it still needed? And should it be listed in DT spec again?
>>
> After the dt change, we no longer require this. But the location_uuid
> is a standard member of an fwu_image_entry and cmd/fwu_mdata.c always
> print it. So I think this should be seen as just what a platform wants
> some unique id to be printed for the image (?).

I am fine with your explanation but documentation should make this clear that 
uuid is required by spec but not actually used by current implementation or 
description.

M
diff mbox series

Patch

diff --git a/board/socionext/developerbox/Makefile b/board/socionext/developerbox/Makefile
index 4a46de995a..1acd067a7e 100644
--- a/board/socionext/developerbox/Makefile
+++ b/board/socionext/developerbox/Makefile
@@ -7,3 +7,4 @@ 
 #
 
 obj-y	:= developerbox.o
+obj-$(CONFIG_FWU_MDATA_MTD) += fwu_plat.o
diff --git a/board/socionext/developerbox/developerbox.c b/board/socionext/developerbox/developerbox.c
index 16e14d4f7f..ce2cccf4f0 100644
--- a/board/socionext/developerbox/developerbox.c
+++ b/board/socionext/developerbox/developerbox.c
@@ -20,6 +20,13 @@ 
 
 #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
 struct efi_fw_image fw_images[] = {
+#if CONFIG_IS_ENABLED(FWU_MULTI_BANK_UPDATE)
+	{
+		.image_type_id = DEVELOPERBOX_FIP_IMAGE_GUID,
+		.fw_name = u"DEVELOPERBOX-FIP",
+		.image_index = 1,
+	},
+#else
 	{
 		.image_type_id = DEVELOPERBOX_UBOOT_IMAGE_GUID,
 		.fw_name = u"DEVELOPERBOX-UBOOT",
@@ -35,6 +42,7 @@  struct efi_fw_image fw_images[] = {
 		.fw_name = u"DEVELOPERBOX-OPTEE",
 		.image_index = 3,
 	},
+#endif
 };
 
 struct efi_capsule_update_info update_info = {
diff --git a/board/socionext/developerbox/fwu_plat.c b/board/socionext/developerbox/fwu_plat.c
new file mode 100644
index 0000000000..29b258f86c
--- /dev/null
+++ b/board/socionext/developerbox/fwu_plat.c
@@ -0,0 +1,57 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#include <efi_loader.h>
+#include <fwu.h>
+#include <fwu_mdata.h>
+#include <memalign.h>
+#include <mtd.h>
+
+#define DFU_ALT_BUF_LEN 256
+
+/* Generate dfu_alt_info from partitions */
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+	int ret;
+	struct mtd_info *mtd;
+
+	ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
+	memset(buf, 0, sizeof(buf));
+
+	mtd_probe_devices();
+
+	mtd = get_mtd_device_nm("nor1");
+	if (IS_ERR_OR_NULL(mtd))
+		return;
+
+	ret = fwu_gen_alt_info_from_mtd(buf, DFU_ALT_BUF_LEN, mtd);
+	if (ret < 0) {
+		log_err("Error: Failed to generate dfu_alt_info. (%d)\n", ret);
+		return;
+	}
+	log_debug("Make dfu_alt_info: '%s'\n", buf);
+
+	env_set("dfu_alt_info", buf);
+}
+
+int fwu_plat_get_alt_num(struct udevice __always_unused *dev,
+			 efi_guid_t *image_id, u8 *alt_num)
+{
+	return fwu_mtd_get_alt_num(image_id, alt_num, "nor1");
+}
+
+void fwu_plat_get_bootidx(uint *boot_idx)
+{
+	int ret;
+	u32 active_idx;
+	u32 *bootidx = boot_idx;
+
+	ret = fwu_get_active_index(&active_idx);
+
+	if (ret < 0)
+		*bootidx = -1;
+
+	*bootidx = active_idx;
+}
diff --git a/configs/synquacer_developerbox_defconfig b/configs/synquacer_developerbox_defconfig
index 09e12b739b..d09684153a 100644
--- a/configs/synquacer_developerbox_defconfig
+++ b/configs/synquacer_developerbox_defconfig
@@ -97,3 +97,11 @@  CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
 CONFIG_EFI_CAPSULE_ON_DISK=y
 CONFIG_EFI_IGNORE_OSINDICATIONS=y
 CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y
+CONFIG_EFI_SECURE_BOOT=y
+CONFIG_FWU_MULTI_BANK_UPDATE=y
+CONFIG_FWU_MDATA=y
+CONFIG_FWU_MDATA_MTD=y
+CONFIG_FWU_NUM_BANKS=2
+CONFIG_FWU_NUM_IMAGES_PER_BANK=1
+CONFIG_CMD_FWU_METADATA=y
+CONFIG_TOOLS_MKFWUMDATA=y
diff --git a/doc/board/socionext/developerbox.rst b/doc/board/socionext/developerbox.rst
index 2d943c23be..908d3a7e6f 100644
--- a/doc/board/socionext/developerbox.rst
+++ b/doc/board/socionext/developerbox.rst
@@ -57,14 +57,20 @@  Installation
 
 You can install the SNI_NOR_UBOOT.fd via NOR flash writer.
 
-Flashing the U-Boot image on DeveloperBox requires a 96boards UART mezzanine or other mezzanine which can connect to LS-UART0 port.
-Connect USB cable from host to the LS-UART0 and set DSW2-7 to ON, and turn the board on again. The flash writer program will be started automatically; don’t forget to turn the DSW2-7 off again after flashing.
+Flashing the U-Boot image on DeveloperBox requires a 96boards UART mezzanine
+or other mezzanine which can connect to LS-UART0 port.
+Connect USB cable from host to the LS-UART0 and set DSW2-7 to ON, and turn the
+board on again. The flash writer program will be started automatically;
+don't forget to turn the DSW2-7 off again after flashing.
 
-*!!CAUTION!! If you failed to write the U-Boot image on wrong address, the board can be bricked. See below page if you need to recover the bricked board. See the following page for more detail*
+*!!CAUTION!! If you write the U-Boot image on wrong address, the board can
+be bricked. See below page if you need to recover the bricked board. See
+the following page for more detail*
 
 https://www.96boards.org/documentation/enterprise/developerbox/installation/board-recovery.md.html
 
-When the serial flasher is running correctly is will show the following boot messages shown via LS-UART0::
+When the serial flasher is running correctly is will show the following boot
+messages shown via LS-UART0::
 
 
   /*------------------------------------------*/
@@ -81,7 +87,144 @@  Once the flasher tool is running we are ready flash the UEFI image::
   flash rawwrite 200000 100000
   >> Send SPI_NOR_UBOOT.fd via XMODEM (Control-A S in minicom) <<
 
-*!!NOTE!! The flasher command parameter is different from the command for board recovery. U-Boot uses the offset 200000 (2-five-0, 2M in hex) and the size 100000 (1-five-0, 1M in hex).*
+*!!NOTE!! The flasher command parameter is different from the command for
+board recovery. U-Boot uses the offset 200000 (2-five-0, 2M in hex) and the
+size 100000 (1-five-0, 1M in hex).*
 
-After transferring the SPI_NOR_UBOOT.fd, turn off the DSW2-7 and reset the board.
+After transferring the SPI_NOR_UBOOT.fd, turn off the DSW2-7 and
+reset the board.
 
+
+Enable FWU Multi Bank Update
+============================
+
+DeveloperBox supports the FWU Multi Bank Update. You *MUST* update both
+*SCP firmware* and *TF-A* for this feature. This will change the layout and
+the boot process but you can switch back to the normal one by changing
+the DSW 1-4 off.
+
+Configure U-Boot
+----------------
+
+To enable the FWU Multi Bank Update on the DeveloperBox, you need to add
+following configurations to configs/synquacer_developerbox_defconfig ::
+
+ CONFIG_FWU_MULTI_BANK_UPDATE=y
+ CONFIG_FWU_MDATA=y
+ CONFIG_FWU_MDATA_MTD=y
+ CONFIG_FWU_NUM_BANKS=2
+ CONFIG_FWU_NUM_IMAGES_PER_BANK=1
+ CONFIG_CMD_FWU_METADATA=y
+
+And build it::
+
+  cd u-boot/
+  export ARCH=arm64
+  export CROSS_COMPILE=aarch64-linux-gnu-
+  make synquacer_developerbox_defconfig
+  make -j `noproc`
+  cd ../
+
+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.
+
+Rebuild SCP firmware
+--------------------
+
+Rebuild SCP firmware which supports FWU Multi Bank Update as below::
+
+  cd SCP-firmware/
+  OUT=./build/product/synquacer
+  ROMFW_FILE=$OUT/scp_romfw/$SCP_BUILD_MODE/bin/scp_romfw.bin
+  RAMFW_FILE=$OUT/scp_ramfw/$SCP_BUILD_MODE/bin/scp_ramfw.bin
+  ROMRAMFW_FILE=scp_romramfw_release.bin
+
+  make CC=arm-none-eabi-gcc PRODUCT=synquacer MODE=release
+  tr "\000" "\377" < /dev/zero | dd of=${ROMRAMFW_FILE} bs=1 count=196608
+  dd if=${ROMFW_FILE} of=${ROMRAMFW_FILE} bs=1 conv=notrunc seek=0
+  dd if=${RAMFW_FILE} of=${ROMRAMFW_FILE} bs=1 seek=65536
+  cd ../
+
+And you can get the `scp_romramfw_release.bin` file
+
+Rebuild OPTEE firmware
+----------------------
+
+Rebuild OPTEE to use in new-layout fip as below::
+
+  cd optee_os/
+  make -j`nproc` PLATFORM=synquacer ARCH=arm \
+    CROSS_COMPILE64=aarch64-linux-gnu- CFG_ARM64_core=y \
+    CFG_CRYPTO_WITH_CE=y CFG_CORE_HEAP_SIZE=524288 CFG_CORE_DYN_SHM=y \
+    CFG_CORE_ARM64_PA_BITS=48 CFG_TEE_CORE_LOG_LEVEL=1 CFG_TEE_TA_LOG_LEVEL=1
+  cp out/arm-plat-synquacer/core/tee-pager_v2.bin ../arm-trusted-firmware/
+
+The produced `tee-pager_v2.bin` is to be used while building TF-A next.
+
+
+Rebuild TF-A and FIP
+--------------------
+
+Rebuild TF-A which supports FWU Multi Bank Update as below::
+
+  cd arm-trusted-firmware/
+  make CROSS_COMPILE=aarch64-linux-gnu- -j`nproc` PLAT=synquacer \
+     TRUSTED_BOARD_BOOT=1 SPD=opteed SQ_RESET_TO_BL2=1 GENERATE_COT=1 \
+     MBEDTLS_DIR=../mbedtls BL32=tee-pager_v2.bin \
+     BL33=../u-boot/u-boot.bin all fip fiptool
+
+And make a FIP image.::
+
+  cp build/synquacer/release/fip.bin SPI_NOR_NEWFIP.fd
+  tools/fiptool/fiptool update --tb-fw build/synquacer/release/bl2.bin SPI_NOR_NEWFIP.fd
+
+UUIDs for the FWU Multi Bank Update
+-----------------------------------
+
+FWU multi-bank update requires some UUIDs. The DeveloperBox platform uses
+following UUIDs.
+
+ - Location UUID for the FIP image: 17e86d77-41f9-4fd7-87ec-a55df9842de5
+ - Image type UUID for the FIP image: 10c36d7d-ca52-b843-b7b9-f9d6c501d108
+ - Image UUID for Bank0 : 5a66a702-99fd-4fef-a392-c26e261a2828
+ - Image UUID for Bank1 : a8f868a1-6e5c-4757-878d-ce63375ef2c0
+
+These UUIDs are used for making a FWU metadata image.
+
+u-boot$ ./tools/mkfwumdata -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
+
+Create Accept & Revert capsules
+
+u-boot$ ./tools/mkeficapsule -A -g 7d6dc310-52ca-43b8-b7b9-f9d6c501d108 NEWFIP_accept.Cap
+u-boot$ ./tools/mkeficapsule -R NEWFIP_revert.Cap
+
+Install via flash writer
+------------------------
+
+As explained in above section, the new FIP image and the FWU metadata image
+can be installed via NOR flash writer. Note that the installation offsets for
+the FWU multi bank update supported firmware.
+
+Once the flasher tool is running we are ready flash the images.::
+Write the FIP image to the Bank-0 & 1 at 6MB and 10MB offset.::
+
+  flash rawwrite 600000 180000
+  flash rawwrite a00000 180000
+  >> Send SPI_NOR_NEWFIP.fd via XMODEM (Control-A S in minicom) <<
+
+  flash rawwrite 500000 1000
+  flash rawwrite 530000 1000
+  >> Send devbox-fwu-mdata.img via XMODEM (Control-A S in minicom) <<
+
+And write the new SCP firmware.::
+
+  flash write cm3
+  >> Send scp_romramfw_release.bin via XMODEM (Control-A S in minicom) <<
+
+At last, turn on the DSW 3-4 on the board, and reboot.
+Note that if DSW 3-4 is turned off, the DeveloperBox will boot from
+the original EDK2 firmware (or non-FWU U-Boot if you already installed.)
diff --git a/include/configs/synquacer.h b/include/configs/synquacer.h
index 8f44c6f66a..cd7359c2f8 100644
--- a/include/configs/synquacer.h
+++ b/include/configs/synquacer.h
@@ -40,19 +40,29 @@ 
 
 /* Since U-Boot 64bit PCIe support is limited, disable 64bit MMIO support */
 
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE
+#define DEFAULT_DFU_ALT_INFO
+#else
 #define DEFAULT_DFU_ALT_INFO "dfu_alt_info="				\
 			"mtd nor1=u-boot.bin raw 200000 100000;"	\
 			"fip.bin raw 180000 78000;"			\
 			"optee.bin raw 500000 100000\0"
+#endif
 
 /* GUIDs for capsule updatable firmware images */
 #define DEVELOPERBOX_UBOOT_IMAGE_GUID \
 	EFI_GUID(0x53a92e83, 0x4ef4, 0x473a, 0x8b, 0x0d, \
 		 0xb5, 0xd8, 0xc7, 0xb2, 0xd6, 0x00)
 
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE
+#define DEVELOPERBOX_FIP_IMAGE_GUID \
+	EFI_GUID(0x7d6dc310, 0x52ca, 0x43b8, 0xb7, 0xb9, \
+		 0xf9, 0xd6, 0xc5, 0x01, 0xd1, 0x08)
+#else
 #define DEVELOPERBOX_FIP_IMAGE_GUID \
 	EFI_GUID(0x880866e9, 0x84ba, 0x4793, 0xa9, 0x08, \
 		 0x33, 0xe0, 0xb9, 0x16, 0xf3, 0x98)
+#endif
 
 #define DEVELOPERBOX_OPTEE_IMAGE_GUID \
 	EFI_GUID(0xc1b629f1, 0xce0e, 0x4894, 0x82, 0xbf, \