aboutsummaryrefslogtreecommitdiff
path: root/lib/efi_loader
diff options
context:
space:
mode:
Diffstat (limited to 'lib/efi_loader')
-rw-r--r--lib/efi_loader/Kconfig34
-rw-r--r--lib/efi_loader/Makefile5
-rw-r--r--lib/efi_loader/efi_bootmgr.c135
-rw-r--r--lib/efi_loader/efi_dt_fixup.c34
-rw-r--r--lib/efi_loader/efi_load_options.c149
-rw-r--r--lib/efi_loader/efi_root_node.c10
-rw-r--r--lib/efi_loader/efi_unicode_collation.c39
-rw-r--r--lib/efi_loader/efi_var_mem.c13
-rw-r--r--lib/efi_loader/efi_variable_tee.c2
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 */