
On Fri, Jan 21, 2022 at 12:31:20AM +0900, Masami Hiramatsu wrote:
The DeveloperBox platform can support the FWU Multi bank update. SCP firmware will switch the boot mode by DSW3-4 and load the Multi bank update supported TF-A BL2 from 0x600000 offset on the SPI flash. Thus it can co-exist with the legacy boot mode (legacy U-Boot or EDK2).
Signed-off-by: Masami Hiramatsu masami.hiramatsu@linaro.org
board/socionext/developerbox/Kconfig | 19 ++++ board/socionext/developerbox/Makefile | 1 board/socionext/developerbox/fwu_plat.c | 158 +++++++++++++++++++++++++++++++ include/configs/synquacer.h | 10 ++ include/efi_loader.h | 3 + lib/efi_loader/efi_firmware.c | 14 +-- 6 files changed, 198 insertions(+), 7 deletions(-) create mode 100644 board/socionext/developerbox/fwu_plat.c
diff --git a/board/socionext/developerbox/Kconfig b/board/socionext/developerbox/Kconfig index c181d26a44..4e2c341aad 100644 --- a/board/socionext/developerbox/Kconfig +++ b/board/socionext/developerbox/Kconfig @@ -32,4 +32,23 @@ config SYS_CONFIG_NAME default "synquacer"
endif
+config FWU_MULTI_BANK_UPDATE
- select FWU_MULTI_BANK_UPDATE_SF
+config FWU_MULTI_BANK_UPDATE_SF
- select DM_SPI_FLASH
+config FWU_NUM_BANKS
- default 6
+config FWU_NUM_IMAGES_PER_BANK
- default 1
+config FWU_SF_PRIMARY_MDATA_OFFSET
- default 0x500000
+config FWU_SF_SECONDARY_MDATA_OFFSET
- default 0x520000
Are those configs DeveloperBox-specific?
-Takahiro Akashi
endif diff --git a/board/socionext/developerbox/Makefile b/board/socionext/developerbox/Makefile index 4a46de995a..15cce9c57e 100644 --- a/board/socionext/developerbox/Makefile +++ b/board/socionext/developerbox/Makefile @@ -7,3 +7,4 @@ #
obj-y := developerbox.o +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE_SF) += fwu_plat.o diff --git a/board/socionext/developerbox/fwu_plat.c b/board/socionext/developerbox/fwu_plat.c new file mode 100644 index 0000000000..dbb814f1fd --- /dev/null +++ b/board/socionext/developerbox/fwu_plat.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (c) 2021, Linaro Limited
- */
+#include <efi_loader.h> +#include <fwu.h> +#include <fwu_mdata.h> +#include <malloc.h> +#include <memalign.h> +#include <spi.h> +#include <spi_flash.h> +#include <flash.h>
+#include <linux/errno.h> +#include <linux/types.h> +#include <u-boot/crc.h>
+/* SPI Flash accessors */ +static struct spi_flash *plat_spi_flash;
+static int __plat_sf_get_flash(void) +{
- struct udevice *new;
- int ret;
- //TODO: use CONFIG_FWU_SPI_*
- ret = spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS,
CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE,
&new);
- if (ret)
return ret;
- plat_spi_flash = dev_get_uclass_priv(new);
- return 0;
+}
+static int plat_sf_get_flash(struct spi_flash **flash) +{
- int ret = 0;
- if (!plat_spi_flash)
ret = __plat_sf_get_flash();
- *flash = plat_spi_flash;
- return ret;
+}
+static int sf_load_data(u32 offs, u32 size, void **data) +{
- struct spi_flash *flash;
- int ret;
- ret = plat_sf_get_flash(&flash);
- if (ret < 0)
return ret;
- *data = memalign(ARCH_DMA_MINALIGN, size);
- if (!*data)
return -ENOMEM;
- ret = spi_flash_read(flash, offs, size, *data);
- if (ret < 0) {
free(*data);
*data = NULL;
- }
- return ret;
+}
+/* Platform dependent GUIDs */
+/* The GUID for the SNI FIP image type GUID */ +#define FWU_IMAGE_TYPE_DEVBOX_FIP_GUID \
- EFI_GUID(0x7d6dc310, 0x52ca, 0x43b8, 0xb7, 0xb9, \
0xf9, 0xd6, 0xc5, 0x01, 0xd1, 0x08)
+#define PLAT_METADATA_OFFSET 0x510000 +#define PLAT_METADATA_SIZE (sizeof(struct devbox_metadata))
+struct __packed devbox_metadata {
- u32 boot_index;
- u32 boot_count;
- u32 invert_dual;
+} *devbox_plat_metadata;
+static const efi_guid_t devbox_fip_image_type_guid = FWU_IMAGE_TYPE_DEVBOX_FIP_GUID;
+int fwu_plat_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank,
int *alt_no)
+{
- /* DeveloperBox FWU Multi bank only supports FIP image. */
- if (guidcmp(&image_type_id, &devbox_fip_image_type_guid))
return -EOPNOTSUPP;
- /*
* DeveloperBox FWU expects Bank:Image = 1:1, and the dfu_alt_info
* only has the entries for banks. Thus the alt_no should be equal
* to the update_bank.
*/
- update_bank %= CONFIG_FWU_NUM_BANKS;
- *alt_no = update_bank;
- return 0;
+}
+/* SPI flash doesn't have GPT, and it's not blk device */ +int fwu_plat_fill_partition_guids(efi_guid_t **part_guid_arr) +{
- efi_status_t ret;
- free(*part_guid_arr);
- ret = efi_fill_part_guid_array(&devbox_fip_image_type_guid, part_guid_arr);
- return (ret != EFI_SUCCESS) ? -ENOMEM : 0;
+}
+/* TBD: add a usage counter for wear leveling */ +int fwu_plat_get_update_index(u32 *update_idx) +{
- int ret;
- u32 active_idx;
- ret = fwu_get_active_index(&active_idx);
- if (ret < 0)
return -1;
- *update_idx = (active_idx + 1) % CONFIG_FWU_NUM_BANKS;
- return ret;
+}
+static int devbox_load_plat_metadata(void) +{
- if (devbox_plat_metadata)
return 0;
- return sf_load_data(PLAT_METADATA_OFFSET, PLAT_METADATA_SIZE,
(void **)&devbox_plat_metadata);
+}
+void fwu_plat_get_bootidx(void *boot_idx) +{
- u32 *bootidx = boot_idx;
- if (devbox_load_plat_metadata() < 0)
*bootidx = 0;
- else
*bootidx = devbox_plat_metadata->boot_index;
+}
+struct fwu_mdata_ops *get_plat_fwu_mdata_ops(void) +{
- return fwu_sf_get_fwu_mdata_ops();
+}
diff --git a/include/configs/synquacer.h b/include/configs/synquacer.h index 6d67bd2af5..f859237550 100644 --- a/include/configs/synquacer.h +++ b/include/configs/synquacer.h @@ -47,8 +47,18 @@
/* Since U-Boot 64bit PCIe support is limited, disable 64bit MMIO support */
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE +#define DEFAULT_DFU_ALT_INFO "dfu_alt_info=" \
"mtd nor1=bank0 raw 600000 400000;" \
"bank1 raw a00000 400000;" \
"bank2 raw e00000 400000;" \
"bank3 raw 1200000 400000;" \
"bank4 raw 1600000 400000;" \
"bank5 raw 1a00000 400000\0"
+#else #define DEFAULT_DFU_ALT_INFO "dfu_alt_info=" \ "mtd nor1=fip.bin raw 600000 400000\0" +#endif
/* Distro boot settings */ #ifndef CONFIG_SPL_BUILD diff --git a/include/efi_loader.h b/include/efi_loader.h index f20d361876..d6dc173feb 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -953,6 +953,9 @@ void efi_memcpy_runtime(void *dest, const void *src, size_t n); u16 *efi_create_indexed_name(u16 *buffer, size_t buffer_size, const char *name, unsigned int index);
+efi_status_t efi_fill_part_guid_array(const efi_guid_t *guid,
efi_guid_t **part_guid_arr);
extern const struct efi_firmware_management_protocol efi_fmp_fit; extern const struct efi_firmware_management_protocol efi_fmp_raw;
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 107f0cb074..c100be35d3 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -97,8 +97,8 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( return EFI_EXIT(EFI_UNSUPPORTED); }
-static efi_status_t fill_part_guid_array(const efi_guid_t *guid,
efi_guid_t **part_guid_arr)
+efi_status_t efi_fill_part_guid_array(const efi_guid_t *guid,
efi_guid_t **part_guid_arr)
{ int i; int dfu_num = 0; @@ -309,8 +309,8 @@ efi_status_t EFIAPI efi_firmware_fit_get_image_info( !descriptor_size || !package_version || !package_version_name)) return EFI_EXIT(EFI_INVALID_PARAMETER);
- ret = fill_part_guid_array(&efi_firmware_image_type_uboot_fit,
&part_guid_arr);
- ret = efi_fill_part_guid_array(&efi_firmware_image_type_uboot_fit,
if (ret != EFI_SUCCESS) goto out;&part_guid_arr);
@@ -429,7 +429,7 @@ efi_status_t EFIAPI efi_firmware_raw_get_image_info( return EFI_EXIT(EFI_INVALID_PARAMETER);
if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
ret = fill_part_guid_array(&null_guid, &part_guid_arr);
if (ret != EFI_SUCCESS) goto out;ret = efi_fill_part_guid_array(&null_guid, &part_guid_arr);
@@ -444,8 +444,8 @@ efi_status_t EFIAPI efi_firmware_raw_get_image_info( goto out; } } else {
ret = fill_part_guid_array(&efi_firmware_image_type_uboot_raw,
&part_guid_arr);
ret = efi_fill_part_guid_array(&efi_firmware_image_type_uboot_raw,
if (ret != EFI_SUCCESS) goto out; }&part_guid_arr);