aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSughosh Ganu <sughosh.ganu@linaro.org>2022-07-18 15:57:21 +0530
committerSughosh Ganu <sughosh.ganu@linaro.org>2022-08-25 14:22:33 +0530
commitcaa844a348b5ea898f7cae2cc8fd9879fba97619 (patch)
tree74d3a15b4b82bc4a7e2fac0be466e05e61a62cea
parentd8388524bf043f895b3b6cc87d9af2f995bdad29 (diff)
FWU: Add helper functions for accessing FWU metadata
Add weak functions for getting the update index value and dfu alternate number needed for FWU Multi Bank update functionality. The current implementation for getting the update index value is for platforms with 2 banks. If a platform supports more than 2 banks, it can implement it's own function. The function to get the dfu alternate number has been added for platforms with GPT partitioned storage devices. Platforms with other storage partition scheme need to implement their own function. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
-rw-r--r--include/fwu.h29
-rw-r--r--lib/fwu_updates/fwu.c27
-rw-r--r--lib/fwu_updates/fwu_gpt.c115
3 files changed, 171 insertions, 0 deletions
diff --git a/include/fwu.h b/include/fwu.h
index ecabf1121042..7ebd3a711535 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -211,4 +211,33 @@ 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);
+/**
+ * fwu_plat_get_alt_num() - Get the DFU Alt Num for the image from the platform
+ * @dev: FWU device
+ * @image_guid: Image GUID for which DFU alt number needs to be retrieved
+ * @alt_num: Pointer to the alt_num
+ *
+ * Get the DFU alt number from the platform for the image specified by the
+ * image GUID.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
+ int *alt_num);
+
+/**
+ * fwu_plat_get_update_index() - Get the value of the update bank
+ * @update_idx: Bank number to which images are to be updated
+ *
+ * Get the value of the bank(partition) to which the update needs to be
+ * made.
+ *
+ * Note: This is a weak function and platforms can override this with
+ * their own implementation for selection of the update bank.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+int fwu_plat_get_update_index(uint *update_idx);
#endif /* _FWU_H_ */
diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
index a871d77b4ca9..94b15859a506 100644
--- a/lib/fwu_updates/fwu.c
+++ b/lib/fwu_updates/fwu.c
@@ -355,3 +355,30 @@ int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank)
return fwu_clrset_image_accept(img_type_id, bank,
IMAGE_ACCEPT_CLEAR);
}
+
+/**
+ * fwu_plat_get_update_index() - Get the value of the update bank
+ * @update_idx: Bank number to which images are to be updated
+ *
+ * Get the value of the bank(partition) to which the update needs to be
+ * made.
+ *
+ * Note: This is a weak function and platforms can override this with
+ * their own implementation for selection of the update bank.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+__weak int fwu_plat_get_update_index(uint *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;
+}
diff --git a/lib/fwu_updates/fwu_gpt.c b/lib/fwu_updates/fwu_gpt.c
new file mode 100644
index 000000000000..a3134b80c949
--- /dev/null
+++ b/lib/fwu_updates/fwu_gpt.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include <blk.h>
+#include <dfu.h>
+#include <efi.h>
+#include <efi_loader.h>
+#include <fwu.h>
+#include <log.h>
+#include <part.h>
+
+#include <linux/errno.h>
+
+static int get_gpt_dfu_identifier(struct blk_desc *desc, efi_guid_t *image_guid)
+{
+ int i;
+ struct disk_partition info;
+ efi_guid_t unique_part_guid;
+
+ for (i = 1; i < MAX_SEARCH_PARTITIONS; i++) {
+ if (part_get_info(desc, i, &info))
+ continue;
+ uuid_str_to_bin(info.uuid, unique_part_guid.b,
+ UUID_STR_FORMAT_GUID);
+
+ if (!guidcmp(&unique_part_guid, image_guid))
+ return i;
+ }
+
+ log_err("No partition found with image_guid %pUs\n", image_guid);
+ return -ENOENT;
+}
+
+static int fwu_gpt_get_alt_num(struct blk_desc *desc, efi_guid_t *image_guid,
+ int *alt_num, unsigned char dfu_dev)
+{
+ int ret = -1;
+ int i, part, dev_num;
+ int nalt;
+ struct dfu_entity *dfu;
+
+ dev_num = desc->devnum;
+ part = get_gpt_dfu_identifier(desc, image_guid);
+ if (part < 0)
+ return -ENOENT;
+
+ dfu_init_env_entities(NULL, NULL);
+
+ nalt = 0;
+ list_for_each_entry(dfu, &dfu_list, list) {
+ nalt++;
+ }
+
+ if (!nalt) {
+ log_warning("No entities in dfu_alt_info\n");
+ dfu_free_entities();
+ return -ENOENT;
+ }
+
+ for (i = 0; i < nalt; i++) {
+ dfu = dfu_get_entity(i);
+
+ if (!dfu)
+ continue;
+
+ /*
+ * Currently, Multi Bank update
+ * feature is being supported
+ * only on GPT partitioned
+ * MMC/SD devices.
+ */
+ if (dfu->dev_type != dfu_dev)
+ continue;
+
+ if (dfu->layout == DFU_RAW_ADDR &&
+ dfu->data.mmc.dev_num == dev_num &&
+ dfu->data.mmc.part == part) {
+ *alt_num = dfu->alt;
+ ret = 0;
+ break;
+ }
+ }
+
+ dfu_free_entities();
+
+ return ret;
+}
+
+/**
+ * fwu_plat_get_alt_num() - Get the DFU alt number
+ * @dev: FWU metadata device
+ * @image_guid: GUID value of the image for which the alt num is to
+ * be obtained
+ * @alt_num: The DFU alt number for the image that is to be updated
+ *
+ * Get the DFU alt number for the image that is to be updated. The
+ * image is identified with the image_guid parameter that is passed
+ * to the function.
+ *
+ * Note: This is a weak function and platforms can override this with
+ * their own implementation for obtaining the alt number value.
+ *
+ * Return: 0 if OK, -ve on error
+ *
+ */
+__weak int fwu_plat_get_alt_num(struct udevice *dev, efi_guid_t *image_guid,
+ int *alt_num)
+{
+ struct fwu_mdata_gpt_blk_priv *priv = dev_get_priv(dev);
+
+ return fwu_gpt_get_alt_num(dev_get_uclass_plat(priv->blk_dev),
+ image_guid, alt_num, DFU_DEV_MMC);
+}