[PATCH 1/2] efi_loader: firmware: decouple dfu_alt_num from image_index

Balaji Selvanathan via U-Boot <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <20260813-efi-firmware-dfu-alt-num-v1-1-43f034253b21@oss.qualcomm.com>
RAW capsule updates assume dfu_alt_num is always image_index - 1, i.e.
that fw_images[] is a positionally-ordered mirror of the DFU alt
settings. That holds for every board that builds its fw_images[] table
by hand, but a platform whose image list is discovered at runtime
(varying per board, with gaps for missing components) can't guarantee
image_index and dfu_alt_num stay in lockstep.

Move the (image_index - 1) calculation into a __weak function that
platforms can override, following the pattern already used for
efi_firmware_get_image_type_id(). The default keeps the
existing behaviour, so no other board needs any change.

Signed-off-by: Balaji Selvanathan <[email protected]>
---
 include/efi_loader.h          | 17 +++++++++++++++++
 lib/efi_loader/efi_firmware.c | 21 +++++++++++++++++++--
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/include/efi_loader.h b/include/efi_loader.h
index 3a4d502631c..6626674f738 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -1187,11 +1187,15 @@ efi_status_t efi_capsule_authenticate(const void *capsule,
  * @fw_name:		Name of the firmware image
  * @image_index:	Image Index, same as value passed to SetImage FMP
  *                      function
+ * @dfu_alt_num:	DFU alt setting number for this image. Only consulted
+ *                      by a platform's efi_firmware_get_dfu_alt_num()
+ *                      override
  */
 struct efi_fw_image {
 	efi_guid_t image_type_id;
 	u16 *fw_name;
 	u8 image_index;
+	u8 dfu_alt_num;
 };
 
 /**
@@ -1240,6 +1244,19 @@ efi_status_t efi_ecpt_register(void);
 efi_status_t efi_esrt_populate(void);
 efi_status_t efi_load_capsule_drivers(void);
 
+/**
+ * efi_firmware_get_dfu_alt_num() - get the DFU alt setting number for an image
+ * @image_index:	image index
+ *
+ * Return the DFU alt setting number to use when writing the image
+ * identified by @image_index. Weak default derives it positionally as
+ * (image_index - 1); a platform whose fw_images[] is not laid out 1:1 with
+ * DFU alt numbers should override this function.
+ *
+ * Return:		DFU alt setting number
+ */
+u8 efi_firmware_get_dfu_alt_num(u8 image_index);
+
 efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz);
 
 efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type,
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index b41969c70fd..c7339412055 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -80,6 +80,22 @@ efi_guid_t *efi_firmware_get_image_type_id(u8 image_index)
 	return NULL;
 }
 
+/**
+ * efi_firmware_get_dfu_alt_num - get the DFU alt setting number for an image
+ * @image_index:	image index
+ *
+ * Return the DFU alt setting number to use when writing the image
+ * identified by @image_index. The generic default derives it positionally
+ * from @image_index; a platform whose fw_images[] is not laid out 1:1 with
+ * DFU alt numbers should override this function.
+ *
+ * Return:		DFU alt setting number
+ */
+u8 __weak efi_firmware_get_dfu_alt_num(u8 image_index)
+{
+	return image_index - 1;
+}
+
 /* Place holder; not supported */
 static
 efi_status_t EFIAPI efi_firmware_get_image_unsupported(
@@ -768,9 +784,10 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
 	/*
 	 * dfu_alt_num is assigned from 0 while image_index starts from 1.
 	 * dfu_alt_num is calculated by (image_index - 1) when multi bank update
-	 * is not used.
+	 * is not used. A platform may override efi_firmware_get_dfu_alt_num()
+	 * if its fw_images[] is not laid out 1:1 with DFU alt numbers.
 	 */
-	dfu_alt_num = image_index - 1;
+	dfu_alt_num = efi_firmware_get_dfu_alt_num(image_index);
 	if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
 		/*
 		 * Based on the value of update bank, derive the

-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.