aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-01-14 09:34:14 -0500
committerTom Rini <trini@konsulko.com>2024-01-14 09:34:14 -0500
commit817fdce324cac70fb4216ba42976f7b9c2ba9f99 (patch)
treeb603968cc2de846e26382fd9e52945abf2391526
parent547d3dd28a46a18d59e00a153c8becca8d4e8cf9 (diff)
parent55125bbfb48cb1330a692059bc972810f77b984a (diff)
downloadu-boot-WIP/14Jan2024.zip
u-boot-WIP/14Jan2024.tar.gz
u-boot-WIP/14Jan2024.tar.bz2
Merge tag 'efi-2024-04-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/14Jan2024
Pull request efi-2024-04-rc1 Documentation: * update coreboot graphics documentation * fix '---' rendering UEFI: * add missing pointer check after memory allocation in efidebug * replace duplicate functions efi_dp_append and efi_dp_concat * support fmp versioning for multi bank update * avoid using dm_scan_other() in EFI app
-rw-r--r--cmd/eficonfig.c7
-rw-r--r--cmd/efidebug.c10
-rw-r--r--configs/efi-x86_app64_defconfig1
-rw-r--r--doc/board/coreboot/coreboot.rst13
-rw-r--r--doc/develop/sending_patches.rst4
-rw-r--r--include/efi_loader.h5
-rw-r--r--include/fwu.h13
-rw-r--r--lib/efi/Makefile2
-rw-r--r--lib/efi/efi_app.c187
-rw-r--r--lib/efi/efi_app_init.c205
-rw-r--r--lib/efi_loader/efi_bootmgr.c6
-rw-r--r--lib/efi_loader/efi_boottime.c2
-rw-r--r--lib/efi_loader/efi_device_path.c70
-rw-r--r--lib/efi_loader/efi_device_path_utilities.c2
-rw-r--r--lib/efi_loader/efi_disk.c15
-rw-r--r--lib/efi_loader/efi_esrt.c18
-rw-r--r--lib/efi_loader/efi_firmware.c86
-rw-r--r--lib/fwu_updates/fwu.c32
-rw-r--r--tools/patman/patman.rst2
19 files changed, 356 insertions, 324 deletions
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 34a59cb..8234e60 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -531,7 +531,7 @@ struct efi_device_path *eficonfig_create_device_path(struct efi_device_path *dp_
dp = efi_dp_shorten(dp_volume);
if (!dp)
dp = dp_volume;
- dp = efi_dp_append(dp, &fp->dp);
+ dp = efi_dp_concat(dp, &fp->dp, false);
free(buf);
return dp;
@@ -1484,7 +1484,8 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
ret = EFI_OUT_OF_RESOURCES;
goto out;
}
- initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp, dp);
+ initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp,
+ dp, false);
efi_free_pool(dp);
}
@@ -1495,7 +1496,7 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
}
final_dp_size = efi_dp_size(dp) + sizeof(END);
if (initrd_dp) {
- final_dp = efi_dp_concat(dp, initrd_dp);
+ final_dp = efi_dp_concat(dp, initrd_dp, true);
final_dp_size += efi_dp_size(initrd_dp) + sizeof(END);
} else {
final_dp = efi_dp_dup(dp);
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index e10fbf8..aa85237 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -699,8 +699,8 @@ struct efi_device_path *create_initrd_dp(const char *dev, const char *part,
if (!short_fp)
short_fp = tmp_fp;
- initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp,
- short_fp);
+ initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp,
+ short_fp, false);
out:
efi_free_pool(tmp_dp);
@@ -754,6 +754,10 @@ static int efi_boot_add_uri(int argc, char *const argv[], u16 *var_name16,
uridp_len = sizeof(struct efi_device_path) + strlen(argv[3]) + 1;
uridp = efi_alloc(uridp_len + sizeof(END));
+ if (!uridp) {
+ log_err("Out of memory\n");
+ return CMD_RET_FAILURE;
+ }
uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI;
uridp->dp.length = uridp_len;
@@ -916,7 +920,7 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
goto out;
}
- final_fp = efi_dp_concat(file_path, initrd_dp);
+ final_fp = efi_dp_concat(file_path, initrd_dp, true);
if (!final_fp) {
printf("Cannot create final device path\n");
r = CMD_RET_FAILURE;
diff --git a/configs/efi-x86_app64_defconfig b/configs/efi-x86_app64_defconfig
index ceaebc7..3d02148 100644
--- a/configs/efi-x86_app64_defconfig
+++ b/configs/efi-x86_app64_defconfig
@@ -18,6 +18,7 @@ CONFIG_BOOTCOMMAND="ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000"
CONFIG_SYS_PBSIZE=532
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_PART=y
diff --git a/doc/board/coreboot/coreboot.rst b/doc/board/coreboot/coreboot.rst
index 10a251c..7154f59 100644
--- a/doc/board/coreboot/coreboot.rst
+++ b/doc/board/coreboot/coreboot.rst
@@ -32,10 +32,9 @@ of _x86boot_start (in arch/x86/cpu/start.S).
If you want to use ELF as the coreboot payload, change U-Boot configuration to
use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE.
-To enable video you must enable these options in coreboot:
+To enable video you must enable CONFIG_GENERIC_LINEAR_FRAMEBUFFER in coreboot:
- - Set framebuffer graphics resolution (1280x1024 32k-color (1:5:5))
- - Keep VESA framebuffer
+ - Devices->Display->Framebuffer mode->Linear "high resolution" framebuffer
At present it seems that for Minnowboard Max, coreboot does not pass through
the video information correctly (it always says the resolution is 0x0). This
@@ -184,13 +183,13 @@ boot as a coreboot payload, based on a known-good build of coreboot.
To update the `coreboot.rom` file which is used:
-#. Build coreboot with `CONFIG_LINEAR_FRAMEBUFFER=y`. If using `make menuconfig`
- this is under
- `Devices ->Display->Framebuffer mode->Linear "high resolution" framebuffer`.
+#. Build coreboot with `CONFIG_GENERIC_LINEAR_FRAMEBUFFER=y`. If using
+ `make menuconfig`, this is under
+ `Devices->Display->Framebuffer mode->Linear "high resolution" framebuffer`.
#. Compress the resulting `coreboot.rom`::
- xz -c /path/to/coreboot/build/coreboot.rom >coreboot.rom.xz
+ xz -c /path/to/coreboot/build/coreboot.rom > coreboot.rom.xz
#. Upload the file to Google drive
diff --git a/doc/develop/sending_patches.rst b/doc/develop/sending_patches.rst
index 5a6962f..3f25b1d 100644
--- a/doc/develop/sending_patches.rst
+++ b/doc/develop/sending_patches.rst
@@ -121,7 +121,7 @@ General Patch Submission Rules
* For new features: a description of the feature and your implementation.
* Additional comments which you don't want included in U-Boot's history can be
- included below the first "---" in the message body.
+ included below the first "``---``" in the message body.
* If your description gets too long, that's a strong indication that you should
split up your patch.
@@ -253,7 +253,7 @@ to observe the following rules.
* Please make sure to keep a "change log", i.e. a description of what you have
changed compared to previous versions of this patch. This change log should
- be added below the "---" line in the patch, which starts the "comment
+ be added below the "``---``" line in the patch, which starts the "comment
section", i.e. which contains text that does not get included into the
actual commit message.
Note: it is *not* sufficient to provide a change log in some cover letter
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 34e7fbb..d372504 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -819,8 +819,6 @@ efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp);
/* size of multi-instance device path excluding end node */
efi_uintn_t efi_dp_size(const struct efi_device_path *dp);
struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp);
-struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1,
- const struct efi_device_path *dp2);
struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
const struct efi_device_path *node);
/* Create a device path node of given type, sub-type, length */
@@ -937,7 +935,8 @@ struct efi_load_option {
struct efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
const efi_guid_t *guid);
struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
- const struct efi_device_path *dp2);
+ const struct efi_device_path *dp2,
+ bool split_end_node);
struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path);
efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data,
efi_uintn_t *size);
diff --git a/include/fwu.h b/include/fwu.h
index ac5c5de..eb5638f 100644
--- a/include/fwu.h
+++ b/include/fwu.h
@@ -122,21 +122,18 @@ int fwu_get_active_index(uint *active_idxp);
int fwu_set_active_index(uint active_idx);
/**
- * fwu_get_image_index() - Get the Image Index to be used for capsule update
- * @image_index: The Image Index for the image
- *
- * The FWU multi bank update feature computes the value of image_index at
- * runtime, based on the bank to which the image needs to be written to.
- * Derive the image_index value for the image.
+ * fwu_get_dfu_alt_num() - Get the dfu_alt_num to be used for capsule update
+ * @image_index: The Image Index for the image
+ * @alt_num: pointer to store dfu_alt_num
*
* Currently, the capsule update driver uses the DFU framework for
* the updates. This function gets the DFU alt number which is to
- * be used as the Image Index
+ * be used for capsule update.
*
* Return: 0 if OK, -ve on error
*
*/
-int fwu_get_image_index(u8 *image_index);
+int fwu_get_dfu_alt_num(u8 image_index, u8 *alt_num);
/**
* fwu_revert_boot_index() - Revert the active index in the FWU metadata
diff --git a/lib/efi/Makefile b/lib/efi/Makefile
index a790d2d..232fa68 100644
--- a/lib/efi/Makefile
+++ b/lib/efi/Makefile
@@ -2,7 +2,7 @@
#
# (C) Copyright 2015 Google, Inc
-obj-$(CONFIG_EFI_APP) += efi_app.o efi.o
+obj-$(CONFIG_EFI_APP) += efi_app.o efi.o efi_app_init.o
obj-$(CONFIG_EFI_STUB) += efi_info.o
CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
index 119db66..88332c3 100644
--- a/lib/efi/efi_app.c
+++ b/lib/efi/efi_app.c
@@ -67,49 +67,6 @@ int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp,
return 0;
}
-/**
- * efi_bind_block() - bind a new block device to an EFI device
- *
- * Binds a new top-level EFI_MEDIA device as well as a child block device so
- * that the block device can be accessed in U-Boot.
- *
- * The device can then be accessed using 'part list efi 0', 'fat ls efi 0:1',
- * for example, just like any other interface type.
- *
- * @handle: handle of the controller on which this driver is installed
- * @blkio: block io protocol proxied by this driver
- * @device_path: EFI device path structure for this
- * @len: Length of @device_path in bytes
- * @devp: Returns the bound device
- * Return: 0 if OK, -ve on error
- */
-int efi_bind_block(efi_handle_t handle, struct efi_block_io *blkio,
- struct efi_device_path *device_path, int len,
- struct udevice **devp)
-{
- struct efi_media_plat plat;
- struct udevice *dev;
- char name[18];
- int ret;
-
- plat.handle = handle;
- plat.blkio = blkio;
- plat.device_path = malloc(device_path->length);
- if (!plat.device_path)
- return log_msg_ret("path", -ENOMEM);
- memcpy(plat.device_path, device_path, device_path->length);
- ret = device_bind(dm_root(), DM_DRIVER_GET(efi_media), "efi_media",
- &plat, ofnode_null(), &dev);
- if (ret)
- return log_msg_ret("bind", ret);
-
- snprintf(name, sizeof(name), "efi_media_%x", dev_seq(dev));
- device_set_name(dev, name);
- *devp = dev;
-
- return 0;
-}
-
static efi_status_t setup_memory(struct efi_priv *priv)
{
struct efi_boot_services *boot = priv->boot;
@@ -178,150 +135,6 @@ static void free_memory(struct efi_priv *priv)
global_data_ptr = NULL;
}
-/**
- * devpath_is_partition() - Figure out if a device path is a partition
- *
- * Checks if a device path refers to a partition on some media device. This
- * works by checking for a valid partition number in a hard-driver media device
- * as the final component of the device path.
- *
- * @path: device path
- * Return: true if a partition, false if not
- * (e.g. it might be media which contains partitions)
- */
-static bool devpath_is_partition(const struct efi_device_path *path)
-{
- const struct efi_device_path *p;
- bool was_part = false;
-
- for (p = path; p->type != DEVICE_PATH_TYPE_END;
- p = (void *)p + p->length) {
- was_part = false;
- if (p->type == DEVICE_PATH_TYPE_MEDIA_DEVICE &&
- p->sub_type == DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH) {
- struct efi_device_path_hard_drive_path *hd =
- (void *)path;
-
- if (hd->partition_number)
- was_part = true;
- }
- }
-
- return was_part;
-}
-
-/**
- * setup_block() - Find all block devices and setup EFI devices for them
- *
- * Partitions are ignored, since U-Boot has partition handling. Errors with
- * particular devices produce a warning but execution continues to try to
- * find others.
- *
- * Return: 0 if found, -ENOSYS if there is no boot-services table, -ENOTSUPP
- * if a required protocol is not supported
- */
-static int setup_block(void)
-{
- efi_guid_t efi_blkio_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
- efi_guid_t efi_devpath_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
- efi_guid_t efi_pathutil_guid = EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
- efi_guid_t efi_pathtext_guid = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
- struct efi_boot_services *boot = efi_get_boot();
- struct efi_device_path_utilities_protocol *util;
- struct efi_device_path_to_text_protocol *text;
- struct efi_device_path *path;
- struct efi_block_io *blkio;
- efi_uintn_t num_handles;
- efi_handle_t *handle;
- int ret, i;
-
- if (!boot)
- return log_msg_ret("sys", -ENOSYS);
-
- /* Find all devices which support the block I/O protocol */
- ret = boot->locate_handle_buffer(BY_PROTOCOL, &efi_blkio_guid, NULL,
- &num_handles, &handle);
- if (ret)
- return log_msg_ret("loc", -ENOTSUPP);
- log_debug("Found %d handles:\n", (int)num_handles);
-
- /* We need to look up the path size and convert it to text */
- ret = boot->locate_protocol(&efi_pathutil_guid, NULL, (void **)&util);
- if (ret)
- return log_msg_ret("util", -ENOTSUPP);
- ret = boot->locate_protocol(&efi_pathtext_guid, NULL, (void **)&text);
- if (ret)
- return log_msg_ret("text", -ENOTSUPP);
-
- for (i = 0; i < num_handles; i++) {
- struct udevice *dev;
- const u16 *name;
- bool is_part;
- int len;
-
- ret = boot->handle_protocol(handle[i], &efi_devpath_guid,
- (void **)&path);
- if (ret) {
- log_warning("- devpath %d failed (ret=%d)\n", i, ret);
- continue;
- }
-
- ret = boot->handle_protocol(handle[i], &efi_blkio_guid,
- (void **)&blkio);
- if (ret) {
- log_warning("- blkio %d failed (ret=%d)\n", i, ret);
- continue;
- }
-
- name = text->convert_device_path_to_text(path, true, false);
- is_part = devpath_is_partition(path);
-
- if (!is_part) {
- len = util->get_device_path_size(path);
- ret = efi_bind_block(handle[i], blkio, path, len, &dev);
- if (ret) {
- log_warning("- blkio bind %d failed (ret=%d)\n",
- i, ret);
- continue;
- }
- } else {
- dev = NULL;
- }
-
- /*
- * Show the device name if we created one. Otherwise indicate
- * that it is a partition.
- */
- printf("%2d: %-12s %ls\n", i, dev ? dev->name : "<partition>",
- name);
- }
- boot->free_pool(handle);
-
- return 0;
-}
-
-/**
- * dm_scan_other() - Scan for UEFI devices that should be available to U-Boot
- *
- * This sets up block devices within U-Boot for those found in UEFI. With this,
- * U-Boot can access those devices
- *
- * @pre_reloc_only: true to only bind pre-relocation devices (ignored)
- * Returns: 0 on success, -ve on error
- */
-int dm_scan_other(bool pre_reloc_only)
-{
- if (gd->flags & GD_FLG_RELOC) {
- int ret;
-
- ret = setup_block();
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
static void scan_tables(struct efi_system_table *sys_table)
{
efi_guid_t acpi = EFI_ACPI_TABLE_GUID;
diff --git a/lib/efi/efi_app_init.c b/lib/efi/efi_app_init.c
new file mode 100644
index 0000000..c5e4192
--- /dev/null
+++ b/lib/efi/efi_app_init.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * EFI-app board implementation
+ *
+ * Copyright 2023 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <dm.h>
+#include <efi.h>
+#include <efi_api.h>
+#include <errno.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <dm/device-internal.h>
+#include <dm/root.h>
+#include <linux/types.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * efi_bind_block() - bind a new block device to an EFI device
+ *
+ * Binds a new top-level EFI_MEDIA device as well as a child block device so
+ * that the block device can be accessed in U-Boot.
+ *
+ * The device can then be accessed using 'part list efi 0', 'fat ls efi 0:1',
+ * for example, just like any other interface type.
+ *
+ * @handle: handle of the controller on which this driver is installed
+ * @blkio: block io protocol proxied by this driver
+ * @device_path: EFI device path structure for this
+ * @len: Length of @device_path in bytes
+ * @devp: Returns the bound device
+ * Return: 0 if OK, -ve on error
+ */
+int efi_bind_block(efi_handle_t handle, struct efi_block_io *blkio,
+ struct efi_device_path *device_path, int len,
+ struct udevice **devp)
+{
+ struct efi_media_plat plat;
+ struct udevice *dev;
+ char name[18];
+ int ret;
+
+ plat.handle = handle;
+ plat.blkio = blkio;
+ plat.device_path = malloc(device_path->length);
+ if (!plat.device_path)
+ return log_msg_ret("path", -ENOMEM);
+ memcpy(plat.device_path, device_path, device_path->length);
+ ret = device_bind(dm_root(), DM_DRIVER_GET(efi_media), "efi_media",
+ &plat, ofnode_null(), &dev);
+ if (ret)
+ return log_msg_ret("bind", ret);
+
+ snprintf(name, sizeof(name), "efi_media_%x", dev_seq(dev));
+ device_set_name(dev, name);
+ *devp = dev;
+
+ return 0;
+}
+
+/**
+ * devpath_is_partition() - Figure out if a device path is a partition
+ *
+ * Checks if a device path refers to a partition on some media device. This
+ * works by checking for a valid partition number in a hard-driver media device
+ * as the final component of the device path.
+ *
+ * @path: device path
+ * Return: true if a partition, false if not
+ * (e.g. it might be media which contains partitions)
+ */
+static bool devpath_is_partition(const struct efi_device_path *path)
+{
+ const struct efi_device_path *p;
+ bool was_part = false;
+
+ for (p = path; p->type != DEVICE_PATH_TYPE_END;
+ p = (void *)p + p->length) {
+ was_part = false;
+ if (p->type == DEVICE_PATH_TYPE_MEDIA_DEVICE &&
+ p->sub_type == DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH) {
+ struct efi_device_path_hard_drive_path *hd =
+ (void *)path;
+
+ if (hd->partition_number)
+ was_part = true;
+ }
+ }
+
+ return was_part;
+}
+
+/**
+ * setup_block() - Find all block devices and setup EFI devices for them
+ *
+ * Partitions are ignored, since U-Boot has partition handling. Errors with
+ * particular devices produce a warning but execution continues to try to
+ * find others.
+ *
+ * Return: 0 if found, -ENOSYS if there is no boot-services table, -ENOTSUPP
+ * if a required protocol is not supported
+ */
+static int setup_block(void)
+{
+ efi_guid_t efi_blkio_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
+ efi_guid_t efi_devpath_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ efi_guid_t efi_pathutil_guid = EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
+ efi_guid_t efi_pathtext_guid = EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
+ struct efi_boot_services *boot = efi_get_boot();
+ struct efi_device_path_utilities_protocol *util;
+ struct efi_device_path_to_text_protocol *text;
+ struct efi_device_path *path;
+ struct efi_block_io *blkio;
+ efi_uintn_t num_handles;
+ efi_handle_t *handle;
+ int ret, i;
+
+ if (!boot)
+ return log_msg_ret("sys", -ENOSYS);
+
+ /* Find all devices which support the block I/O protocol */
+ ret = boot->locate_handle_buffer(BY_PROTOCOL, &efi_blkio_guid, NULL,
+ &num_handles, &handle);
+ if (ret)
+ return log_msg_ret("loc", -ENOTSUPP);
+ log_debug("Found %d handles:\n", (int)num_handles);
+
+ /* We need to look up the path size and convert it to text */
+ ret = boot->locate_protocol(&efi_pathutil_guid, NULL, (void **)&util);
+ if (ret)
+ return log_msg_ret("util", -ENOTSUPP);
+ ret = boot->locate_protocol(&efi_pathtext_guid, NULL, (void **)&text);
+ if (ret)
+ return log_msg_ret("text", -ENOTSUPP);
+
+ for (i = 0; i < num_handles; i++) {
+ struct udevice *dev;
+ const u16 *name;
+ bool is_part;
+ int len;
+
+ ret = boot->handle_protocol(handle[i], &efi_devpath_guid,
+ (void **)&path);
+ if (ret) {
+ log_warning("- devpath %d failed (ret=%d)\n", i, ret);
+ continue;
+ }
+
+ ret = boot->handle_protocol(handle[i], &efi_blkio_guid,
+ (void **)&blkio);
+ if (ret) {
+ log_warning("- blkio %d failed (ret=%d)\n", i, ret);
+ continue;
+ }
+
+ name = text->convert_device_path_to_text(path, true, false);
+ is_part = devpath_is_partition(path);
+
+ if (!is_part) {
+ len = util->get_device_path_size(path);
+ ret = efi_bind_block(handle[i], blkio, path, len, &dev);
+ if (ret) {
+ log_warning("- blkio bind %d failed (ret=%d)\n",
+ i, ret);
+ continue;
+ }
+ } else {
+ dev = NULL;
+ }
+
+ /*
+ * Show the device name if we created one. Otherwise indicate
+ * that it is a partition.
+ */
+ printf("%2d: %-12s %ls\n", i, dev ? dev->name : "<partition>",
+ name);
+ }
+ boot->free_pool(handle);
+
+ return 0;
+}
+
+/**
+ * board_early_init_r() - Scan for UEFI devices that should be available
+ *
+ * This sets up block devices within U-Boot for those found in UEFI. With this,
+ * U-Boot can access those devices
+ *
+ * Returns: 0 on success, -ve on error
+ */
+int board_early_init_r(void)
+{
+ if (gd->flags & GD_FLG_RELOC) {
+ int ret;
+
+ ret = setup_block();
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index a032d3a..dd2dd23 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -143,7 +143,7 @@ static efi_status_t try_load_from_file_path(efi_handle_t *fs_handles,
if (!dp)
continue;
- dp = efi_dp_append(dp, fp);
+ dp = efi_dp_concat(dp, fp, false);
if (!dp)
continue;
@@ -1579,8 +1579,8 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
goto out;
msg_path = file_path;
} else {
- file_path = efi_dp_append(bootefi_device_path,
- bootefi_image_path);
+ file_path = efi_dp_concat(bootefi_device_path,
+ bootefi_image_path, false);
msg_path = bootefi_image_path;
log_debug("Loaded from disk\n");
}
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index c579d89..1951291 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1816,7 +1816,7 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
if (device_path) {
info->device_handle = efi_dp_find_obj(device_path, NULL, NULL);
- dp = efi_dp_append(device_path, file_path);
+ dp = efi_dp_concat(device_path, file_path, false);
if (!dp) {
ret = EFI_OUT_OF_RESOURCES;
goto failure;
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 8dbd810..500fa10 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -271,30 +271,27 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
}
/**
- * efi_dp_append_or_concatenate() - Append or concatenate two device paths.
- * Concatenated device path will be separated
- * by a sub-type 0xff end node
+ * efi_dp_concat() - Concatenate two device paths and add and terminate them
+ * with an end node.
*
- * @dp1: First device path
- * @dp2: Second device path
- * @concat: If true the two device paths will be concatenated and separated
- * by an end of entrire device path sub-type 0xff end node.
- * If true the second device path will be appended to the first and
- * terminated by an end node
+ * @dp1: First device path
+ * @dp2: Second device path
+ * @split_end_node: If true the two device paths will be concatenated and
+ * separated by an end node (DEVICE_PATH_SUB_TYPE_END).
+ * If false the second device path will be concatenated to the
+ * first one as-is.
*
* Return:
* concatenated device path or NULL. Caller must free the returned value
*/
-static struct
-efi_device_path *efi_dp_append_or_concatenate(const struct efi_device_path *dp1,
- const struct efi_device_path *dp2,
- bool concat)
+struct
+efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
+ const struct efi_device_path *dp2,
+ bool split_end_node)
{
struct efi_device_path *ret;
- size_t end_size = sizeof(END);
+ size_t end_size;
- if (concat)
- end_size = 2 * sizeof(END);
if (!dp1 && !dp2) {
/* return an end node */
ret = efi_dp_dup(&END);
@@ -306,14 +303,20 @@ efi_device_path *efi_dp_append_or_concatenate(const struct efi_device_path *dp1,
/* both dp1 and dp2 are non-null */
unsigned sz1 = efi_dp_size(dp1);
unsigned sz2 = efi_dp_size(dp2);
- void *p = efi_alloc(sz1 + sz2 + end_size);
+ void *p;
+
+ if (split_end_node)
+ end_size = 2 * sizeof(END);
+ else
+ end_size = sizeof(END);
+ p = efi_alloc(sz1 + sz2 + end_size);
if (!p)
return NULL;
ret = p;
memcpy(p, dp1, sz1);
p += sz1;
- if (concat) {
+ if (split_end_node) {
memcpy(p, &END, sizeof(END));
p += sizeof(END);
}
@@ -327,37 +330,6 @@ efi_device_path *efi_dp_append_or_concatenate(const struct efi_device_path *dp1,
return ret;
}
-/**
- * efi_dp_append() - Append a device to an existing device path.
- *
- * @dp1: First device path
- * @dp2: Second device path
- *
- * Return:
- * concatenated device path or NULL. Caller must free the returned value
- */
-struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1,
- const struct efi_device_path *dp2)
-{
- return efi_dp_append_or_concatenate(dp1, dp2, false);
-}
-
-/**
- * efi_dp_concat() - Concatenate 2 device paths. The final device path will
- * contain two device paths separated by and end node (0xff).
- *
- * @dp1: First device path
- * @dp2: Second device path
- *
- * Return:
- * concatenated device path or NULL. Caller must free the returned value
- */
-struct efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
- const struct efi_device_path *dp2)
-{
- return efi_dp_append_or_concatenate(dp1, dp2, true);
-}
-
struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
const struct efi_device_path *node)
{
diff --git a/lib/efi_loader/efi_device_path_utilities.c b/lib/efi_loader/efi_device_path_utilities.c
index 844d8ac..c95dbfa 100644
--- a/lib/efi_loader/efi_device_path_utilities.c
+++ b/lib/efi_loader/efi_device_path_utilities.c
@@ -76,7 +76,7 @@ static struct efi_device_path * EFIAPI append_device_path(
const struct efi_device_path *src2)
{
EFI_ENTRY("%pD, %pD", src1, src2);
- return EFI_EXIT(efi_dp_append(src1, src2));
+ return EFI_EXIT(efi_dp_concat(src1, src2, false));
}
/*
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index ed99700..013842f 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -31,20 +31,15 @@ const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
*
* @header: EFI object header
* @ops: EFI disk I/O protocol interface
- * @dev_index: device index of block device
* @media: block I/O media information
* @dp: device path to the block device
- * @part: partition
* @volume: simple file system protocol of the partition
- * @dev: associated DM device
*/
struct efi_disk_obj {
struct efi_object header;
struct efi_block_io ops;
- int dev_index;
struct efi_block_io_media media;
struct efi_device_path *dp;
- unsigned int part;
struct efi_simple_file_system_protocol *volume;
};
@@ -382,7 +377,6 @@ static int efi_fs_exists(struct blk_desc *desc, int part)
* @parent: parent handle
* @dp_parent: parent device path
* @desc: internal block device
- * @dev_index: device index for block device
* @part_info: partition info
* @part: partition
* @disk: pointer to receive the created handle
@@ -393,7 +387,6 @@ static efi_status_t efi_disk_add_dev(
efi_handle_t parent,
struct efi_device_path *dp_parent,
struct blk_desc *desc,
- int dev_index,
struct disk_partition *part_info,
unsigned int part,
struct efi_disk_obj **disk,
@@ -455,7 +448,6 @@ static efi_status_t efi_disk_add_dev(
diskobj->dp = efi_dp_from_part(desc, part);
diskobj->media.last_block = desc->lba - 1;
}
- diskobj->part = part;
/*
* Install the device path and the block IO protocol.
@@ -498,7 +490,6 @@ static efi_status_t efi_disk_add_dev(
goto error;
}
diskobj->ops = block_io_disk_template;
- diskobj->dev_index = dev_index;
/* Fill in EFI IO Media info (for read/write callbacks) */
diskobj->media.removable_media = desc->removable;
@@ -518,7 +509,7 @@ static efi_status_t efi_disk_add_dev(
EFI_PRINT("BlockIO: part %u, present %d, logical %d, removable %d"
", last_block %llu\n",
- diskobj->part,
+ part,
diskobj->media.media_present,
diskobj->media.logical_partition,
diskobj->media.removable_media,
@@ -565,7 +556,7 @@ static int efi_disk_create_raw(struct udevice *dev, efi_handle_t agent_handle)
diskid = desc->devnum;
ret = efi_disk_add_dev(NULL, NULL, desc,
- diskid, NULL, 0, &disk, agent_handle);
+ NULL, 0, &disk, agent_handle);
if (ret != EFI_SUCCESS) {
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", dev->name);
@@ -626,7 +617,7 @@ static int efi_disk_create_part(struct udevice *dev, efi_handle_t agent_handle)
return -1;
dp_parent = (struct efi_device_path *)handler->protocol_interface;
- ret = efi_disk_add_dev(parent, dp_parent, desc, diskid,
+ ret = efi_disk_add_dev(parent, dp_parent, desc,
info, part, &disk, agent_handle);
if (ret != EFI_SUCCESS) {
log_err("Adding partition for %s failed\n", dev->name);
diff --git a/lib/efi_loader/efi_esrt.c b/lib/efi_loader/efi_esrt.c
index dafd447..443bd99 100644
--- a/lib/efi_loader/efi_esrt.c
+++ b/lib/efi_loader/efi_esrt.c
@@ -364,7 +364,7 @@ efi_status_t efi_esrt_populate(void)
if (ret != EFI_SUCCESS) {
EFI_PRINT("ESRT Unable to find FMP handle (%u)\n",
idx);
- goto out;
+ continue;
}
fmp = handler->protocol_interface;
@@ -379,15 +379,14 @@ efi_status_t efi_esrt_populate(void)
* fmp->get_image_info to return BUFFER_TO_SMALL.
*/
EFI_PRINT("ESRT erroneous FMP implementation\n");
- ret = EFI_INVALID_PARAMETER;
- goto out;
+ continue;
}
ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, info_size,
(void **)&img_info);
if (ret != EFI_SUCCESS) {
EFI_PRINT("ESRT failed to allocate memory for image info\n");
- goto out;
+ continue;
}
/*
@@ -405,7 +404,7 @@ efi_status_t efi_esrt_populate(void)
if (ret != EFI_SUCCESS) {
EFI_PRINT("ESRT failed to obtain image info from FMP\n");
efi_free_pool(img_info);
- goto out;
+ continue;
}
num_entries += desc_count;
@@ -413,6 +412,13 @@ efi_status_t efi_esrt_populate(void)
efi_free_pool(img_info);
}
+ /* error occurs in fmp->get_image_info() if num_entries is 0 here */
+ if (!num_entries) {
+ EFI_PRINT("Error occurs, num_entries should not be 0\n");
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
EFI_PRINT("ESRT create table with %u entries\n", num_entries);
/*
* Allocate an ESRT with the sufficient number of entries to accommodate
@@ -436,7 +442,7 @@ efi_status_t efi_esrt_populate(void)
if (ret != EFI_SUCCESS) {
EFI_PRINT("ESRT unable to find FMP handle (%u)\n",
idx);
- break;
+ continue;
}
fmp = handler->protocol_interface;
diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c
index 1fde188..9fd1329 100644
--- a/lib/efi_loader/efi_firmware.c
+++ b/lib/efi_loader/efi_firmware.c
@@ -206,18 +206,10 @@ void efi_firmware_fill_version_info(struct efi_firmware_image_descriptor *image_
{
u16 varname[13]; /* u"FmpStateXXXX" */
efi_status_t ret;
- efi_uintn_t size;
- struct fmp_state var_state = { 0 };
-
- efi_create_indexed_name(varname, sizeof(varname), "FmpState",
- fw_array->image_index);
- size = sizeof(var_state);
- ret = efi_get_variable_int(varname, &fw_array->image_type_id,
- NULL, &size, &var_state, NULL);
- if (ret == EFI_SUCCESS)
- image_info->version = var_state.fw_version;
- else
- image_info->version = 0;
+ efi_uintn_t size, expected_size;
+ uint num_banks = 1;
+ uint active_index = 0;
+ struct fmp_state *var_state;
efi_firmware_get_lsv_from_dtb(fw_array->image_index,
&fw_array->image_type_id,
@@ -226,6 +218,31 @@ void efi_firmware_fill_version_info(struct efi_firmware_image_descriptor *image_
image_info->version_name = NULL; /* not supported */
image_info->last_attempt_version = 0;
image_info->last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS;
+ image_info->version = 0;
+
+ /* get the fw_version */
+ efi_create_indexed_name(varname, sizeof(varname), "FmpState",
+ fw_array->image_index);
+ if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
+ ret = fwu_get_active_index(&active_index);
+ if (ret)
+ return;
+
+ num_banks = CONFIG_FWU_NUM_BANKS;
+ }
+
+ size = num_banks * sizeof(*var_state);
+ expected_size = size;
+ var_state = calloc(1, size);
+ if (!var_state)
+ return;
+
+ ret = efi_get_variable_int(varname, &fw_array->image_type_id,
+ NULL, &size, var_state, NULL);
+ if (ret == EFI_SUCCESS && expected_size == size)
+ image_info->version = var_state[active_index].fw_version;
+
+ free(var_state);
}
/**
@@ -361,8 +378,11 @@ efi_status_t efi_firmware_set_fmp_state_var(struct fmp_state *state, u8 image_in
{
u16 varname[13]; /* u"FmpStateXXXX" */
efi_status_t ret;
+ uint num_banks = 1;
+ uint update_bank = 0;
+ efi_uintn_t size;
efi_guid_t *image_type_id;
- struct fmp_state var_state = { 0 };
+ struct fmp_state *var_state;
image_type_id = efi_firmware_get_image_type_id(image_index);
if (!image_type_id)
@@ -371,19 +391,44 @@ efi_status_t efi_firmware_set_fmp_state_var(struct fmp_state *state, u8 image_in
efi_create_indexed_name(varname, sizeof(varname), "FmpState",
image_index);
+ if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
+ ret = fwu_plat_get_update_index(&update_bank);
+ if (ret)
+ return EFI_INVALID_PARAMETER;
+
+ num_banks = CONFIG_FWU_NUM_BANKS;
+ }
+
+ size = num_banks * sizeof(*var_state);
+ var_state = calloc(1, size);
+ if (!var_state)
+ return EFI_OUT_OF_RESOURCES;
+
+ /*
+ * GetVariable may fail, EFI_NOT_FOUND is returned if FmpState
+ * variable has not been set yet.
+ * Ignore the error here since the correct FmpState variable
+ * is set later.
+ */
+ efi_get_variable_int(varname, image_type_id, NULL, &size, var_state,
+ NULL);
+
/*
* Only the fw_version is set here.
* lowest_supported_version in FmpState variable is ignored since
* it can be tampered if the file based EFI variable storage is used.
*/
- var_state.fw_version = state->fw_version;
+ var_state[update_bank].fw_version = state->fw_version;
+ size = num_banks * sizeof(*var_state);
ret = efi_set_variable_int(varname, image_type_id,
EFI_VARIABLE_READ_ONLY |
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof(var_state), &var_state, false);
+ size, var_state, false);
+
+ free(var_state);
return ret;
}
@@ -610,6 +655,7 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
u16 **abort_reason)
{
int ret;
+ u8 dfu_alt_num;
efi_status_t status;
struct fmp_state state = { 0 };
@@ -624,19 +670,25 @@ efi_status_t EFIAPI efi_firmware_raw_set_image(
if (status != EFI_SUCCESS)
return EFI_EXIT(status);
+ /*
+ * 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.
+ */
+ dfu_alt_num = image_index - 1;
if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) {
/*
* Based on the value of update bank, derive the
* image index value.
*/
- ret = fwu_get_image_index(&image_index);
+ ret = fwu_get_dfu_alt_num(image_index, &dfu_alt_num);
if (ret) {
log_debug("Unable to get FWU image_index\n");
return EFI_EXIT(EFI_DEVICE_ERROR);
}
}
- if (dfu_write_by_alt(image_index - 1, (void *)image, image_size,
+ if (dfu_write_by_alt(dfu_alt_num, (void *)image, image_size,
NULL, NULL))
return EFI_EXIT(EFI_DEVICE_ERROR);
diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
index b580574..8651810 100644
--- a/lib/fwu_updates/fwu.c
+++ b/lib/fwu_updates/fwu.c
@@ -125,16 +125,14 @@ static int in_trial_state(struct fwu_mdata *mdata)
return 0;
}
-static int fwu_get_image_type_id(u8 *image_index, efi_guid_t *image_type_id)
+static int fwu_get_image_type_id(u8 image_index, efi_guid_t *image_type_id)
{
- u8 index;
int i;
struct efi_fw_image *image;
- index = *image_index;
image = update_info.images;
for (i = 0; i < update_info.num_images; i++) {
- if (index == image[i].image_index) {
+ if (image_index == image[i].image_index) {
guidcpy(image_type_id, &image[i].image_type_id);
return 0;
}
@@ -332,24 +330,20 @@ int fwu_set_active_index(uint active_idx)
}
/**
- * fwu_get_image_index() - Get the Image Index to be used for capsule update
- * @image_index: The Image Index for the image
- *
- * The FWU multi bank update feature computes the value of image_index at
- * runtime, based on the bank to which the image needs to be written to.
- * Derive the image_index value for the image.
+ * fwu_get_dfu_alt_num() - Get the dfu_alt_num to be used for capsule update
+ * @image_index: The Image Index for the image
+ * @alt_num: pointer to store dfu_alt_num
*
* Currently, the capsule update driver uses the DFU framework for
* the updates. This function gets the DFU alt number which is to
- * be used as the Image Index
+ * be used for capsule update.
*
* Return: 0 if OK, -ve on error
*
*/
-int fwu_get_image_index(u8 *image_index)
+int fwu_get_dfu_alt_num(u8 image_index, u8 *alt_num)
{
int ret, i;
- u8 alt_num;
uint update_bank;
efi_guid_t *image_guid, image_type_id;
struct fwu_mdata *mdata = &g_mdata;
@@ -365,7 +359,7 @@ int fwu_get_image_index(u8 *image_index)
ret = fwu_get_image_type_id(image_index, &image_type_id);
if (ret) {
log_debug("Unable to get image_type_id for image_index %u\n",
- *image_index);
+ image_index);
goto out;
}
@@ -380,15 +374,13 @@ int fwu_get_image_index(u8 *image_index)
img_entry = &mdata->img_entry[i];
img_bank_info = &img_entry->img_bank_info[update_bank];
image_guid = &img_bank_info->image_uuid;
- ret = fwu_plat_get_alt_num(g_dev, image_guid, &alt_num);
- if (ret) {
+ ret = fwu_plat_get_alt_num(g_dev, image_guid, alt_num);
+ if (ret)
log_debug("alt_num not found for partition with GUID %pUs\n",
image_guid);
- } else {
+ else
log_debug("alt_num %d for partition %pUs\n",
- alt_num, image_guid);
- *image_index = alt_num + 1;
- }
+ *alt_num, image_guid);
goto out;
}
diff --git a/tools/patman/patman.rst b/tools/patman/patman.rst
index a8b317e..e013558 100644
--- a/tools/patman/patman.rst
+++ b/tools/patman/patman.rst
@@ -280,7 +280,7 @@ Series-notes:
Commit-notes:
Similar, but for a single commit (patch). These notes will appear
- immediately below the --- cut in the patch file::
+ immediately below the ``---`` cut in the patch file::
Commit-notes:
blah blah