From: Masami Hiramatsu <masami.hiramatsu@linaro.org>
To: u-boot@lists.denx.de
Cc: Masami Hiramatsu <masami.hiramatsu@linaro.org>,
Patrick Delaunay <patrick.delaunay@foss.st.com>,
Patrice Chotard <patrice.chotard@foss.st.com>,
Heinrich Schuchardt <xypron.glpk@gmx.de>,
Alexander Graf <agraf@csgraf.de>,
AKASHI Takahiro <takahiro.akashi@linaro.org>,
Simon Glass <sjg@chromium.org>, Bin Meng <bmeng.cn@gmail.com>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
Jose Marinho <jose.marinho@arm.com>,
Grant Likely <grant.likely@arm.com>,
Tom Rini <trini@konsulko.com>,
Etienne Carriere <etienne.carriere@linaro.org>,
Sughosh Ganu <sughosh.ganu@linaro.org>,
Paul Liu <paul.liu@linaro.org>
Subject: [RFC PATCH 11/14] FWU: Add FWU Multi Bank Update on SPI Flash
Date: Fri, 21 Jan 2022 00:31:10 +0900 [thread overview]
Message-ID: <164269267060.39378.17392247605833481024.stgit@localhost> (raw)
In-Reply-To: <164269255955.39378.260729958623102750.stgit@localhost>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu@linaro.org>
---
include/fwu.h | 13 ++
lib/fwu_updates/Kconfig | 34 ++++++
lib/fwu_updates/Makefile | 5 -
lib/fwu_updates/fwu_mdata_sf.c | 241 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 288 insertions(+), 5 deletions(-)
create mode 100644 lib/fwu_updates/fwu_mdata_sf.c
diff --git a/include/fwu.h b/include/fwu.h
index 7af94988b7..a013170321 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -64,9 +64,18 @@ int fwu_accept_image(efi_guid_t *img_type_id, u32 bank);
int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank);
int fwu_plat_get_update_index(u32 *update_idx);
-int fwu_plat_get_blk_desc(struct blk_desc **desc);
-int fwu_plat_get_alt_num(void *identifier);
int fwu_plat_fill_partition_guids(efi_guid_t **part_guid_arr);
void fwu_plat_get_bootidx(void *boot_idx);
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE_GPT_BLK
+int fwu_plat_get_blk_desc(struct blk_desc **desc);
+int fwu_plat_get_alt_num(void *identifier);
+#endif
+
+#ifdef CONFIG_FWU_MULTI_BANK_UPDATE_SF
+struct fwu_mdata_ops *fwu_sf_get_fwu_mdata_ops(void);
+int fwu_plat_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank,
+ int *alt_no);
+#endif
+
#endif /* _FWU_H_ */
diff --git a/lib/fwu_updates/Kconfig b/lib/fwu_updates/Kconfig
index 0940a90747..8a369b9872 100644
--- a/lib/fwu_updates/Kconfig
+++ b/lib/fwu_updates/Kconfig
@@ -38,3 +38,37 @@ config FWU_REBOOT_AFTER_UPDATE
Reboot the machine soon after installing a new firmware
and start trial boot. You can disable this option for
debugging or FWU development, but recommended to enable it.
+
+config FWU_MULTI_BANK_UPDATE_GPT_BLK
+ bool "Enable FWU Multi Bank Update for GPT on blockdev"
+ depends on FWU_MULTI_BANK_UPDATE
+ select EFI_PARTITION
+ help
+ Enable FWU Multi Bank Update for GPT on a block device. This
+ driver depends on GPT and the block device. FWU meatadata and
+ firmware will be stored on a block device with GPT.
+
+config FWU_MULTI_BANK_UPDATE_SF
+ bool "Enable FWU Multi Bank Update for SPI Flash"
+ depends on FWU_MULTI_BANK_UPDATE
+ help
+ Enable FWU Multi Bank Update for SPI flash driver. This
+ driver does not depend on GPT. Instead, the platform must
+ provide some APIs and define the offset of the primary and
+ the secondary metadata.
+
+config FWU_SF_PRIMARY_MDATA_OFFSET
+ hex "The offset of the primary metadata"
+ depends on FWU_MULTI_BANK_UPDATE_SF
+ help
+ The offset of the primary metadata on SPI Flash in
+ hexadecimal.
+
+config FWU_SF_SECONDARY_MDATA_OFFSET
+ hex "The offset of the secondary metadata"
+ depends on FWU_MULTI_BANK_UPDATE_SF
+ help
+ The offset of the secondary metadata on SPI Flash in
+ hexadecimal.
+ This must NOT be the same offset of the primary
+ metadata.
diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile
index 73099a30cb..80669344f2 100644
--- a/lib/fwu_updates/Makefile
+++ b/lib/fwu_updates/Makefile
@@ -6,6 +6,5 @@
obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_mdata.o
obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu.o
-ifdef CONFIG_EFI_PARTITION
-obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_mdata_gpt_blk.o
-endif
+obj-$(CONFIG_FWU_MULTI_BANK_UPDATE_GPT_BLK) += fwu_mdata_gpt_blk.o
+obj-$(CONFIG_FWU_MULTI_BANK_UPDATE_SF) += fwu_mdata_sf.o
diff --git a/lib/fwu_updates/fwu_mdata_sf.c b/lib/fwu_updates/fwu_mdata_sf.c
new file mode 100644
index 0000000000..9e3cae7b68
--- /dev/null
+++ b/lib/fwu_updates/fwu_mdata_sf.c
@@ -0,0 +1,241 @@
+// 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>
+
+/*
+ * For the FWU SPI flash driver, the platform must define below functions
+ * according to its dfu_alt_info.
+ */
+extern int fwu_plat_get_image_alt_num(efi_guid_t image_type_id,
+ u32 update_bank, int *alt_no);
+
+static struct spi_flash *fwu_spi_flash;
+
+static int __fwu_sf_get_flash(void)
+{
+ if (IS_ENABLED(CONFIG_DM_SPI_FLASH)) {
+ struct udevice *new;
+ int ret;
+
+ 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;
+
+ fwu_spi_flash = dev_get_uclass_priv(new);
+ } else {
+ fwu_spi_flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS,
+ CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE);
+ if (!fwu_spi_flash)
+ return -EIO;
+ }
+ return 0;
+}
+
+static int fwu_sf_get_flash(struct spi_flash **flash)
+{
+ int ret = 0;
+
+ if (!fwu_spi_flash)
+ ret = __fwu_sf_get_flash();
+
+ *flash = fwu_spi_flash;
+
+ return ret;
+}
+
+static int sf_load_data(u32 offs, u32 size, void **data)
+{
+ struct spi_flash *flash;
+ int ret;
+
+ ret = fwu_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;
+}
+
+static int sf_save_data(u32 offs, u32 size, void *data)
+{
+ struct spi_flash *flash;
+ u32 sect_size, nsect;
+ void *buf;
+ int ret;
+
+ ret = fwu_sf_get_flash(&flash);
+ if (ret < 0)
+ return ret;
+
+ sect_size = flash->mtd.erasesize;
+ nsect = DIV_ROUND_UP(size, sect_size);
+ ret = spi_flash_erase(flash, offs, nsect * sect_size);
+ if (ret < 0)
+ return ret;
+
+ buf = memalign(ARCH_DMA_MINALIGN, size);
+ if (!buf)
+ return -ENOMEM;
+ memcpy(buf, data, size);
+
+ ret = spi_flash_write(flash, offs, size, buf);
+
+ free(buf);
+
+ return ret;
+}
+
+static int fwu_sf_load_mdata(struct fwu_mdata **mdata, u32 offs)
+{
+ int ret;
+
+ ret = sf_load_data(offs, sizeof(struct fwu_mdata), (void **)mdata);
+
+ if (ret >= 0) {
+ ret = fwu_verify_mdata(*mdata,
+ offs == CONFIG_FWU_SF_PRIMARY_MDATA_OFFSET);
+ if (ret < 0) {
+ free(*mdata);
+ *mdata = NULL;
+ }
+ }
+
+ return ret;
+}
+
+static int fwu_sf_load_primary_mdata(struct fwu_mdata **mdata)
+{
+ return fwu_sf_load_mdata(mdata, CONFIG_FWU_SF_PRIMARY_MDATA_OFFSET);
+}
+
+static int fwu_sf_load_secondary_mdata(struct fwu_mdata **mdata)
+{
+ return fwu_sf_load_mdata(mdata, CONFIG_FWU_SF_SECONDARY_MDATA_OFFSET);
+}
+
+static int fwu_sf_save_primary_mdata(struct fwu_mdata *mdata)
+{
+ return sf_save_data(CONFIG_FWU_SF_PRIMARY_MDATA_OFFSET,
+ sizeof(struct fwu_mdata), mdata);
+}
+
+static int fwu_sf_save_secondary_mdata(struct fwu_mdata *mdata)
+{
+ return sf_save_data(CONFIG_FWU_SF_SECONDARY_MDATA_OFFSET,
+ sizeof(struct fwu_mdata), mdata);
+}
+
+static int fwu_sf_get_valid_mdata(struct fwu_mdata **mdata)
+{
+ if (fwu_sf_load_primary_mdata(mdata) == 0)
+ return 0;
+
+ log_err("Failed to load/verify primary mdata. Try secondary.\n");
+
+ if (fwu_sf_load_secondary_mdata(mdata) == 0)
+ return 0;
+
+ log_err("Failed to load/verify secondary mdata.\n");
+
+ return -1;
+}
+
+static int fwu_sf_update_mdata(struct fwu_mdata *mdata)
+{
+ int ret;
+
+ /* Update mdata crc32 field */
+ mdata->crc32 = crc32(0, (void *)&mdata->version,
+ sizeof(*mdata) - sizeof(u32));
+
+ /* First write the primary mdata */
+ ret = fwu_sf_save_primary_mdata(mdata);
+ if (ret < 0) {
+ log_err("Failed to update the primary mdata.\n");
+ return ret;
+ }
+
+ /* And now the replica */
+ ret = fwu_sf_save_secondary_mdata(mdata);
+ if (ret < 0) {
+ log_err("Failed to update the secondary mdata.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int fwu_sf_mdata_check(void)
+{
+ struct fwu_mdata *primary = NULL, *secondary = NULL;
+ int ret;
+
+ ret = fwu_sf_load_primary_mdata(&primary);
+ if (ret < 0)
+ log_err("Failed to read the primary mdata: %d\n", ret);
+
+ ret = fwu_sf_load_secondary_mdata(&secondary);
+ if (ret < 0)
+ log_err("Failed to read the secondary mdata: %d\n", ret);
+
+ if (primary && secondary) {
+ if (memcmp(primary, secondary, sizeof(struct fwu_mdata))) {
+ log_err("The primary and the secondary mdata are different\n");
+ ret = -1;
+ }
+ } else if (primary) {
+ ret = fwu_sf_save_secondary_mdata(primary);
+ if (ret < 0)
+ log_err("Restoring secondary mdata partition failed\n");
+ } else if (secondary) {
+ ret = fwu_sf_save_primary_mdata(secondary);
+ if (ret < 0)
+ log_err("Restoring primary mdata partition failed\n");
+ }
+
+ free(primary);
+ free(secondary);
+ return ret;
+}
+
+static int fwu_sf_get_mdata(struct fwu_mdata **mdata)
+{
+ return fwu_sf_get_valid_mdata(mdata);
+}
+
+static struct fwu_mdata_ops fwu_sf_mdata_ops = {
+ .get_image_alt_num = fwu_plat_get_image_alt_num,
+ .mdata_check = fwu_sf_mdata_check,
+ .get_mdata = fwu_sf_get_mdata,
+ .update_mdata = fwu_sf_update_mdata,
+};
+
+struct fwu_mdata_ops *fwu_sf_get_fwu_mdata_ops(void)
+{
+ return &fwu_sf_mdata_ops;
+}
next prev parent reply other threads:[~2022-01-20 15:31 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-20 15:29 [RFC PATCH 00/14] FWU: Add FWU Multi Bank Update for DeveloerBox Masami Hiramatsu
2022-01-20 15:29 ` [RFC PATCH 01/14] DFU: Do not copy the entity name over the buffer size Masami Hiramatsu
2022-01-20 15:29 ` [RFC PATCH 02/14] DFU: Accept redundant spaces and tabs in dfu_alt_info Masami Hiramatsu
2022-01-20 15:29 ` [RFC PATCH 03/14] DFU: Check the number of arguments and argument string strictly Masami Hiramatsu
2022-01-20 15:30 ` [RFC PATCH 04/14] doc: usage: DFU: Fix dfu_alt_info document Masami Hiramatsu
2022-01-20 15:30 ` [RFC PATCH 05/14] cmd/dfu: Enable 'dfu list' command without DFU_OVER_USB Masami Hiramatsu
2022-01-20 15:30 ` [RFC PATCH 06/14] FWU: Calculate CRC32 in gpt_update_mdata() Masami Hiramatsu
2022-01-20 15:30 ` [RFC PATCH 07/14] FWU: Free metadata copy if gpt_get_mdata() failed Masami Hiramatsu
2022-01-20 15:30 ` [RFC PATCH 08/14] FWU: Move FWU metadata operation code in fwu_mdata.c Masami Hiramatsu
2022-01-20 15:30 ` [RFC PATCH 09/14] synquacer: Update for TBBR based new FIP layout Masami Hiramatsu
2022-01-20 15:31 ` [RFC PATCH 10/14] FWU: Reboot soon after successfully install the new firmware Masami Hiramatsu
2022-01-21 1:46 ` AKASHI Takahiro
2022-01-21 4:35 ` Masami Hiramatsu
2022-01-21 6:54 ` Masami Hiramatsu
2022-01-21 7:08 ` AKASHI Takahiro
2022-01-20 15:31 ` Masami Hiramatsu [this message]
2022-01-21 2:20 ` [RFC PATCH 11/14] FWU: Add FWU Multi Bank Update on SPI Flash AKASHI Takahiro
2022-01-21 4:41 ` Masami Hiramatsu
2022-01-20 15:31 ` [RFC PATCH 12/14] FWU: synquacer: Add FWU Multi bank update support for DeveloperBox Masami Hiramatsu
2022-01-21 2:22 ` AKASHI Takahiro
2022-01-21 4:40 ` Masami Hiramatsu
2022-01-20 15:31 ` [RFC PATCH 13/14] FWU: synquacer: Initialize broken metadata Masami Hiramatsu
2022-01-20 15:31 ` [RFC PATCH 14/14] configs: synquacer: Add FWU support for DeveloperBox Masami Hiramatsu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=164269267060.39378.17392247605833481024.stgit@localhost \
--to=masami.hiramatsu@linaro.org \
--cc=agraf@csgraf.de \
--cc=bmeng.cn@gmail.com \
--cc=etienne.carriere@linaro.org \
--cc=grant.likely@arm.com \
--cc=ilias.apalodimas@linaro.org \
--cc=jose.marinho@arm.com \
--cc=patrice.chotard@foss.st.com \
--cc=patrick.delaunay@foss.st.com \
--cc=paul.liu@linaro.org \
--cc=sjg@chromium.org \
--cc=sughosh.ganu@linaro.org \
--cc=takahiro.akashi@linaro.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
--cc=xypron.glpk@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox