All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines
@ 2020-03-23  7:11 Sughosh Ganu
  2020-03-23  7:11 ` [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk Sughosh Ganu
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Sughosh Ganu @ 2020-03-23  7:11 UTC (permalink / raw)
  To: u-boot

This series is based on the capsule update rfc series sent by Takahiro
Akashi[1].

These routines have been tested on the qemu arm64 platform for
updating the u-boot firmware through the capsule-on-disk functionality
of the uefi spec. A sub-command has been added under the 'efidebug
capsule' category of commands for initiating the firmware update.

The capsule file is placed on the efi system partition(esp), under the
EFI/UpdateCapsule directory. The BootNext and BootXXXX variables are
set accordingly by using the 'efidebug boot add' command.

The capsule update can then be initiated by the following command
'efidebug capsule disk-update'.

The feature can be enabled through the following config options
CONFIG_EFI_CAPSULE_UPDATE=y
CONFIG_EFI_CAPSULE_ON_DISK=y
CONFIG_EFI_CAPSULE_UPDATE_FIRMWARE=y
CONFIG_EFI_FIRMWARE_MANAGEMENT_PROTOCOL=y
CONFIG_CMD_EFIDEBUG=y

The GenerateCapsule.py script in edk2 has been used to generate the
capsule file.

Todo
* Capsule authentication support.
* Implement firmware version support.
* Invoke capsule update functionality during platform boot. This might
  be taken up by Takahiro.

[1] - https://lists.denx.de/pipermail/u-boot/2020-March/403038.html

Sughosh Ganu (4):
  efidebug: capsule: Add a command to update capsule on disk
  semihosting: Change semihosting file operation functions into global
    symbols
  semihosting: Add support for writing to a file
  qemu: arm64: Add support for efi firmware management protocol routines

 arch/arm/lib/semihosting.c              |  48 ++++++-
 board/emulation/qemu-arm/Kconfig        |  12 ++
 board/emulation/qemu-arm/Makefile       |   1 +
 board/emulation/qemu-arm/qemu_efi_fmp.c | 173 ++++++++++++++++++++++++
 cmd/efidebug.c                          |  14 ++
 include/semihosting.h                   |  14 ++
 6 files changed, 257 insertions(+), 5 deletions(-)
 create mode 100644 board/emulation/qemu-arm/qemu_efi_fmp.c
 create mode 100644 include/semihosting.h

-- 
2.17.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk
  2020-03-23  7:11 [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines Sughosh Ganu
@ 2020-03-23  7:11 ` Sughosh Ganu
  2020-03-23 11:50   ` Heinrich Schuchardt
  2020-03-23  7:11 ` [RFC PATCH 2/4] semihosting: Change semihosting file operation functions into global symbols Sughosh Ganu
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Sughosh Ganu @ 2020-03-23  7:11 UTC (permalink / raw)
  To: u-boot

Add a efidebug subcommand to initiate a firmware update using the efi
firmware management protocol(fmp) set_image routine.

The firmware update can be initiated through

'efidebug capsule disk-update'

This would locate the efi capsule file on the efi system partition,
and call the platform's set_image fmp routine to initiate the firmware
update.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
 cmd/efidebug.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 4a7661d0ac..fd8366dc90 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -77,6 +77,16 @@ static int do_efi_capsule_update(cmd_tbl_t *cmdtp, int flag,
 	return CMD_RET_SUCCESS;
 }
 
+static int do_efi_capsule_on_disk_update(cmd_tbl_t *cmdtp, int flag,
+					 int argc, char * const argv[])
+{
+	efi_status_t ret;
+
+	ret = efi_launch_capsules();
+
+	return ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+
 /**
  * do_efi_capsule_show() - show capsule information
  *
@@ -205,6 +215,8 @@ static cmd_tbl_t cmd_efidebug_capsule_sub[] = {
 			 "", ""),
 	U_BOOT_CMD_MKENT(show, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_show,
 			 "", ""),
+	U_BOOT_CMD_MKENT(disk-update, 0, 0, do_efi_capsule_on_disk_update,
+			 "", ""),
 	U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res,
 			 "", ""),
 };
@@ -1387,6 +1399,8 @@ static char efidebug_help_text[] =
 #ifdef CONFIG_EFI_CAPSULE_UPDATE
 	"efidebug capsule update [-v] <capsule address>\n"
 	"  - process a capsule\n"
+	"efidebug capsule disk-update\n"
+	"  - update a capsule from disk\n"
 	"efidebug capsule show <capsule address>\n"
 	"  - show capsule information\n"
 	"efidebug capsule result [<capsule result var>]\n"
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 2/4] semihosting: Change semihosting file operation functions into global symbols
  2020-03-23  7:11 [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines Sughosh Ganu
  2020-03-23  7:11 ` [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk Sughosh Ganu
@ 2020-03-23  7:11 ` Sughosh Ganu
  2020-03-23  7:12 ` [RFC PATCH 3/4] semihosting: Add support for writing to a file Sughosh Ganu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Sughosh Ganu @ 2020-03-23  7:11 UTC (permalink / raw)
  To: u-boot

Change the semihosting file operation functions into external symbols
so that they can be called from outside the file. These functions
would be required to be called for implementing firmware update
functionality for the qemu arm64 platform.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
 arch/arm/lib/semihosting.c |  7 ++++---
 include/semihosting.h      | 13 +++++++++++++
 2 files changed, 17 insertions(+), 3 deletions(-)
 create mode 100644 include/semihosting.h

diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c
index 2658026cf4..3aeda1303a 100644
--- a/arch/arm/lib/semihosting.c
+++ b/arch/arm/lib/semihosting.c
@@ -13,6 +13,7 @@
  */
 #include <common.h>
 #include <command.h>
+#include <semihosting.h>
 
 #define SYSOPEN		0x01
 #define SYSCLOSE	0x02
@@ -43,7 +44,7 @@ static noinline long smh_trap(unsigned int sysnum, void *addr)
  * Open a file on the host. Mode is "r" or "rb" currently. Returns a file
  * descriptor or -1 on error.
  */
-static long smh_open(const char *fname, char *modestr)
+long smh_open(const char *fname, char *modestr)
 {
 	long fd;
 	unsigned long mode;
@@ -82,7 +83,7 @@ static long smh_open(const char *fname, char *modestr)
 /*
  * Read 'len' bytes of file into 'memp'. Returns 0 on success, else failure
  */
-static long smh_read(long fd, void *memp, size_t len)
+long smh_read(long fd, void *memp, size_t len)
 {
 	long ret;
 	struct smh_read_s {
@@ -116,7 +117,7 @@ static long smh_read(long fd, void *memp, size_t len)
 /*
  * Close the file using the file descriptor
  */
-static long smh_close(long fd)
+long smh_close(long fd)
 {
 	long ret;
 
diff --git a/include/semihosting.h b/include/semihosting.h
new file mode 100644
index 0000000000..f1bf419275
--- /dev/null
+++ b/include/semihosting.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020, Linaro Limited
+ */
+
+#if !defined _SEMIHOSTING_H_
+#define _SEMIHOSTING_H_
+
+long smh_open(const char *fname, char *modestr);
+long smh_read(long fd, void *memp, size_t len);
+long smh_close(long fd);
+
+#endif /* _SEMIHOSTING_H_ */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 3/4] semihosting: Add support for writing to a file
  2020-03-23  7:11 [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines Sughosh Ganu
  2020-03-23  7:11 ` [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk Sughosh Ganu
  2020-03-23  7:11 ` [RFC PATCH 2/4] semihosting: Change semihosting file operation functions into global symbols Sughosh Ganu
@ 2020-03-23  7:12 ` Sughosh Ganu
  2020-03-23  7:12 ` [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines Sughosh Ganu
  2020-03-23 12:11 ` [RFC PATCH 0/4] qemu: arm64: Add support for uefi " Heinrich Schuchardt
  4 siblings, 0 replies; 11+ messages in thread
From: Sughosh Ganu @ 2020-03-23  7:12 UTC (permalink / raw)
  To: u-boot

Add a function to enable writing to a file. Currently, support is
added for writing to a binary file. This would be used for
implementing the firmware update functionality for the qemu arm64
platform.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
 arch/arm/lib/semihosting.c | 41 ++++++++++++++++++++++++++++++++++++--
 include/semihosting.h      |  1 +
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c
index 3aeda1303a..08181132d1 100644
--- a/arch/arm/lib/semihosting.c
+++ b/arch/arm/lib/semihosting.c
@@ -17,11 +17,18 @@
 
 #define SYSOPEN		0x01
 #define SYSCLOSE	0x02
+#define SYSWRITE	0x5
 #define SYSREAD		0x06
 #define SYSFLEN		0x0C
 
-#define MODE_READ	0x0
-#define MODE_READBIN	0x1
+#define MODE_READ		0x0
+#define MODE_READBIN		0x1
+#define MODE_READPLUS		0x2
+#define MODE_READPLUSBIN	0x3
+#define MODE_WRITE		0x4
+#define MODE_WRITEBIN		0x5
+#define MODE_WRITEPLUS		0x6
+#define MODE_WRITEPLUSBIN	0x7
 
 /*
  * Call the handler
@@ -61,6 +68,8 @@ long smh_open(const char *fname, char *modestr)
 		mode = MODE_READ;
 	} else if (!(strcmp(modestr, "rb"))) {
 		mode = MODE_READBIN;
+	} else if (!strcmp(modestr, "w+b")) {
+		mode = MODE_WRITEPLUSBIN;
 	} else {
 		printf("%s: ERROR mode \'%s\' not supported\n", __func__,
 		       modestr);
@@ -114,6 +123,34 @@ long smh_read(long fd, void *memp, size_t len)
 	return 0;
 }
 
+/*
+ * Write 'len' bytes into the file referenced by the fd. Returns 0 on success, else
+ * a negavite value for failure
+ */
+long smh_write(long fd, void *memp, size_t len)
+{
+	long ret;
+	struct smh_write_s {
+		long fd;
+		void *memp;
+		size_t len;
+	} write;
+
+	debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len);
+
+	write.fd = fd;
+	write.memp = memp;
+	write.len = len;
+
+	ret = smh_trap(SYSWRITE, &write);
+
+	if (ret > 0)
+		printf("%s: ERROR ret %ld, fd %ld, len %zu, memp %p\n",
+		       __func__, ret, fd, len, memp);
+
+	return ret == 0 ? 0 : -1;
+}
+
 /*
  * Close the file using the file descriptor
  */
diff --git a/include/semihosting.h b/include/semihosting.h
index f1bf419275..fa5cecddf2 100644
--- a/include/semihosting.h
+++ b/include/semihosting.h
@@ -8,6 +8,7 @@
 
 long smh_open(const char *fname, char *modestr);
 long smh_read(long fd, void *memp, size_t len);
+long smh_write(long fd, void *memp, size_t len);
 long smh_close(long fd);
 
 #endif /* _SEMIHOSTING_H_ */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines
  2020-03-23  7:11 [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines Sughosh Ganu
                   ` (2 preceding siblings ...)
  2020-03-23  7:12 ` [RFC PATCH 3/4] semihosting: Add support for writing to a file Sughosh Ganu
@ 2020-03-23  7:12 ` Sughosh Ganu
  2020-03-31  5:50   ` Takahiro Akashi
  2020-03-23 12:11 ` [RFC PATCH 0/4] qemu: arm64: Add support for uefi " Heinrich Schuchardt
  4 siblings, 1 reply; 11+ messages in thread
From: Sughosh Ganu @ 2020-03-23  7:12 UTC (permalink / raw)
  To: u-boot

Add support for the get_image_info and set_image routines, which are
part of the efi firmware management protocol.

The current implementation uses the set_image routine for updating the
u-boot binary image for the qemu arm64 platform. This is supported
using the capsule-on-disk feature of the uefi specification, wherein
the firmware image to be updated is placed on the efi system partition
as a efi capsule under EFI/UpdateCapsule/ directory.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
---
 board/emulation/qemu-arm/Kconfig        |  12 ++
 board/emulation/qemu-arm/Makefile       |   1 +
 board/emulation/qemu-arm/qemu_efi_fmp.c | 173 ++++++++++++++++++++++++
 3 files changed, 186 insertions(+)
 create mode 100644 board/emulation/qemu-arm/qemu_efi_fmp.c

diff --git a/board/emulation/qemu-arm/Kconfig b/board/emulation/qemu-arm/Kconfig
index 02ae4d9884..1ef2a27539 100644
--- a/board/emulation/qemu-arm/Kconfig
+++ b/board/emulation/qemu-arm/Kconfig
@@ -11,3 +11,15 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	imply VIRTIO_BLK
 
 endif
+
+if TARGET_QEMU_ARM_64BIT
+
+config EFI_FIRMWARE_MANAGEMENT_PROTOCOL
+	bool "EFI Firmware Management protocol for Qemu arm64 platform"
+	depends on EFI_CAPSULE_UPDATE && EFI_CAPSULE_UPDATE_FIRMWARE
+	default n
+	help
+	  Select this option for enabling firmware management protocol
+	  for qemu arm64 platform
+
+endif
diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile
index a22d1237ff..c95ac6d233 100644
--- a/board/emulation/qemu-arm/Makefile
+++ b/board/emulation/qemu-arm/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 obj-y	+= qemu-arm.o
+obj-$(CONFIG_EFI_FIRMWARE_MANAGEMENT_PROTOCOL) += qemu_efi_fmp.o
diff --git a/board/emulation/qemu-arm/qemu_efi_fmp.c b/board/emulation/qemu-arm/qemu_efi_fmp.c
new file mode 100644
index 0000000000..17caa59786
--- /dev/null
+++ b/board/emulation/qemu-arm/qemu_efi_fmp.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2020, Linaro Limited
+ */
+
+#include <common.h>
+#include <charset.h>
+#include <efi_api.h>
+#include <efi_loader.h>
+#include <malloc.h>
+#include <semihosting.h>
+
+#define QEMU_UBOOT_IMAGE_INDEX	0x1
+#define QEMU_UBOOT_IMAGE	0x1
+
+#define UBOOT_FILE		"bl33.bin"
+
+static efi_status_t EFIAPI qemu_arm64_fmp_get_image_info(
+	struct efi_firmware_management_protocol *this,
+	efi_uintn_t *image_info_size,
+	struct efi_firmware_image_descriptor *image_info,
+	u32 *desc_version, u8 *desc_count,
+	efi_uintn_t *desc_size, u32 *package_version,
+	u16 **package_version_name)
+{
+	efi_status_t status = EFI_SUCCESS;
+	u16 *image_id_name;
+	const char *image_name = "Qemu Aarch64 U-Boot";
+	const efi_guid_t image_guid = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
+
+	EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, image_info_size,
+		  image_info, desc_version, desc_count, desc_size,
+		  package_version, package_version_name);
+
+	/* Sanity checks */
+	if (*image_info_size && !image_info) {
+		status = EFI_INVALID_PARAMETER;
+		goto back;
+	}
+
+	if (*image_info_size &&
+	    (!desc_version || !desc_count || !desc_size)) {
+		status = EFI_INVALID_PARAMETER;
+		goto back;
+	}
+
+	if (*image_info_size && (!package_version || !package_version_name)) {
+		status = EFI_INVALID_PARAMETER;
+		goto back;
+	}
+
+	if (*image_info_size < sizeof(*image_info)) {
+		*image_info_size = sizeof(*image_info);
+		status = EFI_BUFFER_TOO_SMALL;
+		goto back;
+	}
+
+	if (desc_version)
+		*desc_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
+
+	*desc_count = 0x1;
+	*desc_size = sizeof(*image_info);
+
+	if (package_version)
+		*package_version = 0xffffffff;
+
+	if (package_version_name)
+		*package_version_name = NULL;
+
+	image_info[0].image_type_id = image_guid;
+	image_info[0].image_id = QEMU_UBOOT_IMAGE;
+
+	image_id_name = malloc(40);
+	utf8_utf16_strcpy(&image_id_name, image_name);
+	image_info[0].image_id_name = image_id_name;
+
+	/* Todo: Get a mechanism to store version information */
+	image_info[0]. version = 0x1;
+	image_info[0].version_name = NULL;
+
+	/* Todo: Need to find a mechanism to get the image size */
+	image_info[0].size = 0;
+
+	image_info[0].attributes_supported =
+		EFI_IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+	image_info[0].attributes_setting = EFI_IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+
+	image_info[0].lowest_supported_image_version = 1;
+	image_info[0].last_attempt_version = 0;
+	image_info[0].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
+	image_info[0].hardware_instance = 0;
+
+back:
+	return EFI_EXIT(status);
+}
+
+static efi_status_t EFIAPI qemu_arm64_fmp_set_image(
+	struct efi_firmware_management_protocol *this,
+	u8 image_index, const void *image,
+	efi_uintn_t image_size, const void *vendor_code,
+	efi_status_t (*progress)(efi_uintn_t completion),
+	u16 **abort_reason)
+{
+	long fd, ret;
+	efi_status_t status = EFI_SUCCESS;
+	char *mode = "w+b";
+
+	EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image,
+		  image_size, vendor_code, progress, abort_reason);
+
+	/*
+	 * Put a hack here to offset the size of
+	 * the FMP_PAYLOAD_HEADER that gets added
+	 * by the GenerateCapsule script in edk2.
+	 */
+	image += 0x10;
+	image_size -= 0x10;
+
+	/* Do all the sanity checks first */
+	if (!image) {
+		status = EFI_INVALID_PARAMETER;
+		goto back;
+	}
+
+	if (image_size == 0) {
+		status = EFI_INVALID_PARAMETER;
+		goto back;
+	}
+
+	if (image_index != QEMU_UBOOT_IMAGE_INDEX) {
+		status = EFI_INVALID_PARAMETER;
+		goto back;
+	}
+
+	/* Do the update */
+	fd = smh_open(UBOOT_FILE, mode);
+	if (fd == -1) {
+		printf("%s: Unable to open the firmware image for writing\n",
+		       __func__);
+		status = EFI_DEVICE_ERROR;
+		goto back;
+	}
+
+	ret = smh_write(fd, (void *)image, image_size);
+	if (ret == -1) {
+		printf("%s: Error writing to the firmware image!", __func__);
+		smh_close(fd);
+		status = EFI_DEVICE_ERROR;
+		goto back;
+	}
+
+	printf("%s: Done writing the firmware image file\n", __func__);
+	smh_close(fd);
+back:
+	return EFI_EXIT(status);
+}
+
+const struct efi_firmware_management_protocol efi_qemu_arm64_fmp = {
+	.get_image_info = qemu_arm64_fmp_get_image_info,
+	.set_image = qemu_arm64_fmp_set_image,
+};
+
+efi_status_t arch_efi_load_capsule_drivers(void)
+{
+	efi_status_t ret;
+
+	ret = EFI_CALL(efi_install_multiple_protocol_interfaces(&efi_root,
+					&efi_guid_firmware_management_protocol,
+					&efi_qemu_arm64_fmp,
+					NULL));
+
+	return ret;
+}
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk
  2020-03-23  7:11 ` [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk Sughosh Ganu
@ 2020-03-23 11:50   ` Heinrich Schuchardt
  2020-03-24  3:49     ` Sughosh Ganu
  0 siblings, 1 reply; 11+ messages in thread
From: Heinrich Schuchardt @ 2020-03-23 11:50 UTC (permalink / raw)
  To: u-boot

On 3/23/20 8:11 AM, Sughosh Ganu wrote:
> Add a efidebug subcommand to initiate a firmware update using the efi
> firmware management protocol(fmp) set_image routine.
>
> The firmware update can be initiated through
>
> 'efidebug capsule disk-update'
>
> This would locate the efi capsule file on the efi system partition,
> and call the platform's set_image fmp routine to initiate the firmware
> update.

Hello Sughosh,

why do we need this command? Shouldn't a simple reset do the job?

See chapter 8.5.5 "Delivery of Capsules via file on Mass Storage device"
of UEFI spec 2.8.

What might be of interest is a command to start a capsule from a memory
location. This would allow to load capsules from other locations than
directory \EFI\UpdateCapsule.

Best regards

Heinrich

>
> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> ---
>  cmd/efidebug.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> index 4a7661d0ac..fd8366dc90 100644
> --- a/cmd/efidebug.c
> +++ b/cmd/efidebug.c
> @@ -77,6 +77,16 @@ static int do_efi_capsule_update(cmd_tbl_t *cmdtp, int flag,
>  	return CMD_RET_SUCCESS;
>  }
>
> +static int do_efi_capsule_on_disk_update(cmd_tbl_t *cmdtp, int flag,
> +					 int argc, char * const argv[])
> +{
> +	efi_status_t ret;
> +
> +	ret = efi_launch_capsules();
> +
> +	return ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
> +}
> +
>  /**
>   * do_efi_capsule_show() - show capsule information
>   *
> @@ -205,6 +215,8 @@ static cmd_tbl_t cmd_efidebug_capsule_sub[] = {
>  			 "", ""),
>  	U_BOOT_CMD_MKENT(show, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_show,
>  			 "", ""),
> +	U_BOOT_CMD_MKENT(disk-update, 0, 0, do_efi_capsule_on_disk_update,
> +			 "", ""),
>  	U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res,
>  			 "", ""),
>  };
> @@ -1387,6 +1399,8 @@ static char efidebug_help_text[] =
>  #ifdef CONFIG_EFI_CAPSULE_UPDATE
>  	"efidebug capsule update [-v] <capsule address>\n"
>  	"  - process a capsule\n"
> +	"efidebug capsule disk-update\n"
> +	"  - update a capsule from disk\n"
>  	"efidebug capsule show <capsule address>\n"
>  	"  - show capsule information\n"
>  	"efidebug capsule result [<capsule result var>]\n"
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines
  2020-03-23  7:11 [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines Sughosh Ganu
                   ` (3 preceding siblings ...)
  2020-03-23  7:12 ` [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines Sughosh Ganu
@ 2020-03-23 12:11 ` Heinrich Schuchardt
  2020-03-24  3:55   ` Sughosh Ganu
  4 siblings, 1 reply; 11+ messages in thread
From: Heinrich Schuchardt @ 2020-03-23 12:11 UTC (permalink / raw)
  To: u-boot

On 3/23/20 8:11 AM, Sughosh Ganu wrote:
> This series is based on the capsule update rfc series sent by Takahiro
> Akashi[1].
>
> These routines have been tested on the qemu arm64 platform for
> updating the u-boot firmware through the capsule-on-disk functionality
> of the uefi spec. A sub-command has been added under the 'efidebug
> capsule' category of commands for initiating the firmware update.
>
> The capsule file is placed on the efi system partition(esp), under the
> EFI/UpdateCapsule directory. The BootNext and BootXXXX variables are
> set accordingly by using the 'efidebug boot add' command.
>
> The capsule update can then be initiated by the following command
> 'efidebug capsule disk-update'.

Thanks you for your work on capsule updates.

I am missing here an overview description of the system setup.

I saw a filename bl33.bin. So assume I that you want to use ATF?
In how far is ATF needed for testing the capsule update?

Please, mention the use of semihosting in the overview.

Best regards

Heinrich

>
> The feature can be enabled through the following config options
> CONFIG_EFI_CAPSULE_UPDATE=y
> CONFIG_EFI_CAPSULE_ON_DISK=y
> CONFIG_EFI_CAPSULE_UPDATE_FIRMWARE=y
> CONFIG_EFI_FIRMWARE_MANAGEMENT_PROTOCOL=y
> CONFIG_CMD_EFIDEBUG=y
>
> The GenerateCapsule.py script in edk2 has been used to generate the
> capsule file.
>
> Todo
> * Capsule authentication support.
> * Implement firmware version support.
> * Invoke capsule update functionality during platform boot. This might
>   be taken up by Takahiro.
>
> [1] - https://lists.denx.de/pipermail/u-boot/2020-March/403038.html
>
> Sughosh Ganu (4):
>   efidebug: capsule: Add a command to update capsule on disk
>   semihosting: Change semihosting file operation functions into global
>     symbols
>   semihosting: Add support for writing to a file
>   qemu: arm64: Add support for efi firmware management protocol routines
>
>  arch/arm/lib/semihosting.c              |  48 ++++++-
>  board/emulation/qemu-arm/Kconfig        |  12 ++
>  board/emulation/qemu-arm/Makefile       |   1 +
>  board/emulation/qemu-arm/qemu_efi_fmp.c | 173 ++++++++++++++++++++++++
>  cmd/efidebug.c                          |  14 ++
>  include/semihosting.h                   |  14 ++
>  6 files changed, 257 insertions(+), 5 deletions(-)
>  create mode 100644 board/emulation/qemu-arm/qemu_efi_fmp.c
>  create mode 100644 include/semihosting.h
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk
  2020-03-23 11:50   ` Heinrich Schuchardt
@ 2020-03-24  3:49     ` Sughosh Ganu
  2020-03-31  3:25       ` Takahiro Akashi
  0 siblings, 1 reply; 11+ messages in thread
From: Sughosh Ganu @ 2020-03-24  3:49 UTC (permalink / raw)
  To: u-boot

On Mon, 23 Mar 2020 at 17:20, Heinrich Schuchardt <xypron.glpk@gmx.de>
wrote:

> On 3/23/20 8:11 AM, Sughosh Ganu wrote:
> > Add a efidebug subcommand to initiate a firmware update using the efi
> > firmware management protocol(fmp) set_image routine.
> >
> > The firmware update can be initiated through
> >
> > 'efidebug capsule disk-update'
> >
> > This would locate the efi capsule file on the efi system partition,
> > and call the platform's set_image fmp routine to initiate the firmware
> > update.
>
> Hello Sughosh,
>
> why do we need this command? Shouldn't a simple reset do the job?
>
> See chapter 8.5.5 "Delivery of Capsules via file on Mass Storage device"
> of UEFI spec 2.8.
>

Like i have mentioned in the cover letter, we need to invoke
capsule-on-disk update during the platform boot -- that is on the Todo
list. The spec requires setting the
EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED flag in the
OsIndications variable. But we would not be supporting that, at least for
now, since we do not have support of runtime variables on our platforms.
The idea is to invoke a capsule-on-disk update during the platform boot. I
think Takahiro will be working on this.


>
> What might be of interest is a command to start a capsule from a memory
> location. This would allow to load capsules from other locations than
> directory \EFI\UpdateCapsule.
>

Takahiro has indeed added this command which updates a capsule which has
been loaded into the memory. I thought it might be easier to invoke a
command where the user is not required to load the capsule into memory
first, but that is taken care of directly by the capsule update logic. That
said, I can drop the patch if you prefer just having the version which
updates the capsule from memory.

-sughosh


>
> Best regards
>
> Heinrich
>
> >
> > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> > ---
> >  cmd/efidebug.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> >
> > diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> > index 4a7661d0ac..fd8366dc90 100644
> > --- a/cmd/efidebug.c
> > +++ b/cmd/efidebug.c
> > @@ -77,6 +77,16 @@ static int do_efi_capsule_update(cmd_tbl_t *cmdtp,
> int flag,
> >       return CMD_RET_SUCCESS;
> >  }
> >
> > +static int do_efi_capsule_on_disk_update(cmd_tbl_t *cmdtp, int flag,
> > +                                      int argc, char * const argv[])
> > +{
> > +     efi_status_t ret;
> > +
> > +     ret = efi_launch_capsules();
> > +
> > +     return ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
> > +}
> > +
> >  /**
> >   * do_efi_capsule_show() - show capsule information
> >   *
> > @@ -205,6 +215,8 @@ static cmd_tbl_t cmd_efidebug_capsule_sub[] = {
> >                        "", ""),
> >       U_BOOT_CMD_MKENT(show, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_show,
> >                        "", ""),
> > +     U_BOOT_CMD_MKENT(disk-update, 0, 0, do_efi_capsule_on_disk_update,
> > +                      "", ""),
> >       U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res,
> >                        "", ""),
> >  };
> > @@ -1387,6 +1399,8 @@ static char efidebug_help_text[] =
> >  #ifdef CONFIG_EFI_CAPSULE_UPDATE
> >       "efidebug capsule update [-v] <capsule address>\n"
> >       "  - process a capsule\n"
> > +     "efidebug capsule disk-update\n"
> > +     "  - update a capsule from disk\n"
> >       "efidebug capsule show <capsule address>\n"
> >       "  - show capsule information\n"
> >       "efidebug capsule result [<capsule result var>]\n"
> >
>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines
  2020-03-23 12:11 ` [RFC PATCH 0/4] qemu: arm64: Add support for uefi " Heinrich Schuchardt
@ 2020-03-24  3:55   ` Sughosh Ganu
  0 siblings, 0 replies; 11+ messages in thread
From: Sughosh Ganu @ 2020-03-24  3:55 UTC (permalink / raw)
  To: u-boot

On Mon, 23 Mar 2020 at 17:41, Heinrich Schuchardt <xypron.glpk@gmx.de>
wrote:

> On 3/23/20 8:11 AM, Sughosh Ganu wrote:
> > This series is based on the capsule update rfc series sent by Takahiro
> > Akashi[1].
> >
> > These routines have been tested on the qemu arm64 platform for
> > updating the u-boot firmware through the capsule-on-disk functionality
> > of the uefi spec. A sub-command has been added under the 'efidebug
> > capsule' category of commands for initiating the firmware update.
> >
> > The capsule file is placed on the efi system partition(esp), under the
> > EFI/UpdateCapsule directory. The BootNext and BootXXXX variables are
> > set accordingly by using the 'efidebug boot add' command.
> >
> > The capsule update can then be initiated by the following command
> > 'efidebug capsule disk-update'.
>
> Thanks you for your work on capsule updates.
>
> I am missing here an overview description of the system setup.
>
> I saw a filename bl33.bin. So assume I that you want to use ATF?
> In how far is ATF needed for testing the capsule update?
>
> Please, mention the use of semihosting in the overview.
>

Thanks for looking into this. I will add description of my system setup in
the next version. I think i will wait for Takahiro to send his next version
of capsule update changes. Will base my next version on top of that.
Meanwhile, it would be great if you can review all the patches in the
series, so that I can incorporate any review comments in my next version.

-sughosh


>
> Best regards
>
> Heinrich
>
> >
> > The feature can be enabled through the following config options
> > CONFIG_EFI_CAPSULE_UPDATE=y
> > CONFIG_EFI_CAPSULE_ON_DISK=y
> > CONFIG_EFI_CAPSULE_UPDATE_FIRMWARE=y
> > CONFIG_EFI_FIRMWARE_MANAGEMENT_PROTOCOL=y
> > CONFIG_CMD_EFIDEBUG=y
> >
> > The GenerateCapsule.py script in edk2 has been used to generate the
> > capsule file.
> >
> > Todo
> > * Capsule authentication support.
> > * Implement firmware version support.
> > * Invoke capsule update functionality during platform boot. This might
> >   be taken up by Takahiro.
> >
> > [1] - https://lists.denx.de/pipermail/u-boot/2020-March/403038.html
> >
> > Sughosh Ganu (4):
> >   efidebug: capsule: Add a command to update capsule on disk
> >   semihosting: Change semihosting file operation functions into global
> >     symbols
> >   semihosting: Add support for writing to a file
> >   qemu: arm64: Add support for efi firmware management protocol routines
> >
> >  arch/arm/lib/semihosting.c              |  48 ++++++-
> >  board/emulation/qemu-arm/Kconfig        |  12 ++
> >  board/emulation/qemu-arm/Makefile       |   1 +
> >  board/emulation/qemu-arm/qemu_efi_fmp.c | 173 ++++++++++++++++++++++++
> >  cmd/efidebug.c                          |  14 ++
> >  include/semihosting.h                   |  14 ++
> >  6 files changed, 257 insertions(+), 5 deletions(-)
> >  create mode 100644 board/emulation/qemu-arm/qemu_efi_fmp.c
> >  create mode 100644 include/semihosting.h
> >
>
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk
  2020-03-24  3:49     ` Sughosh Ganu
@ 2020-03-31  3:25       ` Takahiro Akashi
  0 siblings, 0 replies; 11+ messages in thread
From: Takahiro Akashi @ 2020-03-31  3:25 UTC (permalink / raw)
  To: u-boot

On Tue, Mar 24, 2020 at 09:19:55AM +0530, Sughosh Ganu wrote:
> On Mon, 23 Mar 2020 at 17:20, Heinrich Schuchardt <xypron.glpk@gmx.de>
> wrote:
> 
> > On 3/23/20 8:11 AM, Sughosh Ganu wrote:
> > > Add a efidebug subcommand to initiate a firmware update using the efi
> > > firmware management protocol(fmp) set_image routine.
> > >
> > > The firmware update can be initiated through
> > >
> > > 'efidebug capsule disk-update'
> > >
> > > This would locate the efi capsule file on the efi system partition,
> > > and call the platform's set_image fmp routine to initiate the firmware
> > > update.
> >
> > Hello Sughosh,
> >
> > why do we need this command? Shouldn't a simple reset do the job?
> >
> > See chapter 8.5.5 "Delivery of Capsules via file on Mass Storage device"
> > of UEFI spec 2.8.
> >
> 
> Like i have mentioned in the cover letter, we need to invoke
> capsule-on-disk update during the platform boot -- that is on the Todo
> list. The spec requires setting the
> EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED flag in the
> OsIndications variable. But we would not be supporting that, at least for
> now, since we do not have support of runtime variables on our platforms.
> The idea is to invoke a capsule-on-disk update during the platform boot. I
> think Takahiro will be working on this.

To be strict,
under my current implementation, all the capsule files under
\EFI\UpdateCapsule will be applied only at the first time when
any of UEFI-related commands is invoked.
This is the way how the UEFI subsystem is initialized on U-Boot.

I mentioned this in my cover letter, and how we should comply
with UEFI specification and meet users' expectation is a point
of discussion as RFC. 

UpdateCapsule API is provided, but it is more or less an internal
function in the current form so as to directly initiate capsule
handling. It currently ignores CAPSULE_FLAGS_PERSIST_ACROSS_RESET
and CAPSULE_FLAGS_INITIATE_RESET in a capsule.
(I mentioned this in TODO list.)

> 
> >
> > What might be of interest is a command to start a capsule from a memory
> > location. This would allow to load capsules from other locations than
> > directory \EFI\UpdateCapsule.
> >
> 
> Takahiro has indeed added this command which updates a capsule which has
> been loaded into the memory. I thought it might be easier to invoke a
> command where the user is not required to load the capsule into memory
> first, but that is taken care of directly by the capsule update logic. That
> said, I can drop the patch if you prefer just having the version which
> updates the capsule from memory.

"efidebug capsule" command, like other subcommands of efidebug,
is a tool mainly for test/debug purpose.
Keep the functionality in the command won't bother anyone
in that sense.

-Takahiro Akashi


> -sughosh
> 
> 
> >
> > Best regards
> >
> > Heinrich
> >
> > >
> > > Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> > > ---
> > >  cmd/efidebug.c | 14 ++++++++++++++
> > >  1 file changed, 14 insertions(+)
> > >
> > > diff --git a/cmd/efidebug.c b/cmd/efidebug.c
> > > index 4a7661d0ac..fd8366dc90 100644
> > > --- a/cmd/efidebug.c
> > > +++ b/cmd/efidebug.c
> > > @@ -77,6 +77,16 @@ static int do_efi_capsule_update(cmd_tbl_t *cmdtp,
> > int flag,
> > >       return CMD_RET_SUCCESS;
> > >  }
> > >
> > > +static int do_efi_capsule_on_disk_update(cmd_tbl_t *cmdtp, int flag,
> > > +                                      int argc, char * const argv[])
> > > +{
> > > +     efi_status_t ret;
> > > +
> > > +     ret = efi_launch_capsules();
> > > +
> > > +     return ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
> > > +}
> > > +
> > >  /**
> > >   * do_efi_capsule_show() - show capsule information
> > >   *
> > > @@ -205,6 +215,8 @@ static cmd_tbl_t cmd_efidebug_capsule_sub[] = {
> > >                        "", ""),
> > >       U_BOOT_CMD_MKENT(show, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_show,
> > >                        "", ""),
> > > +     U_BOOT_CMD_MKENT(disk-update, 0, 0, do_efi_capsule_on_disk_update,
> > > +                      "", ""),
> > >       U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res,
> > >                        "", ""),
> > >  };
> > > @@ -1387,6 +1399,8 @@ static char efidebug_help_text[] =
> > >  #ifdef CONFIG_EFI_CAPSULE_UPDATE
> > >       "efidebug capsule update [-v] <capsule address>\n"
> > >       "  - process a capsule\n"
> > > +     "efidebug capsule disk-update\n"
> > > +     "  - update a capsule from disk\n"
> > >       "efidebug capsule show <capsule address>\n"
> > >       "  - show capsule information\n"
> > >       "efidebug capsule result [<capsule result var>]\n"
> > >
> >
> >

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines
  2020-03-23  7:12 ` [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines Sughosh Ganu
@ 2020-03-31  5:50   ` Takahiro Akashi
  0 siblings, 0 replies; 11+ messages in thread
From: Takahiro Akashi @ 2020-03-31  5:50 UTC (permalink / raw)
  To: u-boot

Sughosh,

On Mon, Mar 23, 2020 at 12:42:01PM +0530, Sughosh Ganu wrote:
> Add support for the get_image_info and set_image routines, which are
> part of the efi firmware management protocol.
> 
> The current implementation uses the set_image routine for updating the
> u-boot binary image for the qemu arm64 platform. This is supported
> using the capsule-on-disk feature of the uefi specification, wherein
> the firmware image to be updated is placed on the efi system partition
> as a efi capsule under EFI/UpdateCapsule/ directory.
> 
> Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
> ---
>  board/emulation/qemu-arm/Kconfig        |  12 ++
>  board/emulation/qemu-arm/Makefile       |   1 +
>  board/emulation/qemu-arm/qemu_efi_fmp.c | 173 ++++++++++++++++++++++++
>  3 files changed, 186 insertions(+)
>  create mode 100644 board/emulation/qemu-arm/qemu_efi_fmp.c
> 
> diff --git a/board/emulation/qemu-arm/Kconfig b/board/emulation/qemu-arm/Kconfig
> index 02ae4d9884..1ef2a27539 100644
> --- a/board/emulation/qemu-arm/Kconfig
> +++ b/board/emulation/qemu-arm/Kconfig
> @@ -11,3 +11,15 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>  	imply VIRTIO_BLK
>  
>  endif
> +
> +if TARGET_QEMU_ARM_64BIT
> +
> +config EFI_FIRMWARE_MANAGEMENT_PROTOCOL

I think that we should give it a qemu-specific configuration name
as there can co-exist multiple drivers of FMP at the same time.

> +	bool "EFI Firmware Management protocol for Qemu arm64 platform"
> +	depends on EFI_CAPSULE_UPDATE && EFI_CAPSULE_UPDATE_FIRMWARE

Please add a dependency on SEMIHOSTING with some description.

> +	default n
> +	help
> +	  Select this option for enabling firmware management protocol
> +	  for qemu arm64 platform
> +
> +endif
> diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile
> index a22d1237ff..c95ac6d233 100644
> --- a/board/emulation/qemu-arm/Makefile
> +++ b/board/emulation/qemu-arm/Makefile
> @@ -1,3 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0+
>  
>  obj-y	+= qemu-arm.o
> +obj-$(CONFIG_EFI_FIRMWARE_MANAGEMENT_PROTOCOL) += qemu_efi_fmp.o
> diff --git a/board/emulation/qemu-arm/qemu_efi_fmp.c b/board/emulation/qemu-arm/qemu_efi_fmp.c
> new file mode 100644
> index 0000000000..17caa59786
> --- /dev/null
> +++ b/board/emulation/qemu-arm/qemu_efi_fmp.c
> @@ -0,0 +1,173 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2020, Linaro Limited
> + */
> +
> +#include <common.h>
> +#include <charset.h>
> +#include <efi_api.h>
> +#include <efi_loader.h>
> +#include <malloc.h>
> +#include <semihosting.h>
> +
> +#define QEMU_UBOOT_IMAGE_INDEX	0x1
> +#define QEMU_UBOOT_IMAGE	0x1
> +
> +#define UBOOT_FILE		"bl33.bin"

It would be better to parameterize this file name as
a configuration option so as to make this solution more generic
for TFA-based and non-TFA-based system.

-Takahiro Akashi

> +static efi_status_t EFIAPI qemu_arm64_fmp_get_image_info(
> +	struct efi_firmware_management_protocol *this,
> +	efi_uintn_t *image_info_size,
> +	struct efi_firmware_image_descriptor *image_info,
> +	u32 *desc_version, u8 *desc_count,
> +	efi_uintn_t *desc_size, u32 *package_version,
> +	u16 **package_version_name)
> +{
> +	efi_status_t status = EFI_SUCCESS;
> +	u16 *image_id_name;
> +	const char *image_name = "Qemu Aarch64 U-Boot";
> +	const efi_guid_t image_guid = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
> +
> +	EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, image_info_size,
> +		  image_info, desc_version, desc_count, desc_size,
> +		  package_version, package_version_name);
> +
> +	/* Sanity checks */
> +	if (*image_info_size && !image_info) {
> +		status = EFI_INVALID_PARAMETER;
> +		goto back;
> +	}
> +
> +	if (*image_info_size &&
> +	    (!desc_version || !desc_count || !desc_size)) {
> +		status = EFI_INVALID_PARAMETER;
> +		goto back;
> +	}
> +
> +	if (*image_info_size && (!package_version || !package_version_name)) {
> +		status = EFI_INVALID_PARAMETER;
> +		goto back;
> +	}
> +
> +	if (*image_info_size < sizeof(*image_info)) {
> +		*image_info_size = sizeof(*image_info);
> +		status = EFI_BUFFER_TOO_SMALL;
> +		goto back;
> +	}
> +
> +	if (desc_version)
> +		*desc_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
> +
> +	*desc_count = 0x1;
> +	*desc_size = sizeof(*image_info);
> +
> +	if (package_version)
> +		*package_version = 0xffffffff;
> +
> +	if (package_version_name)
> +		*package_version_name = NULL;
> +
> +	image_info[0].image_type_id = image_guid;
> +	image_info[0].image_id = QEMU_UBOOT_IMAGE;
> +
> +	image_id_name = malloc(40);
> +	utf8_utf16_strcpy(&image_id_name, image_name);
> +	image_info[0].image_id_name = image_id_name;
> +
> +	/* Todo: Get a mechanism to store version information */
> +	image_info[0]. version = 0x1;
> +	image_info[0].version_name = NULL;
> +
> +	/* Todo: Need to find a mechanism to get the image size */
> +	image_info[0].size = 0;
> +
> +	image_info[0].attributes_supported =
> +		EFI_IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
> +	image_info[0].attributes_setting = EFI_IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
> +
> +	image_info[0].lowest_supported_image_version = 1;
> +	image_info[0].last_attempt_version = 0;
> +	image_info[0].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
> +	image_info[0].hardware_instance = 0;
> +
> +back:
> +	return EFI_EXIT(status);
> +}
> +
> +static efi_status_t EFIAPI qemu_arm64_fmp_set_image(
> +	struct efi_firmware_management_protocol *this,
> +	u8 image_index, const void *image,
> +	efi_uintn_t image_size, const void *vendor_code,
> +	efi_status_t (*progress)(efi_uintn_t completion),
> +	u16 **abort_reason)
> +{
> +	long fd, ret;
> +	efi_status_t status = EFI_SUCCESS;
> +	char *mode = "w+b";
> +
> +	EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image,
> +		  image_size, vendor_code, progress, abort_reason);
> +
> +	/*
> +	 * Put a hack here to offset the size of
> +	 * the FMP_PAYLOAD_HEADER that gets added
> +	 * by the GenerateCapsule script in edk2.
> +	 */
> +	image += 0x10;
> +	image_size -= 0x10;
> +
> +	/* Do all the sanity checks first */
> +	if (!image) {
> +		status = EFI_INVALID_PARAMETER;
> +		goto back;
> +	}
> +
> +	if (image_size == 0) {
> +		status = EFI_INVALID_PARAMETER;
> +		goto back;
> +	}
> +
> +	if (image_index != QEMU_UBOOT_IMAGE_INDEX) {
> +		status = EFI_INVALID_PARAMETER;
> +		goto back;
> +	}
> +
> +	/* Do the update */
> +	fd = smh_open(UBOOT_FILE, mode);
> +	if (fd == -1) {
> +		printf("%s: Unable to open the firmware image for writing\n",
> +		       __func__);
> +		status = EFI_DEVICE_ERROR;
> +		goto back;
> +	}
> +
> +	ret = smh_write(fd, (void *)image, image_size);
> +	if (ret == -1) {
> +		printf("%s: Error writing to the firmware image!", __func__);
> +		smh_close(fd);
> +		status = EFI_DEVICE_ERROR;
> +		goto back;
> +	}
> +
> +	printf("%s: Done writing the firmware image file\n", __func__);
> +	smh_close(fd);
> +back:
> +	return EFI_EXIT(status);
> +}
> +
> +const struct efi_firmware_management_protocol efi_qemu_arm64_fmp = {
> +	.get_image_info = qemu_arm64_fmp_get_image_info,
> +	.set_image = qemu_arm64_fmp_set_image,
> +};
> +
> +efi_status_t arch_efi_load_capsule_drivers(void)
> +{
> +	efi_status_t ret;
> +
> +	ret = EFI_CALL(efi_install_multiple_protocol_interfaces(&efi_root,
> +					&efi_guid_firmware_management_protocol,
> +					&efi_qemu_arm64_fmp,
> +					NULL));
> +
> +	return ret;
> +}
> -- 
> 2.17.1
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-03-31  5:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-23  7:11 [RFC PATCH 0/4] qemu: arm64: Add support for uefi firmware management protocol routines Sughosh Ganu
2020-03-23  7:11 ` [RFC PATCH 1/4] efidebug: capsule: Add a command to update capsule on disk Sughosh Ganu
2020-03-23 11:50   ` Heinrich Schuchardt
2020-03-24  3:49     ` Sughosh Ganu
2020-03-31  3:25       ` Takahiro Akashi
2020-03-23  7:11 ` [RFC PATCH 2/4] semihosting: Change semihosting file operation functions into global symbols Sughosh Ganu
2020-03-23  7:12 ` [RFC PATCH 3/4] semihosting: Add support for writing to a file Sughosh Ganu
2020-03-23  7:12 ` [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines Sughosh Ganu
2020-03-31  5:50   ` Takahiro Akashi
2020-03-23 12:11 ` [RFC PATCH 0/4] qemu: arm64: Add support for uefi " Heinrich Schuchardt
2020-03-24  3:55   ` Sughosh Ganu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.