aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-10-07 11:51:05 -0400
committerTom Rini <trini@konsulko.com>2022-10-07 11:51:05 -0400
commit11ef7f07ce60b60fb78c330b3ae35fd1037e50c1 (patch)
treefbbc12ec51fc3651d5fce002ebf38c76621dac8e
parentf5717231abad983b4d8f87db612ae60dec86cb1b (diff)
parenta75e8355eaa561ebd6128c92a90288d5d7c1f060 (diff)
downloadu-boot-WIP/07Oct2022.zip
u-boot-WIP/07Oct2022.tar.gz
u-boot-WIP/07Oct2022.tar.bz2
Merge tag 'efi-2023-01-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/07Oct2022
Pull request for efi-2023-01-rc1 UEFI: * Provide driver binding protocol to registered events for block devices * Code simplification and refactoring * Fix pylint errors in test_efi_secboot Other: * Improve checks for register ranges
-rw-r--r--MAINTAINERS7
-rw-r--r--cmd/bootefi.c17
-rw-r--r--cmd/efidebug.c108
-rw-r--r--cmd/nvedit_efi.c11
-rw-r--r--doc/api/efi.rst6
-rw-r--r--doc/develop/package/index.rst2
-rw-r--r--drivers/core/regmap.c4
-rw-r--r--include/efi.h2
-rw-r--r--include/efi_driver.h39
-rw-r--r--include/efi_loader.h17
-rw-r--r--lib/efi_driver/efi_block_device.c137
-rw-r--r--lib/efi_driver/efi_uclass.c42
-rw-r--r--lib/efi_loader/efi_boottime.c214
-rw-r--r--lib/efi_loader/efi_capsule.c15
-rw-r--r--lib/efi_loader/efi_console.c14
-rw-r--r--lib/efi_loader/efi_device_path.c3
-rw-r--r--lib/efi_loader/efi_disk.c40
-rw-r--r--lib/efi_loader/efi_helper.c19
-rw-r--r--lib/efi_loader/efi_load_initrd.c15
-rw-r--r--lib/efi_loader/efi_root_node.c48
-rw-r--r--lib/efi_loader/efi_setup.c8
-rw-r--r--lib/efi_loader/efi_string.c24
-rw-r--r--lib/efi_selftest/efi_selftest_events.c18
-rw-r--r--lib/efi_selftest/efi_selftest_exitbootservices.c6
-rw-r--r--lib/efi_selftest/efi_selftest_tpl.c47
-rw-r--r--lib/efi_selftest/efi_selftest_watchdog.c30
-rw-r--r--test/py/tests/test_efi_secboot/conftest.py12
27 files changed, 520 insertions, 385 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index b4b185a..a26b36c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -871,6 +871,7 @@ F: include/cp437.h
F: include/efi*
F: include/pe.h
F: include/asm-generic/pe.h
+F: include/mm_communication.h
F: lib/charset.c
F: lib/efi*/
F: test/lib/efi_*
@@ -884,12 +885,6 @@ F: tools/efivar.py
F: tools/file2include.c
F: tools/mkeficapsule.c
-EFI VARIABLES VIA OP-TEE
-M: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-S: Maintained
-F: lib/efi_loader/efi_variable_tee.c
-F: include/mm_communication.h
-
ENVIRONMENT
M: Joe Hershberger <joe.hershberger@ni.com>
R: Wolfgang Denk <wd@denx.de>
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 3041873..b93c0d3 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -492,7 +492,7 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
efi_handle_t mem_handle = NULL, handle;
struct efi_device_path *file_path = NULL;
struct efi_device_path *msg_path;
- efi_status_t ret;
+ efi_status_t ret, ret2;
u16 *load_options;
if (!bootefi_device_path || !bootefi_image_path) {
@@ -509,12 +509,9 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
* Make sure that device for device_path exist
* in load_image(). Otherwise, shell and grub will fail.
*/
- ret = efi_create_handle(&mem_handle);
- if (ret != EFI_SUCCESS)
- goto out;
-
- ret = efi_add_protocol(mem_handle, &efi_guid_device_path,
- file_path);
+ ret = efi_install_multiple_protocol_interfaces(&mem_handle,
+ &efi_guid_device_path,
+ file_path, NULL);
if (ret != EFI_SUCCESS)
goto out;
msg_path = file_path;
@@ -542,9 +539,11 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
ret = do_bootefi_exec(handle, load_options);
out:
- efi_delete_handle(mem_handle);
+ ret2 = efi_uninstall_multiple_protocol_interfaces(mem_handle,
+ &efi_guid_device_path,
+ file_path, NULL);
efi_free_pool(file_path);
- return ret;
+ return (ret != EFI_SUCCESS) ? ret : ret2;
}
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 84e6ff5..4b49f30 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -8,6 +8,7 @@
#include <charset.h>
#include <common.h>
#include <command.h>
+#include <dm/device.h>
#include <efi_dt_fixup.h>
#include <efi_load_initrd.h>
#include <efi_loader.h>
@@ -344,80 +345,12 @@ static int do_efi_capsule(struct cmd_tbl *cmdtp, int flag,
}
#endif /* CONFIG_EFI_HAVE_CAPSULE_SUPPORT */
-/**
- * efi_get_device_path_text() - get device path text
- *
- * Return the text representation of the device path of a handle.
- *
- * @handle: handle of UEFI device
- * Return:
- * Pointer to the device path text or NULL.
- * The caller is responsible for calling FreePool().
- */
-static u16 *efi_get_device_path_text(efi_handle_t handle)
-{
- struct efi_handler *handler;
- efi_status_t ret;
-
- ret = efi_search_protocol(handle, &efi_guid_device_path, &handler);
- if (ret == EFI_SUCCESS && handler->protocol_interface) {
- struct efi_device_path *dp = handler->protocol_interface;
-
- return efi_dp_str(dp);
- } else {
- return NULL;
- }
-}
-
#define EFI_HANDLE_WIDTH ((int)sizeof(efi_handle_t) * 2)
static const char spc[] = " ";
static const char sep[] = "================";
/**
- * do_efi_show_devices() - show UEFI devices
- *
- * @cmdtp: Command table
- * @flag: Command flag
- * @argc: Number of arguments
- * @argv: Argument array
- * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
- *
- * Implement efidebug "devices" sub-command.
- * Show all UEFI devices and their information.
- */
-static int do_efi_show_devices(struct cmd_tbl *cmdtp, int flag,
- int argc, char *const argv[])
-{
- efi_handle_t *handles;
- efi_uintn_t num, i;
- u16 *dev_path_text;
- efi_status_t ret;
-
- ret = EFI_CALL(efi_locate_handle_buffer(ALL_HANDLES, NULL, NULL,
- &num, &handles));
- if (ret != EFI_SUCCESS)
- return CMD_RET_FAILURE;
-
- if (!num)
- return CMD_RET_SUCCESS;
-
- printf("Device%.*s Device Path\n", EFI_HANDLE_WIDTH - 6, spc);
- printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
- for (i = 0; i < num; i++) {
- dev_path_text = efi_get_device_path_text(handles[i]);
- if (dev_path_text) {
- printf("%p %ls\n", handles[i], dev_path_text);
- efi_free_pool(dev_path_text);
- }
- }
-
- efi_free_pool(handles);
-
- return CMD_RET_SUCCESS;
-}
-
-/**
* efi_get_driver_handle_info() - get information of UEFI driver
*
* @handle: Handle of UEFI device
@@ -535,26 +468,25 @@ static int do_efi_show_handles(struct cmd_tbl *cmdtp, int flag,
if (!num)
return CMD_RET_SUCCESS;
- printf("Handle%.*s Protocols\n", EFI_HANDLE_WIDTH - 6, spc);
- printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
for (i = 0; i < num; i++) {
- printf("%p", handles[i]);
+ struct efi_handler *handler;
+
+ printf("\n%p", handles[i]);
+ if (handles[i]->dev)
+ printf(" (%s)", handles[i]->dev->name);
+ printf("\n");
+ /* Print device path */
+ ret = efi_search_protocol(handles[i], &efi_guid_device_path,
+ &handler);
+ if (ret == EFI_SUCCESS)
+ printf(" %pD\n", handler->protocol_interface);
ret = EFI_CALL(BS->protocols_per_handle(handles[i], &guid,
&count));
- if (ret || !count) {
- putc('\n');
- continue;
- }
-
+ /* Print other protocols */
for (j = 0; j < count; j++) {
- if (j)
- printf(", ");
- else
- putc(' ');
-
- printf("%pUs", guid[j]);
+ if (guidcmp(guid[j], &efi_guid_device_path))
+ printf(" %pUs\n", guid[j]);
}
- putc('\n');
}
efi_free_pool(handles);
@@ -812,7 +744,6 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
char *endp;
u16 var_name16[9];
efi_guid_t guid;
- size_t label_len, label_len16;
u16 *label;
struct efi_device_path *file_path = NULL;
struct efi_device_path *fp_free = NULL;
@@ -859,13 +790,10 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
"Boot", id);
/* label */
- label_len = strlen(argv[2]);
- label_len16 = utf8_utf16_strnlen(argv[2], label_len);
- label = malloc((label_len16 + 1) * sizeof(u16));
+ label = efi_convert_string(argv[2]);
if (!label)
return CMD_RET_FAILURE;
lo.label = label; /* label will be changed below */
- utf8_utf16_strncpy(&label, argv[2], label_len);
/* file path */
ret = efi_dp_from_name(argv[3], argv[4], argv[5],
@@ -1539,8 +1467,6 @@ static struct cmd_tbl cmd_efidebug_sub[] = {
U_BOOT_CMD_MKENT(capsule, CONFIG_SYS_MAXARGS, 1, do_efi_capsule,
"", ""),
#endif
- U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices,
- "", ""),
U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers,
"", ""),
U_BOOT_CMD_MKENT(dh, CONFIG_SYS_MAXARGS, 1, do_efi_show_handles,
@@ -1630,8 +1556,6 @@ static char efidebug_help_text[] =
#endif
"\n"
#endif
- "efidebug devices\n"
- " - show UEFI devices\n"
"efidebug drivers\n"
" - show UEFI drivers\n"
"efidebug dh\n"
diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c
index 770877c..24944ab 100644
--- a/cmd/nvedit_efi.c
+++ b/cmd/nvedit_efi.c
@@ -382,8 +382,7 @@ int do_env_set_efi(struct cmd_tbl *cmdtp, int flag, int argc,
efi_guid_t guid;
u32 attributes;
bool default_guid, verbose, value_on_memory;
- u16 *var_name16 = NULL, *p;
- size_t len;
+ u16 *var_name16;
efi_status_t ret;
if (argc == 1)
@@ -487,18 +486,15 @@ int do_env_set_efi(struct cmd_tbl *cmdtp, int flag, int argc,
16, 1, value, size, true);
}
- len = utf8_utf16_strnlen(var_name, strlen(var_name));
- var_name16 = malloc((len + 1) * 2);
+ var_name16 = efi_convert_string(var_name);
if (!var_name16) {
printf("## Out of memory\n");
ret = CMD_RET_FAILURE;
goto out;
}
- p = var_name16;
- utf8_utf16_strncpy(&p, var_name, len + 1);
-
ret = efi_set_variable_int(var_name16, &guid, attributes, size, value,
true);
+ free(var_name16);
unmap_sysmem(value);
if (ret == EFI_SUCCESS) {
ret = CMD_RET_SUCCESS;
@@ -533,7 +529,6 @@ out:
unmap_sysmem(value);
else
free(value);
- free(var_name16);
return ret;
}
diff --git a/doc/api/efi.rst b/doc/api/efi.rst
index 2b96783..43d6f93 100644
--- a/doc/api/efi.rst
+++ b/doc/api/efi.rst
@@ -172,6 +172,12 @@ Firmware management protocol
.. kernel-doc:: lib/efi_loader/efi_firmware.c
:internal:
+Driver binding protocol
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/efi_driver.h
+ :internal:
+
Unit testing
------------
diff --git a/doc/develop/package/index.rst b/doc/develop/package/index.rst
index 9374be2..4f44831 100644
--- a/doc/develop/package/index.rst
+++ b/doc/develop/package/index.rst
@@ -4,7 +4,7 @@ Package U-Boot
==============
U-Boot uses Flat Image Tree (FIT) as a standard file format for packaging
-images that it it reads and boots. Documentation about FIT is available at
+images that it reads and boots. Documentation about FIT is available at
doc/uImage.FIT
U-Boot also provides binman for cases not covered by FIT. Examples include
diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c
index 5f98f85..5ccbf9a 100644
--- a/drivers/core/regmap.c
+++ b/drivers/core/regmap.c
@@ -399,7 +399,7 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
range = &map->ranges[range_num];
offset <<= map->reg_offset_shift;
- if (offset + val_len > range->size) {
+ if (offset + val_len > range->size || offset + val_len < offset) {
debug("%s: offset/size combination invalid\n", __func__);
return -ERANGE;
}
@@ -538,7 +538,7 @@ int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset,
range = &map->ranges[range_num];
offset <<= map->reg_offset_shift;
- if (offset + val_len > range->size) {
+ if (offset + val_len > range->size || offset + val_len < offset) {
debug("%s: offset/size combination invalid\n", __func__);
return -ERANGE;
}
diff --git a/include/efi.h b/include/efi.h
index 6159f34..42f4e58 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -37,12 +37,14 @@
#define EFIAPI __attribute__((ms_abi))
#define efi_va_list __builtin_ms_va_list
#define efi_va_start __builtin_ms_va_start
+#define efi_va_copy __builtin_ms_va_copy
#define efi_va_arg __builtin_va_arg
#define efi_va_end __builtin_ms_va_end
#else
#define EFIAPI asmlinkage
#define efi_va_list va_list
#define efi_va_start va_start
+#define efi_va_copy va_copy
#define efi_va_arg va_arg
#define efi_va_end va_end
#endif /* __x86_64__ */
diff --git a/include/efi_driver.h b/include/efi_driver.h
index 2b62219..63a95e4 100644
--- a/include/efi_driver.h
+++ b/include/efi_driver.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * EFI application loader
+ * Internal structures for the EFI driver binding protocol
*
* Copyright (c) 2017 Heinrich Schuchardt
*/
@@ -10,30 +10,39 @@
#include <efi_loader.h>
-/*
- * Operations supported by an EFI driver with respect to the EFI uclass
+/**
+ * struct efi_driver_binding_extended_protocol - extended driver binding protocol
+ *
+ * This structure adds internal fields to the driver binding protocol.
+ *
+ * @bp: driver binding protocol
+ * @ops: operations supported by the driver
+ */
+struct efi_driver_binding_extended_protocol {
+ struct efi_driver_binding_protocol bp;
+ const struct efi_driver_ops *ops;
+};
+
+/**
+ * struct efi_driver_ops - operations support by an EFI driver
*
- * @protocol The GUID of the protocol which is consumed by the
+ * @protocol: The GUID of the protocol which is consumed by the
* driver. This GUID is used by the EFI uclass in the
* supports() and start() methods of the
* EFI_DRIVER_BINDING_PROTOCOL.
- * @child_protocol Protocol supported by the child handles generated by
+ * @child_protocol: Protocol supported by the child handles generated by
* the EFI driver.
- * @bind Function called by the EFI uclass to attach the
+ * @init: Function called by the EFI uclass after installing the
+ * driver binding protocol.
+ * @bind: Function called by the EFI uclass to attach the
* driver to EFI driver to a handle.
*/
struct efi_driver_ops {
const efi_guid_t *protocol;
const efi_guid_t *child_protocol;
- int (*bind)(efi_handle_t handle, void *interface);
-};
-
-/*
- * This structure adds internal fields to the driver binding protocol.
- */
-struct efi_driver_binding_extended_protocol {
- struct efi_driver_binding_protocol bp;
- const struct efi_driver_ops *ops;
+ efi_status_t (*init)(struct efi_driver_binding_extended_protocol *this);
+ efi_status_t (*bind)(struct efi_driver_binding_extended_protocol *this,
+ efi_handle_t handle, void *interface);
};
#endif /* _EFI_DRIVER_H */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index ad01395..69d6d00 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -10,6 +10,7 @@
#include <common.h>
#include <blk.h>
+#include <event.h>
#include <log.h>
#include <part_efi.h>
#include <efi_api.h>
@@ -544,8 +545,6 @@ void efi_carve_out_dt_rsv(void *fdt);
void efi_try_purge_kaslr_seed(void *fdt);
/* Called by bootefi to make console interface available */
efi_status_t efi_console_register(void);
-/* Called by efi_init_early() to add block devices when probed */
-efi_status_t efi_disk_init(void);
/* Called by efi_init_obj_list() to proble all block devices */
efi_status_t efi_disks_register(void);
/* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */
@@ -655,8 +654,10 @@ efi_status_t efi_remove_protocol(const efi_handle_t handle,
/* Delete all protocols from a handle */
efi_status_t efi_remove_all_protocols(const efi_handle_t handle);
/* Install multiple protocol interfaces */
-efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
- (efi_handle_t *handle, ...);
+efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...);
+efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces(efi_handle_t handle, ...);
/* Get handles that support a given protocol */
efi_status_t EFIAPI efi_locate_handle_buffer(
enum efi_locate_search_type search_type,
@@ -708,6 +709,7 @@ const char *guid_to_sha_str(const efi_guid_t *guid);
int algo_to_len(const char *algo);
int efi_link_dev(efi_handle_t handle, struct udevice *dev);
+int efi_unlink_dev(efi_handle_t handle);
/**
* efi_size_in_pages() - convert size in bytes to size in pages
@@ -748,6 +750,10 @@ efi_status_t efi_add_conventional_memory_map(u64 ram_start, u64 ram_end,
/* Called by board init to initialize the EFI drivers */
efi_status_t efi_driver_init(void);
+/* Called when a block device is added */
+int efi_disk_probe(void *ctx, struct event *event);
+/* Called when a block device is removed */
+int efi_disk_remove(void *ctx, struct event *event);
/* Called by board init to initialize the EFI memory map */
int efi_memory_init(void);
/* Adds new or overrides configuration table entry to the system table */
@@ -1014,9 +1020,10 @@ struct pkcs7_message *efi_parse_pkcs7_header(const void *buf,
/* runtime implementation of memcpy() */
void efi_memcpy_runtime(void *dest, const void *src, size_t n);
-/* commonly used helper function */
+/* commonly used helper functions */
u16 *efi_create_indexed_name(u16 *buffer, size_t buffer_size, const char *name,
unsigned int index);
+efi_string_t efi_convert_string(const char *str);
extern const struct efi_firmware_management_protocol efi_fmp_fit;
extern const struct efi_firmware_management_protocol efi_fmp_raw;
diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c
index 3177ab6..add00ee 100644
--- a/lib/efi_driver/efi_block_device.c
+++ b/lib/efi_driver/efi_block_device.c
@@ -37,11 +37,11 @@
#include <dm/root.h>
#include <dm/tag.h>
-/*
- * EFI attributes of the udevice handled by this driver.
+/**
+ * struct efi_blk_plat - attributes of a block device
*
- * handle handle of the controller on which this driver is installed
- * io block io protocol proxied by this driver
+ * @handle: handle of the controller on which this driver is installed
+ * @io: block io protocol proxied by this driver
*/
struct efi_blk_plat {
efi_handle_t handle;
@@ -49,7 +49,7 @@ struct efi_blk_plat {
};
/**
- * Read from block device
+ * efi_bl_read() - read from block device
*
* @dev: device
* @blknr: first block to be read
@@ -78,7 +78,7 @@ static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
}
/**
- * Write to block device
+ * efi_bl_write() - write to block device
*
* @dev: device
* @blknr: first block to be write
@@ -108,45 +108,41 @@ static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
}
/**
- * Create a block device for a handle
+ * efi_bl_create_block_device() - create a block device for a handle
*
* @handle: handle
* @interface: block io protocol
- * Return: 0 = success
+ * Return: status code
*/
-static int efi_bl_bind(efi_handle_t handle, void *interface)
+static efi_status_t
+efi_bl_create_block_device(efi_handle_t handle, void *interface)
{
- struct udevice *bdev, *parent = dm_root();
- int ret, devnum;
+ struct udevice *bdev = NULL, *parent = dm_root();
+ efi_status_t ret;
+ int devnum;
char *name;
- struct efi_object *obj = efi_search_obj(handle);
struct efi_block_io *io = interface;
struct efi_blk_plat *plat;
- EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io);
-
- if (!obj)
- return -ENOENT;
-
devnum = blk_find_max_devnum(UCLASS_EFI_LOADER);
if (devnum == -ENODEV)
devnum = 0;
else if (devnum < 0)
- return devnum;
+ return EFI_OUT_OF_RESOURCES;
name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */
if (!name)
- return -ENOMEM;
+ return EFI_OUT_OF_RESOURCES;
sprintf(name, "efiblk#%d", devnum);
/* Create driver model udevice for the EFI block io device */
- ret = blk_create_device(parent, "efi_blk", name, UCLASS_EFI_LOADER,
- devnum, io->media->block_size,
- (lbaint_t)io->media->last_block, &bdev);
- if (ret)
- return ret;
- if (!bdev)
- return -ENOENT;
+ if (blk_create_device(parent, "efi_blk", name, UCLASS_EFI_LOADER,
+ devnum, io->media->block_size,
+ (lbaint_t)io->media->last_block, &bdev)) {
+ ret = EFI_OUT_OF_RESOURCES;
+ free(name);
+ goto err;
+ }
/* Set the DM_FLAG_NAME_ALLOCED flag to avoid a memory leak */
device_set_name_alloced(bdev);
@@ -154,20 +150,78 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
plat->handle = handle;
plat->io = interface;
- /*
- * FIXME: necessary because we won't do almost nothing in
- * efi_disk_create() when called from device_probe().
- */
- if (efi_link_dev(handle, bdev))
- /* FIXME: cleanup for bdev */
- return ret;
-
- ret = device_probe(bdev);
- if (ret)
- return ret;
+ if (efi_link_dev(handle, bdev)) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto err;
+ }
+
+ if (device_probe(bdev)) {
+ ret = EFI_DEVICE_ERROR;
+ goto err;
+ }
EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
- return 0;
+ return EFI_SUCCESS;
+
+err:
+ efi_unlink_dev(handle);
+ if (bdev)
+ device_unbind(bdev);
+
+ return ret;
+}
+
+/**
+ * efi_bl_bind() - bind to a block io protocol
+ *
+ * @this: driver binding protocol
+ * @handle: handle
+ * @interface: block io protocol
+ * Return: status code
+ */
+static efi_status_t efi_bl_bind(
+ struct efi_driver_binding_extended_protocol *this,
+ efi_handle_t handle, void *interface)
+{
+ efi_status_t ret = EFI_SUCCESS;
+ struct efi_object *obj = efi_search_obj(handle);
+
+ EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, interface);
+
+ if (!obj || !interface)
+ return EFI_INVALID_PARAMETER;
+
+ if (!handle->dev)
+ ret = efi_bl_create_block_device(handle, interface);
+
+ return ret;
+}
+
+/**
+ * efi_bl_init() - initialize block device driver
+ *
+ * @this: extended driver binding protocol
+ */
+static efi_status_t
+efi_bl_init(struct efi_driver_binding_extended_protocol *this)
+{
+ int ret;
+
+ ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
+ efi_disk_probe, this);
+ if (ret) {
+ log_err("Event registration for efi_disk add failed\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ret = event_register("efi_disk del", EVT_DM_PRE_REMOVE,
+ efi_disk_remove, this);
+ if (ret) {
+ log_err("Event registration for efi_disk del failed\n");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
}
/* Block device driver operators */
@@ -178,9 +232,9 @@ static const struct blk_ops efi_blk_ops = {
/* Identify as block device driver */
U_BOOT_DRIVER(efi_blk) = {
- .name = "efi_blk",
- .id = UCLASS_BLK,
- .ops = &efi_blk_ops,
+ .name = "efi_blk",
+ .id = UCLASS_BLK,
+ .ops = &efi_blk_ops,
.plat_auto = sizeof(struct efi_blk_plat),
};
@@ -188,6 +242,7 @@ U_BOOT_DRIVER(efi_blk) = {
static const struct efi_driver_ops driver_ops = {
.protocol = &efi_block_io_guid,
.child_protocol = &efi_block_io_guid,
+ .init = efi_bl_init,
.bind = efi_bl_bind,
};
diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
index 74dd003..2193f84 100644
--- a/lib/efi_driver/efi_uclass.c
+++ b/lib/efi_driver/efi_uclass.c
@@ -11,7 +11,7 @@
* The uclass provides the bind, start, and stop entry points for the driver
* binding protocol.
*
- * In bind() and stop() it checks if the controller implements the protocol
+ * In supported() and bind() it checks if the controller implements the protocol
* supported by the EFI driver. In the start() function it calls the bind()
* function of the EFI driver. In the stop() function it destroys the child
* controllers.
@@ -144,18 +144,19 @@ static efi_status_t EFIAPI efi_uc_start(
goto out;
}
ret = check_node_type(controller_handle);
- if (ret != EFI_SUCCESS) {
- r = EFI_CALL(systab.boottime->close_protocol(
- controller_handle, bp->ops->protocol,
- this->driver_binding_handle,
- controller_handle));
- if (r != EFI_SUCCESS)
- EFI_PRINT("Failure to close handle\n");
+ if (ret != EFI_SUCCESS)
+ goto err;
+ ret = bp->ops->bind(bp, controller_handle, interface);
+ if (ret == EFI_SUCCESS)
goto out;
- }
- /* TODO: driver specific stuff */
- bp->ops->bind(controller_handle, interface);
+err:
+ r = EFI_CALL(systab.boottime->close_protocol(
+ controller_handle, bp->ops->protocol,
+ this->driver_binding_handle,
+ controller_handle));
+ if (r != EFI_SUCCESS)
+ EFI_PRINT("Failure to close handle\n");
out:
return EFI_EXIT(ret);
@@ -245,7 +246,7 @@ static efi_status_t EFIAPI efi_uc_stop(
goto out;
}
}
- ret = EFI_CALL(systab.boottime->free_pool(entry_buffer));
+ ret = efi_free_pool(entry_buffer);
if (ret != EFI_SUCCESS)
log_err("Cannot free EFI memory pool\n");
@@ -283,7 +284,7 @@ static efi_status_t efi_add_driver(struct driver *drv)
bp->bp.start = efi_uc_start;
bp->bp.stop = efi_uc_stop;
bp->bp.version = 0xffffffff;
- bp->ops = drv->ops;
+ bp->ops = ops;
ret = efi_create_handle(&bp->bp.driver_binding_handle);
if (ret != EFI_SUCCESS) {
@@ -293,13 +294,20 @@ static efi_status_t efi_add_driver(struct driver *drv)
bp->bp.image_handle = bp->bp.driver_binding_handle;
ret = efi_add_protocol(bp->bp.driver_binding_handle,
&efi_guid_driver_binding_protocol, bp);
- if (ret != EFI_SUCCESS) {
- efi_delete_handle(bp->bp.driver_binding_handle);
- free(bp);
- goto out;
+ if (ret != EFI_SUCCESS)
+ goto err;
+ if (ops->init) {
+ ret = ops->init(bp);
+ if (ret != EFI_SUCCESS)
+ goto err;
}
out:
return ret;
+
+err:
+ efi_delete_handle(bp->bp.driver_binding_handle);
+ free(bp);
+ return ret;
}
/**
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 1bfd094..e776d25 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2590,35 +2590,31 @@ found:
}
/**
- * efi_install_multiple_protocol_interfaces() - Install multiple protocol
+ * efi_install_multiple_protocol_interfaces_int() - Install multiple protocol
* interfaces
* @handle: handle on which the protocol interfaces shall be installed
- * @...: NULL terminated argument list with pairs of protocol GUIDS and
- * interfaces
+ * @argptr: va_list of args
*
- * This function implements the MultipleProtocolInterfaces service.
- *
- * See the Unified Extensible Firmware Interface (UEFI) specification for
- * details.
+ * Core functionality of efi_install_multiple_protocol_interfaces
+ * Must not be called directly
*
* Return: status code
*/
-efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
- (efi_handle_t *handle, ...)
+static efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces_int(efi_handle_t *handle,
+ efi_va_list argptr)
{
- EFI_ENTRY("%p", handle);
-
- efi_va_list argptr;
const efi_guid_t *protocol;
void *protocol_interface;
efi_handle_t old_handle;
- efi_status_t r = EFI_SUCCESS;
+ efi_status_t ret = EFI_SUCCESS;
int i = 0;
+ efi_va_list argptr_copy;
if (!handle)
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
- efi_va_start(argptr, handle);
+ efi_va_copy(argptr_copy, argptr);
for (;;) {
protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
@@ -2628,104 +2624,212 @@ efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
if (!guidcmp(protocol, &efi_guid_device_path)) {
struct efi_device_path *dp = protocol_interface;
- r = EFI_CALL(efi_locate_device_path(protocol, &dp,
- &old_handle));
- if (r == EFI_SUCCESS &&
+ ret = EFI_CALL(efi_locate_device_path(protocol, &dp,
+ &old_handle));
+ if (ret == EFI_SUCCESS &&
dp->type == DEVICE_PATH_TYPE_END) {
EFI_PRINT("Path %pD already installed\n",
protocol_interface);
- r = EFI_ALREADY_STARTED;
+ ret = EFI_ALREADY_STARTED;
break;
}
}
- r = EFI_CALL(efi_install_protocol_interface(
- handle, protocol,
- EFI_NATIVE_INTERFACE,
- protocol_interface));
- if (r != EFI_SUCCESS)
+ ret = EFI_CALL(efi_install_protocol_interface(handle, protocol,
+ EFI_NATIVE_INTERFACE,
+ protocol_interface));
+ if (ret != EFI_SUCCESS)
break;
i++;
}
- efi_va_end(argptr);
- if (r == EFI_SUCCESS)
- return EFI_EXIT(r);
+ if (ret == EFI_SUCCESS)
+ goto out;
/* If an error occurred undo all changes. */
- efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = efi_va_arg(argptr, efi_guid_t*);
- protocol_interface = efi_va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr_copy, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr_copy, void*);
EFI_CALL(efi_uninstall_protocol_interface(*handle, protocol,
protocol_interface));
}
- efi_va_end(argptr);
- return EFI_EXIT(r);
+out:
+ efi_va_end(argptr_copy);
+ return ret;
+
}
/**
- * efi_uninstall_multiple_protocol_interfaces() - uninstall multiple protocol
- * interfaces
- * @handle: handle from which the protocol interfaces shall be removed
+ * efi_install_multiple_protocol_interfaces() - Install multiple protocol
+ * interfaces
+ * @handle: handle on which the protocol interfaces shall be installed
* @...: NULL terminated argument list with pairs of protocol GUIDS and
* interfaces
*
- * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * This is the function for internal usage in U-Boot. For the API function
+ * implementing the InstallMultipleProtocol service see
+ * efi_install_multiple_protocol_interfaces_ext()
+ *
+ * Return: status code
+ */
+efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...)
+{
+ efi_status_t ret;
+ efi_va_list argptr;
+
+ efi_va_start(argptr, handle);
+ ret = efi_install_multiple_protocol_interfaces_int(handle, argptr);
+ efi_va_end(argptr);
+ return ret;
+}
+
+/**
+ * efi_install_multiple_protocol_interfaces_ext() - Install multiple protocol
+ * interfaces
+ * @handle: handle on which the protocol interfaces shall be installed
+ * @...: NULL terminated argument list with pairs of protocol GUIDS and
+ * interfaces
+ *
+ * This function implements the MultipleProtocolInterfaces service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* Return: status code
*/
-static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
- efi_handle_t handle, ...)
+static efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces_ext(efi_handle_t *handle, ...)
{
EFI_ENTRY("%p", handle);
-
+ efi_status_t ret;
efi_va_list argptr;
+
+ efi_va_start(argptr, handle);
+ ret = efi_install_multiple_protocol_interfaces_int(handle, argptr);
+ efi_va_end(argptr);
+ return EFI_EXIT(ret);
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces_int() - wrapper for uninstall
+ * multiple protocol
+ * interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @argptr: va_list of args
+ *
+ * Core functionality of efi_uninstall_multiple_protocol_interfaces
+ * Must not be called directly
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces_int(efi_handle_t handle,
+ efi_va_list argptr)
+{
const efi_guid_t *protocol;
void *protocol_interface;
- efi_status_t r = EFI_SUCCESS;
+ efi_status_t ret;
size_t i = 0;
+ efi_va_list argptr_copy;
if (!handle)
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
- efi_va_start(argptr, handle);
+ efi_va_copy(argptr_copy, argptr);
for (;;) {
protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
break;
protocol_interface = efi_va_arg(argptr, void*);
- r = efi_uninstall_protocol(handle, protocol,
- protocol_interface);
- if (r != EFI_SUCCESS)
+ ret = efi_uninstall_protocol(handle, protocol,
+ protocol_interface);
+ if (ret != EFI_SUCCESS)
break;
i++;
}
- efi_va_end(argptr);
- if (r == EFI_SUCCESS) {
+ if (ret == EFI_SUCCESS) {
/* If the last protocol has been removed, delete the handle. */
if (list_empty(&handle->protocols)) {
list_del(&handle->link);
free(handle);
}
- return EFI_EXIT(r);
+ goto out;
}
/* If an error occurred undo all changes. */
- efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = efi_va_arg(argptr, efi_guid_t*);
- protocol_interface = efi_va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr_copy, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr_copy, void*);
EFI_CALL(efi_install_protocol_interface(&handle, protocol,
EFI_NATIVE_INTERFACE,
protocol_interface));
}
+ /*
+ * If any errors are generated while the protocol interfaces are being
+ * uninstalled, then the protocols uninstalled prior to the error will
+ * be reinstalled using InstallProtocolInterface() and the status code
+ * EFI_INVALID_PARAMETER is returned.
+ */
+ ret = EFI_INVALID_PARAMETER;
+
+out:
+ efi_va_end(argptr_copy);
+ return ret;
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces() - uninstall multiple protocol
+ * interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @...: NULL terminated argument list with pairs of protocol GUIDS and
+ * interfaces
+ *
+ * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * This is the function for internal usage in U-Boot. For the API function
+ * implementing the UninstallMultipleProtocolInterfaces service see
+ * efi_uninstall_multiple_protocol_interfaces_ext()
+ *
+ * Return: status code
+ */
+efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces(efi_handle_t handle, ...)
+{
+ efi_status_t ret;
+ efi_va_list argptr;
+
+ efi_va_start(argptr, handle);
+ ret = efi_uninstall_multiple_protocol_interfaces_int(handle, argptr);
efi_va_end(argptr);
+ return ret;
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces_ext() - uninstall multiple protocol
+ * interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @...: NULL terminated argument list with pairs of protocol GUIDS and
+ * interfaces
+ *
+ * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces_ext(efi_handle_t handle, ...)
+{
+ EFI_ENTRY("%p", handle);
+ efi_status_t ret;
+ efi_va_list argptr;
- /* In case of an error always return EFI_INVALID_PARAMETER */
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ efi_va_start(argptr, handle);
+ ret = efi_uninstall_multiple_protocol_interfaces_int(handle, argptr);
+ efi_va_end(argptr);
+ return EFI_EXIT(ret);
}
/**
@@ -3785,9 +3889,9 @@ static struct efi_boot_services efi_boot_services = {
.locate_handle_buffer = efi_locate_handle_buffer,
.locate_protocol = efi_locate_protocol,
.install_multiple_protocol_interfaces =
- efi_install_multiple_protocol_interfaces,
+ efi_install_multiple_protocol_interfaces_ext,
.uninstall_multiple_protocol_interfaces =
- efi_uninstall_multiple_protocol_interfaces,
+ efi_uninstall_multiple_protocol_interfaces_ext,
.calculate_crc32 = efi_calculate_crc32,
.copy_mem = efi_copy_mem,
.set_mem = efi_set_mem,
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index a6b98f0..b6bd2d6 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -636,17 +636,18 @@ efi_status_t __weak efi_load_capsule_drivers(void)
if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) {
handle = NULL;
- ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
- &handle, &efi_guid_firmware_management_protocol,
- &efi_fmp_fit, NULL));
+ ret = efi_install_multiple_protocol_interfaces(&handle,
+ &efi_guid_firmware_management_protocol,
+ &efi_fmp_fit,
+ NULL);
}
if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) {
handle = NULL;
- ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
- &handle,
- &efi_guid_firmware_management_protocol,
- &efi_fmp_raw, NULL));
+ ret = efi_install_multiple_protocol_interfaces(&handle,
+ &efi_guid_firmware_management_protocol,
+ &efi_fmp_raw,
+ NULL);
}
return ret;
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index cf9fbd9..3354b21 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -1278,12 +1278,14 @@ efi_status_t efi_console_register(void)
struct efi_device_path *dp;
/* Install protocols on root node */
- r = EFI_CALL(efi_install_multiple_protocol_interfaces
- (&efi_root,
- &efi_guid_text_output_protocol, &efi_con_out,
- &efi_guid_text_input_protocol, &efi_con_in,
- &efi_guid_text_input_ex_protocol, &efi_con_in_ex,
- NULL));
+ r = efi_install_multiple_protocol_interfaces(&efi_root,
+ &efi_guid_text_output_protocol,
+ &efi_con_out,
+ &efi_guid_text_input_protocol,
+ &efi_con_in,
+ &efi_guid_text_input_ex_protocol,
+ &efi_con_in_ex,
+ NULL);
/* Create console node and install device path protocols */
if (CONFIG_IS_ENABLED(DM_SERIAL)) {
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index ebffb77..acae007 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -936,7 +936,8 @@ struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
dpsize = sizeof(struct efi_device_path_hard_drive_path);
buf = dp_alloc(dpsize);
- dp_part_node(buf, desc, part);
+ if (buf)
+ dp_part_node(buf, desc, part);
return buf;
}
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 39ea1a6..e6a356b 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -415,6 +415,11 @@ static efi_status_t efi_disk_add_dev(
struct efi_handler *handler;
void *protocol_interface;
+ if (!node) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto error;
+ }
+
/* Parent must expose EFI_BLOCK_IO_PROTOCOL */
ret = efi_search_protocol(parent, &efi_block_io_guid, &handler);
if (ret != EFI_SUCCESS)
@@ -449,10 +454,12 @@ static efi_status_t efi_disk_add_dev(
* in this case.
*/
handle = &diskobj->header;
- ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
- &handle, &efi_guid_device_path, diskobj->dp,
- &efi_block_io_guid, &diskobj->ops,
- guid, NULL, NULL));
+ ret = efi_install_multiple_protocol_interfaces(&handle,
+ &efi_guid_device_path,
+ diskobj->dp,
+ &efi_block_io_guid,
+ &diskobj->ops, guid,
+ NULL, NULL);
if (ret != EFI_SUCCESS)
goto error;
@@ -620,7 +627,7 @@ static int efi_disk_create_part(struct udevice *dev)
*
* @return 0 on success, -1 otherwise
*/
-static int efi_disk_probe(void *ctx, struct event *event)
+int efi_disk_probe(void *ctx, struct event *event)
{
struct udevice *dev;
enum uclass_id id;
@@ -724,7 +731,7 @@ static int efi_disk_delete_part(struct udevice *dev)
*
* @return 0 on success, -1 otherwise
*/
-static int efi_disk_remove(void *ctx, struct event *event)
+int efi_disk_remove(void *ctx, struct event *event)
{
enum uclass_id id;
struct udevice *dev;
@@ -740,27 +747,6 @@ static int efi_disk_remove(void *ctx, struct event *event)
return 0;
}
-efi_status_t efi_disk_init(void)
-{
- int ret;
-
- ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
- efi_disk_probe, NULL);
- if (ret) {
- log_err("Event registration for efi_disk add failed\n");
- return EFI_OUT_OF_RESOURCES;
- }
-
- ret = event_register("efi_disk del", EVT_DM_PRE_REMOVE,
- efi_disk_remove, NULL);
- if (ret) {
- log_err("Event registration for efi_disk del failed\n");
- return EFI_OUT_OF_RESOURCES;
- }
-
- return EFI_SUCCESS;
-}
-
/**
* efi_disk_get_device_name() - get U-Boot device name associated with EFI handle
*
diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c
index 8ed564e..c71e87d 100644
--- a/lib/efi_loader/efi_helper.c
+++ b/lib/efi_loader/efi_helper.c
@@ -171,3 +171,22 @@ int efi_link_dev(efi_handle_t handle, struct udevice *dev)
handle->dev = dev;
return dev_tag_set_ptr(dev, DM_TAG_EFI, handle);
}
+
+/**
+ * efi_unlink_dev() - unlink udevice and handle
+ *
+ * @handle: EFI handle to unlink
+ *
+ * Return: 0 on success, negative on failure
+ */
+int efi_unlink_dev(efi_handle_t handle)
+{
+ int ret;
+
+ ret = dev_tag_del(handle->dev, DM_TAG_EFI);
+ if (ret)
+ return ret;
+ handle->dev = NULL;
+
+ return 0;
+}
diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c
index 3d6044f..87fde3f 100644
--- a/lib/efi_loader/efi_load_initrd.c
+++ b/lib/efi_loader/efi_load_initrd.c
@@ -208,14 +208,13 @@ efi_status_t efi_initrd_register(void)
if (ret != EFI_SUCCESS)
return ret;
- ret = EFI_CALL(efi_install_multiple_protocol_interfaces
- (&efi_initrd_handle,
- /* initramfs */
- &efi_guid_device_path, &dp_lf2_handle,
- /* LOAD_FILE2 */
- &efi_guid_load_file2_protocol,
- (void *)&efi_lf2_protocol,
- NULL));
+ ret = efi_install_multiple_protocol_interfaces(&efi_initrd_handle,
+ /* initramfs */
+ &efi_guid_device_path, &dp_lf2_handle,
+ /* LOAD_FILE2 */
+ &efi_guid_load_file2_protocol,
+ (void *)&efi_lf2_protocol,
+ NULL);
return ret;
}
diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c
index 739c686..a4eb6f4 100644
--- a/lib/efi_loader/efi_root_node.c
+++ b/lib/efi_loader/efi_root_node.c
@@ -49,38 +49,38 @@ efi_status_t efi_root_node_register(void)
dp->end.length = sizeof(struct efi_device_path);
/* Create root node and install protocols */
- ret = EFI_CALL(efi_install_multiple_protocol_interfaces
- (&efi_root,
- /* Device path protocol */
- &efi_guid_device_path, dp,
+ ret = efi_install_multiple_protocol_interfaces
+ (&efi_root,
+ /* Device path protocol */
+ &efi_guid_device_path, dp,
#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT)
- /* Device path to text protocol */
- &efi_guid_device_path_to_text_protocol,
- (void *)&efi_device_path_to_text,
+ /* Device path to text protocol */
+ &efi_guid_device_path_to_text_protocol,
+ &efi_device_path_to_text,
#endif
-#ifdef CONFIG_EFI_DEVICE_PATH_UTIL
- /* Device path utilities protocol */
- &efi_guid_device_path_utilities_protocol,
- (void *)&efi_device_path_utilities,
+#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_UTIL)
+ /* Device path utilities protocol */
+ &efi_guid_device_path_utilities_protocol,
+ &efi_device_path_utilities,
#endif
-#ifdef CONFIG_EFI_DT_FIXUP
- /* Device-tree fix-up protocol */
- &efi_guid_dt_fixup_protocol,
- (void *)&efi_dt_fixup_prot,
+#if CONFIG_IS_ENABLED(EFI_DT_FIXUP)
+ /* Device-tree fix-up protocol */
+ &efi_guid_dt_fixup_protocol,
+ &efi_dt_fixup_prot,
#endif
#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL2)
- &efi_guid_unicode_collation_protocol2,
- (void *)&efi_unicode_collation_protocol2,
+ &efi_guid_unicode_collation_protocol2,
+ &efi_unicode_collation_protocol2,
#endif
#if CONFIG_IS_ENABLED(EFI_LOADER_HII)
- /* HII string protocol */
- &efi_guid_hii_string_protocol,
- (void *)&efi_hii_string,
- /* HII database protocol */
- &efi_guid_hii_database_protocol,
- (void *)&efi_hii_database,
+ /* HII string protocol */
+ &efi_guid_hii_string_protocol,
+ &efi_hii_string,
+ /* HII database protocol */
+ &efi_guid_hii_database_protocol,
+ &efi_hii_database,
#endif
- NULL));
+ NULL);
efi_root->type = EFI_OBJECT_TYPE_U_BOOT_FIRMWARE;
return ret;
}
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index c633fcd..9d71893 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -198,7 +198,8 @@ static efi_status_t __efi_init_early(void)
if (ret != EFI_SUCCESS)
goto out;
- ret = efi_disk_init();
+ /* Initialize EFI driver uclass */
+ ret = efi_driver_init();
out:
return ret;
}
@@ -319,11 +320,6 @@ efi_status_t efi_init_obj_list(void)
if (ret != EFI_SUCCESS)
goto out;
- /* Initialize EFI driver uclass */
- ret = efi_driver_init();
- if (ret != EFI_SUCCESS)
- goto out;
-
if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) {
ret = efi_load_capsule_drivers();
if (ret != EFI_SUCCESS)
diff --git a/lib/efi_loader/efi_string.c b/lib/efi_loader/efi_string.c
index 8bf1e49..e21e09c 100644
--- a/lib/efi_loader/efi_string.c
+++ b/lib/efi_loader/efi_string.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <charset.h>
#include <efi_loader.h>
+#include <malloc.h>
/**
* efi_create_indexed_name - create a string name with an index
@@ -41,3 +42,26 @@ u16 *efi_create_indexed_name(u16 *buffer, size_t buffer_size, const char *name,
return p;
}
+
+/**
+ * efi_convert_string - Convert an ASCII or UTF-8 string to UTF-16
+ * @str: String to be converted
+ *
+ * Return: Converted string in UTF-16 format. The caller is responsible for
+ * freeing this string when it is no longer needed.
+ */
+efi_string_t efi_convert_string(const char *str)
+{
+ efi_string_t str_16, tmp;
+ size_t sz_16;
+
+ sz_16 = utf8_utf16_strlen(str);
+ str_16 = calloc(sz_16 + 1, sizeof(u16));
+ if (!str_16)
+ return NULL;
+
+ tmp = str_16;
+ utf8_utf16_strcpy(&tmp, str);
+
+ return str_16;
+}
diff --git a/lib/efi_selftest/efi_selftest_events.c b/lib/efi_selftest/efi_selftest_events.c
index 9007153..743a6b9 100644
--- a/lib/efi_selftest/efi_selftest_events.c
+++ b/lib/efi_selftest/efi_selftest_events.c
@@ -11,7 +11,7 @@
#include <efi_selftest.h>
-static struct efi_event *event_notify;
+static struct efi_event *efi_st_event_notify;
static struct efi_event *event_wait;
static unsigned int timer_ticks;
static struct efi_boot_services *boottime;
@@ -50,7 +50,7 @@ static int setup(const efi_handle_t handle,
ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
TPL_CALLBACK, notify, (void *)&timer_ticks,
- &event_notify);
+ &efi_st_event_notify);
if (ret != EFI_SUCCESS) {
efi_st_error("could not create event\n");
return EFI_ST_FAILURE;
@@ -75,9 +75,9 @@ static int teardown(void)
{
efi_status_t ret;
- if (event_notify) {
- ret = boottime->close_event(event_notify);
- event_notify = NULL;
+ if (efi_st_event_notify) {
+ ret = boottime->close_event(efi_st_event_notify);
+ efi_st_event_notify = NULL;
if (ret != EFI_SUCCESS) {
efi_st_error("could not close event\n");
return EFI_ST_FAILURE;
@@ -112,7 +112,8 @@ static int execute(void)
/* Set 10 ms timer */
timer_ticks = 0;
- ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000);
+ ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_PERIODIC,
+ 100000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
@@ -146,14 +147,15 @@ static int execute(void)
efi_st_error("Incorrect timing of events\n");
return EFI_ST_FAILURE;
}
- ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0);
+ ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_STOP, 0);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not cancel timer\n");
return EFI_ST_FAILURE;
}
/* Set 10 ms timer */
timer_ticks = 0;
- ret = boottime->set_timer(event_notify, EFI_TIMER_RELATIVE, 100000);
+ ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_RELATIVE,
+ 100000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_exitbootservices.c b/lib/efi_selftest/efi_selftest_exitbootservices.c
index f5e0d9d..11b43fd 100644
--- a/lib/efi_selftest/efi_selftest_exitbootservices.c
+++ b/lib/efi_selftest/efi_selftest_exitbootservices.c
@@ -26,7 +26,7 @@ struct notification_context {
};
static struct efi_boot_services *boottime;
-static struct efi_event *event_notify;
+static struct efi_event *efi_st_event_notify;
struct notification_record record;
struct notification_context context_before = {
@@ -75,7 +75,7 @@ static int setup(const efi_handle_t handle,
ret = boottime->create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES,
TPL_CALLBACK, ebs_notify,
&context,
- &event_notify);
+ &efi_st_event_notify);
if (ret != EFI_SUCCESS) {
efi_st_error("could not create event\n");
return EFI_ST_FAILURE;
@@ -83,7 +83,7 @@ static int setup(const efi_handle_t handle,
ret = boottime->create_event_ex(0, TPL_CALLBACK, ebs_notify,
&context_before,
&guid_before_exit_boot_services,
- &event_notify);
+ &efi_st_event_notify);
if (ret != EFI_SUCCESS) {
efi_st_error("could not create event\n");
return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_tpl.c b/lib/efi_selftest/efi_selftest_tpl.c
index f4e4672..909c78a 100644
--- a/lib/efi_selftest/efi_selftest_tpl.c
+++ b/lib/efi_selftest/efi_selftest_tpl.c
@@ -10,8 +10,8 @@
#include <efi_selftest.h>
-static struct efi_event *event_notify;
-static struct efi_event *event_wait;
+static struct efi_event *efi_st_event_notify;
+static struct efi_event *efi_st_event_wait;
static unsigned int notification_count;
static struct efi_boot_services *boottime;
@@ -49,13 +49,14 @@ static int setup(const efi_handle_t handle,
ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
TPL_CALLBACK, notify,
(void *)&notification_count,
- &event_notify);
+ &efi_st_event_notify);
if (ret != EFI_SUCCESS) {
efi_st_error("could not create event\n");
return EFI_ST_FAILURE;
}
ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT,
- TPL_NOTIFY, notify, NULL, &event_wait);
+ TPL_NOTIFY, notify, NULL,
+ &efi_st_event_wait);
if (ret != EFI_SUCCESS) {
efi_st_error("could not create event\n");
return EFI_ST_FAILURE;
@@ -74,17 +75,17 @@ static int teardown(void)
{
efi_status_t ret;
- if (event_notify) {
- ret = boottime->close_event(event_notify);
- event_notify = NULL;
+ if (efi_st_event_notify) {
+ ret = boottime->close_event(efi_st_event_notify);
+ efi_st_event_notify = NULL;
if (ret != EFI_SUCCESS) {
efi_st_error("could not close event\n");
return EFI_ST_FAILURE;
}
}
- if (event_wait) {
- ret = boottime->close_event(event_wait);
- event_wait = NULL;
+ if (efi_st_event_wait) {
+ ret = boottime->close_event(efi_st_event_wait);
+ efi_st_event_wait = NULL;
if (ret != EFI_SUCCESS) {
efi_st_error("could not close event\n");
return EFI_ST_FAILURE;
@@ -116,24 +117,26 @@ static int execute(void)
/* Set 10 ms timer */
notification_count = 0;
- ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000);
+ ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_PERIODIC,
+ 100000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
/* Set 100 ms timer */
- ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 1000000);
+ ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE,
+ 1000000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
index = 5;
- ret = boottime->wait_for_event(1, &event_wait, &index);
+ ret = boottime->wait_for_event(1, &efi_st_event_wait, &index);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not wait for event\n");
return EFI_ST_FAILURE;
}
- ret = boottime->check_event(event_wait);
+ ret = boottime->check_event(efi_st_event_wait);
if (ret != EFI_NOT_READY) {
efi_st_error("Signaled state was not cleared.\n");
efi_st_printf("ret = %u\n", (unsigned int)ret);
@@ -150,7 +153,7 @@ static int execute(void)
efi_st_error("Incorrect timing of events\n");
return EFI_ST_FAILURE;
}
- ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0);
+ ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_STOP, 0);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not cancel timer\n");
return EFI_ST_FAILURE;
@@ -163,19 +166,21 @@ static int execute(void)
}
/* Set 10 ms timer */
notification_count = 0;
- ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000);
+ ret = boottime->set_timer(efi_st_event_notify, EFI_TIMER_PERIODIC,
+ 100000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
/* Set 100 ms timer */
- ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 1000000);
+ ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE,
+ 1000000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
do {
- ret = boottime->check_event(event_wait);
+ ret = boottime->check_event(efi_st_event_wait);
} while (ret == EFI_NOT_READY);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not check event\n");
@@ -189,14 +194,14 @@ static int execute(void)
return EFI_ST_FAILURE;
}
/* Set 1 ms timer */
- ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 1000);
+ ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE, 1000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
/* Restore the old TPL level */
boottime->restore_tpl(TPL_APPLICATION);
- ret = boottime->wait_for_event(1, &event_wait, &index);
+ ret = boottime->wait_for_event(1, &efi_st_event_wait, &index);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not wait for event\n");
return EFI_ST_FAILURE;
@@ -208,7 +213,7 @@ static int execute(void)
efi_st_error("Queued timer event did not fire\n");
return EFI_ST_FAILURE;
}
- ret = boottime->set_timer(event_wait, EFI_TIMER_STOP, 0);
+ ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_STOP, 0);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not cancel timer\n");
return EFI_ST_FAILURE;
diff --git a/lib/efi_selftest/efi_selftest_watchdog.c b/lib/efi_selftest/efi_selftest_watchdog.c
index a352d4a..4d7ed5a 100644
--- a/lib/efi_selftest/efi_selftest_watchdog.c
+++ b/lib/efi_selftest/efi_selftest_watchdog.c
@@ -28,8 +28,8 @@ struct notify_context {
unsigned int timer_ticks;
};
-static struct efi_event *event_notify;
-static struct efi_event *event_wait;
+static struct efi_event *efi_st_event_notify;
+static struct efi_event *efi_st_event_wait;
static struct efi_boot_services *boottime;
static struct notify_context notification_context;
static bool watchdog_reset;
@@ -79,13 +79,14 @@ static int setup(const efi_handle_t handle,
ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
TPL_CALLBACK, notify,
(void *)&notification_context,
- &event_notify);
+ &efi_st_event_notify);
if (ret != EFI_SUCCESS) {
efi_st_error("could not create event\n");
return EFI_ST_FAILURE;
}
ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_WAIT,
- TPL_CALLBACK, notify, NULL, &event_wait);
+ TPL_CALLBACK, notify, NULL,
+ &efi_st_event_wait);
if (ret != EFI_SUCCESS) {
efi_st_error("could not create event\n");
return EFI_ST_FAILURE;
@@ -138,17 +139,17 @@ static int teardown(void)
efi_st_error("Setting watchdog timer failed\n");
return EFI_ST_FAILURE;
}
- if (event_notify) {
- ret = boottime->close_event(event_notify);
- event_notify = NULL;
+ if (efi_st_event_notify) {
+ ret = boottime->close_event(efi_st_event_notify);
+ efi_st_event_notify = NULL;
if (ret != EFI_SUCCESS) {
efi_st_error("Could not close event\n");
return EFI_ST_FAILURE;
}
}
- if (event_wait) {
- ret = boottime->close_event(event_wait);
- event_wait = NULL;
+ if (efi_st_event_wait) {
+ ret = boottime->close_event(efi_st_event_wait);
+ efi_st_event_wait = NULL;
if (ret != EFI_SUCCESS) {
efi_st_error("Could not close event\n");
return EFI_ST_FAILURE;
@@ -181,21 +182,22 @@ static int execute(void)
}
if (watchdog_reset) {
/* Set 600 ms timer */
- ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC,
- 6000000);
+ ret = boottime->set_timer(efi_st_event_notify,
+ EFI_TIMER_PERIODIC, 6000000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
}
/* Set 1350 ms timer */
- ret = boottime->set_timer(event_wait, EFI_TIMER_RELATIVE, 13500000);
+ ret = boottime->set_timer(efi_st_event_wait, EFI_TIMER_RELATIVE,
+ 13500000);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE;
}
- ret = boottime->wait_for_event(1, &event_wait, &index);
+ ret = boottime->wait_for_event(1, &efi_st_event_wait, &index);
if (ret != EFI_SUCCESS) {
efi_st_error("Could not wait for event\n");
return EFI_ST_FAILURE;
diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py
index db6b8d3..406131c 100644
--- a/test/py/tests/test_efi_secboot/conftest.py
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -2,18 +2,12 @@
# Copyright (c) 2019, Linaro Limited
# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
-import os
-import os.path
-from subprocess import call, check_call, check_output, CalledProcessError
+""" Fixture for UEFI secure boot test """
+
+from subprocess import call, check_call, CalledProcessError
import pytest
from defs import *
-
-#
-# Fixture for UEFI secure boot test
-#
-
-
@pytest.fixture(scope='session')
def efi_boot_env(request, u_boot_config):
"""Set up a file system to be used in UEFI secure boot test.