summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2024-04-08 14:33:59 -0600
committerTom Rini <[email protected]>2024-04-08 14:33:59 -0600
commit069d07396e30aa9be396c1dd3fc158ac199e6843 (patch)
treef4f2b1af27384f789e5531f9a98cf61ad7f2cdf3 /lib
parent9cba29b19f43f9450117e8bc89e7dda691ed5ab5 (diff)
parent3f8d13044b32ddd906bb9f2fc705b988ec93df35 (diff)
Merge tag 'efi-2024-07-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request efi-2024-07-rc1 Documentation: * improve description of FAT partition name generation * add missing :: in doc/usage/cmd/itest.rst UEFI: * fix address mode for __efi_runtime_start/stop, __efi_runtime_rel_start/stop * fix size of variable attribute constants * enable booting via EFI boot manager by default * correct the sequence of the EFI boot methods * correct finding the default EFI binary * don't delete variable from memory if update failed * fix append write behavior to non-existent variable * Use binman for testing capsule updates on the sandbox * Consider capsule test files in .gitignore and make clean
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/Kconfig1
-rw-r--r--lib/efi_loader/Makefile3
-rw-r--r--lib/efi_loader/efi_memory.c4
-rw-r--r--lib/efi_loader/efi_runtime.c6
-rw-r--r--lib/efi_loader/efi_var_common.c2
-rw-r--r--lib/efi_loader/efi_variable.c45
-rw-r--r--lib/efi_selftest/efi_selftest_variables.c48
7 files changed, 85 insertions, 24 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index a7c3e05c13a..e13a6f9f4c3 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -44,7 +44,6 @@ config EFI_BINARY_EXEC
config EFI_BOOTMGR
bool "UEFI Boot Manager"
default y
- select BOOTMETH_GLOBAL if BOOTSTD
help
Select this option if you want to select the UEFI binary to be booted
via UEFI variables Boot####, BootOrder, and BootNext. You should also
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index fcb0af7e7d6..086521fb287 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -6,8 +6,7 @@
# This file only gets included with CONFIG_EFI_LOADER set, so all
# object inclusion implicitly depends on it
-asflags-y += -DHOST_ARCH="$(HOST_ARCH)" -I.
-ccflags-y += -DHOST_ARCH="$(HOST_ARCH)"
+asflags-y += -I.
CFLAGS_efi_boottime.o += \
-DFW_VERSION="0x$(VERSION)" \
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index edfad2d95a1..aba3100c768 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -933,8 +933,8 @@ static void add_u_boot_and_runtime(void)
* Add Runtime Services. We mark surrounding boottime code as runtime as
* well to fulfill the runtime alignment constraints but avoid padding.
*/
- runtime_start = (ulong)&__efi_runtime_start & ~runtime_mask;
- runtime_end = (ulong)&__efi_runtime_stop;
+ runtime_start = (uintptr_t)__efi_runtime_start & ~runtime_mask;
+ runtime_end = (uintptr_t)__efi_runtime_stop;
runtime_end = (runtime_end + runtime_mask) & ~runtime_mask;
runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
efi_add_memory_map_pg(runtime_start, runtime_pages,
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 9185f1894c4..a61c9a77b13 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -669,14 +669,14 @@ static __efi_runtime void efi_relocate_runtime_table(ulong offset)
void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map)
{
#ifdef IS_RELA
- struct elf_rela *rel = (void*)&__efi_runtime_rel_start;
+ struct elf_rela *rel = (void *)__efi_runtime_rel_start;
#else
- struct elf_rel *rel = (void*)&__efi_runtime_rel_start;
+ struct elf_rel *rel = (void *)__efi_runtime_rel_start;
static ulong lastoff = CONFIG_TEXT_BASE;
#endif
debug("%s: Relocating to offset=%lx\n", __func__, offset);
- for (; (ulong)rel < (ulong)&__efi_runtime_rel_stop; rel++) {
+ for (; (uintptr_t)rel < (uintptr_t)__efi_runtime_rel_stop; rel++) {
ulong base = CONFIG_TEXT_BASE;
ulong *p;
ulong newaddr;
diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
index d528747f3fb..16b2c3d4882 100644
--- a/lib/efi_loader/efi_var_common.c
+++ b/lib/efi_loader/efi_var_common.c
@@ -99,7 +99,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
data_size, data);
/* Make sure that the EFI_VARIABLE_READ_ONLY flag is not set */
- if (attributes & ~(u32)EFI_VARIABLE_MASK)
+ if (attributes & ~EFI_VARIABLE_MASK)
ret = EFI_INVALID_PARAMETER;
else
ret = efi_set_variable_int(variable_name, vendor, attributes,
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 40f7a0fb10d..2951dc78c7d 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -235,8 +235,12 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
if (data_size && !data)
return EFI_INVALID_PARAMETER;
- /* EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated */
- if (attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
+ /*
+ * EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated.
+ * We don't support EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS.
+ */
+ if (attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \
+ EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS))
return EFI_UNSUPPORTED;
/* Make sure if runtime bit is set, boot service bit is set also */
@@ -259,7 +263,7 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
/* check if a variable exists */
var = efi_var_mem_find(vendor, variable_name, NULL);
append = !!(attributes & EFI_VARIABLE_APPEND_WRITE);
- attributes &= ~(u32)EFI_VARIABLE_APPEND_WRITE;
+ attributes &= ~EFI_VARIABLE_APPEND_WRITE;
delete = !append && (!data_size || !attributes);
/* check attributes */
@@ -276,17 +280,27 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
/* attributes won't be changed */
if (!delete &&
((ro_check && var->attr != attributes) ||
- (!ro_check && ((var->attr & ~(u32)EFI_VARIABLE_READ_ONLY)
- != (attributes & ~(u32)EFI_VARIABLE_READ_ONLY))))) {
+ (!ro_check && ((var->attr & ~EFI_VARIABLE_READ_ONLY)
+ != (attributes & ~EFI_VARIABLE_READ_ONLY))))) {
return EFI_INVALID_PARAMETER;
}
time = var->time;
} else {
- if (delete || append)
- /*
- * Trying to delete or to update a non-existent
- * variable.
- */
+ /*
+ * UEFI specification does not clearly describe the expected
+ * behavior of append write with data size 0, we follow
+ * the EDK II reference implementation.
+ */
+ if (append && !data_size)
+ return EFI_SUCCESS;
+
+ /*
+ * EFI_VARIABLE_APPEND_WRITE to non-existent variable is accepted
+ * and new variable is created in EDK II reference implementation.
+ * We follow it and only check the deletion here.
+ */
+ if (delete)
+ /* Trying to delete a non-existent variable. */
return EFI_NOT_FOUND;
}
@@ -329,7 +343,11 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
/* EFI_NOT_FOUND has been handled before */
attributes = var->attr;
ret = EFI_SUCCESS;
- } else if (append) {
+ } else if (append && var) {
+ /*
+ * data is appended if EFI_VARIABLE_APPEND_WRITE is set and
+ * variable exists.
+ */
u16 *old_data = var->name;
for (; *old_data; ++old_data)
@@ -342,11 +360,12 @@ efi_status_t efi_set_variable_int(const u16 *variable_name,
ret = efi_var_mem_ins(variable_name, vendor, attributes,
data_size, data, 0, NULL, time);
}
- efi_var_mem_del(var);
if (ret != EFI_SUCCESS)
return ret;
+ efi_var_mem_del(var);
+
if (var_type == EFI_AUTH_VAR_PK)
ret = efi_init_secure_state();
else
@@ -384,7 +403,7 @@ efi_status_t efi_query_variable_info_int(u32 attributes,
EFI_VARIABLE_RUNTIME_ACCESS)
return EFI_INVALID_PARAMETER;
- if (attributes & ~(u32)EFI_VARIABLE_MASK)
+ if (attributes & ~EFI_VARIABLE_MASK)
return EFI_INVALID_PARAMETER;
*maximum_variable_storage_size = EFI_VAR_BUF_SIZE -
diff --git a/lib/efi_selftest/efi_selftest_variables.c b/lib/efi_selftest/efi_selftest_variables.c
index c7a3fdbaa67..39ad03a090d 100644
--- a/lib/efi_selftest/efi_selftest_variables.c
+++ b/lib/efi_selftest/efi_selftest_variables.c
@@ -131,13 +131,57 @@ static int execute(void)
(unsigned int)len);
if (memcmp(data, v, len))
efi_st_todo("GetVariable returned wrong value\n");
- /* Append variable 2 */
+
+ /* Append variable 2, write to non-existent variable with datasize=0 */
+ ret = runtime->set_variable(u"efi_none", &guid_vendor1,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_APPEND_WRITE,
+ 0, v);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error(
+ "SetVariable(APPEND_WRITE) with size 0 to non-existent variable returns wrong code\n");
+ return EFI_ST_FAILURE;
+ }
+ len = EFI_ST_MAX_DATA_SIZE;
+ ret = runtime->get_variable(u"efi_none", &guid_vendor1,
+ &attr, &len, data);
+ if (ret != EFI_NOT_FOUND) {
+ efi_st_error("Variable must not be created\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Append variable 2, write to non-existent variable with valid data size*/
ret = runtime->set_variable(u"efi_none", &guid_vendor1,
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_APPEND_WRITE,
15, v);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("SetVariable(APPEND_WRITE) with valid size and data to non-existent variable must be succcessful\n");
+ return EFI_ST_FAILURE;
+ }
+ len = EFI_ST_MAX_DATA_SIZE;
+ ret = runtime->get_variable(u"efi_none", &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",
+ (unsigned int)len);
+ if (memcmp(data, v, len))
+ efi_st_todo("GetVariable returned wrong value\n");
+ /* Delete variable efi_none */
+ ret = runtime->set_variable(u"efi_none", &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(u"efi_none", &guid_vendor1,
+ &attr, &len, data);
if (ret != EFI_NOT_FOUND) {
- efi_st_error("SetVariable(APPEND_WRITE) with size 0 to non-existent variable returns wrong code\n");
+ efi_st_error("Variable was not deleted\n");
return EFI_ST_FAILURE;
}
/* Enumerate variables */