aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-03-25 17:34:34 -0400
committerTom Rini <trini@konsulko.com>2023-03-25 17:34:34 -0400
commitfde439219ff53a46bdd5dff69e049ccd4be57310 (patch)
tree423643707fad940e0845cbebf74d545b05b3d336
parent4b635046b5e92e419fbd1bf93e5b0ef86dbcadc2 (diff)
parent93e3364804ffd4a5d4a0df9c750a1859f9fe298b (diff)
downloadu-boot-WIP/25Mar2023-next.zip
u-boot-WIP/25Mar2023-next.tar.gz
u-boot-WIP/25Mar2023-next.tar.bz2
Merge tag 'efi-next-20230325' of https://source.denx.de/u-boot/custodians/u-boot-efi into nextWIP/25Mar2023-next
Pull request for efi-next-20230325 Documenation: * add man-page for efi command UEFI: * Let EFI app call ExitBootServices() before legacy booting kernel * Support zboot and bootm in the EFI app * Let efi command show configuration tables * Support booting a 64-bit kernel from 64-bit EFI app * Allocate device-tree copy from high memory * simplify efi_str_to_u16()
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/include/asm/bootm.h12
-rw-r--r--arch/x86/include/asm/bootparam.h70
-rw-r--r--arch/x86/include/asm/cpu.h1
-rw-r--r--arch/x86/lib/bootm.c43
-rw-r--r--arch/x86/lib/zimage.c17
-rw-r--r--cmd/Makefile4
-rw-r--r--cmd/bootefi.c19
-rw-r--r--cmd/efi.c31
-rw-r--r--cmd/efi_common.c26
-rw-r--r--cmd/efidebug.c6
-rw-r--r--configs/efi-x86_app32_defconfig2
-rw-r--r--configs/efi-x86_app64_defconfig3
-rw-r--r--doc/usage/cmd/efi.rst219
-rw-r--r--doc/usage/index.rst1
-rw-r--r--include/efi.h22
-rw-r--r--include/efi_api.h31
-rw-r--r--include/efi_loader.h4
-rw-r--r--lib/efi_loader/efi_device_path.c85
-rw-r--r--lib/efi_loader/efi_device_path_to_text.c12
-rw-r--r--lib/efi_loader/efi_memory.c46
-rw-r--r--lib/uuid.c10
-rwxr-xr-xscripts/build-efi.sh14
23 files changed, 539 insertions, 143 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 07be5cd..99e59d9 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -32,8 +32,8 @@ config X86_RUN_32BIT
config X86_RUN_64BIT
bool "64-bit"
select X86_64
- select SPL
- select SPL_SEPARATE_BSS
+ select SPL if !EFI_APP
+ select SPL_SEPARATE_BSS if !EFI_APP
help
Build U-Boot as a 64-bit binary with a 32-bit SPL. This is
experimental and many features are missing. U-Boot SPL starts up,
diff --git a/arch/x86/include/asm/bootm.h b/arch/x86/include/asm/bootm.h
index 109f686..3b64178 100644
--- a/arch/x86/include/asm/bootm.h
+++ b/arch/x86/include/asm/bootm.h
@@ -14,14 +14,14 @@ void bootm_announce_and_cleanup(void);
* This boots a kernel image, either 32-bit or 64-bit. It will also work with
* a self-extracting kernel, if you set @image_64bit to false.
*
- * @setup_base: Pointer to the setup.bin information for the kernel
- * @load_address: Pointer to the start of the kernel image
- * @image_64bit: true if the image is a raw 64-bit kernel, false if it
- * is raw 32-bit or any type of self-extracting kernel
- * such as a bzImage.
+ * @setup_base: Address of the setup.bin information for the kernel
+ * @entry: Address of the kernel entry point
+ * @image_64bit: true if the image is a raw 64-bit kernel, or a kernel
+ * which supports booting in 64-bit mode; false if it is raw 32-bit or any type
+ * of self-extracting kernel such as a bzImage.
* Return: -ve error code. This function does not return if the kernel was
* booted successfully.
*/
-int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit);
+int boot_linux_kernel(ulong setup_base, ulong entry, bool image_64bit);
#endif
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 7a3c1f5..ea816ca 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -9,19 +9,54 @@
#include <asm/ist.h>
#include <asm/video/edid.h>
-/* setup data types */
-enum {
- SETUP_NONE = 0,
- SETUP_E820_EXT,
- SETUP_DTB,
-};
+/* setup_data/setup_indirect types */
+#define SETUP_NONE 0
+#define SETUP_E820_EXT 1
+#define SETUP_DTB 2
+#define SETUP_PCI 3
+#define SETUP_EFI 4
+#define SETUP_APPLE_PROPERTIES 5
+#define SETUP_JAILHOUSE 6
+#define SETUP_CC_BLOB 7
+#define SETUP_IMA 8
+#define SETUP_RNG_SEED 9
+#define SETUP_ENUM_MAX SETUP_RNG_SEED
+
+#define SETUP_INDIRECT BIT(31)
+#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
+
+/* ram_size flags */
+#define RAMDISK_IMAGE_START_MASK 0x07FF
+#define RAMDISK_PROMPT_FLAG 0x8000
+#define RAMDISK_LOAD_FLAG 0x4000
+
+/* loadflags */
+#define LOADED_HIGH BIT(0)
+#define KASLR_FLAG BIT(1)
+#define QUIET_FLAG BIT(5)
+#define KEEP_SEGMENTS BIT(6)
+#define CAN_USE_HEAP BIT(7)
+
+#define XLF_KERNEL_64 BIT(0)
+#define XLF_CAN_BE_LOADED_ABOVE_4G BIT(1)
+#define XLF_EFI_HANDOVER_32 BIT(2)
+#define XLF_EFI_HANDOVER_64 BIT(3)
+#define XLF_EFI_KEXEC BIT(4)
/* extensible setup data list node */
struct setup_data {
__u64 next;
__u32 type;
__u32 len;
- __u8 data[0];
+ __u8 data[];
+};
+
+/* extensible setup indirect data node */
+struct setup_indirect {
+ __u32 type;
+ __u32 reserved; /* Reserved, must be set to zero. */
+ __u64 len;
+ __u64 addr;
};
/**
@@ -34,9 +69,6 @@ struct setup_header {
__u16 root_flags;
__u32 syssize;
__u16 ram_size;
-#define RAMDISK_IMAGE_START_MASK 0x07FF
-#define RAMDISK_PROMPT_FLAG 0x8000
-#define RAMDISK_LOAD_FLAG 0x4000
__u16 vid_mode;
__u16 root_dev;
__u16 boot_flag;
@@ -44,15 +76,10 @@ struct setup_header {
__u32 header;
__u16 version;
__u32 realmode_swtch;
- __u16 start_sys;
+ __u16 start_sys_seg;
__u16 kernel_version;
__u8 type_of_loader;
__u8 loadflags;
-#define LOADED_HIGH BIT(0)
-#define KASLR_FLAG BIT(1)
-#define QUIET_FLAG BIT(5)
-#define KEEP_SEGMENTS BIT(6) /* Obsolete */
-#define CAN_USE_HEAP BIT(7)
__u16 setup_move_size;
__u32 code32_start;
__u32 ramdisk_image;
@@ -65,13 +92,8 @@ struct setup_header {
__u32 initrd_addr_max;
__u32 kernel_alignment;
__u8 relocatable_kernel;
- u8 min_alignment;
-#define XLF_KERNEL_64 BIT(0)
-#define XLF_CAN_BE_LOADED_ABOVE_4G BIT(1)
-#define XLF_EFI_HANDOVER_32 BIT(2)
-#define XLF_EFI_HANDOVER_64 BIT(3)
-#define XLF_EFI_KEXEC BIT(4)
- u16 xloadflags;
+ __u8 min_alignment;
+ __u16 xloadflags;
__u32 cmdline_size;
__u32 hardware_subarch;
__u64 hardware_subarch_data;
@@ -81,7 +103,7 @@ struct setup_header {
__u64 pref_address;
__u32 init_size;
__u32 handover_offset;
- u32 kernel_info_offset;
+ __u32 kernel_info_offset;
} __attribute__((packed));
struct sys_desc_table {
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 3346012..073f80b 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -262,6 +262,7 @@ void cpu_call32(ulong code_seg32, ulong target, ulong table);
*
* @setup_base: Pointer to the setup.bin information for the kernel
* @target: Pointer to the start of the kernel image
+ * Return: -EFAULT if the kernel returned; otherwise does not return
*/
int cpu_jump_to_64bit(ulong setup_base, ulong target);
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 873e2bc..61cb7bc 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <bootstage.h>
#include <command.h>
+#include <efi.h>
#include <hang.h>
#include <log.h>
#include <asm/global_data.h>
@@ -149,26 +150,52 @@ error:
return 1;
}
-int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
+int boot_linux_kernel(ulong setup_base, ulong entry, bool image_64bit)
{
bootm_announce_and_cleanup();
#ifdef CONFIG_SYS_COREBOOT
timestamp_add_now(TS_U_BOOT_START_KERNEL);
#endif
+
+ /*
+ * Exit EFI boot services just before jumping, after all console
+ * output, since the console won't be available afterwards.
+ */
+ if (IS_ENABLED(CONFIG_EFI_APP)) {
+ int ret;
+
+ ret = efi_store_memory_map(efi_get_priv());
+ if (ret)
+ return ret;
+ printf("Exiting EFI boot services\n");
+ ret = efi_call_exit_boot_services();
+ if (ret)
+ return ret;
+ }
+
if (image_64bit) {
if (!cpu_has_64bit()) {
puts("Cannot boot 64-bit kernel on 32-bit machine\n");
return -EFAULT;
}
- /* At present 64-bit U-Boot does not support booting a
+ /*
+ * At present 64-bit U-Boot only supports booting a 64-bit
* kernel.
- * TODO(sjg@chromium.org): Support booting both 32-bit and
- * 64-bit kernels from 64-bit U-Boot.
+ *
+ * TODO(sjg@chromium.org): Support booting 32-bit kernels from
+ * 64-bit U-Boot
*/
-#if !CONFIG_IS_ENABLED(X86_64)
- return cpu_jump_to_64bit(setup_base, load_address);
-#endif
+ if (CONFIG_IS_ENABLED(X86_64)) {
+ typedef void (*h_func)(ulong zero, ulong setup);
+ h_func func;
+
+ /* jump to Linux with rdi=0, rsi=setup_base */
+ func = (h_func)entry;
+ func(0, setup_base);
+ } else {
+ return cpu_jump_to_64bit(setup_base, entry);
+ }
} else {
/*
* Set %ebx, %ebp, and %edi to 0, %esi to point to the
@@ -190,7 +217,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
"movl $0, %%ebp\n"
"cli\n"
"jmp *%[kernel_entry]\n"
- :: [kernel_entry]"a"(load_address),
+ :: [kernel_entry]"a"(entry),
[boot_params] "S"(setup_base),
"b"(0), "D"(0)
);
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 9cc0449..e5ea512 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -504,13 +504,24 @@ static int do_zboot_info(struct cmd_tbl *cmdtp, int flag, int argc,
static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
+ struct boot_params *params = state.base_ptr;
+ struct setup_header *hdr = &params->hdr;
+ bool image_64bit;
+ ulong entry;
int ret;
disable_interrupts();
+ entry = state.load_address;
+ image_64bit = false;
+ if (IS_ENABLED(CONFIG_X86_RUN_64BIT) &&
+ (hdr->xloadflags & XLF_KERNEL_64)) {
+ entry += 0x200;
+ image_64bit = true;
+ }
+
/* we assume that the kernel is in place */
- ret = boot_linux_kernel((ulong)state.base_ptr, state.load_address,
- false);
+ ret = boot_linux_kernel((ulong)state.base_ptr, entry, image_64bit);
printf("Kernel returned! (err=%d)\n", ret);
return CMD_RET_FAILURE;
@@ -655,7 +666,7 @@ void zimage_dump(struct boot_params *base_ptr)
printf("%-20s %s\n", "", "Ancient kernel, using version 100");
print_num("Version", hdr->version);
print_num("Real mode switch", hdr->realmode_swtch);
- print_num("Start sys", hdr->start_sys);
+ print_num("Start sys seg", hdr->start_sys_seg);
print_num("Kernel version", hdr->kernel_version);
version = get_kernel_version(base_ptr, (void *)state.bzimage_addr);
if (version)
diff --git a/cmd/Makefile b/cmd/Makefile
index 7198029..d95833b 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -62,8 +62,8 @@ obj-$(CONFIG_CMD_EXTENSION) += extension_board.o
obj-$(CONFIG_CMD_ECHO) += echo.o
obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o
obj-$(CONFIG_CMD_EEPROM) += eeprom.o
-obj-$(CONFIG_EFI) += efi.o
-obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o
+obj-$(CONFIG_EFI) += efi.o efi_common.o
+obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o efi_common.o
obj-$(CONFIG_CMD_EFICONFIG) += eficonfig.o
ifdef CONFIG_CMD_EFICONFIG
ifdef CONFIG_EFI_MM_COMM_TEE
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 6618335..8aa15a6 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -204,25 +204,12 @@ static efi_status_t copy_fdt(void **fdtp)
fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000);
fdt_size = fdt_pages << EFI_PAGE_SHIFT;
- /*
- * Safe fdt location is at 127 MiB.
- * On the sandbox convert from the sandbox address space.
- */
- new_fdt_addr = (uintptr_t)map_sysmem(fdt_ram_start + 0x7f00000 +
- fdt_size, 0);
- ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+ ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
EFI_ACPI_RECLAIM_MEMORY, fdt_pages,
&new_fdt_addr);
if (ret != EFI_SUCCESS) {
- /* If we can't put it there, put it somewhere */
- new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size);
- ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
- EFI_ACPI_RECLAIM_MEMORY, fdt_pages,
- &new_fdt_addr);
- if (ret != EFI_SUCCESS) {
- log_err("ERROR: Failed to reserve space for FDT\n");
- goto done;
- }
+ log_err("ERROR: Failed to reserve space for FDT\n");
+ goto done;
}
new_fdt = (void *)(uintptr_t)new_fdt_addr;
memcpy(new_fdt, fdt, fdt_totalsize(fdt));
diff --git a/cmd/efi.c b/cmd/efi.c
index c0384e0..6cd5361 100644
--- a/cmd/efi.c
+++ b/cmd/efi.c
@@ -7,10 +7,12 @@
#include <common.h>
#include <command.h>
#include <efi.h>
+#include <efi_api.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <sort.h>
+#include <uuid.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -273,8 +275,34 @@ done:
return ret ? CMD_RET_FAILURE : 0;
}
+static int do_efi_tables(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct efi_system_table *systab;
+
+ if (IS_ENABLED(CONFIG_EFI_APP)) {
+ systab = efi_get_sys_table();
+ if (!systab) {
+ printf("Cannot read system table\n");
+ return CMD_RET_FAILURE;
+ }
+ } else {
+ int size;
+ int ret;
+
+ ret = efi_info_get(EFIET_SYS_TABLE, (void **)&systab, &size);
+ if (ret) /* this should not happen */
+ return CMD_RET_FAILURE;
+ }
+
+ efi_show_tables(systab);
+
+ return 0;
+}
+
static struct cmd_tbl efi_commands[] = {
U_BOOT_CMD_MKENT(mem, 1, 1, do_efi_mem, "", ""),
+ U_BOOT_CMD_MKENT(tables, 1, 1, do_efi_tables, "", ""),
};
static int do_efi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
@@ -298,5 +326,6 @@ static int do_efi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
U_BOOT_CMD(
efi, 3, 1, do_efi,
"EFI access",
- "mem [all] Dump memory information [include boot services]"
+ "mem [all] Dump memory information [include boot services]\n"
+ "tables Dump tables"
);
diff --git a/cmd/efi_common.c b/cmd/efi_common.c
new file mode 100644
index 0000000..f405609
--- /dev/null
+++ b/cmd/efi_common.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Common code for EFI commands
+ *
+ * Copyright 2023 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <efi_api.h>
+#include <uuid.h>
+
+void efi_show_tables(struct efi_system_table *systab)
+{
+ int i;
+
+ for (i = 0; i < systab->nr_tables; i++) {
+ struct efi_configuration_table *tab = &systab->tables[i];
+ char guid_str[37];
+
+ uuid_bin_to_str(tab->guid.b, guid_str, 1);
+ printf("%p %pUl %s\n", tab->table, guid_str,
+ uuid_guid_get_str(tab->guid.b) ?: "(unknown)");
+ }
+}
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index e6959ed..9622430 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -649,11 +649,7 @@ static int do_efi_show_memmap(struct cmd_tbl *cmdtp, int flag,
static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- efi_uintn_t i;
-
- for (i = 0; i < systab.nr_tables; ++i)
- printf("%pUl (%pUs)\n",
- &systab.tables[i].guid, &systab.tables[i].guid);
+ efi_show_tables(&systab);
return CMD_RET_SUCCESS;
}
diff --git a/configs/efi-x86_app32_defconfig b/configs/efi-x86_app32_defconfig
index 905f375..50975db 100644
--- a/configs/efi-x86_app32_defconfig
+++ b/configs/efi-x86_app32_defconfig
@@ -19,7 +19,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_LAST_STAGE_INIT=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PBSIZE=532
-# CONFIG_CMD_BOOTM is not set
+CONFIG_CMD_BOOTZ=y
CONFIG_CMD_PART=y
# CONFIG_CMD_NET is not set
CONFIG_CMD_TIME=y
diff --git a/configs/efi-x86_app64_defconfig b/configs/efi-x86_app64_defconfig
index dae4884..0fc358d 100644
--- a/configs/efi-x86_app64_defconfig
+++ b/configs/efi-x86_app64_defconfig
@@ -4,6 +4,7 @@ CONFIG_ENV_SIZE=0x1000
CONFIG_DEFAULT_DEVICE_TREE="efi-x86_app"
CONFIG_DEBUG_UART_BASE=0
CONFIG_DEBUG_UART_CLOCK=0
+CONFIG_X86_RUN_64BIT=y
CONFIG_VENDOR_EFI=y
CONFIG_TARGET_EFI_APP64=y
CONFIG_DEBUG_UART=y
@@ -19,7 +20,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_LAST_STAGE_INIT=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PBSIZE=532
-# CONFIG_CMD_BOOTM is not set
+CONFIG_CMD_BOOTZ=y
CONFIG_CMD_PART=y
# CONFIG_CMD_NET is not set
CONFIG_CMD_CACHE=y
diff --git a/doc/usage/cmd/efi.rst b/doc/usage/cmd/efi.rst
new file mode 100644
index 0000000..ef37ff2
--- /dev/null
+++ b/doc/usage/cmd/efi.rst
@@ -0,0 +1,219 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
+
+efi command
+===========
+
+Synopsis
+--------
+
+::
+
+ efi mem [all]
+ efi tables
+
+Description
+-----------
+
+The *efi* command provides information about the EFI environment U-Boot is
+running in, when it is started from EFI.
+
+When running as an EFI app, this command queries EFI boot services for the
+information. When running as an EFI payload, EFI boot services have been
+stopped, so it uses the information collected by the boot stub before that
+happened.
+
+efi mem
+~~~~~~~
+
+This shows the EFI memory map, sorted in order of physical address.
+
+This is normally a very large table. To help reduce the amount of detritus,
+boot-time memory is normally merged with conventional memory. Use the 'all'
+argument to show everything.
+
+The fields are as follows:
+
+#
+ Entry number (sequentially from 0)
+
+Type
+ Memory type. EFI has a large number of memory types. The type is shown in
+ the format <n>:<name> where in is the format number in hex and <name> is the
+ name.
+
+Physical
+ Physical address
+
+Virtual
+ Virtual address
+
+Size
+ Size of memory area in bytes
+
+Attributes
+ Shows a code for memory attributes. The key for this is shown below the
+ table.
+
+efi tables
+~~~~~~~~~~
+
+This shows a list of the EFI tables provided in the system table. These use
+GUIDs so it is not possible in general to show the name of a table. But some
+effort is made to provide a useful table, where the GUID is known by U-Boot.
+
+
+Example
+-------
+
+::
+
+ => efi mem
+ EFI table at 0, memory map 000000001ad38b60, size 1260, key a79, version 1, descr. size 0x30
+ # Type Physical Virtual Size Attributes
+ 0 7:conv 0000000000 0000000000 00000a0000 f
+ <gap> 00000a0000 0000060000
+ 1 7:conv 0000100000 0000000000 0000700000 f
+ 2 a:acpi_nvs 0000800000 0000000000 0000008000 f
+ 3 7:conv 0000808000 0000000000 0000008000 f
+ 4 a:acpi_nvs 0000810000 0000000000 00000f0000 f
+ 5 7:conv 0000900000 0000000000 001efef000 f
+ 6 6:rt_data 001f8ef000 0000000000 0000100000 rf
+ 7 5:rt_code 001f9ef000 0000000000 0000100000 rf
+ 8 0:reserved 001faef000 0000000000 0000080000 f
+ 9 9:acpi_reclaim 001fb6f000 0000000000 0000010000 f
+ 10 a:acpi_nvs 001fb7f000 0000000000 0000080000 f
+ 11 7:conv 001fbff000 0000000000 0000359000 f
+ 12 6:rt_data 001ff58000 0000000000 0000020000 rf
+ 13 a:acpi_nvs 001ff78000 0000000000 0000088000 f
+ <gap> 0020000000 0090000000
+ 14 0:reserved 00b0000000 0000000000 0010000000 1
+
+ Attributes key:
+ f: uncached, write-coalescing, write-through, write-back
+ rf: uncached, write-coalescing, write-through, write-back, needs runtime mapping
+ 1: uncached
+ *Some areas are merged (use 'all' to see)
+
+
+ => efi mem all
+ EFI table at 0, memory map 000000001ad38bb0, size 1260, key a79, version 1, descr. size 0x30
+ # Type Physical Virtual Size Attributes
+ 0 3:bs_code 0000000000 0000000000 0000001000 f
+ 1 7:conv 0000001000 0000000000 000009f000 f
+ <gap> 00000a0000 0000060000
+ 2 7:conv 0000100000 0000000000 0000700000 f
+ 3 a:acpi_nvs 0000800000 0000000000 0000008000 f
+ 4 7:conv 0000808000 0000000000 0000008000 f
+ 5 a:acpi_nvs 0000810000 0000000000 00000f0000 f
+ 6 4:bs_data 0000900000 0000000000 0000c00000 f
+ 7 7:conv 0001500000 0000000000 000aa36000 f
+ 8 2:loader_data 000bf36000 0000000000 0010000000 f
+ 9 4:bs_data 001bf36000 0000000000 0000020000 f
+ 10 7:conv 001bf56000 0000000000 00021e1000 f
+ 11 1:loader_code 001e137000 0000000000 00000c4000 f
+ 12 7:conv 001e1fb000 0000000000 000009b000 f
+ 13 1:loader_code 001e296000 0000000000 00000e2000 f
+ 14 7:conv 001e378000 0000000000 000005b000 f
+ 15 4:bs_data 001e3d3000 0000000000 000001e000 f
+ 16 7:conv 001e3f1000 0000000000 0000016000 f
+ 17 4:bs_data 001e407000 0000000000 0000016000 f
+ 18 2:loader_data 001e41d000 0000000000 0000002000 f
+ 19 4:bs_data 001e41f000 0000000000 0000828000 f
+ 20 3:bs_code 001ec47000 0000000000 0000045000 f
+ 21 4:bs_data 001ec8c000 0000000000 0000001000 f
+ 22 3:bs_code 001ec8d000 0000000000 000000e000 f
+ 23 4:bs_data 001ec9b000 0000000000 0000001000 f
+ 24 3:bs_code 001ec9c000 0000000000 000002c000 f
+ 25 4:bs_data 001ecc8000 0000000000 0000001000 f
+ 26 3:bs_code 001ecc9000 0000000000 000000c000 f
+ 27 4:bs_data 001ecd5000 0000000000 0000006000 f
+ 28 3:bs_code 001ecdb000 0000000000 0000014000 f
+ 29 4:bs_data 001ecef000 0000000000 0000001000 f
+ 30 3:bs_code 001ecf0000 0000000000 000005b000 f
+ 31 4:bs_data 001ed4b000 0000000000 000000b000 f
+ 32 3:bs_code 001ed56000 0000000000 0000024000 f
+ 33 4:bs_data 001ed7a000 0000000000 0000006000 f
+ 34 3:bs_code 001ed80000 0000000000 0000010000 f
+ 35 4:bs_data 001ed90000 0000000000 0000002000 f
+ 36 3:bs_code 001ed92000 0000000000 0000025000 f
+ 37 4:bs_data 001edb7000 0000000000 0000003000 f
+ 38 3:bs_code 001edba000 0000000000 0000011000 f
+ 39 4:bs_data 001edcb000 0000000000 0000008000 f
+ 40 3:bs_code 001edd3000 0000000000 000002d000 f
+ 41 4:bs_data 001ee00000 0000000000 0000201000 f
+ 42 3:bs_code 001f001000 0000000000 0000024000 f
+ 43 4:bs_data 001f025000 0000000000 0000002000 f
+ 44 3:bs_code 001f027000 0000000000 0000009000 f
+ 45 4:bs_data 001f030000 0000000000 0000005000 f
+ 46 3:bs_code 001f035000 0000000000 000002f000 f
+ 47 4:bs_data 001f064000 0000000000 0000001000 f
+ 48 3:bs_code 001f065000 0000000000 0000005000 f
+ 49 4:bs_data 001f06a000 0000000000 0000005000 f
+ 50 3:bs_code 001f06f000 0000000000 0000007000 f
+ 51 4:bs_data 001f076000 0000000000 0000007000 f
+ 52 3:bs_code 001f07d000 0000000000 000000d000 f
+ 53 4:bs_data 001f08a000 0000000000 0000001000 f
+ 54 3:bs_code 001f08b000 0000000000 0000006000 f
+ 55 4:bs_data 001f091000 0000000000 0000004000 f
+ 56 3:bs_code 001f095000 0000000000 000000d000 f
+ 57 4:bs_data 001f0a2000 0000000000 0000003000 f
+ 58 3:bs_code 001f0a5000 0000000000 0000026000 f
+ 59 4:bs_data 001f0cb000 0000000000 0000005000 f
+ 60 3:bs_code 001f0d0000 0000000000 0000019000 f
+ 61 4:bs_data 001f0e9000 0000000000 0000004000 f
+ 62 3:bs_code 001f0ed000 0000000000 0000024000 f
+ 63 4:bs_data 001f111000 0000000000 0000008000 f
+ 64 3:bs_code 001f119000 0000000000 000000b000 f
+ 65 4:bs_data 001f124000 0000000000 0000001000 f
+ 66 3:bs_code 001f125000 0000000000 0000002000 f
+ 67 4:bs_data 001f127000 0000000000 0000002000 f
+ 68 3:bs_code 001f129000 0000000000 0000009000 f
+ 69 4:bs_data 001f132000 0000000000 0000003000 f
+ 70 3:bs_code 001f135000 0000000000 0000005000 f
+ 71 4:bs_data 001f13a000 0000000000 0000003000 f
+ 72 3:bs_code 001f13d000 0000000000 0000005000 f
+ 73 4:bs_data 001f142000 0000000000 0000003000 f
+ 74 3:bs_code 001f145000 0000000000 0000011000 f
+ 75 4:bs_data 001f156000 0000000000 000000b000 f
+ 76 3:bs_code 001f161000 0000000000 0000009000 f
+ 77 4:bs_data 001f16a000 0000000000 0000400000 f
+ 78 3:bs_code 001f56a000 0000000000 0000006000 f
+ 79 4:bs_data 001f570000 0000000000 0000001000 f
+ 80 3:bs_code 001f571000 0000000000 0000001000 f
+ 81 4:bs_data 001f572000 0000000000 0000002000 f
+ 82 3:bs_code 001f574000 0000000000 0000017000 f
+ 83 4:bs_data 001f58b000 0000000000 0000364000 f
+ 84 6:rt_data 001f8ef000 0000000000 0000100000 rf
+ 85 5:rt_code 001f9ef000 0000000000 0000100000 rf
+ 86 0:reserved 001faef000 0000000000 0000080000 f
+ 87 9:acpi_reclaim 001fb6f000 0000000000 0000010000 f
+ 88 a:acpi_nvs 001fb7f000 0000000000 0000080000 f
+ 89 4:bs_data 001fbff000 0000000000 0000201000 f
+ 90 7:conv 001fe00000 0000000000 00000e8000 f
+ 91 4:bs_data 001fee8000 0000000000 0000020000 f
+ 92 3:bs_code 001ff08000 0000000000 0000026000 f
+ 93 4:bs_data 001ff2e000 0000000000 0000009000 f
+ 94 3:bs_code 001ff37000 0000000000 0000021000 f
+ 95 6:rt_data 001ff58000 0000000000 0000020000 rf
+ 96 a:acpi_nvs 001ff78000 0000000000 0000088000 f
+ <gap> 0020000000 0090000000
+ 97 0:reserved 00b0000000 0000000000 0010000000 1
+
+ Attributes key:
+ f: uncached, write-coalescing, write-through, write-back
+ rf: uncached, write-coalescing, write-through, write-back, needs runtime mapping
+ 1: uncached
+
+
+ => efi tables
+ 000000001f8edf98 ee4e5898-3914-4259-9d6e-dc7bd79403cf EFI_LZMA_COMPRESSED
+ 000000001ff2ace0 05ad34ba-6f02-4214-952e-4da0398e2bb9 EFI_DXE_SERVICES
+ 000000001f8ea018 7739f24c-93d7-11d4-9a3a-0090273fc14d EFI_HOB_LIST
+ 000000001ff2bac0 4c19049f-4137-4dd3-9c10-8b97a83ffdfa EFI_MEMORY_TYPE
+ 000000001ff2cb10 49152e77-1ada-4764-b7a2-7afefed95e8b (unknown)
+ 000000001f9ac018 060cc026-4c0d-4dda-8f41-595fef00a502 EFI_MEM_STATUS_CODE_REC
+ 000000001f9ab000 eb9d2d31-2d88-11d3-9a16-0090273fc14d SMBIOS table
+ 000000001fb7e000 eb9d2d30-2d88-11d3-9a16-0090273fc14d EFI_GUID_EFI_ACPI1
+ 000000001fb7e014 8868e871-e4f1-11d3-bc22-0080c73c8881 ACPI table
+ 000000001e654018 dcfa911d-26eb-469f-a220-38b7dc461220 (unknown)
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index d01d38c..bc85e1d 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -43,6 +43,7 @@ Shell commands
cmd/dm
cmd/ebtupdate
cmd/echo
+ cmd/efi
cmd/eficonfig
cmd/env
cmd/event
diff --git a/include/efi.h b/include/efi.h
index c3087d3..f0e5faa 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -52,7 +52,18 @@
#define EFI32_LOADER_SIGNATURE "EL32"
#define EFI64_LOADER_SIGNATURE "EL64"
-struct efi_device_path;
+/**
+ * struct efi_device_path - device path protocol
+ *
+ * @type: device path type
+ * @sub_type: device path sub-type
+ * @length: length of the device path node including the header
+ */
+struct efi_device_path {
+ u8 type;
+ u8 sub_type;
+ u16 length;
+} __packed;
/*
* The EFI spec defines the EFI_GUID as
@@ -637,4 +648,13 @@ int efi_call_exit_boot_services(void);
int efi_get_mmap(struct efi_mem_desc **descp, int *sizep, uint *keyp,
int *desc_sizep, uint *versionp);
+/**
+ * efi_show_tables() - Show a list of available tables
+ *
+ * Shows the address, GUID (and name where known) for each table
+ *
+ * @systab: System table containing the list of tables
+ */
+void efi_show_tables(struct efi_system_table *systab);
+
#endif /* _LINUX_EFI_H */
diff --git a/include/efi_api.h b/include/efi_api.h
index 2d18d25..c4512ee 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -557,12 +557,6 @@ struct efi_loaded_image {
# define DEVICE_PATH_SUB_TYPE_INSTANCE_END 0x01
# define DEVICE_PATH_SUB_TYPE_END 0xff
-struct efi_device_path {
- u8 type;
- u8 sub_type;
- u16 length;
-} __packed;
-
struct efi_mac_addr {
u8 addr[32];
} __packed;
@@ -570,6 +564,7 @@ struct efi_mac_addr {
#define DEVICE_PATH_TYPE_HARDWARE_DEVICE 0x01
# define DEVICE_PATH_SUB_TYPE_MEMORY 0x03
# define DEVICE_PATH_SUB_TYPE_VENDOR 0x04
+# define DEVICE_PATH_SUB_TYPE_CONTROLLER 0x05
struct efi_device_path_memory {
struct efi_device_path dp;
@@ -584,6 +579,11 @@ struct efi_device_path_vendor {
u8 vendor_data[];
} __packed;
+struct efi_device_path_controller {
+ struct efi_device_path dp;
+ u32 controller_number;
+} __packed;
+
#define DEVICE_PATH_TYPE_ACPI_DEVICE 0x02
# define DEVICE_PATH_SUB_TYPE_ACPI_DEVICE 0x01
@@ -1909,6 +1909,25 @@ struct efi_system_resource_table {
EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \
0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
+#define EFI_LZMA_COMPRESSED \
+ EFI_GUID(0xee4e5898, 0x3914, 0x4259, 0x9d, 0x6e, \
+ 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf)
+#define EFI_DXE_SERVICES \
+ EFI_GUID(0x05ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, \
+ 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9)
+#define EFI_HOB_LIST \
+ EFI_GUID(0x7739f24c, 0x93d7, 0x11d4, 0x9a, 0x3a, \
+ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define EFI_MEMORY_TYPE \
+ EFI_GUID(0x4c19049f, 0x4137, 0x4dd3, 0x9c, 0x10, \
+ 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa)
+#define EFI_MEM_STATUS_CODE_REC \
+ EFI_GUID(0x060cc026, 0x4c0d, 0x4dda, 0x8f, 0x41, \
+ 0x59, 0x5f, 0xef, 0x00, 0xa5, 0x02)
+#define EFI_GUID_EFI_ACPI1 \
+ EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, \
+ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+
/**
* struct win_certificate_uefi_guid - A certificate that encapsulates
* a GUID-specific signature
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 1542b4b..cee04cb 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -724,8 +724,8 @@ efi_status_t efi_next_variable_name(efi_uintn_t *size, u16 **buf,
* Return: size in pages
*/
#define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
-/* Generic EFI memory allocator, call this to get memory */
-void *efi_alloc(uint64_t len, int memory_type);
+/* Allocate boot service data pool memory */
+void *efi_alloc(size_t len);
/* Allocate pages on the specified alignment */
void *efi_alloc_aligned_pages(u64 len, int memory_type, size_t align);
/* More specific EFI memory allocator, called by EFI payloads */
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 3b267b7..d5cc495 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -63,20 +63,6 @@ static bool is_sd(struct blk_desc *desc)
}
#endif
-static void *dp_alloc(size_t sz)
-{
- void *buf;
-
- if (efi_allocate_pool(EFI_BOOT_SERVICES_DATA, sz, &buf) !=
- EFI_SUCCESS) {
- debug("EFI: ERROR: out of memory in %s\n", __func__);
- return NULL;
- }
-
- memset(buf, 0, sz);
- return buf;
-}
-
/*
* Iterate to next block in device-path, terminating (returning NULL)
* at /End* node.
@@ -147,7 +133,7 @@ struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
* in practice fallback.efi just uses MEDIA:HARD_DRIVE
* so not sure when we would see these other cases.
*/
- if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_CLASS) ||
+ if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB) ||
EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) ||
EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH))
return dp;
@@ -302,7 +288,7 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
if (!dp)
return NULL;
- ndp = dp_alloc(sz);
+ ndp = efi_alloc(sz);
if (!ndp)
return NULL;
memcpy(ndp, dp, sz);
@@ -346,7 +332,7 @@ efi_device_path *efi_dp_append_or_concatenate(const struct efi_device_path *dp1,
/* both dp1 and dp2 are non-null */
unsigned sz1 = efi_dp_size(dp1);
unsigned sz2 = efi_dp_size(dp2);
- void *p = dp_alloc(sz1 + sz2 + end_size);
+ void *p = efi_alloc(sz1 + sz2 + end_size);
if (!p)
return NULL;
ret = p;
@@ -409,7 +395,7 @@ struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
ret = efi_dp_dup(dp);
} else if (!dp) {
size_t sz = node->length;
- void *p = dp_alloc(sz + sizeof(END));
+ void *p = efi_alloc(sz + sizeof(END));
if (!p)
return NULL;
memcpy(p, node, sz);
@@ -418,7 +404,7 @@ struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
} else {
/* both dp and node are non-null */
size_t sz = efi_dp_size(dp);
- void *p = dp_alloc(sz + node->length + sizeof(END));
+ void *p = efi_alloc(sz + node->length + sizeof(END));
if (!p)
return NULL;
memcpy(p, dp, sz);
@@ -439,7 +425,7 @@ struct efi_device_path *efi_dp_create_device_node(const u8 type,
if (length < sizeof(struct efi_device_path))
return NULL;
- ret = dp_alloc(length);
+ ret = efi_alloc(length);
if (!ret)
return ret;
ret->type = type;
@@ -461,7 +447,7 @@ struct efi_device_path *efi_dp_append_instance(
return efi_dp_dup(dpi);
sz = efi_dp_size(dp);
szi = efi_dp_instance_size(dpi);
- p = dp_alloc(sz + szi + 2 * sizeof(END));
+ p = efi_alloc(sz + szi + 2 * sizeof(END));
if (!p)
return NULL;
ret = p;
@@ -486,7 +472,7 @@ struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
if (!dp || !*dp)
return NULL;
sz = efi_dp_instance_size(*dp);
- p = dp_alloc(sz + sizeof(END));
+ p = efi_alloc(sz + sizeof(END));
if (!p)
return NULL;
memcpy(p, *dp, sz + sizeof(END));
@@ -564,6 +550,11 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
return dp_size(dev->parent)
+ sizeof(struct efi_device_path_vendor) + 1;
#endif
+#ifdef CONFIG_USB
+ case UCLASS_MASS_STORAGE:
+ return dp_size(dev->parent)
+ + sizeof(struct efi_device_path_controller);
+#endif
#ifdef CONFIG_VIRTIO_BLK
case UCLASS_VIRTIO:
/*
@@ -585,7 +576,7 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev)
case UCLASS_MASS_STORAGE:
case UCLASS_USB_HUB:
return dp_size(dev->parent) +
- sizeof(struct efi_device_path_usb_class);
+ sizeof(struct efi_device_path_usb);
default:
/* just skip over unknown classes: */
return dp_size(dev->parent);
@@ -742,6 +733,19 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
return &dp[1];
}
#endif
+#if defined(CONFIG_USB)
+ case UCLASS_MASS_STORAGE: {
+ struct blk_desc *desc = desc = dev_get_uclass_plat(dev);
+ struct efi_device_path_controller *dp =
+ dp_fill(buf, dev->parent);
+
+ dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+ dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CONTROLLER;
+ dp->dp.length = sizeof(*dp);
+ dp->controller_number = desc->lun;
+ return &dp[1];
+ }
+#endif
default:
debug("%s(%u) %s: unhandled parent class: %s (%u)\n",
__FILE__, __LINE__, __func__,
@@ -767,19 +771,22 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
#endif
case UCLASS_MASS_STORAGE:
case UCLASS_USB_HUB: {
- struct efi_device_path_usb_class *udp =
- dp_fill(buf, dev->parent);
- struct usb_device *udev = dev_get_parent_priv(dev);
- struct usb_device_descriptor *desc = &udev->descriptor;
+ struct efi_device_path_usb *udp = dp_fill(buf, dev->parent);
+ switch (device_get_uclass_id(dev->parent)) {
+ case UCLASS_USB_HUB: {
+ struct usb_device *udev = dev_get_parent_priv(dev);
+
+ udp->parent_port_number = udev->portnr;
+ break;
+ }
+ default:
+ udp->parent_port_number = 0;
+ }
udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
- udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS;
+ udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
udp->dp.length = sizeof(*udp);
- udp->vendor_id = desc->idVendor;
- udp->product_id = desc->idProduct;
- udp->device_class = desc->bDeviceClass;
- udp->device_subclass = desc->bDeviceSubClass;
- udp->device_protocol = desc->bDeviceProtocol;
+ udp->usb_interface = 0;
return &udp[1];
}
@@ -906,7 +913,7 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
{
void *buf, *start;
- start = buf = dp_alloc(dp_part_size(desc, part) + sizeof(END));
+ start = buf = efi_alloc(dp_part_size(desc, part) + sizeof(END));
if (!buf)
return NULL;
@@ -933,7 +940,7 @@ struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
dpsize = sizeof(struct efi_device_path_cdrom_path);
else
dpsize = sizeof(struct efi_device_path_hard_drive_path);
- buf = dp_alloc(dpsize);
+ buf = efi_alloc(dpsize);
if (buf)
dp_part_node(buf, desc, part);
@@ -1007,7 +1014,7 @@ struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
dpsize += fpsize;
- start = buf = dp_alloc(dpsize + sizeof(END));
+ start = buf = efi_alloc(dpsize + sizeof(END));
if (!buf)
return NULL;
@@ -1035,7 +1042,7 @@ struct efi_device_path *efi_dp_from_uart(void)
struct efi_device_path_uart *uart;
size_t dpsize = sizeof(ROOT) + sizeof(*uart) + sizeof(END);
- buf = dp_alloc(dpsize);
+ buf = efi_alloc(dpsize);
if (!buf)
return NULL;
pos = buf;
@@ -1061,7 +1068,7 @@ struct efi_device_path *efi_dp_from_eth(void)
dpsize += dp_size(eth_get_dev());
- start = buf = dp_alloc(dpsize + sizeof(END));
+ start = buf = efi_alloc(dpsize + sizeof(END));
if (!buf)
return NULL;
@@ -1081,7 +1088,7 @@ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
struct efi_device_path_memory *mdp;
void *buf, *start;
- start = buf = dp_alloc(sizeof(*mdp) + sizeof(END));
+ start = buf = efi_alloc(sizeof(*mdp) + sizeof(END));
if (!buf)
return NULL;
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index 9062058..8c76d8b 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -32,11 +32,10 @@ static u16 *efi_str_to_u16(char *str)
{
efi_uintn_t len;
u16 *out, *dst;
- efi_status_t ret;
len = sizeof(u16) * (utf8_utf16_strlen(str) + 1);
- ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, len, (void **)&out);
- if (ret != EFI_SUCCESS)
+ out = efi_alloc(len);
+ if (!out)
return NULL;
dst = out;
utf8_utf16_strcpy(&dst, str);
@@ -77,6 +76,13 @@ static char *dp_hardware(char *s, struct efi_device_path *dp)
s += sprintf(s, ")");
break;
}
+ case DEVICE_PATH_SUB_TYPE_CONTROLLER: {
+ struct efi_device_path_controller *cdp =
+ (struct efi_device_path_controller *)dp;
+
+ s += sprintf(s, "Ctrl(0x%0x)", cdp->controller_number);
+ break;
+ }
default:
s = dp_unknown(s, dp);
break;
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index b7bee98..8f82496 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -5,9 +5,12 @@
* Copyright (c) 2016 Alexander Graf
*/
+#define LOG_CATEGORY LOGC_EFI
+
#include <common.h>
#include <efi_loader.h>
#include <init.h>
+#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <watchdog.h>
@@ -534,27 +537,6 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
}
/**
- * efi_alloc() - allocate memory pages
- *
- * @len: size of the memory to be allocated
- * @memory_type: usage type of the allocated memory
- * Return: pointer to the allocated memory area or NULL
- */
-void *efi_alloc(uint64_t len, int memory_type)
-{
- uint64_t ret = 0;
- uint64_t pages = efi_size_in_pages(len);
- efi_status_t r;
-
- r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type, pages,
- &ret);
- if (r == EFI_SUCCESS)
- return (void*)(uintptr_t)ret;
-
- return NULL;
-}
-
-/**
* efi_free_pages() - free memory pages
*
* @memory: start of the memory area to be freed
@@ -673,6 +655,28 @@ efi_status_t efi_allocate_pool(enum efi_memory_type pool_type, efi_uintn_t size,
}
/**
+ * efi_alloc() - allocate boot services data pool memory
+ *
+ * Allocate memory from pool and zero it out.
+ *
+ * @size: number of bytes to allocate
+ * Return: pointer to allocated memory or NULL
+ */
+void *efi_alloc(size_t size)
+{
+ void *buf;
+
+ if (efi_allocate_pool(EFI_BOOT_SERVICES_DATA, size, &buf) !=
+ EFI_SUCCESS) {
+ log_err("out of memory");
+ return NULL;
+ }
+ memset(buf, 0, size);
+
+ return buf;
+}
+
+/**
* efi_free_pool() - free memory from pool
*
* @buffer: start of memory to be freed
diff --git a/lib/uuid.c b/lib/uuid.c
index 465e1ac..96e1af3 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -102,7 +102,7 @@ static const struct {
{"lvm", PARTITION_LINUX_LVM_GUID},
{"u-boot-env", PARTITION_U_BOOT_ENVIRONMENT},
#endif
-#ifdef CONFIG_CMD_EFIDEBUG
+#if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI)
{
"Device Path",
EFI_DEVICE_PATH_PROTOCOL_GUID,
@@ -255,6 +255,14 @@ static const struct {
EFI_CERT_TYPE_PKCS7_GUID,
},
#endif
+#ifdef CONFIG_EFI
+ { "EFI_LZMA_COMPRESSED", EFI_LZMA_COMPRESSED },
+ { "EFI_DXE_SERVICES", EFI_DXE_SERVICES },
+ { "EFI_HOB_LIST", EFI_HOB_LIST },
+ { "EFI_MEMORY_TYPE", EFI_MEMORY_TYPE },
+ { "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC },
+ { "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 },
+#endif
};
/*
diff --git a/scripts/build-efi.sh b/scripts/build-efi.sh
index 46c2880..6b7df2e 100755
--- a/scripts/build-efi.sh
+++ b/scripts/build-efi.sh
@@ -18,12 +18,15 @@
# OVMF-pure-efi.x64.fd at
# https://drive.google.com/file/d/1c39YI9QtpByGQ4V0UNNQtGqttEzS-eFV/view?usp=sharing
+bzimage_fname=/tmp/kernel/arch/x86/boot/bzImage
+
set -e
usage() {
echo "Usage: $0 [-a | -p] [other opts]" 1>&2
echo 1>&2
echo " -a - Package up the app" 1>&2
+ echo " -k - Add a kernel" 1>&2
echo " -o - Use old EFI app build (before 32/64 split)" 1>&2
echo " -p - Package up the payload" 1>&2
echo " -P - Create a partition table" 1>&2
@@ -52,11 +55,14 @@ serial=
# before the 32/64 split of the app
old=
+# package up a kernel as well
+kernel=
+
# Set ubdir to the build directory where you build U-Boot out-of-tree
# We avoid in-tree build because it gets confusing trying different builds
ubdir=/tmp/b/
-while getopts "aopPrsw" opt; do
+while getopts "akopPrsw" opt; do
case "${opt}" in
a)
type=app
@@ -64,6 +70,9 @@ while getopts "aopPrsw" opt; do
p)
type=payload
;;
+ k)
+ kernel=1
+ ;;
r)
run=1
;;
@@ -124,6 +133,9 @@ EOF
# Copy files into the filesystem
copy_files() {
sudo cp $TMP/* $MNT
+ if [[ -n "${kernel}" ]]; then
+ sudo cp ${bzimage_fname} $MNT/vmlinuz
+ fi
}
# Create a filesystem on a raw device and copy in the files