summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/bootefi.c34
-rw-r--r--configs/qemu_arm_defconfig1
-rw-r--r--include/config_distro_bootcmd.h9
-rw-r--r--lib/efi_loader/Kconfig1
-rw-r--r--lib/efi_loader/efi_load_initrd.c59
-rw-r--r--lib/efi_selftest/efi_selftest.c31
-rw-r--r--lib/efi_selftest/efi_selftest_console.c35
-rw-r--r--lib/efi_selftest/efi_selftest_load_initrd.c2
-rw-r--r--lib/efi_selftest/efi_selftest_set_virtual_address_map.c2
9 files changed, 122 insertions, 52 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 40d5ef2b3a..fdf909f8da 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -135,12 +135,29 @@ done:
return ret;
}
-static void efi_reserve_memory(u64 addr, u64 size)
+/**
+ * efi_reserve_memory() - add reserved memory to memory map
+ *
+ * @addr: start address of the reserved memory range
+ * @size: size of the reserved memory range
+ * @nomap: indicates that the memory range shall not be accessed by the
+ * UEFI payload
+ */
+static void efi_reserve_memory(u64 addr, u64 size, bool nomap)
{
+ int type;
+ efi_uintn_t ret;
+
/* Convert from sandbox address space. */
addr = (uintptr_t)map_sysmem(addr, 0);
- if (efi_add_memory_map(addr, size,
- EFI_RESERVED_MEMORY_TYPE) != EFI_SUCCESS)
+
+ if (nomap)
+ type = EFI_RESERVED_MEMORY_TYPE;
+ else
+ type = EFI_BOOT_SERVICES_DATA;
+
+ ret = efi_add_memory_map(addr, size, type);
+ if (ret != EFI_SUCCESS)
log_err("Reserved memory mapping failed addr %llx size %llx\n",
addr, size);
}
@@ -166,7 +183,7 @@ static void efi_carve_out_dt_rsv(void *fdt)
for (i = 0; i < nr_rsv; i++) {
if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
continue;
- efi_reserve_memory(addr, size);
+ efi_reserve_memory(addr, size, false);
}
/* process reserved-memory */
@@ -186,8 +203,13 @@ static void efi_carve_out_dt_rsv(void *fdt)
* a size instead of a reg property.
*/
if (fdt_addr != FDT_ADDR_T_NONE &&
- fdtdec_get_is_enabled(fdt, subnode))
- efi_reserve_memory(fdt_addr, fdt_size);
+ fdtdec_get_is_enabled(fdt, subnode)) {
+ bool nomap;
+
+ nomap = !!fdt_getprop(fdt, subnode, "no-map",
+ NULL);
+ efi_reserve_memory(fdt_addr, fdt_size, nomap);
+ }
subnode = fdt_next_subnode(fdt, subnode);
}
}
diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig
index 1ffa727e63..278d8f41f4 100644
--- a/configs/qemu_arm_defconfig
+++ b/configs/qemu_arm_defconfig
@@ -56,4 +56,3 @@ CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_PCI=y
-# CONFIG_EFI_GRUB_ARM32_WORKAROUND is not set
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index fc0935fa21..ff29ef5a90 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -123,12 +123,14 @@
#define BOOTENV_SHARED_EFI \
- "boot_efi_binary=" \
+ "boot_efi_bootmgr=" \
"if fdt addr ${fdt_addr_r}; then " \
"bootefi bootmgr ${fdt_addr_r};" \
"else " \
- "bootefi bootmgr ${fdtcontroladdr};" \
- "fi;" \
+ "bootefi bootmgr;" \
+ "fi\0" \
+ \
+ "boot_efi_binary=" \
"load ${devtype} ${devnum}:${distro_bootpart} " \
"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; " \
"if fdt addr ${fdt_addr_r}; then " \
@@ -152,6 +154,7 @@
"run load_efi_dtb; " \
"fi;" \
"done;" \
+ "run boot_efi_bootmgr;" \
"if test -e ${devtype} ${devnum}:${distro_bootpart} " \
"efi/boot/"BOOTEFI_NAME"; then " \
"echo Found EFI removable media binary " \
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index bad1a29ba8..ab42f3ba75 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -164,6 +164,7 @@ config EFI_HAVE_RUNTIME_RESET
config EFI_GRUB_ARM32_WORKAROUND
bool "Workaround for GRUB on 32bit ARM"
+ default n if ARCH_QEMU
default y
depends on ARM && !ARM64
help
diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c
index 574a83d7e3..d517d686c3 100644
--- a/lib/efi_loader/efi_load_initrd.c
+++ b/lib/efi_loader/efi_load_initrd.c
@@ -47,9 +47,9 @@ static const struct efi_initrd_dp dp = {
/**
* get_file_size() - retrieve the size of initramfs, set efi status on error
*
- * @dev: device to read from. i.e "mmc"
- * @part: device partition. i.e "0:1"
- * @file: name fo file
+ * @dev: device to read from, e.g. "mmc"
+ * @part: device partition, e.g. "0:1"
+ * @file: name of file
* @status: EFI exit code in case of failure
*
* Return: size of file
@@ -78,15 +78,16 @@ out:
}
/**
- * load_file2() - get information about random number generation
+ * efi_load_file2initrd() - load initial RAM disk
+ *
+ * This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL
+ * in order to load an initial RAM disk requested by the Linux kernel stub.
*
- * This function implement the LoadFile2() service in order to load an initram
- * disk requested by the Linux kernel stub.
* See the UEFI spec for details.
*
- * @this: loadfile2 protocol instance
- * @file_path: relative path of the file. "" in this case
- * @boot_policy: must be false for Loadfile2
+ * @this: EFI_LOAD_FILE2_PROTOCOL instance
+ * @file_path: media device path of the file, "" in this case
+ * @boot_policy: must be false
* @buffer_size: size of allocated buffer
* @buffer: buffer to load the file
*
@@ -97,19 +98,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
struct efi_device_path *file_path, bool boot_policy,
efi_uintn_t *buffer_size, void *buffer)
{
- const char *filespec = CONFIG_EFI_INITRD_FILESPEC;
+ char *filespec;
efi_status_t status = EFI_NOT_FOUND;
loff_t file_sz = 0, read_sz = 0;
char *dev, *part, *file;
- char *s;
+ char *pos;
int ret;
EFI_ENTRY("%p, %p, %d, %p, %p", this, file_path, boot_policy,
buffer_size, buffer);
- s = strdup(filespec);
- if (!s)
+ filespec = strdup(CONFIG_EFI_INITRD_FILESPEC);
+ if (!filespec)
goto out;
+ pos = filespec;
if (!this || this != &efi_lf2_protocol ||
!buffer_size) {
@@ -128,14 +130,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
goto out;
}
- /* expect something like 'mmc 0:1 initrd.cpio.gz' */
- dev = strsep(&s, " ");
+ /*
+ * expect a string with three space separated parts:
+ *
+ * * a block device type, e.g. "mmc"
+ * * a device and partition identifier, e.g. "0:1"
+ * * a file path on the block device, e.g. "/boot/initrd.cpio.gz"
+ */
+ dev = strsep(&pos, " ");
if (!dev)
goto out;
- part = strsep(&s, " ");
+ part = strsep(&pos, " ");
if (!part)
goto out;
- file = strsep(&s, " ");
+ file = strsep(&pos, " ");
if (!file)
goto out;
@@ -163,28 +171,25 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
}
out:
- free(s);
+ free(filespec);
return EFI_EXIT(status);
}
/**
- * efi_initrd_register() - Register a handle and loadfile2 protocol
+ * efi_initrd_register() - create handle for loading initial RAM disk
*
- * This function creates a new handle and installs a linux specific GUID
- * to handle initram disk loading during boot.
- * See the UEFI spec for details.
+ * This function creates a new handle and installs a Linux specific vendor
+ * device path and an EFI_LOAD_FILE_2_PROTOCOL. Linux uses the device path
+ * to identify the handle and then calls the LoadFile service of the
+ * EFI_LOAD_FILE_2_PROTOCOL to read the initial RAM disk.
*
- * Return: status code
+ * Return: status code
*/
efi_status_t efi_initrd_register(void)
{
efi_handle_t efi_initrd_handle = NULL;
efi_status_t ret;
- /*
- * Set up the handle with the EFI_LOAD_FILE2_PROTOCOL which Linux may
- * use to load the initial ramdisk.
- */
ret = EFI_CALL(efi_install_multiple_protocol_interfaces
(&efi_initrd_handle,
/* initramfs */
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index 165fa265f2..85e819bdfa 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -143,6 +143,27 @@ static int teardown(struct efi_unit_test *test, unsigned int *failures)
}
/*
+ * Check that a test requiring reset exists.
+ *
+ * @testname: name of the test
+ * @return: test, or NULL if not found
+ */
+static bool need_reset(const u16 *testname)
+{
+ struct efi_unit_test *test;
+
+ for (test = ll_entry_start(struct efi_unit_test, efi_unit_test);
+ test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) {
+ if (testname && efi_st_strcmp_16_8(testname, test->name))
+ continue;
+ if (test->phase == EFI_SETUP_BEFORE_BOOTTIME_EXIT ||
+ test->phase == EFI_SETUP_AFTER_BOOTTIME_EXIT)
+ return true;
+ }
+ return false;
+}
+
+/*
* Check that a test exists.
*
* @testname: name of the test
@@ -290,6 +311,16 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN,
&failures);
+ if (!need_reset(testname)) {
+ if (failures)
+ ret = EFI_PROTOCOL_ERROR;
+
+ /* Give feedback */
+ efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n",
+ failures);
+ return ret;
+ }
+
/* Execute mixed tests */
efi_st_do_tests(testname, EFI_SETUP_BEFORE_BOOTTIME_EXIT,
EFI_ST_SETUP, &failures);
diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c
index 13f3ee6bc1..0219bd70e0 100644
--- a/lib/efi_selftest/efi_selftest_console.c
+++ b/lib/efi_selftest/efi_selftest_console.c
@@ -44,25 +44,28 @@ static void mac(void *pointer, u16 **buf)
}
/*
- * Print a pointer to an u16 string
+ * printx() - print hexadecimal number to an u16 string
*
- * @pointer: pointer
- * @buf: pointer to buffer address
- * on return position of terminating zero word
+ * @pointer: pointer
+ * @prec: minimum number of digits to print
+ * @buf: pointer to buffer address,
+ * on return position of terminating zero word
+ * @size: size of value to be printed in bytes
*/
-static void pointer(void *pointer, u16 **buf)
+static void printx(u64 p, int prec, u16 **buf)
{
int i;
u16 c;
- uintptr_t p = (uintptr_t)pointer;
u16 *pos = *buf;
- for (i = 8 * sizeof(p) - 4; i >= 0; i -= 4) {
- c = (p >> i) & 0x0f;
- c += '0';
- if (c > '9')
- c += 'a' - '9' - 1;
- *pos++ = c;
+ for (i = 2 * sizeof(p) - 1; i >= 0; --i) {
+ c = (p >> (4 * i)) & 0x0f;
+ if (c || pos != *buf || !i || i < prec) {
+ c += '0';
+ if (c > '9')
+ c += 'a' - '9' - 1;
+ *pos++ = c;
+ }
}
*pos = 0;
*buf = pos;
@@ -212,7 +215,9 @@ void efi_st_printc(int color, const char *fmt, ...)
break;
default:
--c;
- pointer(va_arg(args, void*), &pos);
+ printx((uintptr_t)va_arg(args, void *),
+ 2 * sizeof(void *), &pos);
+ break;
}
break;
case 's':
@@ -223,6 +228,10 @@ void efi_st_printc(int color, const char *fmt, ...)
case 'u':
uint2dec(va_arg(args, u32), prec, &pos);
break;
+ case 'x':
+ printx((u64)va_arg(args, unsigned int),
+ prec, &pos);
+ break;
default:
break;
}
diff --git a/lib/efi_selftest/efi_selftest_load_initrd.c b/lib/efi_selftest/efi_selftest_load_initrd.c
index e16163caca..fe060a6644 100644
--- a/lib/efi_selftest/efi_selftest_load_initrd.c
+++ b/lib/efi_selftest/efi_selftest_load_initrd.c
@@ -200,7 +200,7 @@ static int execute(void)
efi_st_error("Could not determine CRC32\n");
return EFI_ST_FAILURE;
}
- efi_st_printf("CRC32 %u\n", (unsigned int)crc32);
+ efi_st_printf("CRC32 %.8x\n", (unsigned int)crc32);
status = boottime->free_pool(buf);
if (status != EFI_SUCCESS) {
diff --git a/lib/efi_selftest/efi_selftest_set_virtual_address_map.c b/lib/efi_selftest/efi_selftest_set_virtual_address_map.c
index a4e5a50f63..b097a81136 100644
--- a/lib/efi_selftest/efi_selftest_set_virtual_address_map.c
+++ b/lib/efi_selftest/efi_selftest_set_virtual_address_map.c
@@ -23,7 +23,7 @@ static u32 notify_call_count;
static bool convert_pointer_failed;
/**
- * notify () - notification function
+ * notify() - notification function
*
* This function is called when the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event
* occurs. The correct output of ConvertPointer() is checked.