[U-Boot] [PATCH 0/2] efi_loader: adjust definitions of variable services

The definitons of the variable services are adjusted: - use efi_uintn_t instead of unsigned long - use u16 * instead of s16 * for Unicode strings - correct definition of QueryVariableInfo - rename efi_get_next_variable to efi_get_next_variable_name
A unit test for the variable services is supplied.
Heinrich Schuchardt (2): efi_loader: adjust definitions of variable services efi_selftest: unit test for variable services
include/efi_api.h | 20 ++++++++++---------- include/efi_loader.h | 14 +++++++------- lib/efi_loader/efi_bootmgr.c | 10 +++++----- lib/efi_loader/efi_runtime.c | 10 +++++----- lib/efi_loader/efi_variable.c | 18 +++++++++--------- lib/efi_selftest/Makefile | 1 + 6 files changed, 37 insertions(+), 36 deletions(-)

The definitons of the variable services are adjusted: - use efi_uintn_t instead of unsigned long - use u16 * instead of s16 * for Unicode strings - correct definition of QueryVariableInfo - rename efi_get_next_variable to efi_get_next_variable_name
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de --- include/efi_api.h | 24 ++++++++++++------------ include/efi_loader.h | 18 +++++++++--------- lib/efi_loader/efi_bootmgr.c | 10 +++++----- lib/efi_loader/efi_runtime.c | 10 +++++----- lib/efi_loader/efi_variable.c | 24 ++++++++++++------------ 5 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/include/efi_api.h b/include/efi_api.h index 64c27e494bc..094be6edf9b 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -214,15 +214,15 @@ struct efi_runtime_services { uint32_t descriptor_version, struct efi_mem_desc *virtmap); efi_status_t (*convert_pointer)(unsigned long dbg, void **address); - efi_status_t (EFIAPI *get_variable)(s16 *variable_name, - efi_guid_t *vendor, u32 *attributes, - unsigned long *data_size, void *data); - efi_status_t (EFIAPI *get_next_variable)( - unsigned long *variable_name_size, - s16 *variable_name, efi_guid_t *vendor); - efi_status_t (EFIAPI *set_variable)(s16 *variable_name, - efi_guid_t *vendor, u32 attributes, - unsigned long data_size, void *data); + efi_status_t (EFIAPI *get_variable)(u16 *variable_name, + efi_guid_t *vendor, u32 *attributes, + efi_uintn_t *data_size, void *data); + efi_status_t (EFIAPI *get_next_variable_name)( + efi_uintn_t *variable_name_size, + u16 *variable_name, efi_guid_t *vendor); + efi_status_t (EFIAPI *set_variable)(u16 *variable_name, + efi_guid_t *vendor, u32 attributes, + efi_uintn_t data_size, void *data); efi_status_t (EFIAPI *get_next_high_mono_count)( uint32_t *high_count); void (EFIAPI *reset_system)(enum efi_reset_type reset_type, @@ -239,9 +239,9 @@ struct efi_runtime_services { u32 reset_type); efi_status_t (EFIAPI *query_variable_info)( u32 attributes, - u64 maximum_variable_storage_size, - u64 remaining_variable_storage_size, - u64 maximum_variable_size); + u64 *maximum_variable_storage_size, + u64 *remaining_variable_storage_size, + u64 *maximum_variable_size); };
/* EFI event group GUID definitions */ diff --git a/include/efi_loader.h b/include/efi_loader.h index 2868ca25abb..4e9e9d05c76 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -415,15 +415,15 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, struct efi_system_table *systab); #endif
-efi_status_t EFIAPI efi_get_variable(s16 *variable_name, - efi_guid_t *vendor, u32 *attributes, - unsigned long *data_size, void *data); -efi_status_t EFIAPI efi_get_next_variable( - unsigned long *variable_name_size, - s16 *variable_name, efi_guid_t *vendor); -efi_status_t EFIAPI efi_set_variable(s16 *variable_name, - efi_guid_t *vendor, u32 attributes, - unsigned long data_size, void *data); +efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, + u32 *attributes, efi_uintn_t *data_size, + void *data); +efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, + u16 *variable_name, + efi_guid_t *vendor); +efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor, + u32 attributes, efi_uintn_t data_size, + void *data);
void *efi_bootmgr_load(struct efi_device_path **device_path, struct efi_device_path **file_path); diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 153e1737573..853358ab937 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -70,17 +70,17 @@ static void parse_load_option(struct load_option *lo, void *ptr)
/* free() the result */ static void *get_var(u16 *name, const efi_guid_t *vendor, - unsigned long *size) + efi_uintn_t *size) { efi_guid_t *v = (efi_guid_t *)vendor; efi_status_t ret; void *buf = NULL;
*size = 0; - EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf)); + EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf)); if (ret == EFI_BUFFER_TOO_SMALL) { buf = malloc(*size); - EFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf)); + EFI_CALL(ret = rs->get_variable(name, v, NULL, size, buf)); }
if (ret != EFI_SUCCESS) { @@ -104,7 +104,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path, u16 varname[] = L"Boot0000"; u16 hexmap[] = L"0123456789ABCDEF"; void *load_option, *image = NULL; - unsigned long size; + efi_uintn_t size;
varname[4] = hexmap[(n & 0xf000) >> 12]; varname[5] = hexmap[(n & 0x0f00) >> 8]; @@ -147,7 +147,7 @@ void *efi_bootmgr_load(struct efi_device_path **device_path, struct efi_device_path **file_path) { uint16_t *bootorder; - unsigned long size; + efi_uintn_t size; void *image = NULL; int i, num;
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 779e1e1d78d..9ea9493c8b5 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -200,7 +200,7 @@ static const struct efi_runtime_detach_list_struct efi_runtime_detach_list[] = { .ptr = &efi_runtime_services.get_variable, .patchto = &efi_device_error, }, { - .ptr = &efi_runtime_services.get_next_variable, + .ptr = &efi_runtime_services.get_next_variable_name, .patchto = &efi_device_error, }, { .ptr = &efi_runtime_services.set_variable, @@ -420,9 +420,9 @@ efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps(
efi_status_t __efi_runtime EFIAPI efi_query_variable_info( u32 attributes, - u64 maximum_variable_storage_size, - u64 remaining_variable_storage_size, - u64 maximum_variable_size) + u64 *maximum_variable_storage_size, + u64 *remaining_variable_storage_size, + u64 *maximum_variable_size) { return EFI_UNSUPPORTED; } @@ -440,7 +440,7 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = { .set_virtual_address_map = &efi_set_virtual_address_map, .convert_pointer = (void *)&efi_invalid_parameter, .get_variable = efi_get_variable, - .get_next_variable = efi_get_next_variable, + .get_next_variable_name = efi_get_next_variable_name, .set_variable = efi_set_variable, .get_next_high_mono_count = (void *)&efi_device_error, .reset_system = &efi_reset_system_boottime, diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 45454118f2a..90b637215e4 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -101,8 +101,8 @@ static char *mem2hex(char *hexstr, const u8 *mem, int count) return hexstr; }
-static efi_status_t efi_to_native(char *native, s16 *variable_name, - efi_guid_t *vendor) +static efi_status_t efi_to_native(char *native, u16 *variable_name, + efi_guid_t *vendor) { size_t len;
@@ -164,9 +164,9 @@ static const char *parse_attr(const char *str, u32 *attrp) }
/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetVariable.28.2... */ -efi_status_t EFIAPI efi_get_variable(s16 *variable_name, - efi_guid_t *vendor, u32 *attributes, - unsigned long *data_size, void *data) +efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, + u32 *attributes, efi_uintn_t *data_size, + void *data) { char native_name[MAX_NATIVE_VAR_NAME + 1]; efi_status_t ret; @@ -242,9 +242,9 @@ efi_status_t EFIAPI efi_get_variable(s16 *variable_name, }
/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableN... */ -efi_status_t EFIAPI efi_get_next_variable( - unsigned long *variable_name_size, - s16 *variable_name, efi_guid_t *vendor) +efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, + u16 *variable_name, + efi_guid_t *vendor) { EFI_ENTRY("%p "%ls" %pUl", variable_name_size, variable_name, vendor);
@@ -252,16 +252,16 @@ efi_status_t EFIAPI efi_get_next_variable( }
/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVariable.28.2... */ -efi_status_t EFIAPI efi_set_variable(s16 *variable_name, - efi_guid_t *vendor, u32 attributes, - unsigned long data_size, void *data) +efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor, + u32 attributes, efi_uintn_t data_size, + void *data) { char native_name[MAX_NATIVE_VAR_NAME + 1]; efi_status_t ret = EFI_SUCCESS; char *val, *s; u32 attr;
- EFI_ENTRY(""%ls" %pUl %x %lu %p", variable_name, vendor, attributes, + EFI_ENTRY(""%ls" %pUl %x %zu %p", variable_name, vendor, attributes, data_size, data);
if (!variable_name || !vendor)

Provide a unit test for variable services.
Signed-off-by: Heinrich Schuchardt xypron.glpk@gmx.de --- lib/efi_selftest/Makefile | 1 + lib/efi_selftest/efi_selftest_variables.c | 178 ++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_variables.c
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 80c43026458..2b943bc4d84 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -28,6 +28,7 @@ efi_selftest_textinput.o \ efi_selftest_textoutput.o \ efi_selftest_tpl.o \ efi_selftest_util.o \ +efi_selftest_variables.o \ efi_selftest_watchdog.o
ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy) diff --git a/lib/efi_selftest/efi_selftest_variables.c b/lib/efi_selftest/efi_selftest_variables.c new file mode 100644 index 00000000000..992f45d60a5 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_variables.c @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * efi_selftest_variables + * + * Copyright (c) 2018 Heinrich Schuchardt xypron.glpk@gmx.de + * + * This unit test checks the following protocol services: + * ConnectController, DisconnectController, + * InstallProtocol, ReinstallProtocol, UninstallProtocol, + * OpenProtocol, CloseProtcol, OpenProtocolInformation + */ + +#include <efi_selftest.h> + +#define EFI_ST_MAX_DATA_SIZE 16 +#define EFI_ST_MAX_VARNAME_SIZE 40 + +static struct efi_boot_services *boottime; +static struct efi_runtime_services *runtime; +static efi_guid_t guid_vendor0 = + EFI_GUID(0x67029eb5, 0x0af2, 0xf6b1, + 0xda, 0x53, 0xfc, 0xb5, 0x66, 0xdd, 0x1c, 0xe6); +static efi_guid_t guid_vendor1 = + EFI_GUID(0xff629290, 0x1fc1, 0xd73f, + 0x8f, 0xb1, 0x32, 0xf9, 0x0c, 0xa0, 0x42, 0xea); + +/* + * Setup unit test. + * + * @handle handle of the loaded image + * @systable system table + */ +static int setup(const efi_handle_t img_handle, + const struct efi_system_table *systable) +{ + boottime = systable->boottime; + runtime = systable->runtime; + + return EFI_ST_SUCCESS; +} + +/* + * Execute unit test. + */ +static int execute(void) +{ + efi_status_t ret; + efi_uintn_t len; + u32 attr; + u8 v[16] = {0x5d, 0xd1, 0x5e, 0x51, 0x5a, 0x05, 0xc7, 0x0c, + 0x35, 0x4a, 0xae, 0x87, 0xa5, 0xdf, 0x0f, 0x65,}; + u8 *data[EFI_ST_MAX_DATA_SIZE]; + u16 varname[EFI_ST_MAX_VARNAME_SIZE]; + int flag; + efi_guid_t guid; + u64 max_storage, rem_storage, max_size; + + ret = runtime->query_variable_info(EFI_VARIABLE_BOOTSERVICE_ACCESS, + &max_storage, &rem_storage, + &max_size); + if (ret != EFI_SUCCESS) { + efi_st_todo("QueryVariableInfo failed\n"); + } else if (!max_storage || !rem_storage || !max_size) { + efi_st_error("QueryVariableInfo: wrong info\n"); + return EFI_ST_FAILURE; + } + /* Set variable 0 */ + ret = runtime->set_variable(L"efi_st_var0", &guid_vendor0, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + 3, v + 4); + if (ret != EFI_SUCCESS) { + efi_st_error("SetVariable failed\n"); + return EFI_ST_FAILURE; + } + /* Set variable 1 */ + ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + 8, v); + if (ret != EFI_SUCCESS) { + efi_st_error("SetVariable failed\n"); + return EFI_ST_FAILURE; + } + len = EFI_ST_MAX_DATA_SIZE; + ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1, + &attr, &len, data); + if (ret != EFI_SUCCESS) { + efi_st_error("GetVariable failed\n"); + return EFI_ST_FAILURE; + } + if (len != 8) { + efi_st_error("GetVariable returned wrong length %u\n", len); + return EFI_ST_FAILURE; + } + if (efi_st_memcmp(data, v, 8)) { + efi_st_error("GetVariable returned wrong value\n"); + return EFI_ST_FAILURE; + } + /* Append variable 1 */ + ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_APPEND_WRITE, + 7, v + 8); + if (ret != EFI_SUCCESS) { + efi_st_error("SetVariable failed\n"); + return EFI_ST_FAILURE; + } + len = EFI_ST_MAX_DATA_SIZE; + ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1, + &attr, &len, data); + if (ret != EFI_SUCCESS) { + efi_st_error("GetVariable failed\n"); + return EFI_ST_FAILURE; + } + if (len != 15) + efi_st_todo("GetVariable returned wrong length %u\n", len); + if (efi_st_memcmp(data, v, len)) + efi_st_todo("GetVariable returned wrong value\n"); + /* Enumerate variables */ + boottime->set_mem(&guid, 16, 0); + *varname = 0; + flag = 0; + for (;;) { + len = EFI_ST_MAX_VARNAME_SIZE; + ret = runtime->get_next_variable_name(&len, varname, &guid); + if (ret == EFI_NOT_FOUND) + break; + if (ret != EFI_SUCCESS) { + efi_st_todo("GetNextVariableName failed\n"); + break; + } + if (!efi_st_memcmp(&guid, &guid_vendor0, sizeof(efi_guid_t)) && + !efi_st_strcmp_16_8(varname, "efi_st_var0")) + flag |= 2; + if (!efi_st_memcmp(&guid, &guid_vendor1, sizeof(efi_guid_t)) && + !efi_st_strcmp_16_8(varname, "efi_st_var1")) + flag |= 2; + } + if (flag != 3) + efi_st_todo( + "GetNextVariableName did not return all variables\n"); + /* Delete variable 1 */ + ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1, + 0, 0, NULL); + if (ret != EFI_SUCCESS) { + efi_st_error("SetVariable failed\n"); + return EFI_ST_FAILURE; + } + len = EFI_ST_MAX_DATA_SIZE; + ret = runtime->get_variable(L"efi_st_var1", &guid_vendor1, + &attr, &len, data); + if (ret != EFI_NOT_FOUND) { + efi_st_error("Variable was not deleted\n"); + return EFI_ST_FAILURE; + } + /* Delete variable 0 */ + ret = runtime->set_variable(L"efi_st_var0", &guid_vendor0, + 0, 0, NULL); + if (ret != EFI_SUCCESS) { + efi_st_error("SetVariable failed\n"); + return EFI_ST_FAILURE; + } + len = EFI_ST_MAX_DATA_SIZE; + ret = runtime->get_variable(L"efi_st_var0", &guid_vendor0, + &attr, &len, data); + if (ret != EFI_NOT_FOUND) { + efi_st_error("Variable was not deleted\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(variables) = { + .name = "variables", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, +};
participants (1)
-
Heinrich Schuchardt