Merge tag 'efi-next-20230325' of https://source.denx.de/u-boot/custodians/u-boot-efi into 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()
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_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 @@
  * 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 @@
 	__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 @@
 	__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 @@
 	__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 @@
 	__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 @@
  *
  * @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 @@
 	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 @@
 		"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_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 @@
 		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_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 @@
 	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 @@
 	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 @@
 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_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_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_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_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 @@
    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_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 @@
 #  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 @@
 #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 @@
 	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 @@
 	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 @@
  * 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 @@
 }
 #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 @@
 		 * 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 @@
 	if (!dp)
 		return NULL;
 
-	ndp = dp_alloc(sz);
+	ndp = efi_alloc(sz);
 	if (!ndp)
 		return NULL;
 	memcpy(ndp, dp, sz);
@@ -346,7 +332,7 @@
 		/* 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 @@
 		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 @@
 	} 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 @@
 	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 @@
 		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 @@
 	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 @@
 			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 @@
 	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 @@
 			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 @@
 #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 @@
 {
 	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 @@
 		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 @@
 
 	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_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 @@
 
 	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_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 @@
 {
 	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 @@
 		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_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_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 @@
 	{"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 @@
 		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 @@
 # 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 @@
 	p)
 		type=payload
 		;;
+	k)
+		kernel=1
+		;;
 	r)
 		run=1
 		;;
@@ -124,6 +133,9 @@
 # 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