diff mbox series

[v2,06/21] fwu: add some API's for metadata version 2 access

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

Commit Message

Sughosh Ganu Feb. 12, 2024, 7:46 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>
---

Changes since V1:
* Use the helper functions from the previous patch to access the
  image information in the metadata.

 include/fwu.h         |  53 ++++++++++++++++
 lib/fwu_updates/fwu.c | 144 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 197 insertions(+)
diff mbox series

Patch

diff --git a/include/fwu.h b/include/fwu.h
index 8f2492bb7e..ce8c98921a 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -153,6 +153,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
@@ -202,6 +222,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
@@ -335,4 +367,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
+ */
+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 2da19c9003..587ca779d3 100644
--- a/lib/fwu_updates/fwu.c
+++ b/lib/fwu_updates/fwu.c
@@ -240,6 +240,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
+ */
+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 = fwu_get_fw_desc(g_mdata)->num_banks;
+	*nimages = fwu_get_fw_desc(g_mdata)->num_images;
+
+	return 0;
+}
+
 /**
  * fwu_get_mdata() - Read, verify and return the FWU metadata
  * @mdata: Output FWU metadata read or NULL
@@ -564,6 +672,42 @@  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_bank_info *img_bank_info;
+
+	if (!mdata)
+		return -EINVAL;
+
+	num_images = fwu_get_fw_desc(mdata)->num_images;
+	for (i = 0; i < num_images; i++) {
+		img_bank_info = fwu_img_bank_info_offset(g_mdata, i,
+							 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