From: Takahiro Akashi <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [RFC PATCH 4/4] qemu: arm64: Add support for efi firmware management protocol routines
Date: Tue, 31 Mar 2020 14:50:47 +0900 [thread overview]
Message-ID: <20200331055045.GL11504@linaro.org> (raw)
In-Reply-To: <20200323071201.5992-5-sughosh.ganu@linaro.org>
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
>
next prev parent reply other threads:[~2020-03-31 5:50 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2020-03-23 12:11 ` [RFC PATCH 0/4] qemu: arm64: Add support for uefi " Heinrich Schuchardt
2020-03-24 3:55 ` Sughosh Ganu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200331055045.GL11504@linaro.org \
--to=takahiro.akashi@linaro.org \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.