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
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmM/VwAACgkQxIHbvCwF
 GsRtgQ//b2KU6grVe1jImsElzdWYC0D2uiRWBq9xkaVFUThqvkyBX9qpUghzXWfo
 D8wBAT1FN4xgVJfo6ex/R8AcAYRnEOL1ClcxrDWikH2m+Xwy4xzuH8qSUzK6NX0O
 HB4n4Z/WlNHuur4WXBn6sga84eAudoOrz5net8f7Q7YhGdG/u1vCvvGflDKvKDNP
 8YP05i2PdeeO0mDfEWXvRkEqK2dfXawGNewBwS7Kj3F9gDML9jjLB0OjPTlT4h88
 KwzZHJa/RlNMvSZUKry63BvHt5N44eBYh7TA7SoKMluUHHv76zNWttCIjqa+RMkn
 H9VQfnSPUbRbxaidyCDzTHOS+vX46lNO3ktneV+99D4ROYkdF+QbLtbcIoz/VngS
 +kd5al5jq3DdCorpQtqhpzpQBteHHr/FyndFp0dBv5NOb+650W04YsStXVFtlC6j
 //udbvIMWPSAuLTZA5dm6NySnZFI6JFeIQIh94AiUHCF3Y55Xl9dTM+pu+ceCt/F
 wdyQ1BEQ8wSeinSsUsf47fNrYBLzhb7QuOyoUYTOvegohgpi+I8LgEYGJQ5r5mZR
 0KFw2lmSnGPJj1/seaCXAr2/Mw2p/3V44e1JzcG+uobG/Z/7fWLGCuqksLoYxt/e
 Eo/mq/l5J92x83qaVvTMRmYQ1BSEFtO2YFeEsN4OyeSkvnD9HQM=
 =kEiJ
 -----END PGP SIGNATURE-----

Merge tag 'efi-2023-01-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi

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
This commit is contained in:
Tom Rini 2022-10-07 11:51:05 -04:00
commit 11ef7f07ce
27 changed files with 553 additions and 418 deletions

View file

@ -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>

View file

@ -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

View file

@ -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,79 +345,11 @@ 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
*
@ -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"

View file

@ -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;
}

View file

@ -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
------------

View file

@ -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

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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
*
* @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
* the EFI driver.
* @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.
*
* @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
* 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
* the EFI driver.
* @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;
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 */

View file

@ -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;

View file

@ -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;
if (efi_link_dev(handle, bdev)) {
ret = EFI_OUT_OF_RESOURCES;
goto err;
}
ret = device_probe(bdev);
if (ret)
return ret;
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,
};

View file

@ -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;
}
/**

View file

@ -2589,6 +2589,75 @@ found:
return EFI_EXIT(EFI_SUCCESS);
}
/**
* efi_install_multiple_protocol_interfaces_int() - Install multiple protocol
* interfaces
* @handle: handle on which the protocol interfaces shall be installed
* @argptr: va_list of args
*
* Core functionality of efi_install_multiple_protocol_interfaces
* Must not be called directly
*
* Return: status code
*/
static efi_status_t EFIAPI
efi_install_multiple_protocol_interfaces_int(efi_handle_t *handle,
efi_va_list argptr)
{
const efi_guid_t *protocol;
void *protocol_interface;
efi_handle_t old_handle;
efi_status_t ret = EFI_SUCCESS;
int i = 0;
efi_va_list argptr_copy;
if (!handle)
return EFI_INVALID_PARAMETER;
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*);
/* Check that a device path has not been installed before */
if (!guidcmp(protocol, &efi_guid_device_path)) {
struct efi_device_path *dp = protocol_interface;
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);
ret = EFI_ALREADY_STARTED;
break;
}
}
ret = EFI_CALL(efi_install_protocol_interface(handle, protocol,
EFI_NATIVE_INTERFACE,
protocol_interface));
if (ret != EFI_SUCCESS)
break;
i++;
}
if (ret == EFI_SUCCESS)
goto out;
/* If an error occurred undo all changes. */
for (; i; --i) {
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));
}
out:
efi_va_end(argptr_copy);
return ret;
}
/**
* efi_install_multiple_protocol_interfaces() - Install multiple protocol
* interfaces
@ -2596,6 +2665,32 @@ found:
* @...: NULL terminated argument list with pairs of protocol GUIDS and
* interfaces
*
*
* 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
@ -2603,64 +2698,84 @@ found:
*
* 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_ext(efi_handle_t *handle, ...)
{
EFI_ENTRY("%p", handle);
efi_status_t ret;
efi_va_list argptr;
const efi_guid_t *protocol;
void *protocol_interface;
efi_handle_t old_handle;
efi_status_t r = EFI_SUCCESS;
int i = 0;
if (!handle)
return EFI_EXIT(EFI_INVALID_PARAMETER);
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 ret;
size_t i = 0;
efi_va_list argptr_copy;
if (!handle)
return EFI_INVALID_PARAMETER;
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*);
/* Check that a device path has not been installed before */
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 &&
dp->type == DEVICE_PATH_TYPE_END) {
EFI_PRINT("Path %pD already installed\n",
protocol_interface);
r = EFI_ALREADY_STARTED;
break;
}
}
r = EFI_CALL(efi_install_protocol_interface(
handle, protocol,
EFI_NATIVE_INTERFACE,
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)
return EFI_EXIT(r);
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);
}
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*);
EFI_CALL(efi_uninstall_protocol_interface(*handle, protocol,
protocol_interface));
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));
}
efi_va_end(argptr);
/*
* 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;
return EFI_EXIT(r);
out:
efi_va_end(argptr_copy);
return ret;
}
/**
@ -2672,60 +2787,49 @@ efi_status_t EFIAPI efi_install_multiple_protocol_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(
efi_handle_t handle, ...)
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;
const efi_guid_t *protocol;
void *protocol_interface;
efi_status_t r = EFI_SUCCESS;
size_t i = 0;
if (!handle)
return EFI_EXIT(EFI_INVALID_PARAMETER);
efi_va_start(argptr, handle);
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)
break;
i++;
}
ret = efi_uninstall_multiple_protocol_interfaces_int(handle, argptr);
efi_va_end(argptr);
if (r == 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);
}
/* 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*);
EFI_CALL(efi_install_protocol_interface(&handle, protocol,
EFI_NATIVE_INTERFACE,
protocol_interface));
}
efi_va_end(argptr);
/* In case of an error always return EFI_INVALID_PARAMETER */
return EFI_EXIT(EFI_INVALID_PARAMETER);
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,

View file

@ -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;

View file

@ -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)) {

View file

@ -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;
}

View file

@ -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
*

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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.