diff options
Diffstat (limited to 'lib/efi_loader')
-rw-r--r-- | lib/efi_loader/Kconfig | 34 | ||||
-rw-r--r-- | lib/efi_loader/Makefile | 5 | ||||
-rw-r--r-- | lib/efi_loader/efi_bootmgr.c | 135 | ||||
-rw-r--r-- | lib/efi_loader/efi_dt_fixup.c | 34 | ||||
-rw-r--r-- | lib/efi_loader/efi_load_options.c | 149 | ||||
-rw-r--r-- | lib/efi_loader/efi_root_node.c | 10 | ||||
-rw-r--r-- | lib/efi_loader/efi_unicode_collation.c | 39 | ||||
-rw-r--r-- | lib/efi_loader/efi_var_mem.c | 13 | ||||
-rw-r--r-- | lib/efi_loader/efi_variable_tee.c | 2 |
9 files changed, 217 insertions, 204 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index fdf245dea30..e729f727df1 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -27,6 +27,14 @@ config EFI_LOADER if EFI_LOADER +config CMD_BOOTEFI_BOOTMGR + bool "UEFI Boot Manager" + default y + help + Select this option if you want to select the UEFI binary to be booted + via UEFI variables Boot####, BootOrder, and BootNext. This enables the + 'bootefi bootmgr' command. + config EFI_SETUP_EARLY bool default n @@ -200,6 +208,21 @@ config EFI_DEVICE_PATH_TO_TEXT The device path to text protocol converts device nodes and paths to human readable strings. +config EFI_DEVICE_PATH_UTIL + bool "Device path utilities protocol" + default y + help + The device path utilities protocol creates and manipulates device + paths and device nodes. It is required to run the EFI Shell. + +config EFI_DT_FIXUP + bool "Device tree fixup protocol" + depends on !GENERATE_ACPI_TABLE + default y + help + The EFI device-tree fix-up protocol provides a function to let the + firmware apply fix-ups. This may be used by boot loaders. + config EFI_LOADER_HII bool "HII protocols" default y @@ -229,17 +252,6 @@ config EFI_UNICODE_CAPITALIZATION set, only the the correct handling of the letters of the codepage used by the FAT file system is ensured. -config EFI_UNICODE_COLLATION_PROTOCOL - bool "Deprecated version of the Unicode collation protocol" - default n - help - In EFI 1.10 a version of the Unicode collation protocol using ISO - 639-2 language codes existed. This protocol is not part of the UEFI - specification any longer. Unfortunately it is required to run the - UEFI Self Certification Test (SCT) II, version 2.6, 2017. - - Choose this option for testing only. It is bound to be removed. - endif config EFI_LOADER_BOUNCE_BUFFER diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 412fa882455..10b42e8847b 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -21,20 +21,21 @@ targets += helloworld.o endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o -obj-y += efi_bootmgr.o +obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o obj-y += efi_boottime.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o -obj-y += efi_device_path_utilities.o +obj-$(CONFIG_EFI_DEVICE_PATH_UTIL) += efi_device_path_utilities.o ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) obj-y += efi_dt_fixup.o endif obj-y += efi_file.o obj-$(CONFIG_EFI_LOADER_HII) += efi_hii.o obj-y += efi_image_loader.o +obj-y += efi_load_options.o obj-y += efi_memory.o obj-y += efi_root_node.o obj-y += efi_runtime.o diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index d3be2f94c60..25f5cebfdb6 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -31,141 +31,6 @@ static const struct efi_runtime_services *rs; */ /** - * efi_set_load_options() - set the load options of a loaded image - * - * @handle: the image handle - * @load_options_size: size of load options - * @load_options: pointer to load options - * Return: status code - */ -efi_status_t efi_set_load_options(efi_handle_t handle, - efi_uintn_t load_options_size, - void *load_options) -{ - struct efi_loaded_image *loaded_image_info; - efi_status_t ret; - - ret = EFI_CALL(systab.boottime->open_protocol( - handle, - &efi_guid_loaded_image, - (void **)&loaded_image_info, - efi_root, NULL, - EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); - if (ret != EFI_SUCCESS) - return EFI_INVALID_PARAMETER; - - loaded_image_info->load_options = load_options; - loaded_image_info->load_options_size = load_options_size; - - return EFI_CALL(systab.boottime->close_protocol(handle, - &efi_guid_loaded_image, - efi_root, NULL)); -} - - -/** - * efi_deserialize_load_option() - parse serialized data - * - * Parse serialized data describing a load option and transform it to the - * efi_load_option structure. - * - * @lo: pointer to target - * @data: serialized data - * @size: size of the load option, on return size of the optional data - * Return: status code - */ -efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, - efi_uintn_t *size) -{ - efi_uintn_t len; - - len = sizeof(u32); - if (*size < len + 2 * sizeof(u16)) - return EFI_INVALID_PARAMETER; - lo->attributes = get_unaligned_le32(data); - data += len; - *size -= len; - - len = sizeof(u16); - lo->file_path_length = get_unaligned_le16(data); - data += len; - *size -= len; - - lo->label = (u16 *)data; - len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); - if (lo->label[len]) - return EFI_INVALID_PARAMETER; - len = (len + 1) * sizeof(u16); - if (*size < len) - return EFI_INVALID_PARAMETER; - data += len; - *size -= len; - - len = lo->file_path_length; - if (*size < len) - return EFI_INVALID_PARAMETER; - lo->file_path = (struct efi_device_path *)data; - if (efi_dp_check_length(lo->file_path, len) < 0) - return EFI_INVALID_PARAMETER; - data += len; - *size -= len; - - lo->optional_data = data; - - return EFI_SUCCESS; -} - -/** - * efi_serialize_load_option() - serialize load option - * - * Serialize efi_load_option structure into byte stream for BootXXXX. - * - * @data: buffer for serialized data - * @lo: load option - * Return: size of allocated buffer - */ -unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) -{ - unsigned long label_len; - unsigned long size; - u8 *p; - - label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); - - /* total size */ - size = sizeof(lo->attributes); - size += sizeof(lo->file_path_length); - size += label_len; - size += lo->file_path_length; - if (lo->optional_data) - size += (utf8_utf16_strlen((const char *)lo->optional_data) - + 1) * sizeof(u16); - p = malloc(size); - if (!p) - return 0; - - /* copy data */ - *data = p; - memcpy(p, &lo->attributes, sizeof(lo->attributes)); - p += sizeof(lo->attributes); - - memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); - p += sizeof(lo->file_path_length); - - memcpy(p, lo->label, label_len); - p += label_len; - - memcpy(p, lo->file_path, lo->file_path_length); - p += lo->file_path_length; - - if (lo->optional_data) { - utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); - p += sizeof(u16); /* size of trailing \0 */ - } - return size; -} - -/** * get_var() - get UEFI variable * * It is the caller's duty to free the returned buffer. diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index 5f0ae5c3383..3850ab3b0fe 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -10,16 +10,6 @@ #include <efi_loader.h> #include <mapmem.h> -static efi_status_t EFIAPI efi_dt_fixup(struct efi_dt_fixup_protocol *this, - void *dtb, - efi_uintn_t *buffer_size, - u32 flags); - -struct efi_dt_fixup_protocol efi_dt_fixup_prot = { - .revision = EFI_DT_FIXUP_PROTOCOL_REVISION, - .fixup = efi_dt_fixup -}; - const efi_guid_t efi_guid_dt_fixup_protocol = EFI_DT_FIXUP_PROTOCOL_GUID; /** @@ -102,10 +92,21 @@ void efi_carve_out_dt_rsv(void *fdt) } } -static efi_status_t EFIAPI efi_dt_fixup(struct efi_dt_fixup_protocol *this, - void *dtb, - efi_uintn_t *buffer_size, - u32 flags) +/** + * efi_dt_fixup() - fix up device tree + * + * This function implements the Fixup() service of the + * EFI Device Tree Fixup Protocol. + * + * @this: instance of the protocol + * @dtb: device tree provided by caller + * @buffer_size: size of buffer for the device tree including free space + * @flags: bit field designating action to be performed + * Return: status code + */ +static efi_status_t __maybe_unused EFIAPI +efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, + efi_uintn_t *buffer_size, u32 flags) { efi_status_t ret; size_t required_size; @@ -158,3 +159,8 @@ static efi_status_t EFIAPI efi_dt_fixup(struct efi_dt_fixup_protocol *this, out: return EFI_EXIT(ret); } + +struct efi_dt_fixup_protocol efi_dt_fixup_prot = { + .revision = EFI_DT_FIXUP_PROTOCOL_REVISION, + .fixup = efi_dt_fixup +}; diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c new file mode 100644 index 00000000000..68cd85ba2ee --- /dev/null +++ b/lib/efi_loader/efi_load_options.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI boot manager + * + * Copyright (c) 2018 AKASHI Takahiro, et.al. + */ + +#define LOG_CATEGORY LOGC_EFI + +#include <common.h> +#include <charset.h> +#include <log.h> +#include <malloc.h> +#include <efi_loader.h> +#include <asm/unaligned.h> + +/** + * efi_set_load_options() - set the load options of a loaded image + * + * @handle: the image handle + * @load_options_size: size of load options + * @load_options: pointer to load options + * Return: status code + */ +efi_status_t efi_set_load_options(efi_handle_t handle, + efi_uintn_t load_options_size, + void *load_options) +{ + struct efi_loaded_image *loaded_image_info; + efi_status_t ret; + + ret = EFI_CALL(systab.boottime->open_protocol( + handle, + &efi_guid_loaded_image, + (void **)&loaded_image_info, + efi_root, NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); + if (ret != EFI_SUCCESS) + return EFI_INVALID_PARAMETER; + + loaded_image_info->load_options = load_options; + loaded_image_info->load_options_size = load_options_size; + + return EFI_CALL(systab.boottime->close_protocol(handle, + &efi_guid_loaded_image, + efi_root, NULL)); +} + +/** + * efi_deserialize_load_option() - parse serialized data + * + * Parse serialized data describing a load option and transform it to the + * efi_load_option structure. + * + * @lo: pointer to target + * @data: serialized data + * @size: size of the load option, on return size of the optional data + * Return: status code + */ +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, + efi_uintn_t *size) +{ + efi_uintn_t len; + + len = sizeof(u32); + if (*size < len + 2 * sizeof(u16)) + return EFI_INVALID_PARAMETER; + lo->attributes = get_unaligned_le32(data); + data += len; + *size -= len; + + len = sizeof(u16); + lo->file_path_length = get_unaligned_le16(data); + data += len; + *size -= len; + + lo->label = (u16 *)data; + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); + if (lo->label[len]) + return EFI_INVALID_PARAMETER; + len = (len + 1) * sizeof(u16); + if (*size < len) + return EFI_INVALID_PARAMETER; + data += len; + *size -= len; + + len = lo->file_path_length; + if (*size < len) + return EFI_INVALID_PARAMETER; + lo->file_path = (struct efi_device_path *)data; + if (efi_dp_check_length(lo->file_path, len) < 0) + return EFI_INVALID_PARAMETER; + data += len; + *size -= len; + + lo->optional_data = data; + + return EFI_SUCCESS; +} + +/** + * efi_serialize_load_option() - serialize load option + * + * Serialize efi_load_option structure into byte stream for BootXXXX. + * + * @data: buffer for serialized data + * @lo: load option + * Return: size of allocated buffer + */ +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) +{ + unsigned long label_len; + unsigned long size; + u8 *p; + + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); + + /* total size */ + size = sizeof(lo->attributes); + size += sizeof(lo->file_path_length); + size += label_len; + size += lo->file_path_length; + if (lo->optional_data) + size += (utf8_utf16_strlen((const char *)lo->optional_data) + + 1) * sizeof(u16); + p = malloc(size); + if (!p) + return 0; + + /* copy data */ + *data = p; + memcpy(p, &lo->attributes, sizeof(lo->attributes)); + p += sizeof(lo->attributes); + + memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length)); + p += sizeof(lo->file_path_length); + + memcpy(p, lo->label, label_len); + p += label_len; + + memcpy(p, lo->file_path, lo->file_path_length); + p += lo->file_path_length; + + if (lo->optional_data) { + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); + p += sizeof(u16); /* size of trailing \0 */ + } + return size; +} diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c index b411a12cf66..739c6867f41 100644 --- a/lib/efi_loader/efi_root_node.c +++ b/lib/efi_loader/efi_root_node.c @@ -58,21 +58,17 @@ efi_status_t efi_root_node_register(void) &efi_guid_device_path_to_text_protocol, (void *)&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(GENERATE_ACPI_TABLE) +#endif +#ifdef CONFIG_EFI_DT_FIXUP /* Device-tree fix-up protocol */ &efi_guid_dt_fixup_protocol, (void *)&efi_dt_fixup_prot, #endif #if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL2) -#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL) - /* Deprecated Unicode collation protocol */ - &efi_guid_unicode_collation_protocol, - (void *)&efi_unicode_collation_protocol, -#endif - /* Current Unicode collation protocol */ &efi_guid_unicode_collation_protocol2, (void *)&efi_unicode_collation_protocol2, #endif diff --git a/lib/efi_loader/efi_unicode_collation.c b/lib/efi_loader/efi_unicode_collation.c index 6655c68092e..f6c875bc33c 100644 --- a/lib/efi_loader/efi_unicode_collation.c +++ b/lib/efi_loader/efi_unicode_collation.c @@ -38,7 +38,7 @@ const efi_guid_t efi_guid_unicode_collation_protocol2 = * @s2: second string * * This function implements the StriColl() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. * * See the Unified Extensible Firmware Interface (UEFI) specification for * details. @@ -179,7 +179,7 @@ static bool metai_match(const u16 *string, const u16 *pattern) * - [<char1>-<char2>] matches any character in the range * * This function implements the MetaMatch() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. * * Return: true if the string is matched. */ @@ -204,7 +204,7 @@ static bool EFIAPI efi_metai_match(struct efi_unicode_collation_protocol *this, * same number of words this does not pose a problem. * * This function implements the StrLwr() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. */ static void EFIAPI efi_str_lwr(struct efi_unicode_collation_protocol *this, u16 *string) @@ -225,7 +225,7 @@ static void EFIAPI efi_str_lwr(struct efi_unicode_collation_protocol *this, * same number of words this does not pose a problem. * * This function implements the StrUpr() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. */ static void EFIAPI efi_str_upr(struct efi_unicode_collation_protocol *this, u16 *string) @@ -245,7 +245,7 @@ static void EFIAPI efi_str_upr(struct efi_unicode_collation_protocol *this, * @string: converted string * * This function implements the FatToStr() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. */ static void EFIAPI efi_fat_to_str(struct efi_unicode_collation_protocol *this, efi_uintn_t fat_size, char *fat, u16 *string) @@ -276,7 +276,7 @@ static void EFIAPI efi_fat_to_str(struct efi_unicode_collation_protocol *this, * @fat: converted string * * This function implements the StrToFat() service of the - * EFI_UNICODE_COLLATION_PROTOCOL. + * EFI_UNICODE_COLLATION_PROTOCOL2. * * Return: true if an illegal character was substituted by '_'. */ @@ -337,30 +337,3 @@ const struct efi_unicode_collation_protocol efi_unicode_collation_protocol2 = { .str_to_fat = efi_str_to_fat, .supported_languages = "en", }; - -/* - * In EFI 1.10 a version of the Unicode collation protocol using ISO 639-2 - * language codes existed. This protocol is not part of the UEFI specification - * any longer. Unfortunately it is required to run the UEFI Self Certification - * Test (SCT) II, version 2.6, 2017. So we implement it here for the sole - * purpose of running the SCT. It can be removed when a compliant SCT is - * available. - */ -#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL) - -/* GUID of the EFI_UNICODE_COLLATION_PROTOCOL */ -const efi_guid_t efi_guid_unicode_collation_protocol = - EFI_UNICODE_COLLATION_PROTOCOL_GUID; - -const struct efi_unicode_collation_protocol efi_unicode_collation_protocol = { - .stri_coll = efi_stri_coll, - .metai_match = efi_metai_match, - .str_lwr = efi_str_lwr, - .str_upr = efi_str_upr, - .fat_to_str = efi_fat_to_str, - .str_to_fat = efi_str_to_fat, - /* ISO 639-2 language code */ - .supported_languages = "eng", -}; - -#endif diff --git a/lib/efi_loader/efi_var_mem.c b/lib/efi_loader/efi_var_mem.c index d155f25f60e..3d335a82746 100644 --- a/lib/efi_loader/efi_var_mem.c +++ b/lib/efi_loader/efi_var_mem.c @@ -10,7 +10,13 @@ #include <efi_variable.h> #include <u-boot/crc.h> -struct efi_var_file __efi_runtime_data *efi_var_buf; +/* + * The variables efi_var_file and efi_var_entry must be static to avoid + * referencing them via the global offset table (section .got). The GOT + * is neither mapped as EfiRuntimeServicesData nor do we support its + * relocation during SetVirtualAddressMap(). + */ +static struct efi_var_file __efi_runtime_data *efi_var_buf; static struct efi_var_entry __efi_runtime_data *efi_current_var; /** @@ -339,3 +345,8 @@ efi_get_next_variable_name_mem(efi_uintn_t *variable_name_size, return EFI_SUCCESS; } + +void efi_var_buf_update(struct efi_var_file *var_buf) +{ + memcpy(efi_var_buf, var_buf, EFI_VAR_BUF_SIZE); +} diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c index b8808fdecad..51920bcb51a 100644 --- a/lib/efi_loader/efi_variable_tee.c +++ b/lib/efi_loader/efi_variable_tee.c @@ -702,7 +702,7 @@ void efi_variables_boot_exit_notify(void) if (ret != EFI_SUCCESS) log_err("Can't populate EFI variables. No runtime variables will be available\n"); else - memcpy(efi_var_buf, var_buf, len); + efi_var_buf_update(var_buf); free(var_buf); /* Update runtime service table */ |