diff mbox series

[04/18] fwu: Add some API's for metadata version 2 access

Message ID 20240122115439.653871-5-sughosh.ganu@linaro.org
State New
Headers show
Series FWU: Migrate FWU metadata to version 2 | expand

Commit Message

Sughosh Ganu Jan. 22, 2024, 11:54 a.m. UTC
There are certain fields added in version 2 of the FWU metadata
structure. Also, information like number of banks and number of images
per bank are also part of the metadata structure. Add functions to
access fields of the version 2 of the metadata structure.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
 include/fwu.h         |  53 ++++++++++++++++
 lib/fwu_updates/fwu.c | 142 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 195 insertions(+)
diff mbox series

Patch

diff --git a/include/fwu.h b/include/fwu.h
index 1815bd0064..d3e97a5360 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -104,6 +104,26 @@  int fwu_write_mdata(struct udevice *dev, struct fwu_mdata *mdata,
  */
 int fwu_get_mdata(struct fwu_mdata *mdata);
 
+/**
+ * fwu_mdata_copies_allocate() - Allocate memory for metadata
+ *
+ * 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(void);
+
+/**
+ * fwu_get_mdata_size() - Get the FWU metadata size
+ *
+ * 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_get_active_index() - Get active_index from the FWU metadata
  * @active_idxp: active_index value to be read
@@ -153,6 +173,18 @@  int fwu_get_dfu_alt_num(u8 image_index, u8 *alt_num);
  */
 int fwu_revert_boot_index(void);
 
+/**
+ * fwu_bank_state_update() - Check and update the bank_state of the metadata
+ * @update_index: Bank for which the bank_state needs to be updated
+ *
+ * Check that all the images for the given bank have been accepted, and if
+ * they are, set the status of the bank to Accepted in the bank_state field
+ * of the metadata.
+ *
+ * Return: 0 if OK, -ve on error
+ */
+int fwu_bank_state_update(uint update_index);
+
 /**
  * fwu_accept_image() - Set the Acceptance bit for the image
  * @img_type_id: GUID of the image type for which the accepted bit is to be
@@ -286,4 +318,25 @@  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_get_banks_images() - Get the number of banks and images from the metadata
+ * @nbanks: Number of banks
+ * @nimages: Number of images per bank
+ *
+ * Get the values of number of banks and number of images per bank from the
+ * metadata.
+ *
+ * Return: 0 if OK, -ve on error
+ */
+__maybe_unused int fwu_get_banks_images(u8 *nbanks, u16 *nimages);
+
+/**
+ * fwu_get_dev() - Return the FWU metadata device
+ *
+ * Return the pointer to the FWU metadata device.
+ *
+ * Return: Pointer to the FWU metadata dev
+ */
+__maybe_unused struct udevice *fwu_get_dev(void);
+
 #endif /* _FWU_H_ */
diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
index 86518108c2..5bfa24067b 100644
--- a/lib/fwu_updates/fwu.c
+++ b/lib/fwu_updates/fwu.c
@@ -188,6 +188,114 @@  static inline int mdata_crc_check(struct fwu_mdata *mdata)
 	return calc_crc32 == mdata->crc32 ? 0 : -EINVAL;
 }
 
+/**
+ * fwu_mdata_copies_allocate() - Allocate memory for metadata
+ *
+ * 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(void)
+{
+	int err;
+	uint32_t mdata_size;
+
+	if (g_mdata)
+		return 0;
+
+	err = fwu_get_mdata_size(&mdata_size);
+	if (err)
+		return err;
+
+	/*
+	 * Now allocate the total memory that would be needed for both
+	 * the copies.
+	 */
+	g_mdata = calloc(2, mdata_size);
+	if (!g_mdata) {
+		log_err("Unable to allocate space for FWU metadata\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * fwu_get_mdata_size() - Get the FWU metadata size
+ *
+ * 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 err = 0;
+	struct fwu_mdata mdata = { 0 };
+
+	if (g_mdata && !mdata_crc_check(g_mdata)) {
+		*mdata_size = g_mdata->metadata_size;
+		return 0;
+	}
+
+	err = fwu_read_mdata(g_dev, &mdata, 1, sizeof(struct fwu_mdata));
+	if (err) {
+		log_err("FWU metadata read failed\n");
+		return err;
+	}
+
+	if (mdata.version != 0x2) {
+		log_err("FWU metadata version %u. Expected value of 2\n",
+			mdata.version);
+		return -EINVAL;
+	}
+
+	*mdata_size = mdata.metadata_size;
+	if (!*mdata_size)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * fwu_get_dev() - Return the FWU metadata device
+ *
+ * Return the pointer to the FWU metadata device.
+ *
+ * Return: Pointer to the FWU metadata dev
+ */
+__maybe_unused struct udevice *fwu_get_dev(void)
+{
+	return g_dev;
+}
+
+/**
+ * fwu_get_banks_images() - Get the number of banks and images from the metadata
+ * @nbanks: Number of banks
+ * @nimages: Number of images per bank
+ *
+ * Get the values of number of banks and number of images per bank from the
+ * metadata.
+ *
+ * Return: 0 if OK, -ve on error
+ */
+__maybe_unused int fwu_get_banks_images(u8 *nbanks, u16 *nimages)
+{
+	int ret;
+
+	if (mdata_crc_check(g_mdata)) {
+		ret = fwu_get_mdata(NULL);
+		if (ret)
+			return ret;
+	}
+
+	*nbanks = g_mdata->fw_desc[0].num_banks;
+	*nimages = g_mdata->fw_desc[0].num_images;
+
+	return 0;
+}
+
 /**
  * fwu_get_mdata() - Read, verify and return the FWU metadata
  * @mdata: Output FWU metadata read or NULL
@@ -473,6 +581,40 @@  out:
 	return ret;
 }
 
+/**
+ * fwu_bank_state_update() - Check and update the bank_state of the metadata
+ * @update_index: Bank for which the bank_state needs to be updated
+ *
+ * Check that all the images for the given bank have been accepted, and if
+ * they are, set the status of the bank to Accepted in the bank_state field
+ * of the metadata.
+ *
+ * Return: 0 if OK, -ve on error
+ */
+int fwu_bank_state_update(uint update_index)
+{
+	int ret = 0, i;
+	u16 num_images;
+	struct fwu_mdata *mdata = g_mdata;
+	struct fwu_image_entry *img_entry;
+	struct fwu_image_bank_info *img_bank_info;
+
+	img_entry = &mdata->fw_desc[0].img_entry[0];
+	num_images = mdata->fw_desc[0].num_images;
+	for (i = 0; i < num_images; i++) {
+		img_bank_info = &img_entry[i].img_bank_info[update_index];
+		if (!(img_bank_info->accepted & FWU_IMAGE_ACCEPTED))
+			return 0;
+	}
+
+	mdata->bank_state[update_index] = FWU_BANK_ACCEPTED;
+	ret = fwu_sync_mdata(mdata, BOTH_PARTS);
+	if (ret)
+		log_err("Unable to set bank_state for bank %u\n", update_index);
+
+	return ret;
+}
+
 /**
  * fwu_accept_image() - Set the Acceptance bit for the image
  * @img_type_id: GUID of the image type for which the accepted bit is to be