[v4,07/14] efi_loader: Add logic to parse EDKII specific fmp payload header

Message ID 20201230135712.5289-8-sughosh.ganu@linaro.org
State Accepted
Commit 675b62e12f9db639bd5ebcfd6c68b46d66a46a3c
Headers show
Series
  • qemu: arm64: Add support for uefi capsule update on qemu arm platform
Related show

Commit Message

Sughosh Ganu Dec. 30, 2020, 1:57 p.m.
When building the capsule using scripts in edk2, a fmp header is
added on top of the binary payload. Add logic to detect presence of
the header. When present, the pointer to the image needs to be
adjusted as per the size of the header to point to the actual binary
payload.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>

---

Changes since V3: None

 lib/efi_loader/efi_firmware.c | 41 +++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

-- 
2.17.1

Patch

diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 72c560dbc2..5d2ecde2f1 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -11,8 +11,30 @@ 
 #include <dfu.h>
 #include <efi_loader.h>
 #include <image.h>
+#include <signatures.h>
+
 #include <linux/list.h>
 
+#define FMP_PAYLOAD_HDR_SIGNATURE	SIGNATURE_32('M', 'S', 'S', '1')
+
+/**
+ * struct fmp_payload_header - EDK2 header for the FMP payload
+ *
+ * This structure describes the header which is preprended to the
+ * FMP payload by the edk2 capsule generation scripts.
+ *
+ * @signature:			Header signature used to identify the header
+ * @header_size:		Size of the structure
+ * @fw_version:			Firmware versions used
+ * @lowest_supported_version:	Lowest supported version
+ */
+struct fmp_payload_header {
+	u32 signature;
+	u32 header_size;
+	u32 fw_version;
+	u32 lowest_supported_version;
+};
+
 /* Place holder; not supported */
 static
 efi_status_t EFIAPI efi_firmware_get_image_unsupported(
@@ -379,12 +401,31 @@  efi_status_t EFIAPI efi_firmware_raw_set_image(
 	efi_status_t (*progress)(efi_uintn_t completion),
 	u16 **abort_reason)
 {
+	u32 fmp_hdr_signature;
+	struct fmp_payload_header *header;
+
 	EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image,
 		  image_size, vendor_code, progress, abort_reason);
 
 	if (!image)
 		return EFI_EXIT(EFI_INVALID_PARAMETER);
 
+	fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE;
+	header = (void *)image;
+
+	if (!memcmp(&header->signature, &fmp_hdr_signature,
+		    sizeof(fmp_hdr_signature))) {
+		/*
+		 * When building the capsule with the scripts in
+		 * edk2, a FMP header is inserted above the capsule
+		 * payload. Compensate for this header to get the
+		 * actual payload that is to be updated.
+		 */
+		image += header->header_size;
+		image_size -= header->header_size;
+
+	}
+
 	if (dfu_write_by_alt(image_index - 1, (void *)image, image_size,
 			     NULL, NULL))
 		return EFI_EXIT(EFI_DEVICE_ERROR);