Merge tag 'xilinx-for-v2018.05-rc2' of git://git.denx.de/u-boot-microblaze

Xilinx changes for v2018.05-rc2

- Various DT changes and sync with mainline kernel
- Various defconfig updates
- Add SPL init for zcu102 revA
- Add new zynqmp boards zcu100/zcu104/zcu106/zcu111/zc12XX
  and zc1751-dc3
- Net fixes - xlnx,phy-type
- 64bit axi ethernet support
- arasan: Fix nand write issue
- fpga fixes
- Maintainer file updates
diff --git a/MAINTAINERS b/MAINTAINERS
index 4337c6d..2e75f39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -330,7 +330,7 @@
 M:	Alexander Graf <agraf@suse.de>
 S:	Maintained
 T:	git git://github.com/agraf/u-boot.git
-F:	doc/README.efi
+F:	doc/README.uefi
 F:	doc/README.iscsi
 F:	include/efi*
 F:	include/pe.h
diff --git a/README b/README
index fda2d58..6f98e09 100644
--- a/README
+++ b/README
@@ -812,14 +812,6 @@
 		CONFIG_AT91_HW_WDT_TIMEOUT
 		specify the timeout in seconds. default 2 seconds.
 
-- U-Boot Version:
-		CONFIG_VERSION_VARIABLE
-		If this variable is defined, an environment variable
-		named "ver" is created by U-Boot showing the U-Boot
-		version as printed by the "version" command.
-		Any change to this variable will be reverted at the
-		next reset.
-
 - Real-Time Clock:
 
 		When CONFIG_CMD_DATE is selected, the type of the RTC
@@ -2213,12 +2205,6 @@
 		the environment like the "source" command or the
 		boot command first.
 
-		CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
-		Define this in order to add variables describing certain
-		run-time determined information about the hardware to the
-		environment.  These will be named board_name, board_rev.
-
 		CONFIG_DELAY_ENVIRONMENT
 
 		Normally the environment is loaded when the board is
diff --git a/arch/arm/cpu/arm926ejs/spear/spr_misc.c b/arch/arm/cpu/arm926ejs/spear/spr_misc.c
index a02304f..f072f2e 100644
--- a/arch/arm/cpu/arm926ejs/spear/spr_misc.c
+++ b/arch/arm/cpu/arm926ejs/spear/spr_misc.c
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <environment.h>
 #include <i2c.h>
 #include <net.h>
 #include <linux/mtd/st_smi.h>
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 70a6070..45cbd91 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -644,6 +644,7 @@
 	switch (reset_type) {
 	case EFI_RESET_COLD:
 	case EFI_RESET_WARM:
+	case EFI_RESET_PLATFORM_SPECIFIC:
 		reset_cpu(0);
 		break;
 	case EFI_RESET_SHUTDOWN:
@@ -654,9 +655,9 @@
 	while (1) { }
 }
 
-void efi_reset_system_init(void)
+efi_status_t efi_reset_system_init(void)
 {
-       efi_add_runtime_mmio(&rstcr, sizeof(*rstcr));
+	return efi_add_runtime_mmio(&rstcr, sizeof(*rstcr));
 }
 
 #endif
diff --git a/arch/arm/cpu/armv8/fwcall.c b/arch/arm/cpu/armv8/fwcall.c
index c220267..ff0712b 100644
--- a/arch/arm/cpu/armv8/fwcall.c
+++ b/arch/arm/cpu/armv8/fwcall.c
@@ -146,6 +146,7 @@
 	switch (reset_type) {
 	case EFI_RESET_COLD:
 	case EFI_RESET_WARM:
+	case EFI_RESET_PLATFORM_SPECIFIC:
 		psci_system_reset();
 		break;
 	case EFI_RESET_SHUTDOWN:
diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
index 80869ad..cda4d48 100644
--- a/arch/arm/lib/interrupts.c
+++ b/arch/arm/lib/interrupts.c
@@ -20,6 +20,7 @@
  */
 
 #include <common.h>
+#include <efi_loader.h>
 #include <asm/proc-armv/ptrace.h>
 #include <asm/u-boot-arm.h>
 #include <efi_loader.h>
@@ -51,6 +52,11 @@
 	reset_cpu (0);
 }
 
+static void show_efi_loaded_images(struct pt_regs *regs)
+{
+	efi_print_image_infos((void *)instruction_pointer(regs));
+}
+
 void show_regs (struct pt_regs *regs)
 {
 	unsigned long __maybe_unused flags;
@@ -106,6 +112,7 @@
 	printf ("undefined instruction\n");
 	fixup_pc(pt_regs, -4);
 	show_regs (pt_regs);
+	show_efi_loaded_images(pt_regs);
 	bad_mode ();
 }
 
@@ -115,6 +122,7 @@
 	printf ("software interrupt\n");
 	fixup_pc(pt_regs, -4);
 	show_regs (pt_regs);
+	show_efi_loaded_images(pt_regs);
 	bad_mode ();
 }
 
@@ -124,6 +132,7 @@
 	printf ("prefetch abort\n");
 	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
+	show_efi_loaded_images(pt_regs);
 	bad_mode ();
 }
 
@@ -133,6 +142,7 @@
 	printf ("data abort\n");
 	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
+	show_efi_loaded_images(pt_regs);
 	bad_mode ();
 }
 
@@ -142,6 +152,7 @@
 	printf ("not used\n");
 	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
+	show_efi_loaded_images(pt_regs);
 	bad_mode ();
 }
 
@@ -151,6 +162,7 @@
 	printf ("fast interrupt request\n");
 	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
+	show_efi_loaded_images(pt_regs);
 	bad_mode ();
 }
 
@@ -160,5 +172,6 @@
 	printf ("interrupt request\n");
 	fixup_pc(pt_regs, -8);
 	show_regs (pt_regs);
+	show_efi_loaded_images(pt_regs);
 	bad_mode ();
 }
diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c
index b62cb8a..aa02d3f 100644
--- a/arch/arm/mach-bcm283x/reset.c
+++ b/arch/arm/mach-bcm283x/reset.c
@@ -63,6 +63,7 @@
 	switch (reset_type) {
 	case EFI_RESET_COLD:
 	case EFI_RESET_WARM:
+	case EFI_RESET_PLATFORM_SPECIFIC:
 		reset_cpu(0);
 		break;
 	case EFI_RESET_SHUTDOWN:
@@ -82,9 +83,9 @@
 	while (1) { }
 }
 
-void efi_reset_system_init(void)
+efi_status_t efi_reset_system_init(void)
 {
-	efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs));
+	return efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs));
 }
 
 #endif
diff --git a/arch/arm/mach-davinci/misc.c b/arch/arm/mach-davinci/misc.c
index 461ff77..7b9d961 100644
--- a/arch/arm/mach-davinci/misc.c
+++ b/arch/arm/mach-davinci/misc.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <i2c.h>
 #include <net.h>
 #include <asm/arch/hardware.h>
diff --git a/arch/arm/mach-omap2/utils.c b/arch/arm/mach-omap2/utils.c
index 7d1ca27..1d39625 100644
--- a/arch/arm/mach-omap2/utils.c
+++ b/arch/arm/mach-omap2/utils.c
@@ -5,6 +5,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 #include <common.h>
+#include <environment.h>
 #include <asm/setup.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/omap_common.h>
diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c
index e1fee11..3bdaa5f 100644
--- a/arch/powerpc/cpu/mpc85xx/fdt.c
+++ b/arch/powerpc/cpu/mpc85xx/fdt.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <linux/libfdt.h>
 #include <fdt_support.h>
 #include <asm/processor.h>
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 472ada5..69074f4 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -94,12 +94,16 @@
 EFI_LDS := elf_x86_64_efi.lds
 EFI_CRT0 := crt0_x86_64_efi.o
 EFI_RELOC := reloc_x86_64_efi.o
-EFI_TARGET := --target=efi-app-ia32
 else
 EFI_LDS := elf_ia32_efi.lds
 EFI_CRT0 := crt0_ia32_efi.o
 EFI_RELOC := reloc_ia32_efi.o
+endif
+
+ifdef CONFIG_X86_64
 EFI_TARGET := --target=efi-app-x86_64
+else
+EFI_TARGET := --target=efi-app-ia32
 endif
 
 endif
diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c
index d82b8cd..f0a97fa 100644
--- a/board/BuR/common/common.c
+++ b/board/BuR/common/common.c
@@ -11,6 +11,7 @@
  */
 #include <version.h>
 #include <common.h>
+#include <environment.h>
 #include <errno.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/hardware.h>
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index b03c0a3..c693aae 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <i2c.h>
 #include <miiphy.h>
 #include <netdev.h>
diff --git a/board/LaCie/net2big_v2/net2big_v2.c b/board/LaCie/net2big_v2/net2big_v2.c
index f639a37..3e070d2 100644
--- a/board/LaCie/net2big_v2/net2big_v2.c
+++ b/board/LaCie/net2big_v2/net2big_v2.c
@@ -11,6 +11,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <environment.h>
 #include <i2c.h>
 #include <asm/mach-types.h>
 #include <asm/arch/cpu.h>
diff --git a/board/LaCie/netspace_v2/netspace_v2.c b/board/LaCie/netspace_v2/netspace_v2.c
index 52f3664..3bd9fa9 100644
--- a/board/LaCie/netspace_v2/netspace_v2.c
+++ b/board/LaCie/netspace_v2/netspace_v2.c
@@ -11,6 +11,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <environment.h>
 #include <asm/mach-types.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
diff --git a/board/amlogic/khadas-vim/khadas-vim.c b/board/amlogic/khadas-vim/khadas-vim.c
index 5e19856..83b1b6e 100644
--- a/board/amlogic/khadas-vim/khadas-vim.c
+++ b/board/amlogic/khadas-vim/khadas-vim.c
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <asm/io.h>
 #include <asm/arch/gxbb.h>
 #include <asm/arch/mem.h>
diff --git a/board/amlogic/libretech-cc/libretech-cc.c b/board/amlogic/libretech-cc/libretech-cc.c
index 6be6e2a..5795340 100644
--- a/board/amlogic/libretech-cc/libretech-cc.c
+++ b/board/amlogic/libretech-cc/libretech-cc.c
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <asm/io.h>
 #include <asm/arch/gxbb.h>
 #include <asm/arch/sm.h>
diff --git a/board/amlogic/odroid-c2/odroid-c2.c b/board/amlogic/odroid-c2/odroid-c2.c
index 0cb5714..8645f22 100644
--- a/board/amlogic/odroid-c2/odroid-c2.c
+++ b/board/amlogic/odroid-c2/odroid-c2.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <asm/io.h>
 #include <asm/arch/gxbb.h>
 #include <asm/arch/sm.h>
diff --git a/board/amlogic/p212/p212.c b/board/amlogic/p212/p212.c
index 5fde534..7c0abbc 100644
--- a/board/amlogic/p212/p212.c
+++ b/board/amlogic/p212/p212.c
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <asm/io.h>
 #include <asm/arch/gxbb.h>
 #include <asm/arch/sm.h>
diff --git a/board/atmel/common/mac_eeprom.c b/board/atmel/common/mac_eeprom.c
index 60ddf00..91b86e0 100644
--- a/board/atmel/common/mac_eeprom.c
+++ b/board/atmel/common/mac_eeprom.c
@@ -7,6 +7,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <i2c_eeprom.h>
 #include <netdev.h>
 
diff --git a/board/buffalo/lsxl/lsxl.c b/board/buffalo/lsxl/lsxl.c
index 2d01ac2..8ae4207 100644
--- a/board/buffalo/lsxl/lsxl.c
+++ b/board/buffalo/lsxl/lsxl.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <net.h>
 #include <malloc.h>
 #include <netdev.h>
diff --git a/board/compulab/cl-som-am57x/eth.c b/board/compulab/cl-som-am57x/eth.c
index b615fb9..9f9525e 100644
--- a/board/compulab/cl-som-am57x/eth.c
+++ b/board/compulab/cl-som-am57x/eth.c
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <cpsw.h>
+#include <environment.h>
 #include <miiphy.h>
 #include <asm/gpio.h>
 #include <asm/arch/sys_proto.h>
diff --git a/board/compulab/cl-som-imx7/cl-som-imx7.c b/board/compulab/cl-som-imx7/cl-som-imx7.c
index f8b1cda..dfa81f5 100644
--- a/board/compulab/cl-som-imx7/cl-som-imx7.c
+++ b/board/compulab/cl-som-imx7/cl-som-imx7.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <mmc.h>
 #include <phy.h>
 #include <netdev.h>
diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c
index 673de03..c72efc5 100644
--- a/board/compulab/cm_fx6/cm_fx6.c
+++ b/board/compulab/cm_fx6/cm_fx6.c
@@ -12,6 +12,7 @@
 #include <ahci.h>
 #include <dm.h>
 #include <dwc_ahsata.h>
+#include <environment.h>
 #include <fsl_esdhc.h>
 #include <miiphy.h>
 #include <mtd_node.h>
diff --git a/board/compulab/cm_t335/cm_t335.c b/board/compulab/cm_t335/cm_t335.c
index 6f6ba49..6eabd38 100644
--- a/board/compulab/cm_t335/cm_t335.c
+++ b/board/compulab/cm_t335/cm_t335.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <errno.h>
 #include <miiphy.h>
 #include <cpsw.h>
diff --git a/board/compulab/cm_t35/cm_t35.c b/board/compulab/cm_t35/cm_t35.c
index d5cfba4..e8f604f 100644
--- a/board/compulab/cm_t35/cm_t35.c
+++ b/board/compulab/cm_t35/cm_t35.c
@@ -13,6 +13,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <status_led.h>
 #include <netdev.h>
 #include <net.h>
diff --git a/board/compulab/cm_t3517/cm_t3517.c b/board/compulab/cm_t3517/cm_t3517.c
index 0ff49dc..e4e3460 100644
--- a/board/compulab/cm_t3517/cm_t3517.c
+++ b/board/compulab/cm_t3517/cm_t3517.c
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <status_led.h>
 #include <net.h>
 #include <netdev.h>
diff --git a/board/compulab/cm_t54/cm_t54.c b/board/compulab/cm_t54/cm_t54.c
index 3e6235a..a1aeafb 100644
--- a/board/compulab/cm_t54/cm_t54.c
+++ b/board/compulab/cm_t54/cm_t54.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <fdt_support.h>
 #include <usb.h>
 #include <mmc.h>
diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c
index 83c9f29..37a0d72 100644
--- a/board/davinci/da8xxevm/da850evm.c
+++ b/board/davinci/da8xxevm/da850evm.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <i2c.h>
 #include <net.h>
 #include <netdev.h>
diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c
index b00d0e4..1d8b831 100644
--- a/board/dhelectronics/dh_imx6/dh_imx6.c
+++ b/board/dhelectronics/dh_imx6/dh_imx6.c
@@ -19,6 +19,7 @@
 #include <asm/mach-imx/iomux-v3.h>
 #include <asm/mach-imx/mxc_i2c.h>
 #include <asm/mach-imx/sata.h>
+#include <environment.h>
 #include <errno.h>
 #include <fsl_esdhc.h>
 #include <fuse.h>
diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index 4ddc7e1..332c506 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -22,6 +22,7 @@
 #include <asm/setup.h>
 #include <dm.h>
 #include <dm/platform_data/serial_mxc.h>
+#include <environment.h>
 #include <hwconfig.h>
 #include <i2c.h>
 #include <fdt_support.h>
diff --git a/board/ge/mx53ppd/mx53ppd.c b/board/ge/mx53ppd/mx53ppd.c
index 90dbccc..0010998 100644
--- a/board/ge/mx53ppd/mx53ppd.c
+++ b/board/ge/mx53ppd/mx53ppd.c
@@ -20,6 +20,7 @@
 #include <linux/errno.h>
 #include <asm/mach-imx/mxc_i2c.h>
 #include <asm/mach-imx/mx5_video.h>
+#include <environment.h>
 #include <netdev.h>
 #include <i2c.h>
 #include <mmc.h>
diff --git a/board/kosagi/novena/novena.c b/board/kosagi/novena/novena.c
index f0ace03..91bc9c2 100644
--- a/board/kosagi/novena/novena.c
+++ b/board/kosagi/novena/novena.c
@@ -21,6 +21,7 @@
 #include <asm/mach-imx/mxc_i2c.h>
 #include <asm/mach-imx/sata.h>
 #include <asm/mach-imx/video.h>
+#include <environment.h>
 #include <fsl_esdhc.h>
 #include <i2c.h>
 #include <input.h>
diff --git a/board/logicpd/zoom1/zoom1.c b/board/logicpd/zoom1/zoom1.c
index e6c2526..fe1183b 100644
--- a/board/logicpd/zoom1/zoom1.c
+++ b/board/logicpd/zoom1/zoom1.c
@@ -16,6 +16,7 @@
  */
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <ns16550.h>
 #include <netdev.h>
 #include <twl4030.h>
diff --git a/board/phytec/pcm051/board.c b/board/phytec/pcm051/board.c
index 52ad5b6..c57625b 100644
--- a/board/phytec/pcm051/board.c
+++ b/board/phytec/pcm051/board.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <errno.h>
 #include <spl.h>
 #include <asm/arch/cpu.h>
diff --git a/board/phytec/phycore_rk3288/phycore-rk3288.c b/board/phytec/phycore_rk3288/phycore-rk3288.c
index 47b069e..a1b407d 100644
--- a/board/phytec/phycore_rk3288/phycore-rk3288.c
+++ b/board/phytec/phycore_rk3288/phycore-rk3288.c
@@ -8,6 +8,7 @@
 #include <asm/io.h>
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <i2c.h>
 #include <i2c_eeprom.h>
 #include <netdev.h>
diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index de8e308..3049505 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -8,6 +8,7 @@
 #include <inttypes.h>
 #include <config.h>
 #include <dm.h>
+#include <environment.h>
 #include <efi_loader.h>
 #include <fdt_support.h>
 #include <fdt_simplefb.h>
diff --git a/board/renesas/alt/alt.c b/board/renesas/alt/alt.c
index 0bf8160..f2200ef 100644
--- a/board/renesas/alt/alt.c
+++ b/board/renesas/alt/alt.c
@@ -10,6 +10,7 @@
 #include <malloc.h>
 #include <dm.h>
 #include <dm/platform_data/serial_sh.h>
+#include <environment.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/blanche/blanche.c b/board/renesas/blanche/blanche.c
index 574dcda..5dc3073 100644
--- a/board/renesas/blanche/blanche.c
+++ b/board/renesas/blanche/blanche.c
@@ -12,6 +12,7 @@
 #include <netdev.h>
 #include <dm.h>
 #include <dm/platform_data/serial_sh.h>
+#include <environment.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/gose/gose.c b/board/renesas/gose/gose.c
index 54e1269..99d4ba6 100644
--- a/board/renesas/gose/gose.c
+++ b/board/renesas/gose/gose.c
@@ -10,6 +10,7 @@
 #include <malloc.h>
 #include <dm.h>
 #include <dm/platform_data/serial_sh.h>
+#include <environment.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/koelsch/koelsch.c b/board/renesas/koelsch/koelsch.c
index 8fa648e..e7b47ae 100644
--- a/board/renesas/koelsch/koelsch.c
+++ b/board/renesas/koelsch/koelsch.c
@@ -11,6 +11,7 @@
 #include <malloc.h>
 #include <dm.h>
 #include <dm/platform_data/serial_sh.h>
+#include <environment.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/lager/lager.c b/board/renesas/lager/lager.c
index 562be04..3566bcc 100644
--- a/board/renesas/lager/lager.c
+++ b/board/renesas/lager/lager.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <malloc.h>
 #include <netdev.h>
 #include <dm.h>
diff --git a/board/renesas/sh7752evb/sh7752evb.c b/board/renesas/sh7752evb/sh7752evb.c
index 4a76fb7..5da6f39 100644
--- a/board/renesas/sh7752evb/sh7752evb.c
+++ b/board/renesas/sh7752evb/sh7752evb.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <malloc.h>
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/board/renesas/sh7753evb/sh7753evb.c b/board/renesas/sh7753evb/sh7753evb.c
index ca9e144..8604d88 100644
--- a/board/renesas/sh7753evb/sh7753evb.c
+++ b/board/renesas/sh7753evb/sh7753evb.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <malloc.h>
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/board/renesas/sh7757lcr/sh7757lcr.c b/board/renesas/sh7757lcr/sh7757lcr.c
index 3f970fc..1c598fb 100644
--- a/board/renesas/sh7757lcr/sh7757lcr.c
+++ b/board/renesas/sh7757lcr/sh7757lcr.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <malloc.h>
 #include <asm/processor.h>
 #include <asm/io.h>
diff --git a/board/renesas/silk/silk.c b/board/renesas/silk/silk.c
index a8de402..9e2080b 100644
--- a/board/renesas/silk/silk.c
+++ b/board/renesas/silk/silk.c
@@ -11,6 +11,7 @@
 #include <malloc.h>
 #include <dm.h>
 #include <dm/platform_data/serial_sh.h>
+#include <environment.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/renesas/stout/stout.c b/board/renesas/stout/stout.c
index d681148..3cb16db 100644
--- a/board/renesas/stout/stout.c
+++ b/board/renesas/stout/stout.c
@@ -14,6 +14,7 @@
 #include <netdev.h>
 #include <dm.h>
 #include <dm/platform_data/serial_sh.h>
+#include <environment.h>
 #include <asm/processor.h>
 #include <asm/mach-types.h>
 #include <asm/io.h>
diff --git a/board/rockchip/tinker_rk3288/tinker-rk3288.c b/board/rockchip/tinker_rk3288/tinker-rk3288.c
index 790a921..0f2abe2 100644
--- a/board/rockchip/tinker_rk3288/tinker-rk3288.c
+++ b/board/rockchip/tinker_rk3288/tinker-rk3288.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <i2c_eeprom.h>
 #include <netdev.h>
 
diff --git a/board/samtec/vining_2000/vining_2000.c b/board/samtec/vining_2000/vining_2000.c
index cced08b..0cc8421 100644
--- a/board/samtec/vining_2000/vining_2000.c
+++ b/board/samtec/vining_2000/vining_2000.c
@@ -18,6 +18,7 @@
 #include <asm/mach-imx/mxc_i2c.h>
 #include <linux/sizes.h>
 #include <common.h>
+#include <environment.h>
 #include <fsl_esdhc.h>
 #include <mmc.h>
 #include <i2c.h>
diff --git a/board/samtec/vining_fpga/socfpga.c b/board/samtec/vining_fpga/socfpga.c
index 229b12f..14ac7ef 100644
--- a/board/samtec/vining_fpga/socfpga.c
+++ b/board/samtec/vining_fpga/socfpga.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <asm/arch/reset_manager.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
diff --git a/board/siemens/common/factoryset.c b/board/siemens/common/factoryset.c
index 7fa2673..f3e82d4 100644
--- a/board/siemens/common/factoryset.c
+++ b/board/siemens/common/factoryset.c
@@ -9,6 +9,7 @@
 #if !defined(CONFIG_SPL_BUILD)
 
 #include <common.h>
+#include <environment.h>
 #include <i2c.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
diff --git a/board/siemens/pxm2/board.c b/board/siemens/pxm2/board.c
index 8bbb035..ab54e58 100644
--- a/board/siemens/pxm2/board.c
+++ b/board/siemens/pxm2/board.c
@@ -14,6 +14,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <errno.h>
 #include <spl.h>
 #include <asm/arch/cpu.h>
diff --git a/board/silica/pengwyn/board.c b/board/silica/pengwyn/board.c
index 0429e6f..e736afb 100644
--- a/board/silica/pengwyn/board.c
+++ b/board/silica/pengwyn/board.c
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/ddr_defs.h>
diff --git a/board/technologic/ts4800/ts4800.c b/board/technologic/ts4800/ts4800.c
index e5bec57..c4dad69 100644
--- a/board/technologic/ts4800/ts4800.c
+++ b/board/technologic/ts4800/ts4800.c
@@ -17,6 +17,7 @@
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
 #include <asm/mach-imx/mx5_video.h>
+#include <environment.h>
 #include <mmc.h>
 #include <input.h>
 #include <fsl_esdhc.h>
diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
index c6690fa..1d8b605 100644
--- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c
+++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <misc.h>
 #include <spl.h>
 #include <syscon.h>
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index 7f0fb5d..c33bf58 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -563,8 +563,8 @@
 }
 #endif
 
-#if !defined(CONFIG_SPL_BUILD) || \
-	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
+#if defined(CONFIG_CLOCK_SYNTHESIZER) && (!defined(CONFIG_SPL_BUILD) || \
+	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)))
 static void request_and_set_gpio(int gpio, char *name, int val)
 {
 	int ret;
@@ -621,8 +621,8 @@
 	gpmc_init();
 #endif
 
-#if !defined(CONFIG_SPL_BUILD) || \
-	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
+#if defined(CONFIG_CLOCK_SYNTHESIZER) && (!defined(CONFIG_SPL_BUILD) || \
+	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD)))
 	if (board_is_icev2()) {
 		int rv;
 		u32 reg;
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index 0564df2..0431cd4 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <i2c.h>
 #include <linux/errno.h>
 #include <spl.h>
diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c
index cdde6a8..4a0f829 100644
--- a/board/ti/ti814x/evm.c
+++ b/board/ti/ti814x/evm.c
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <cpsw.h>
+#include <environment.h>
 #include <errno.h>
 #include <spl.h>
 #include <asm/arch/cpu.h>
diff --git a/board/ti/ti816x/evm.c b/board/ti/ti816x/evm.c
index cb40cc5..abc961a 100644
--- a/board/ti/ti816x/evm.c
+++ b/board/ti/ti816x/evm.c
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <spl.h>
 #include <netdev.h>
 #include <asm/cache.h>
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c
index 741b3ac..4bbbd81 100644
--- a/board/timll/devkit8000/devkit8000.c
+++ b/board/timll/devkit8000/devkit8000.c
@@ -18,6 +18,7 @@
  */
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <ns16550.h>
 #include <twl4030.h>
 #include <asm/io.h>
diff --git a/board/toradex/common/tdx-common.c b/board/toradex/common/tdx-common.c
index 6e12d27..d6d3671 100644
--- a/board/toradex/common/tdx-common.c
+++ b/board/toradex/common/tdx-common.c
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <g_dnl.h>
 #include <linux/libfdt.h>
 
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 6546272..5a2a810 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -22,37 +22,65 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static uint8_t efi_obj_list_initalized;
+#define OBJ_LIST_NOT_INITIALIZED 1
+
+static efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
 
 static struct efi_device_path *bootefi_image_path;
 static struct efi_device_path *bootefi_device_path;
 
 /* Initialize and populate EFI object list */
-static void efi_init_obj_list(void)
+efi_status_t efi_init_obj_list(void)
 {
-	efi_obj_list_initalized = 1;
+	efi_status_t ret = EFI_SUCCESS;
+
+	/* Initialize once only */
+	if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
+		return efi_obj_list_initialized;
 
 	/* Initialize EFI driver uclass */
-	efi_driver_init();
+	ret = efi_driver_init();
+	if (ret != EFI_SUCCESS)
+		goto out;
 
-	efi_console_register();
+	ret = efi_console_register();
+	if (ret != EFI_SUCCESS)
+		goto out;
 #ifdef CONFIG_PARTITIONS
-	efi_disk_register();
+	ret = efi_disk_register();
+	if (ret != EFI_SUCCESS)
+		goto out;
 #endif
 #if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO)
-	efi_gop_register();
+	ret = efi_gop_register();
+	if (ret != EFI_SUCCESS)
+		goto out;
 #endif
 #ifdef CONFIG_CMD_NET
-	efi_net_register();
+	ret = efi_net_register();
+	if (ret != EFI_SUCCESS)
+		goto out;
 #endif
 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
-	efi_smbios_register();
+	ret = efi_smbios_register();
+	if (ret != EFI_SUCCESS)
+		goto out;
 #endif
-	efi_watchdog_register();
+	ret = efi_watchdog_register();
+	if (ret != EFI_SUCCESS)
+		goto out;
 
 	/* Initialize EFI runtime services */
-	efi_reset_system_init();
-	efi_get_time_init();
+	ret = efi_reset_system_init();
+	if (ret != EFI_SUCCESS)
+		goto out;
+	ret = efi_get_time_init();
+	if (ret != EFI_SUCCESS)
+		goto out;
+
+out:
+	efi_obj_list_initialized = ret;
+	return ret;
 }
 
 /*
@@ -150,24 +178,85 @@
 }
 #endif
 
+/* Carve out DT reserved memory ranges */
+static efi_status_t efi_carve_out_dt_rsv(void *fdt)
+{
+	int nr_rsv, i;
+	uint64_t addr, size, pages;
+
+	nr_rsv = fdt_num_mem_rsv(fdt);
+
+	/* Look for an existing entry and add it to the efi mem map. */
+	for (i = 0; i < nr_rsv; i++) {
+		if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
+			continue;
+
+		pages = ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
+		efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
+				   false);
+	}
+
+	return EFI_SUCCESS;
+}
+
+static efi_status_t efi_install_fdt(void *fdt)
+{
+	bootm_headers_t img = { 0 };
+	ulong fdt_pages, fdt_size, fdt_start, fdt_end;
+	efi_status_t ret;
+
+	if (fdt_check_header(fdt)) {
+		printf("ERROR: invalid device tree\n");
+		return EFI_INVALID_PARAMETER;
+	}
+
+	/* Prepare fdt for payload */
+	fdt = copy_fdt(fdt);
+	if (!fdt)
+		return EFI_OUT_OF_RESOURCES;
+
+	if (image_setup_libfdt(&img, fdt, 0, NULL)) {
+		printf("ERROR: failed to process device tree\n");
+		return EFI_LOAD_ERROR;
+	}
+
+	if (efi_carve_out_dt_rsv(fdt) != EFI_SUCCESS) {
+		printf("ERROR: failed to carve out memory\n");
+		return EFI_LOAD_ERROR;
+	}
+
+	/* Link to it in the efi tables */
+	ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
+	if (ret != EFI_SUCCESS)
+		return EFI_OUT_OF_RESOURCES;
+
+	/* And reserve the space in the memory map */
+	fdt_start = ((ulong)fdt) & ~EFI_PAGE_MASK;
+	fdt_end = ((ulong)fdt) + fdt_totalsize(fdt);
+	fdt_size = (fdt_end - fdt_start) + EFI_PAGE_MASK;
+	fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
+	/* Give a bootloader the chance to modify the device tree */
+	fdt_pages += 2;
+	ret = efi_add_memory_map(fdt_start, fdt_pages,
+				 EFI_BOOT_SERVICES_DATA, true);
+	return ret;
+}
+
 /*
  * Load an EFI payload into a newly allocated piece of memory, register all
  * EFI objects it would want to access and jump to it.
  */
-static efi_status_t do_bootefi_exec(void *efi, void *fdt,
+static efi_status_t do_bootefi_exec(void *efi,
 				    struct efi_device_path *device_path,
 				    struct efi_device_path *image_path)
 {
 	struct efi_loaded_image loaded_image_info = {};
 	struct efi_object loaded_image_info_obj = {};
 	struct efi_device_path *memdp = NULL;
-	ulong ret;
+	efi_status_t ret;
 
 	EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
 				     struct efi_system_table *st);
-	ulong fdt_pages, fdt_size, fdt_start, fdt_end;
-	const efi_guid_t fdt_guid = EFI_FDT_GUID;
-	bootm_headers_t img = { 0 };
 
 	/*
 	 * Special case for efi payload not loaded from disk, such as
@@ -183,10 +272,6 @@
 		assert(device_path && image_path);
 	}
 
-	/* Initialize and populate EFI object list */
-	if (!efi_obj_list_initalized)
-		efi_init_obj_list();
-
 	efi_setup_loaded_image(&loaded_image_info, &loaded_image_info_obj,
 			       device_path, image_path);
 
@@ -196,38 +281,12 @@
 	 */
 	efi_save_gd();
 
-	if (fdt && !fdt_check_header(fdt)) {
-		/* Prepare fdt for payload */
-		fdt = copy_fdt(fdt);
-
-		if (image_setup_libfdt(&img, fdt, 0, NULL)) {
-			printf("ERROR: Failed to process device tree\n");
-			return -EINVAL;
-		}
-
-		/* Link to it in the efi tables */
-		efi_install_configuration_table(&fdt_guid, fdt);
-
-		/* And reserve the space in the memory map */
-		fdt_start = ((ulong)fdt) & ~EFI_PAGE_MASK;
-		fdt_end = ((ulong)fdt) + fdt_totalsize(fdt);
-		fdt_size = (fdt_end - fdt_start) + EFI_PAGE_MASK;
-		fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
-		/* Give a bootloader the chance to modify the device tree */
-		fdt_pages += 2;
-		efi_add_memory_map(fdt_start, fdt_pages,
-				   EFI_BOOT_SERVICES_DATA, true);
-	} else {
-		printf("WARNING: Invalid device tree, expect boot to fail\n");
-		efi_install_configuration_table(&fdt_guid, NULL);
-	}
-
 	/* Transfer environment variable bootargs as load options */
 	set_load_options(&loaded_image_info, "bootargs");
 	/* Load the EFI payload */
 	entry = efi_load_pe(efi, &loaded_image_info);
 	if (!entry) {
-		ret = -ENOENT;
+		ret = EFI_LOAD_ERROR;
 		goto exit;
 	}
 
@@ -277,16 +336,12 @@
 	return ret;
 }
 
-static int do_bootefi_bootmgr_exec(unsigned long fdt_addr)
+static int do_bootefi_bootmgr_exec(void)
 {
 	struct efi_device_path *device_path, *file_path;
 	void *addr;
 	efi_status_t r;
 
-	/* Initialize and populate EFI object list */
-	if (!efi_obj_list_initalized)
-		efi_init_obj_list();
-
 	/*
 	 * gd lives in a fixed register which may get clobbered while we execute
 	 * the payload. So save it here and restore it on every callback entry
@@ -298,7 +353,7 @@
 		return 1;
 
 	printf("## Starting EFI application at %p ...\n", addr);
-	r = do_bootefi_exec(addr, (void *)fdt_addr, device_path, file_path);
+	r = do_bootefi_exec(addr, device_path, file_path);
 	printf("## Application terminated, r = %lu\n",
 	       r & ~EFI_ERROR_MASK);
 
@@ -311,12 +366,37 @@
 /* Interpreter command to boot an arbitrary EFI image from memory */
 static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	char *saddr, *sfdt;
-	unsigned long addr, fdt_addr = 0;
+	unsigned long addr;
+	char *saddr;
 	efi_status_t r;
+	void *fdt_addr;
+
+	/* Initialize EFI drivers */
+	r = efi_init_obj_list();
+	if (r != EFI_SUCCESS) {
+		printf("Error: Cannot set up EFI drivers, r = %lu\n",
+		       r & ~EFI_ERROR_MASK);
+		return CMD_RET_FAILURE;
+	}
 
 	if (argc < 2)
 		return CMD_RET_USAGE;
+
+	if (argc > 2) {
+		fdt_addr = (void *)simple_strtoul(argv[2], NULL, 16);
+		if (!fdt_addr && *argv[2] != '0')
+			return CMD_RET_USAGE;
+		/* Install device tree */
+		r = efi_install_fdt(fdt_addr);
+		if (r != EFI_SUCCESS) {
+			printf("ERROR: failed to install device tree\n");
+			return CMD_RET_FAILURE;
+		}
+	} else {
+		/* Remove device tree. EFI_NOT_FOUND can be ignored here */
+		efi_install_configuration_table(&efi_guid_fdt, NULL);
+		printf("WARNING: booting without device tree\n");
+	}
 #ifdef CONFIG_CMD_BOOTEFI_HELLO
 	if (!strcmp(argv[1], "hello")) {
 		ulong size = __efi_helloworld_end - __efi_helloworld_begin;
@@ -350,8 +430,7 @@
 		 */
 		efi_save_gd();
 		/* Initialize and populate EFI object list */
-		if (!efi_obj_list_initalized)
-			efi_init_obj_list();
+		efi_init_obj_list();
 		/* Transfer environment variable efi_selftest as load options */
 		set_load_options(&loaded_image_info, "efi_selftest");
 		/* Execute the test */
@@ -363,12 +442,7 @@
 	} else
 #endif
 	if (!strcmp(argv[1], "bootmgr")) {
-		unsigned long fdt_addr = 0;
-
-		if (argc > 2)
-			fdt_addr = simple_strtoul(argv[2], NULL, 16);
-
-		return do_bootefi_bootmgr_exec(fdt_addr);
+		return do_bootefi_bootmgr_exec();
 	} else {
 		saddr = argv[1];
 
@@ -377,15 +451,11 @@
 		if (!addr && *saddr != '0')
 			return CMD_RET_USAGE;
 
-		if (argc > 2) {
-			sfdt = argv[2];
-			fdt_addr = simple_strtoul(sfdt, NULL, 16);
-		}
 	}
 
 	printf("## Starting EFI application at %08lx ...\n", addr);
-	r = do_bootefi_exec((void *)addr, (void *)fdt_addr,
-			    bootefi_device_path, bootefi_image_path);
+	r = do_bootefi_exec((void *)addr, bootefi_device_path,
+			    bootefi_image_path);
 	printf("## Application terminated, r = %lu\n",
 	       r & ~EFI_ERROR_MASK);
 
@@ -406,7 +476,7 @@
 	"  - boot a sample Hello World application stored within U-Boot\n"
 #endif
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
-	"bootefi selftest\n"
+	"bootefi selftest [fdt address]\n"
 	"  - boot an EFI selftest application stored within U-Boot\n"
 	"    Use environment variable efi_selftest to select a single test.\n"
 	"    Use 'setenv efi_selftest list' to enumerate all tests.\n"
@@ -424,16 +494,6 @@
 	bootefi_help_text
 );
 
-static int parse_partnum(const char *devnr)
-{
-	const char *str = strchr(devnr, ':');
-	if (str) {
-		str++;
-		return simple_strtoul(str, NULL, 16);
-	}
-	return 0;
-}
-
 void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 {
 	char filename[32] = { 0 }; /* dp->str is u16[32] long */
@@ -441,12 +501,13 @@
 
 	if (strcmp(dev, "Net")) {
 		struct blk_desc *desc;
+		disk_partition_t fs_partition;
 		int part;
 
-		desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10));
-		if (!desc)
+		part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
+					       1);
+		if (part < 0)
 			return;
-		part = parse_partnum(devnr);
 
 		bootefi_device_path = efi_dp_from_part(desc, part);
 	} else {
diff --git a/cmd/elf.c b/cmd/elf.c
index f874073..0387964 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -16,6 +16,7 @@
 #include <common.h>
 #include <command.h>
 #include <elf.h>
+#include <environment.h>
 #include <net.h>
 #include <vxworks.h>
 #ifdef CONFIG_X86
diff --git a/cmd/ethsw.c b/cmd/ethsw.c
index b600965..92a60b4 100644
--- a/cmd/ethsw.c
+++ b/cmd/ethsw.c
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <environment.h>
 #include <errno.h>
 #include <env_flags.h>
 #include <ethsw.h>
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index 4cb25b8..9838678 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -341,6 +341,36 @@
 	return value;
 }
 
+void eth_parse_enetaddr(const char *addr, uint8_t *enetaddr)
+{
+	char *end;
+	int i;
+
+	for (i = 0; i < 6; ++i) {
+		enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
+		if (addr)
+			addr = (*end) ? end + 1 : end;
+	}
+}
+
+int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr)
+{
+	eth_parse_enetaddr(env_get(name), enetaddr);
+	return is_valid_ethaddr(enetaddr);
+}
+
+int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr)
+{
+	char buf[ARP_HLEN_ASCII + 1];
+
+	if (eth_env_get_enetaddr(name, (uint8_t *)buf))
+		return -EEXIST;
+
+	sprintf(buf, "%pM", enetaddr);
+
+	return env_set(name, buf);
+}
+
 #ifndef CONFIG_SPL_BUILD
 static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
diff --git a/configs/am335x_baltos_defconfig b/configs/am335x_baltos_defconfig
index 8839538..2ceb761 100644
--- a/configs/am335x_baltos_defconfig
+++ b/configs/am335x_baltos_defconfig
@@ -38,11 +38,12 @@
 CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:128k(SPL),128k(SPL.backup1),128k(SPL.backup2),128k(SPL.backup3),1920k(u-boot),-(UBI)"
 CONFIG_CMD_UBI=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_SYS_OMAP24_I2C_SPEED=1000
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig
index e31366d..5688e44 100644
--- a/configs/am335x_boneblack_defconfig
+++ b/configs/am335x_boneblack_defconfig
@@ -23,6 +23,7 @@
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_TFTP=y
 CONFIG_DFU_MMC=y
@@ -30,7 +31,7 @@
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index 5ff51e3..b9726ed 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -25,6 +25,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 # CONFIG_BLK is not set
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
@@ -34,8 +35,8 @@
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 1e8a467..158ae0a 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -27,6 +27,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 # CONFIG_BLK is not set
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
@@ -39,8 +40,8 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
diff --git a/configs/am335x_evm_nor_defconfig b/configs/am335x_evm_nor_defconfig
index 49a04f9..af12695 100644
--- a/configs/am335x_evm_nor_defconfig
+++ b/configs/am335x_evm_nor_defconfig
@@ -20,6 +20,7 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:128k(NAND.SPL),128k(NAND.SPL.backup1),128k(NAND.SPL.backup2),128k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),1m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),-(NAND.file-system)"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
@@ -29,7 +30,7 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/am335x_evm_norboot_defconfig b/configs/am335x_evm_norboot_defconfig
index 22182f5..068c3f2 100644
--- a/configs/am335x_evm_norboot_defconfig
+++ b/configs/am335x_evm_norboot_defconfig
@@ -18,13 +18,14 @@
 CONFIG_MTDIDS_DEFAULT="nor0=physmap-flash.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=physmap-flash.0:512k(u-boot),128k(u-boot-env1),128k(u-boot-env2),4m(kernel),-(rootfs)"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_MTD_NOR_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig
index c0ebb4d..874d67d 100644
--- a/configs/am335x_evm_spiboot_defconfig
+++ b/configs/am335x_evm_spiboot_defconfig
@@ -21,13 +21,14 @@
 CONFIG_MTDIDS_DEFAULT="nor0=m25p80-flash.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=m25p80-flash.0:128k(SPL),512k(u-boot),128k(u-boot-env1),128k(u-boot-env2),3464k(kernel),-(rootfs)"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig
index b240505..25d01bb 100644
--- a/configs/am335x_evm_usbspl_defconfig
+++ b/configs/am335x_evm_usbspl_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_MTDPARTS=y
 CONFIG_MTDIDS_DEFAULT="nand0=nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:128k(NAND.SPL),128k(NAND.SPL.backup1),128k(NAND.SPL.backup2),128k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),1m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),-(NAND.file-system)"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_NETCONSOLE=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
@@ -37,7 +38,7 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/am335x_hs_evm_defconfig b/configs/am335x_hs_evm_defconfig
index 74fe162..4eb5e27 100644
--- a/configs/am335x_hs_evm_defconfig
+++ b/configs/am335x_hs_evm_defconfig
@@ -33,6 +33,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 # CONFIG_BLK is not set
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
@@ -46,8 +47,8 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
diff --git a/configs/am335x_hs_evm_uart_defconfig b/configs/am335x_hs_evm_uart_defconfig
index 97519ea..1321d52 100644
--- a/configs/am335x_hs_evm_uart_defconfig
+++ b/configs/am335x_hs_evm_uart_defconfig
@@ -30,6 +30,7 @@
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am335x-evm am335x-bone am335x-boneblack am335x-evmsk am335x-bonegreen am335x-icev2"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 # CONFIG_BLK is not set
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
@@ -42,8 +43,8 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
diff --git a/configs/am335x_igep003x_defconfig b/configs/am335x_igep003x_defconfig
index c1cdf96..48dc3c9 100644
--- a/configs/am335x_igep003x_defconfig
+++ b/configs/am335x_igep003x_defconfig
@@ -39,10 +39,11 @@
 CONFIG_CMD_UBI=y
 # CONFIG_CMD_UBIFS is not set
 CONFIG_ENV_IS_IN_UBI=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
 CONFIG_MTD_UBI_FASTMAP=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am335x_pdu001_defconfig b/configs/am335x_pdu001_defconfig
index a9d0f8e..87ae88c 100644
--- a/configs/am335x_pdu001_defconfig
+++ b/configs/am335x_pdu001_defconfig
@@ -39,6 +39,7 @@
 CONFIG_DM_I2C=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_MMC_SDHCI=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_DM_PMIC=y
diff --git a/configs/am335x_shc_defconfig b/configs/am335x_shc_defconfig
index 3843727..3be3063 100644
--- a/configs/am335x_shc_defconfig
+++ b/configs/am335x_shc_defconfig
@@ -35,8 +35,9 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am335x_shc_ict_defconfig b/configs/am335x_shc_ict_defconfig
index fe69ba7..1fe5bf8 100644
--- a/configs/am335x_shc_ict_defconfig
+++ b/configs/am335x_shc_ict_defconfig
@@ -36,8 +36,9 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am335x_shc_netboot_defconfig b/configs/am335x_shc_netboot_defconfig
index 3d91106..bd61102 100644
--- a/configs/am335x_shc_netboot_defconfig
+++ b/configs/am335x_shc_netboot_defconfig
@@ -37,8 +37,9 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am335x_shc_prompt_defconfig b/configs/am335x_shc_prompt_defconfig
index 5607789..9658fb9 100644
--- a/configs/am335x_shc_prompt_defconfig
+++ b/configs/am335x_shc_prompt_defconfig
@@ -34,8 +34,9 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am335x_shc_sdboot_defconfig b/configs/am335x_shc_sdboot_defconfig
index 0b4ffdf..f8f88d3 100644
--- a/configs/am335x_shc_sdboot_defconfig
+++ b/configs/am335x_shc_sdboot_defconfig
@@ -36,8 +36,9 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am335x_shc_sdboot_prompt_defconfig b/configs/am335x_shc_sdboot_prompt_defconfig
index 0b4ffdf..f8f88d3 100644
--- a/configs/am335x_shc_sdboot_prompt_defconfig
+++ b/configs/am335x_shc_sdboot_prompt_defconfig
@@ -36,8 +36,9 @@
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_SPL_ISO_PARTITION is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am335x_sl50_defconfig b/configs/am335x_sl50_defconfig
index bf0efb3..d51812e 100644
--- a/configs/am335x_sl50_defconfig
+++ b/configs/am335x_sl50_defconfig
@@ -38,9 +38,10 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_FAT_WRITE=y
diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig
index 0cb79ea..edb4119 100644
--- a/configs/am43xx_evm_defconfig
+++ b/configs/am43xx_evm_defconfig
@@ -24,6 +24,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),512k(NAND.u-boot-spl-os),1m(NAND.u-boot),256k(NAND.u-boot-env),256k(NAND.u-boot-env.backup1),7m(NAND.kernel),-(NAND.file-system)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
@@ -35,7 +36,7 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
diff --git a/configs/am43xx_evm_ethboot_defconfig b/configs/am43xx_evm_ethboot_defconfig
index 8e51dc7..fcb502c 100644
--- a/configs/am43xx_evm_ethboot_defconfig
+++ b/configs/am43xx_evm_ethboot_defconfig
@@ -34,6 +34,7 @@
 CONFIG_MTDIDS_DEFAULT="nand0=nand.0"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),512k(NAND.u-boot-spl-os),1m(NAND.u-boot),256k(NAND.u-boot-env),256k(NAND.u-boot-env.backup1),7m(NAND.kernel),-(NAND.file-system)"
 CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_DFU_SF=y
@@ -41,7 +42,7 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_TI_QSPI=y
 CONFIG_USB=y
diff --git a/configs/am43xx_evm_qspiboot_defconfig b/configs/am43xx_evm_qspiboot_defconfig
index 3fbf701..99daf5d 100644
--- a/configs/am43xx_evm_qspiboot_defconfig
+++ b/configs/am43xx_evm_qspiboot_defconfig
@@ -29,6 +29,7 @@
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
@@ -39,7 +40,7 @@
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_TI_QSPI=y
 CONFIG_USB=y
diff --git a/configs/am43xx_evm_rtconly_defconfig b/configs/am43xx_evm_rtconly_defconfig
index d6e1e0d..f37ceb0 100644
--- a/configs/am43xx_evm_rtconly_defconfig
+++ b/configs/am43xx_evm_rtconly_defconfig
@@ -25,6 +25,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),512k(NAND.u-boot-spl-os),1m(NAND.u-boot),256k(NAND.u-boot-env),256k(NAND.u-boot-env.backup1),7m(NAND.kernel),-(NAND.file-system)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
diff --git a/configs/am43xx_evm_usbhost_boot_defconfig b/configs/am43xx_evm_usbhost_boot_defconfig
index 505890e..4e9a614 100644
--- a/configs/am43xx_evm_usbhost_boot_defconfig
+++ b/configs/am43xx_evm_usbhost_boot_defconfig
@@ -38,6 +38,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
 CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
@@ -49,7 +50,7 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
diff --git a/configs/am43xx_hs_evm_defconfig b/configs/am43xx_hs_evm_defconfig
index 98b0cea..d290af0 100644
--- a/configs/am43xx_hs_evm_defconfig
+++ b/configs/am43xx_hs_evm_defconfig
@@ -35,6 +35,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),512k(NAND.u-boot-spl-os),1m(NAND.u-boot),256k(NAND.u-boot-env),256k(NAND.u-boot-env.backup1),7m(NAND.kernel),-(NAND.file-system)"
 CONFIG_OF_CONTROL=y
 CONFIG_OF_LIST="am437x-gp-evm am437x-sk-evm am43x-epos-evm am437x-idk-evm"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
 CONFIG_DFU_MMC=y
@@ -46,7 +47,7 @@
 CONFIG_NAND=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index 9f2a7f7..0424887 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -37,6 +37,7 @@
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_LIST="am57xx-beagle-x15 am57xx-beagle-x15-revb1 am57xx-beagle-x15-revc am572x-idk am571x-idk am574x-idk"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SCSI_AHCI=y
@@ -51,10 +52,10 @@
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_PALMAS=y
 CONFIG_DM_REGULATOR=y
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index b3e739a..403dfda 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -40,6 +40,7 @@
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_LIST="am57xx-beagle-x15 am57xx-beagle-x15-revb1 am57xx-beagle-x15-revc am572x-idk am571x-idk am574x-idk"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SCSI_AHCI=y
@@ -54,10 +55,10 @@
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_PALMAS=y
 CONFIG_DM_REGULATOR=y
diff --git a/configs/apalis_imx6_defconfig b/configs/apalis_imx6_defconfig
index 63e940b..77a4008 100644
--- a/configs/apalis_imx6_defconfig
+++ b/configs/apalis_imx6_defconfig
@@ -14,6 +14,7 @@
 CONFIG_BOOTDELAY=1
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -48,6 +49,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DWC_AHSATA=y
 CONFIG_FSL_ESDHC=y
 CONFIG_PHYLIB=y
diff --git a/configs/apalis_imx6_nospl_com_defconfig b/configs/apalis_imx6_nospl_com_defconfig
index d47061f..89af27f 100644
--- a/configs/apalis_imx6_nospl_com_defconfig
+++ b/configs/apalis_imx6_nospl_com_defconfig
@@ -9,6 +9,7 @@
 CONFIG_BOOTDELAY=1
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -37,6 +38,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DWC_AHSATA=y
 CONFIG_FSL_ESDHC=y
 CONFIG_PHYLIB=y
diff --git a/configs/apalis_imx6_nospl_it_defconfig b/configs/apalis_imx6_nospl_it_defconfig
index 65a868d..048d4f8 100644
--- a/configs/apalis_imx6_nospl_it_defconfig
+++ b/configs/apalis_imx6_nospl_it_defconfig
@@ -9,6 +9,7 @@
 CONFIG_BOOTDELAY=1
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -37,6 +38,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DWC_AHSATA=y
 CONFIG_FSL_ESDHC=y
 CONFIG_PHYLIB=y
diff --git a/configs/birdland_bav335a_defconfig b/configs/birdland_bav335a_defconfig
index 5a20dc9..edc24d6 100644
--- a/configs/birdland_bav335a_defconfig
+++ b/configs/birdland_bav335a_defconfig
@@ -42,13 +42,14 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/birdland_bav335b_defconfig b/configs/birdland_bav335b_defconfig
index b9ad03b..4f814e4 100644
--- a/configs/birdland_bav335b_defconfig
+++ b/configs/birdland_bav335b_defconfig
@@ -42,13 +42,14 @@
 CONFIG_CMD_USB_MASS_STORAGE=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig
index 2079ed9..e202bc3 100644
--- a/configs/brppt1_mmc_defconfig
+++ b/configs/brppt1_mmc_defconfig
@@ -54,7 +54,7 @@
 CONFIG_BOOTP_SUBNETMASK=y
 CONFIG_BOOTCOUNT_LIMIT=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_USB_MUSB_HOST=y
diff --git a/configs/brppt1_nand_defconfig b/configs/brppt1_nand_defconfig
index 66cea79..8adbfa0 100644
--- a/configs/brppt1_nand_defconfig
+++ b/configs/brppt1_nand_defconfig
@@ -56,7 +56,7 @@
 CONFIG_BOOTCOUNT_LIMIT=y
 # CONFIG_MMC is not set
 CONFIG_NAND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_USB_MUSB_HOST=y
diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig
index 67c254f..2ab44c3 100644
--- a/configs/brppt1_spi_defconfig
+++ b/configs/brppt1_spi_defconfig
@@ -63,7 +63,7 @@
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig
index 4b07bea..45f11d1 100644
--- a/configs/brxre1_defconfig
+++ b/configs/brxre1_defconfig
@@ -54,7 +54,7 @@
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_SUBNETMASK=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_USB=y
 CONFIG_USB_MUSB_HOST=y
diff --git a/configs/cgtqmx6eval_defconfig b/configs/cgtqmx6eval_defconfig
index 2b49782..697c9cf 100644
--- a/configs/cgtqmx6eval_defconfig
+++ b/configs/cgtqmx6eval_defconfig
@@ -46,6 +46,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DWC_AHSATA=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_SF=y
diff --git a/configs/chiliboard_defconfig b/configs/chiliboard_defconfig
index d934182..344a3a0 100644
--- a/configs/chiliboard_defconfig
+++ b/configs/chiliboard_defconfig
@@ -34,7 +34,7 @@
 CONFIG_DM_GPIO=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/cl-som-am57x_defconfig b/configs/cl-som-am57x_defconfig
index d826b70..53746bf 100644
--- a/configs/cl-som-am57x_defconfig
+++ b/configs/cl-som-am57x_defconfig
@@ -24,6 +24,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_SCSI_AHCI=y
 CONFIG_CMD_PCA953X=y
 CONFIG_LED_STATUS=y
@@ -42,7 +43,7 @@
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_CONS_INDEX=3
 CONFIG_SYS_NS16550=y
 CONFIG_TI_QSPI=y
diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig
index 74936d7..884cc8c 100644
--- a/configs/cm_fx6_defconfig
+++ b/configs/cm_fx6_defconfig
@@ -45,6 +45,7 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:768k(uboot),256k(uboot-environment),-(reserved)"
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DWC_AHSATA=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
diff --git a/configs/cm_t335_defconfig b/configs/cm_t335_defconfig
index c8390bd..9b0eed8 100644
--- a/configs/cm_t335_defconfig
+++ b/configs/cm_t335_defconfig
@@ -45,7 +45,7 @@
 CONFIG_LED_STATUS_BOOT=0
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_FAT_WRITE=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/cm_t43_defconfig b/configs/cm_t43_defconfig
index f748547..fadf65d 100644
--- a/configs/cm_t43_defconfig
+++ b/configs/cm_t43_defconfig
@@ -41,6 +41,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_DM_GPIO=y
 CONFIG_MMC_OMAP_HS=y
@@ -55,7 +56,7 @@
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_SPI_FLASH_SST=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_DM_SERIAL=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
diff --git a/configs/cm_t54_defconfig b/configs/cm_t54_defconfig
index 24c2a60..20cb0fd 100644
--- a/configs/cm_t54_defconfig
+++ b/configs/cm_t54_defconfig
@@ -28,6 +28,7 @@
 # CONFIG_CMD_NFS is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_SCSI_AHCI=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SCSI=y
diff --git a/configs/colibri_imx6_defconfig b/configs/colibri_imx6_defconfig
index 1711c8a..c19e782 100644
--- a/configs/colibri_imx6_defconfig
+++ b/configs/colibri_imx6_defconfig
@@ -14,6 +14,7 @@
 CONFIG_BOOTDELAY=1
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -48,6 +49,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/colibri_imx6_nospl_defconfig b/configs/colibri_imx6_nospl_defconfig
index 7b65566..aecc179 100644
--- a/configs/colibri_imx6_nospl_defconfig
+++ b/configs/colibri_imx6_nospl_defconfig
@@ -9,6 +9,7 @@
 CONFIG_BOOTDELAY=1
 # CONFIG_CONSOLE_MUX is not set
 CONFIG_SUPPORT_RAW_INITRD=y
+CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_EARLY_INIT_F=y
@@ -37,6 +38,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/colibri_imx7_defconfig b/configs/colibri_imx7_defconfig
index d4fe57f..b6139c0 100644
--- a/configs/colibri_imx7_defconfig
+++ b/configs/colibri_imx7_defconfig
@@ -43,6 +43,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_OF_EMBED=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
diff --git a/configs/colibri_pxa270_defconfig b/configs/colibri_pxa270_defconfig
index c305e99..64e740c 100644
--- a/configs/colibri_pxa270_defconfig
+++ b/configs/colibri_pxa270_defconfig
@@ -23,6 +23,7 @@
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_FAT=y
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig
index 07c9bd8..77ad26e 100644
--- a/configs/colibri_vf_defconfig
+++ b/configs/colibri_vf_defconfig
@@ -39,6 +39,7 @@
 CONFIG_CMD_UBI=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_NAND=y
diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig
index cb210cf..595c1b5 100644
--- a/configs/dra7xx_evm_defconfig
+++ b/configs/dra7xx_evm_defconfig
@@ -37,6 +37,7 @@
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupt-parent"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
@@ -60,8 +61,8 @@
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_PHYLIB=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_SPL_PHY=y
 CONFIG_PMIC_PALMAS=y
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index 3e18023..f0dac9e 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -39,6 +39,7 @@
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_LIST="dra7-evm dra72-evm dra72-evm-revc dra71-evm dra76-evm"
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_REGMAP=y
@@ -59,8 +60,8 @@
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
 CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_PHYLIB=y
 CONFIG_DM_ETH=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_PHY_GIGE=y
 CONFIG_SPL_PHY=y
 CONFIG_PMIC_PALMAS=y
diff --git a/configs/draco_defconfig b/configs/draco_defconfig
index 87b0726..ae1822c 100644
--- a/configs/draco_defconfig
+++ b/configs/draco_defconfig
@@ -65,7 +65,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/duovero_defconfig b/configs/duovero_defconfig
index c55a93c..23ca1b7 100644
--- a/configs/duovero_defconfig
+++ b/configs/duovero_defconfig
@@ -23,6 +23,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 # CONFIG_SPL_EFI_PARTITION is not set
 CONFIG_SPL_PARTITION_UUIDS=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NETDEVICES=y
 CONFIG_SMC911X=y
diff --git a/configs/etamin_defconfig b/configs/etamin_defconfig
index 77f82af..6e5d4c2 100644
--- a/configs/etamin_defconfig
+++ b/configs/etamin_defconfig
@@ -65,7 +65,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/imx6q_logic_defconfig b/configs/imx6q_logic_defconfig
index b4e1dbb..f0974bf 100644
--- a/configs/imx6q_logic_defconfig
+++ b/configs/imx6q_logic_defconfig
@@ -24,6 +24,7 @@
 CONFIG_MTDIDS_DEFAULT="nand0=gpmi-nand"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=gpmi-nand:4m(uboot),1m(env),16m(kernel),1m(dtb),-(fs)"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_SYS_I2C_MXC=y
 CONFIG_FSL_ESDHC=y
 CONFIG_NAND=y
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig
index c71f67c..8a2dc7f 100644
--- a/configs/k2g_evm_defconfig
+++ b/configs/k2g_evm_defconfig
@@ -30,6 +30,7 @@
 CONFIG_OF_LIST="keystone-k2g-generic keystone-k2g-evm keystone-k2g-ice"
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
 CONFIG_DM_MMC=y
diff --git a/configs/k2g_hs_evm_defconfig b/configs/k2g_hs_evm_defconfig
index b0c0e08..86cb526 100644
--- a/configs/k2g_hs_evm_defconfig
+++ b/configs/k2g_hs_evm_defconfig
@@ -24,6 +24,7 @@
 CONFIG_OF_LIST="keystone-k2g-generic keystone-k2g-evm keystone-k2g-ice"
 CONFIG_DTB_RESELECT=y
 CONFIG_MULTI_DTB_FIT=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 # CONFIG_BLK is not set
 CONFIG_DM_MMC=y
diff --git a/configs/mccmon6_nor_defconfig b/configs/mccmon6_nor_defconfig
index d9d756d..990944c 100644
--- a/configs/mccmon6_nor_defconfig
+++ b/configs/mccmon6_nor_defconfig
@@ -24,6 +24,7 @@
 CONFIG_MTDIDS_DEFAULT="nor0=8000000.nor"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nor:32m@0x0(mccmon6-image.nor),256k@0x40000(u-boot-env.nor),1m@0x80000(u-boot.nor),8m@0x180000(kernel.nor),8m@0x980000(swupdate-kernel.nor),8m@0x1180000(swupdate-rootfs.nor),128k@0x1980000(kernel-dtb.nor),128k@0x19C0000(swupdate-kernel-dtb.nor)"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD=y
diff --git a/configs/mccmon6_sd_defconfig b/configs/mccmon6_sd_defconfig
index 2ad871c..ff0a935 100644
--- a/configs/mccmon6_sd_defconfig
+++ b/configs/mccmon6_sd_defconfig
@@ -25,6 +25,7 @@
 CONFIG_MTDIDS_DEFAULT="nor0=8000000.nor"
 CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nor:32m@0x0(mccmon6-image.nor),256k@0x40000(u-boot-env.nor),1m@0x80000(u-boot.nor),8m@0x180000(kernel.nor),8m@0x980000(swupdate-kernel.nor),8m@0x1180000(swupdate-rootfs.nor),128k@0x1980000(kernel-dtb.nor),128k@0x19C0000(swupdate-kernel-dtb.nor)"
 CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_FSL_ESDHC=y
 CONFIG_MTD=y
diff --git a/configs/mx6cuboxi_defconfig b/configs/mx6cuboxi_defconfig
index 1b38577..6222ac6 100644
--- a/configs/mx6cuboxi_defconfig
+++ b/configs/mx6cuboxi_defconfig
@@ -27,6 +27,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 # CONFIG_SPL_PARTITION_UUIDS is not set
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_DWC_AHSATA=y
 CONFIG_FSL_ESDHC=y
diff --git a/configs/mx6sabreauto_defconfig b/configs/mx6sabreauto_defconfig
index 77958c8..2e4e0ff 100644
--- a/configs/mx6sabreauto_defconfig
+++ b/configs/mx6sabreauto_defconfig
@@ -39,6 +39,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_SF=y
 CONFIG_FSL_ESDHC=y
diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig
index a56d685..c2d1cd4 100644
--- a/configs/mx6sabresd_defconfig
+++ b/configs/mx6sabresd_defconfig
@@ -51,6 +51,7 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_EFI_PARTITION=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig
index c467588..6ea92bb 100644
--- a/configs/mx6sxsabresd_defconfig
+++ b/configs/mx6sxsabresd_defconfig
@@ -31,6 +31,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig
index 9c03546..7b408e2 100644
--- a/configs/mx6sxsabresd_spl_defconfig
+++ b/configs/mx6sxsabresd_spl_defconfig
@@ -40,6 +40,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_DM_MMC=y
diff --git a/configs/mx6ul_14x14_evk_defconfig b/configs/mx6ul_14x14_evk_defconfig
index 821c8f9..fd6962e 100644
--- a/configs/mx6ul_14x14_evk_defconfig
+++ b/configs/mx6ul_14x14_evk_defconfig
@@ -35,6 +35,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
diff --git a/configs/mx6ul_9x9_evk_defconfig b/configs/mx6ul_9x9_evk_defconfig
index d1448c5..86c942c 100644
--- a/configs/mx6ul_9x9_evk_defconfig
+++ b/configs/mx6ul_9x9_evk_defconfig
@@ -35,6 +35,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_BAR=y
diff --git a/configs/mx6ull_14x14_evk_defconfig b/configs/mx6ull_14x14_evk_defconfig
index 1172f41..7a85397 100644
--- a/configs/mx6ull_14x14_evk_defconfig
+++ b/configs/mx6ull_14x14_evk_defconfig
@@ -23,6 +23,7 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_74X164=y
 CONFIG_DM_I2C=y
diff --git a/configs/mx6ull_14x14_evk_plugin_defconfig b/configs/mx6ull_14x14_evk_plugin_defconfig
index 0475c1f..0db69cd 100644
--- a/configs/mx6ull_14x14_evk_plugin_defconfig
+++ b/configs/mx6ull_14x14_evk_plugin_defconfig
@@ -24,6 +24,7 @@
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_74X164=y
 CONFIG_DM_I2C=y
diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig
index bd3a7de..5943c19 100644
--- a/configs/odroid-xu3_defconfig
+++ b/configs/odroid-xu3_defconfig
@@ -25,6 +25,7 @@
 CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_ADC=y
 CONFIG_ADC_EXYNOS=y
 CONFIG_DFU_MMC=y
diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig
index 810874d..04a5e2c 100644
--- a/configs/odroid_defconfig
+++ b/configs/odroid_defconfig
@@ -30,6 +30,7 @@
 CONFIG_CMD_REGULATOR=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_SYS_I2C_S3C24X0=y
 CONFIG_DM_MMC=y
diff --git a/configs/omap4_panda_defconfig b/configs/omap4_panda_defconfig
index 9fb4aec..7e01646 100644
--- a/configs/omap4_panda_defconfig
+++ b/configs/omap4_panda_defconfig
@@ -26,6 +26,7 @@
 CONFIG_ENV_IS_IN_FAT=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_CONS_INDEX=3
 CONFIG_SYS_NS16550=y
diff --git a/configs/omap5_uevm_defconfig b/configs/omap5_uevm_defconfig
index 7d4b708..abff63d 100644
--- a/configs/omap5_uevm_defconfig
+++ b/configs/omap5_uevm_defconfig
@@ -24,6 +24,7 @@
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_SCSI_AHCI=y
 CONFIG_DFU_MMC=y
 CONFIG_DFU_RAM=y
diff --git a/configs/pcm051_rev1_defconfig b/configs/pcm051_rev1_defconfig
index 079ac8b..3f06b6a 100644
--- a/configs/pcm051_rev1_defconfig
+++ b/configs/pcm051_rev1_defconfig
@@ -39,10 +39,11 @@
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/pcm051_rev3_defconfig b/configs/pcm051_rev3_defconfig
index f43c008..6a30fc0 100644
--- a/configs/pcm051_rev3_defconfig
+++ b/configs/pcm051_rev3_defconfig
@@ -39,10 +39,11 @@
 CONFIG_CMD_USB=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/pengwyn_defconfig b/configs/pengwyn_defconfig
index 0a8edb4..ab88d06 100644
--- a/configs/pengwyn_defconfig
+++ b/configs/pengwyn_defconfig
@@ -44,9 +44,10 @@
 CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:512k(SPL),512k(SPL.backup1),512k(SPL.backup2),512k(SPL.backup3),1536k(u-boot),512k(u-boot-spl-os),512k(u-boot-env),5m(kernel),-(rootfs)"
 CONFIG_CMD_DIAG=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
 CONFIG_NAND=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/pepper_defconfig b/configs/pepper_defconfig
index b9ee513..91e9937 100644
--- a/configs/pepper_defconfig
+++ b/configs/pepper_defconfig
@@ -28,10 +28,11 @@
 CONFIG_CMD_SPI=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
 CONFIG_PHY_MICREL_KSZ90X1=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_NETDEVICES=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
diff --git a/configs/pxm2_defconfig b/configs/pxm2_defconfig
index 5833a1a..65e13a6 100644
--- a/configs/pxm2_defconfig
+++ b/configs/pxm2_defconfig
@@ -67,7 +67,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/rastaban_defconfig b/configs/rastaban_defconfig
index 30ef7fc..ae6bbca 100644
--- a/configs/rastaban_defconfig
+++ b/configs/rastaban_defconfig
@@ -65,7 +65,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/rpi_0_w_defconfig b/configs/rpi_0_w_defconfig
index 3570dc9..fcc2ae6 100644
--- a/configs/rpi_0_w_defconfig
+++ b/configs/rpi_0_w_defconfig
@@ -15,6 +15,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
diff --git a/configs/rpi_2_defconfig b/configs/rpi_2_defconfig
index 1e3e08e..204af74 100644
--- a/configs/rpi_2_defconfig
+++ b/configs/rpi_2_defconfig
@@ -15,6 +15,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
diff --git a/configs/rpi_3_32b_defconfig b/configs/rpi_3_32b_defconfig
index 05586b5..9e142ca 100644
--- a/configs/rpi_3_32b_defconfig
+++ b/configs/rpi_3_32b_defconfig
@@ -16,6 +16,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
diff --git a/configs/rpi_3_defconfig b/configs/rpi_3_defconfig
index d8836f9..f46e504 100644
--- a/configs/rpi_3_defconfig
+++ b/configs/rpi_3_defconfig
@@ -16,6 +16,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
diff --git a/configs/rpi_defconfig b/configs/rpi_defconfig
index d9c78a5..82c90d4 100644
--- a/configs/rpi_defconfig
+++ b/configs/rpi_defconfig
@@ -15,6 +15,7 @@
 CONFIG_OF_EMBED=y
 CONFIG_ENV_FAT_INTERFACE="mmc"
 CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM_KEYBOARD=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
diff --git a/configs/rut_defconfig b/configs/rut_defconfig
index 7605b0e..f4e96fb 100644
--- a/configs/rut_defconfig
+++ b/configs/rut_defconfig
@@ -68,7 +68,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/s5p_goni_defconfig b/configs/s5p_goni_defconfig
index 237b590..a54dd5f 100644
--- a/configs/s5p_goni_defconfig
+++ b/configs/s5p_goni_defconfig
@@ -26,6 +26,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_FAT=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 # CONFIG_NET is not set
 CONFIG_DFU_MMC=y
 CONFIG_DM_I2C_GPIO=y
diff --git a/configs/s5pc210_universal_defconfig b/configs/s5pc210_universal_defconfig
index 5014216..62b585d 100644
--- a/configs/s5pc210_universal_defconfig
+++ b/configs/s5pc210_universal_defconfig
@@ -25,6 +25,7 @@
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_MTDPARTS_DEFAULT="mtdparts=samsung-onenand:128k(s-boot),896k(bootloader),256k(params),2816k(config),8m(csa),7m(kernel),1m(log),12m(modem),60m(qboot),-(UBI)"
 CONFIG_OF_CONTROL=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_SYS_I2C_S3C24X0=y
 CONFIG_DM_MMC=y
diff --git a/configs/sama5d36ek_cmp_mmc_defconfig b/configs/sama5d36ek_cmp_mmc_defconfig
index 186f9f4..1c9148d 100644
--- a/configs/sama5d36ek_cmp_mmc_defconfig
+++ b/configs/sama5d36ek_cmp_mmc_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/sama5d36ek_cmp_nandflash_defconfig b/configs/sama5d36ek_cmp_nandflash_defconfig
index 83bea11..a39e230 100644
--- a/configs/sama5d36ek_cmp_nandflash_defconfig
+++ b/configs/sama5d36ek_cmp_nandflash_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/sama5d36ek_cmp_spiflash_defconfig b/configs/sama5d36ek_cmp_spiflash_defconfig
index 4d3b83c..d0be9fe 100644
--- a/configs/sama5d36ek_cmp_spiflash_defconfig
+++ b/configs/sama5d36ek_cmp_spiflash_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/sama5d3xek_mmc_defconfig b/configs/sama5d3xek_mmc_defconfig
index 5394048..4beedb6 100644
--- a/configs/sama5d3xek_mmc_defconfig
+++ b/configs/sama5d3xek_mmc_defconfig
@@ -44,6 +44,7 @@
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
 CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/sama5d3xek_nandflash_defconfig b/configs/sama5d3xek_nandflash_defconfig
index fda2c44..53346ed 100644
--- a/configs/sama5d3xek_nandflash_defconfig
+++ b/configs/sama5d3xek_nandflash_defconfig
@@ -39,6 +39,7 @@
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/sama5d3xek_spiflash_defconfig b/configs/sama5d3xek_spiflash_defconfig
index 88a9fa1..1b66f3c 100644
--- a/configs/sama5d3xek_spiflash_defconfig
+++ b/configs/sama5d3xek_spiflash_defconfig
@@ -38,6 +38,7 @@
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_SPL_REMOVE_PROPS="interrupts interrupt-parent dmas dma-names"
 CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/thuban_defconfig b/configs/thuban_defconfig
index 5136dba..2db2112 100644
--- a/configs/thuban_defconfig
+++ b/configs/thuban_defconfig
@@ -65,7 +65,7 @@
 CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_MTD_UBI_FASTMAP=y
 CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OMAP3_SPI=y
 CONFIG_USB=y
diff --git a/configs/ti814x_evm_defconfig b/configs/ti814x_evm_defconfig
index 337f4f3..fa77800 100644
--- a/configs/ti814x_evm_defconfig
+++ b/configs/ti814x_evm_defconfig
@@ -32,10 +32,11 @@
 CONFIG_CMD_PING=y
 CONFIG_CMD_EXT2=y
 CONFIG_CMD_FAT=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_DNS=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_SUBNETMASK=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_PHYLIB=y
+CONFIG_DRIVER_TI_CPSW=y
 CONFIG_SYS_NS16550=y
 CONFIG_OF_LIBFDT=y
diff --git a/configs/trats2_defconfig b/configs/trats2_defconfig
index 3ca154b..0ee5670 100644
--- a/configs/trats2_defconfig
+++ b/configs/trats2_defconfig
@@ -27,6 +27,7 @@
 # CONFIG_CMD_MISC is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_I2C_GPIO=y
 CONFIG_SYS_I2C_S3C24X0=y
diff --git a/configs/trats_defconfig b/configs/trats_defconfig
index 019dca3..fde2b13 100644
--- a/configs/trats_defconfig
+++ b/configs/trats_defconfig
@@ -26,6 +26,7 @@
 # CONFIG_CMD_MISC is not set
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_OF_CONTROL=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DFU_MMC=y
 CONFIG_DM_I2C_GPIO=y
 CONFIG_SYS_I2C_S3C24X0=y
diff --git a/configs/udoo_defconfig b/configs/udoo_defconfig
index 658f577..2d8cedf 100644
--- a/configs/udoo_defconfig
+++ b/configs/udoo_defconfig
@@ -31,6 +31,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_DWC_AHSATA=y
 CONFIG_FSL_ESDHC=y
diff --git a/configs/udoo_neo_defconfig b/configs/udoo_neo_defconfig
index ec0f152..fb02fc5 100644
--- a/configs/udoo_neo_defconfig
+++ b/configs/udoo_neo_defconfig
@@ -24,6 +24,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_TIME=y
 CONFIG_CMD_EXT4_WRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_PHYLIB=y
 CONFIG_PHY_MICREL=y
diff --git a/configs/vining_2000_defconfig b/configs/vining_2000_defconfig
index dc2f85d..1d28b2f 100644
--- a/configs/vining_2000_defconfig
+++ b/configs/vining_2000_defconfig
@@ -29,6 +29,7 @@
 CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 CONFIG_EFI_PARTITION=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_PHYLIB=y
 CONFIG_PCI=y
diff --git a/configs/wandboard_defconfig b/configs/wandboard_defconfig
index e6707a0..0333529 100644
--- a/configs/wandboard_defconfig
+++ b/configs/wandboard_defconfig
@@ -31,6 +31,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_DM=y
 CONFIG_DWC_AHSATA=y
 CONFIG_FSL_ESDHC=y
diff --git a/configs/wb50n_defconfig b/configs/wb50n_defconfig
index ce3677b..5b2daae 100644
--- a/configs/wb50n_defconfig
+++ b/configs/wb50n_defconfig
@@ -23,6 +23,7 @@
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_ENV_IS_IN_NAND=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_BOOTP_BOOTPATH=y
 CONFIG_BOOTP_GATEWAY=y
 CONFIG_BOOTP_HOSTNAME=y
diff --git a/configs/zc5202_defconfig b/configs/zc5202_defconfig
index c84ae3c..faf9365 100644
--- a/configs/zc5202_defconfig
+++ b/configs/zc5202_defconfig
@@ -29,6 +29,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/zc5601_defconfig b/configs/zc5601_defconfig
index 958f8f5..892c7f8 100644
--- a/configs/zc5601_defconfig
+++ b/configs/zc5601_defconfig
@@ -28,6 +28,7 @@
 CONFIG_CMD_CACHE=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
 CONFIG_FSL_ESDHC=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/doc/README.efi b/doc/README.efi
deleted file mode 100644
index 956f5bf..0000000
--- a/doc/README.efi
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# Copyright (C) 2015 Google, Inc
-#
-# SPDX-License-Identifier:	GPL-2.0+
-#
-
-EFI on U-Boot
-=============
-This document provides information about the implementation of the UEFI API [1]
-in U-Boot.
-
-
-=========== Table of Contents ===========
-
-Motivation
-How do I get it?
-Status
-Future work
-
-
-Motivation
-----------
-
-With this API support in place, you can run any UEFI payload (such as the Linux
-kernel, grub2 or gummiboot) on U-Boot. This dramatically simplifies boot loader
-configuration, as U-Boot based systems now look and feel (almost) the same way
-as TianoCore based systems.
-
-How do I get it?
-----------------
-
-EFI support for 32bit ARM and AArch64 is already included in U-Boot. All you
-need to do is enable
-
-  CONFIG_CMD_BOOTEFI=y
-  CONFIG_EFI_LOADER=y
-
-in your .config file and you will automatically get a bootefi command to run
-an efi application as well as snippet in the default distro boot script that
-scans for removable media efi binaries as fallback.
-
-Status
-------
-
-I am successfully able to run grub2 and Linux EFI binaries with this code on
-ARMv7 as well as AArch64 systems.
-
-When enabled, the resulting U-Boot binary only grows by ~10KB, so it's very
-light weight.
-
-All storage devices are directly accessible from the uEFI payload
-
-Removable media booting (search for /efi/boot/boota{a64,arm}.efi) is supported.
-
-Simple use cases like "Plug this SD card into my ARM device and it just
-boots into grub which boots into Linux", work very well.
-
-
-Running HelloWord.efi
----------------------
-
-You can run a simple 'hello world' EFI program in U-Boot.
-Enable the option CONFIG_CMD_BOOTEFI_HELLO.
-
-Then you can boot into U-Boot and type:
-
-   > bootefi hello
-
-The 'hello world EFI' program will then run, print a message and exit.
-
-
-Future work
------------
-
-Of course, there are still a few things one could do on top:
-
-   - Improve disk media detection (don't scan, use what information we
-have)
-   - Add EFI variable support using NVRAM
-   - Add GFX support
-   - Make EFI Shell work
-   - Network device support
-   - Support for payload exit
-   - Payload Watchdog support
-
-[1] http://uefi.org/
diff --git a/doc/README.uefi b/doc/README.uefi
new file mode 100644
index 0000000..7403be3
--- /dev/null
+++ b/doc/README.uefi
@@ -0,0 +1,332 @@
+<!--
+    Copyright (c) 2018 Heinrich Schuchardt
+
+    SPDX-License-Identifier:     GPL-2.0+
+-->
+
+# UEFI on U-Boot
+
+The Unified Extensible Firmware Interface Specification (UEFI) [1] has become
+the default for booting on AArch64 and x86 systems. It provides a stable API for
+the interaction of drivers and applications with the firmware. The API comprises
+access to block storage, network, and console to name a few. The Linux kernel
+and boot loaders like GRUB or the FreeBSD loader can be executed.
+
+## Building for UEFI
+
+The UEFI standard supports only little endian systems. The UEFI support can be
+activated for ARM and x86 by specifying
+
+    CONFIG_CMD_BOOTEFI=y
+    CONFIG_EFI_LOADER=y
+
+in the .config file.
+
+Support for attaching virtual block devices, e.g. iSCSI drives connected by the
+loaded UEFI application [3], requires
+
+    CONFIG_BLK=y
+    CONFIG_PARTITIONS=y
+
+### Executing a UEFI binary
+
+The bootefi command is used to start UEFI applications or to install UEFI
+drivers. It takes two parameters
+
+    bootefi <image address> [fdt address]
+
+* image address - the memory address of the UEFI binary
+* fdt address - the memory address of the flattened device tree
+
+Below you find the output of an example session starting GRUB.
+
+    => load mmc 0:2 ${fdt_addr_r} boot/dtb
+    29830 bytes read in 14 ms (2 MiB/s)
+    => load mmc 0:1 ${kernel_addr_r} efi/debian/grubaa64.efi
+    reading efi/debian/grubaa64.efi
+    120832 bytes read in 7 ms (16.5 MiB/s)
+    => bootefi ${kernel_addr_r} ${fdt_addr_r}
+
+The environment variable 'bootargs' is passed as load options in the UEFI system
+table. The Linux kernel EFI stub uses the load options as command line
+arguments.
+
+### Executing the boot manager
+
+The UEFI specfication foresees to define boot entries and boot sequence via UEFI
+variables. Booting according to these variables is possible via
+
+    bootefi bootmgr [fdt address]
+
+As of U-Boot v2018.03 UEFI variables are not persisted and cannot be set at
+runtime.
+
+### Executing the built in hello world application
+
+A hello world UEFI application can be built with
+
+    CONFIG_CMD_BOOTEFI_HELLO_COMPILE=y
+
+It can be embedded into the U-Boot binary with
+
+    CONFIG_CMD_BOOTEFI_HELLO=y
+
+The bootefi command is used to start the embedded hello world application.
+
+    bootefi hello [fdt address]
+
+Below you find the output of an example session.
+
+    => bootefi hello ${fdtcontroladdr}
+    ## Starting EFI application at 01000000 ...
+    WARNING: using memory device/image path, this may confuse some payloads!
+    Hello, world!
+    Running on UEFI 2.7
+    Have SMBIOS table
+    Have device tree
+    Load options: root=/dev/sdb3 init=/sbin/init rootwait ro
+    ## Application terminated, r = 0
+
+The environment variable fdtcontroladdr points to U-Boot's internal device tree
+(if available).
+
+### Executing the built-in selftest
+
+An UEFI selftest suite can be embedded in U-Boot by building with
+
+    CONFIG_CMD_BOOTEFI_SELFTEST=y
+
+For testing the UEFI implementation the bootefi command can be used to start the
+selftest.
+
+    bootefi selftest [fdt address]
+
+The environment variable 'efi_selftest' can be used to select a single test. If
+it is not provided all tests are executed except those marked as 'on request'.
+If the environment variable is set to 'list' a list of all tests is shown.
+
+Below you can find the output of an example session.
+
+    => setenv efi_selftest simple network protocol
+    => bootefi selftest
+    Testing EFI API implementation
+    Selected test: 'simple network protocol'
+    Setting up 'simple network protocol'
+    Setting up 'simple network protocol' succeeded
+    Executing 'simple network protocol'
+    DHCP Discover
+    DHCP reply received from 192.168.76.2 (52:55:c0:a8:4c:02)
+      as broadcast message.
+    Executing 'simple network protocol' succeeded
+    Tearing down 'simple network protocol'
+    Tearing down 'simple network protocol' succeeded
+    Boot services terminated
+    Summary: 0 failures
+    Preparing for reset. Press any key.
+
+## The UEFI life cycle
+
+After the U-Boot platform has been initialized the UEFI API provides two kinds
+of services
+
+* boot services and
+* runtime services.
+
+The API can be extended by loading UEFI drivers which come in two variants
+
+* boot drivers and
+* runtime drivers.
+
+UEFI drivers are installed with U-Boot's bootefi command. With the same command
+UEFI applications can be executed.
+
+Loaded images of UEFI drivers stay in memory after returning to U-Boot while
+loaded images of applications are removed from memory.
+
+An UEFI application (e.g. an operating system) that wants to take full control
+of the system calls ExitBootServices. After a UEFI application calls
+ExitBootServices
+
+* boot services are not available anymore
+* timer events are stopped
+* the memory used by U-Boot except for runtime services is released
+* the memory used by boot time drivers is released
+
+So this is a point of no return. Afterwards the UEFI application can only return
+to U-Boot by rebooting.
+
+## The UEFI object model
+
+UEFI offers a flexible and expandable object model. The objects in the UEFI API
+are devices, drivers, and loaded images. These objects are referenced by
+handles.
+
+The interfaces implemented by the objects are referred to as protocols. These
+are identified by GUIDs. They can be installed and uninstalled by calling the
+appropriate boot services.
+
+Handles are created by the InstallProtocolInterface or the
+InstallMultipleProtocolinterfaces service if NULL is passed as handle.
+
+Handles are deleted when the last protocol has been removed with the
+UninstallProtocolInterface or the UninstallMultipleProtocolInterfaces service.
+
+Devices offer the EFI_DEVICE_PATH_PROTOCOL. A device path is the concatenation
+of device nodes. By their device paths all devices of a system are arranged in a
+tree.
+
+Drivers offer the EFI_DRIVER_BINDING_PROTOCOL. This protocol is used to connect
+a driver to devices (which are referenced as controllers in this context).
+
+Loaded images offer the EFI_LOADED_IMAGE_PROTOCOL. This protocol provides meta
+information about the image and a pointer to the unload callback function.
+
+## The UEFI events
+
+In the UEFI terminology an event is a data object referencing a notification
+function which is queued for calling when the event is signaled. The following
+types of events exist:
+
+* periodic and single shot timer events
+* exit boot services events, triggered by calling the ExitBootServices() service
+* virtual address change events
+* memory map change events
+* read to boot events
+* reset system events
+* system table events
+* events that are only triggered programmatically
+
+Events can be created with the CreateEvent service and deleted with CloseEvent
+service.
+
+Events can be assigned to an event group. If any of the events in a group is
+signaled, all other events in the group are also set to the signaled state.
+
+## The UEFI driver model
+
+A driver is specific for a single protocol installed on a device. To install a
+driver on a device the ConnectController service is called. In this context
+controller refers to the device for which the driver is installed.
+
+The relevant drivers are identified using the EFI_DRIVER_BINDING_PROTOCOL. This
+protocol has has three functions:
+
+* supported - determines if the driver is compatible with the device
+* start - installs the driver by opening the relevant protocol with
+  attribute EFI_OPEN_PROTOCOL_BY_DRIVER
+* stop - uninstalls the driver
+
+The driver may create child controllers (child devices). E.g. a driver for block
+IO devices will create the device handles for the partitions. The child
+controllers  will open the supported protocol with the attribute
+EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+A driver can be detached from a device using the DisconnectController service.
+
+## U-Boot devices mapped as UEFI devices
+
+Some of the U-Boot devices are mapped as UEFI devices
+
+* block IO devices
+* console
+* graphical output
+* network adapter
+
+As of U-Boot 2018.03 the logic for doing this is hard coded.
+
+The development target is to integrate the setup of these UEFI devices with the
+U-Boot driver model. So when a U-Boot device is discovered a handle should be
+created and the device path protocol and the relevant IO protocol should be
+installed. The UEFI driver then would be attached by calling ConnectController.
+When a U-Boot device is removed DisconnectController should be called.
+
+## UEFI devices mapped as U-Boot devices
+
+UEFI drivers binaries and applications may create new (virtual) devices, install
+a protocol and call the ConnectController service. Now the matching UEFI driver
+is determined by iterating over the implementations of the
+EFI_DRIVER_BINDING_PROTOCOL.
+
+It is the task of the UEFI driver to create a corresponding U-Boot device and to
+proxy calls for this U-Boot device to the controller.
+
+In U-Boot 2018.03 this has only been implemented for block IO devices.
+
+### UEFI uclass
+
+An UEFI uclass driver (lib/efi_driver/efi_uclass.c) has been created that
+takes care of initializing the UEFI drivers and providing the
+EFI_DRIVER_BINDING_PROTOCOL implementation for the UEFI drivers.
+
+A linker created list is used to keep track of the UEFI drivers. To create an
+entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying
+UCLASS_EFI as the ID of its uclass, e.g.
+
+    /* Identify as UEFI driver */
+    U_BOOT_DRIVER(efi_block) = {
+    	.name  = "EFI block driver",
+    	.id    = UCLASS_EFI,
+    	.ops   = &driver_ops,
+    };
+
+The available operations are defined via the structure struct efi_driver_ops.
+
+    struct efi_driver_ops {
+        const efi_guid_t *protocol;
+        const efi_guid_t *child_protocol;
+        int (*bind)(efi_handle_t handle, void *interface);
+    };
+
+When the supported() function of the EFI_DRIVER_BINDING_PROTOCOL is called the
+uclass checks if the protocol GUID matches the protocol GUID of the UEFI driver.
+In the start() function the bind() function of the UEFI driver is called after
+checking the GUID.
+The stop() function of the EFI_DRIVER_BINDING_PROTOCOL disconnects the child
+controllers created by the UEFI driver and the UEFI driver. (In U-Boot v2013.03
+this is not yet completely implemented.)
+
+### UEFI block IO driver
+
+The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL.
+
+When connected it creates a new U-Boot block IO device with interface type
+IF_TYPE_EFI, adds child controllers mapping the partitions, and installs the
+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
+software iPXE to boot from iSCSI network drives [3].
+
+This driver is only available if U-Boot is configured with
+
+    CONFIG_BLK=y
+    CONFIG_PARTITIONS=y
+
+## TODOs as of U-Boot 2018.03
+
+* unimplemented or incompletely implemented boot services
+  * Exit - call unload function, unload applications only
+  * ReinstallProtocolInterface
+  * UnloadImage
+
+* unimplemented events
+  * EVT_RUNTIME
+  * EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
+  * event groups
+
+* data model
+  * manage events in a linked list
+  * manage configuration tables in a linked list
+
+* UEFI drivers
+  * support DisconnectController for UEFI block devices.
+
+* support for CONFIG_EFI_LOADER in the sandbox (CONFIG_SANDBOX=y)
+
+* UEFI variables
+  * persistence
+  * runtime support
+
+## Links
+
+* [1](http://uefi.org/specifications)
+  http://uefi.org/specifications - UEFI specifications
+* [2](./driver-model/README.txt) doc/driver-model/README.txt - Driver model
+* [3](./README.iscsi) doc/README.iscsi - iSCSI booting with U-Boot and iPXE
diff --git a/doc/git-mailrc b/doc/git-mailrc
index 5a365cd..d5e3097 100644
--- a/doc/git-mailrc
+++ b/doc/git-mailrc
@@ -15,6 +15,7 @@
 alias abrodkin       Alexey Brodkin <alexey.brodkin@synopsys.com>
 alias afleming       Andy Fleming <afleming@gmail.com>
 alias ag             Anatolij Gustschin <agust@denx.de>
+alias agraf          Alexander Graf <agraf@suse.de>
 alias alisonwang     Alison Wang <alison.wang@freescale.com>
 alias angelo_ts      Angelo Dureghello <angelo@sysam.it>
 alias bmeng          Bin Meng <bmeng.cn@gmail.com>
@@ -120,6 +121,7 @@
 alias dm             uboot, sjg
 alias cfi            uboot, stroese
 alias dfu            uboot, lukma
+alias efi            uboot, agraf
 alias eth            uboot, jhersh
 alias kerneldoc      uboot, marex
 alias fdt            uboot, sjg
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f2cfcb0..98573cb 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -11,6 +11,13 @@
 	  This is currently implemented in net/eth.c
 	  Look in include/net.h for details.
 
+config DRIVER_TI_CPSW
+	bool "TI Common Platform Ethernet Switch"
+	select PHYLIB
+	help
+	  This driver supports the TI three port switch gigabit ethernet
+	  subsystem found in the TI SoCs.
+
 menuconfig NETDEVICES
 	bool "Network device support"
 	depends on NET
diff --git a/drivers/net/cpsw-common.c b/drivers/net/cpsw-common.c
index 0dc83ab..7bd312a 100644
--- a/drivers/net/cpsw-common.c
+++ b/drivers/net/cpsw-common.c
@@ -8,6 +8,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <fdt_support.h>
 #include <asm/io.h>
 #include <cpsw.h>
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index ff7ad91..29af85c 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <malloc.h>
 #include <memalign.h>
 #include <miiphy.h>
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
index 2d89cea..00d905c 100644
--- a/drivers/net/fsl_mcdmafec.c
+++ b/drivers/net/fsl_mcdmafec.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <malloc.h>
 #include <command.h>
 #include <config.h>
diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c
index ebcbed9..505a2d1 100644
--- a/drivers/net/mcffec.c
+++ b/drivers/net/mcffec.c
@@ -9,6 +9,7 @@
  */
 
 #include <common.h>
+#include <environment.h>
 #include <malloc.h>
 
 #include <command.h>
diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c
index fb088e0..421aa20 100644
--- a/drivers/net/ne2000_base.c
+++ b/drivers/net/ne2000_base.c
@@ -74,6 +74,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <environment.h>
 #include <net.h>
 #include <malloc.h>
 #include <linux/compiler.h>
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 6f48e93..e3416f3 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -11,6 +11,7 @@
 
 #include <config.h>
 #include <common.h>
+#include <environment.h>
 #include <malloc.h>
 #include <net.h>
 #include <netdev.h>
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 6825e6b..26b4d12 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -158,6 +158,7 @@
 
 config USB_ETHER
 	bool "USB Ethernet Gadget"
+	depends on NET
 	default y if ARCH_SUNXI && USB_MUSB_GADGET
 	help
 	  Creates an Ethernet network device through a USB peripheral
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index a80486e..386505d 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <console.h>
+#include <environment.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/usb/ch9.h>
diff --git a/env/Kconfig b/env/Kconfig
index 680441c..f403906 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -497,4 +497,11 @@
 	  containing key=value pairs, blank lines and lines beginning
 	  with # are ignored.
 
+config ENV_VARS_UBOOT_RUNTIME_CONFIG
+	bool "Add run-time information to the environment"
+	help
+	  Enable this in order to add variables describing certain
+	  run-time determined information about the hardware to the
+	  environment.  These will be named board_name, board_rev.
+
 endmenu
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index 8d45b6f..89334ff 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -56,8 +56,6 @@
 #define NANDARGS ""
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #define BOOTENV_DEV_LEGACY_MMC(devtypeu, devtypel, instance) \
 	"bootcmd_" #devtypel #instance "=" \
 	"setenv mmcdev " #instance"; "\
@@ -74,14 +72,26 @@
 #define BOOTENV_DEV_NAME_NAND(devtypeu, devtypel, instance) \
 	#devtypel #instance " "
 
+#if CONFIG_IS_ENABLED(CMD_PXE)
+# define BOOT_TARGET_PXE(func) func(PXE, pxe, na)
+#else
+# define BOOT_TARGET_PXE(func)
+#endif
+
+#if CONFIG_IS_ENABLED(CMD_DHCP)
+# define BOOT_TARGET_DHCP(func) func(DHCP, dhcp, na)
+#else
+# define BOOT_TARGET_DHCP(func)
+#endif
+
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0) \
 	func(LEGACY_MMC, legacy_mmc, 0) \
 	func(MMC, mmc, 1) \
 	func(LEGACY_MMC, legacy_mmc, 1) \
 	func(NAND, nand, 0) \
-	func(PXE, pxe, na) \
-	func(DHCP, dhcp, na)
+	BOOT_TARGET_PXE(func) \
+	BOOT_TARGET_DHCP(func)
 
 #include <config_distro_bootcmd.h>
 
diff --git a/include/configs/am335x_igep003x.h b/include/configs/am335x_igep003x.h
index fe3f838..a429dd9 100644
--- a/include/configs/am335x_igep003x.h
+++ b/include/configs/am335x_igep003x.h
@@ -22,8 +22,6 @@
 
 #define CONFIG_ENV_SIZE			(96 << 10)	/*  96 KiB */
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	DEFAULT_LINUX_BOOT_ENV \
diff --git a/include/configs/am335x_shc.h b/include/configs/am335x_shc.h
index 60b162e..e29de0e 100644
--- a/include/configs/am335x_shc.h
+++ b/include/configs/am335x_shc.h
@@ -64,8 +64,6 @@
 # define CONFIG_RESET_TO_RETRY
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x80200000\0" \
@@ -250,7 +248,6 @@
 #undef CONFIG_TIMER
 #endif
 
-#define CONFIG_DRIVER_TI_CPSW
 #define CONFIG_MII
 #define CONFIG_BOOTP_DEFAULT
 #define CONFIG_BOOTP_DNS2
diff --git a/include/configs/am335x_sl50.h b/include/configs/am335x_sl50.h
index 739a998..9687f37 100644
--- a/include/configs/am335x_sl50.h
+++ b/include/configs/am335x_sl50.h
@@ -26,8 +26,6 @@
 /* Always 128 KiB env size */
 #define CONFIG_ENV_SIZE			(128 << 10)
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #ifndef CONFIG_SPL_BUILD
 
 #define MEM_LAYOUT_ENV_SETTINGS \
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h
index 663f861..d2c1810 100644
--- a/include/configs/am43xx_evm.h
+++ b/include/configs/am43xx_evm.h
@@ -62,8 +62,6 @@
 /* Always 64 KiB env size */
 #define CONFIG_ENV_SIZE			(64 << 10)
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* Clock Defines */
 #define V_OSCK				24000000  /* Clock output from T2 */
 #define V_SCLK				(V_OSCK)
@@ -221,7 +219,6 @@
 #define CONFIG_NET_RETRY_COUNT		10
 #endif
 
-#define CONFIG_DRIVER_TI_CPSW
 #define PHY_ANEG_TIMEOUT	8000 /* PHY needs longer aneg time at 1G */
 
 #define CONFIG_SYS_RX_ETH_BUFFER	64
diff --git a/include/configs/am57xx_evm.h b/include/configs/am57xx_evm.h
index c079a3a..7211cde 100644
--- a/include/configs/am57xx_evm.h
+++ b/include/configs/am57xx_evm.h
@@ -78,7 +78,6 @@
 #define CONFIG_BOOTP_DNS2
 #define CONFIG_BOOTP_SEND_HOSTNAME
 #define CONFIG_NET_RETRY_COUNT		10
-#define CONFIG_DRIVER_TI_CPSW		/* Driver for IP block */
 #define CONFIG_MII			/* Required in net/eth.c */
 #define PHY_ANEG_TIMEOUT	8000	/* PHY needs longer aneg time at 1G */
 
diff --git a/include/configs/apalis_imx6.h b/include/configs/apalis_imx6.h
index 7a75f6d..eb8ffda 100644
--- a/include/configs/apalis_imx6.h
+++ b/include/configs/apalis_imx6.h
@@ -38,10 +38,6 @@
 #define CONFIG_MXC_UART
 #define CONFIG_MXC_UART_BASE		UART1_BASE
 
-/* Make the HW version stuff available in U-Boot env */
-#define CONFIG_VERSION_VARIABLE		/* ver environment variable */
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* I2C Configs */
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MXC
diff --git a/include/configs/baltos.h b/include/configs/baltos.h
index 943a6f8..19db350 100644
--- a/include/configs/baltos.h
+++ b/include/configs/baltos.h
@@ -69,8 +69,6 @@
 #define NANDARGS ""
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	DEFAULT_LINUX_BOOT_ENV \
diff --git a/include/configs/bav335x.h b/include/configs/bav335x.h
index e7f65d6..a044329 100644
--- a/include/configs/bav335x.h
+++ b/include/configs/bav335x.h
@@ -56,8 +56,6 @@
 #define NANDARGS ""
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS \
 DEFAULT_LINUX_BOOT_ENV \
diff --git a/include/configs/bur_am335x_common.h b/include/configs/bur_am335x_common.h
index 4aa0cb6..37d6aa5 100644
--- a/include/configs/bur_am335x_common.h
+++ b/include/configs/bur_am335x_common.h
@@ -28,7 +28,6 @@
 #define CONFIG_SYS_NS16550_COM1		0x44e09000	/* UART0 */
 
 /* Network defines */
-#define CONFIG_DRIVER_TI_CPSW		/* Driver for IP block */
 #define CONFIG_MII			/* Required in net/eth.c */
 #define CONFIG_PHY_NATSEMI
 
diff --git a/include/configs/cgtqmx6eval.h b/include/configs/cgtqmx6eval.h
index afc0bae..b3814a6 100644
--- a/include/configs/cgtqmx6eval.h
+++ b/include/configs/cgtqmx6eval.h
@@ -99,7 +99,6 @@
 #define CONFIG_MMCROOT		"/dev/mmcblk0p2"
 #define CONFIG_SYS_MMC_ENV_DEV		0
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"script=boot.scr\0" \
 	"image=zImage\0" \
diff --git a/include/configs/cl-som-am57x.h b/include/configs/cl-som-am57x.h
index 596e060..922ba93 100644
--- a/include/configs/cl-som-am57x.h
+++ b/include/configs/cl-som-am57x.h
@@ -45,7 +45,6 @@
 
 /* Environment */
 #define CONFIG_ENV_SIZE			(16 << 10) /* 16 KiB env size */
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 
 #define CONFIG_ENV_SECT_SIZE		(64 * 1024)
 #define CONFIG_ENV_OFFSET		(768 * 1024)
@@ -81,7 +80,6 @@
 /* USB Networking options */
 
 /* CPSW Ethernet */
-#define CONFIG_DRIVER_TI_CPSW
 #define CONFIG_MII
 #define CONFIG_BOOTP_DEFAULT
 #define CONFIG_BOOTP_SEND_HOSTNAME
diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
index 4f36930..9cf559e 100644
--- a/include/configs/cm_fx6.h
+++ b/include/configs/cm_fx6.h
@@ -63,7 +63,6 @@
 #define CONFIG_ENV_OFFSET		(768 * 1024)
 
 #ifndef CONFIG_SPL_BUILD
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"fdt_high=0xffffffff\0" \
 	"initrd_high=0xffffffff\0" \
diff --git a/include/configs/cm_t43.h b/include/configs/cm_t43.h
index da78519..4bb4817 100644
--- a/include/configs/cm_t43.h
+++ b/include/configs/cm_t43.h
@@ -45,7 +45,6 @@
 					 50, 51, 52, 53, 54, 55, 56, 57, }
 
 /* CPSW Ethernet support */
-#define CONFIG_DRIVER_TI_CPSW
 #define CONFIG_MII
 #define CONFIG_BOOTP_DEFAULT
 #define CONFIG_BOOTP_SEND_HOSTNAME
@@ -84,7 +83,6 @@
 #undef CONFIG_SYS_MONITOR_LEN
 
 #define CONFIG_ENV_SIZE			(16 * 1024)
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 
 #define V_OSCK				24000000  /* Clock output from T2 */
 #define V_SCLK				(V_OSCK)
diff --git a/include/configs/colibri_imx6.h b/include/configs/colibri_imx6.h
index d257e5c..0c372c5 100644
--- a/include/configs/colibri_imx6.h
+++ b/include/configs/colibri_imx6.h
@@ -36,10 +36,6 @@
 #define CONFIG_MXC_UART
 #define CONFIG_MXC_UART_BASE		UART1_BASE
 
-/* Make the HW version stuff available in U-Boot env */
-#define CONFIG_VERSION_VARIABLE		/* ver environment variable */
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* I2C Configs */
 #define CONFIG_SYS_I2C
 #define CONFIG_SYS_I2C_MXC
diff --git a/include/configs/colibri_imx7.h b/include/configs/colibri_imx7.h
index 6f97c1e..daa0859 100644
--- a/include/configs/colibri_imx7.h
+++ b/include/configs/colibri_imx7.h
@@ -17,8 +17,6 @@
 /*#define CONFIG_DBG_MONITOR*/
 #define PHYS_SDRAM_SIZE			SZ_512M
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(32 * SZ_1M)
 
diff --git a/include/configs/colibri_pxa270.h b/include/configs/colibri_pxa270.h
index 2588731..f5f648d 100644
--- a/include/configs/colibri_pxa270.h
+++ b/include/configs/colibri_pxa270.h
@@ -24,7 +24,6 @@
  * Environment settings
  */
 #define	CONFIG_ENV_OVERWRITE
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define	CONFIG_SYS_MALLOC_LEN		(128 * 1024)
 #define	CONFIG_ARCH_CPU_INIT
 #define	CONFIG_BOOTCOMMAND						\
diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h
index 2d8b627..4d55c01 100644
--- a/include/configs/colibri_vf.h
+++ b/include/configs/colibri_vf.h
@@ -37,7 +37,6 @@
 
 /* Allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 
 /* NAND support */
 #define CONFIG_SYS_NAND_ONFI_DETECTION
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h
index e82de2a..13efc3e 100644
--- a/include/configs/dra7xx_evm.h
+++ b/include/configs/dra7xx_evm.h
@@ -97,7 +97,6 @@
 #define CONFIG_BOOTP_DNS2
 #define CONFIG_BOOTP_SEND_HOSTNAME
 #define CONFIG_NET_RETRY_COUNT		10
-#define CONFIG_DRIVER_TI_CPSW		/* Driver for IP block */
 #define CONFIG_MII			/* Required in net/eth.c */
 #define CONFIG_PHY_TI
 
diff --git a/include/configs/duovero.h b/include/configs/duovero.h
index 96644b1..1fecac2 100644
--- a/include/configs/duovero.h
+++ b/include/configs/duovero.h
@@ -34,6 +34,4 @@
 
 /* ENV related config options */
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #endif /* __CONFIG_DUOVERO_H */
diff --git a/include/configs/el6x_common.h b/include/configs/el6x_common.h
index 2dac12f..e6b6be4 100644
--- a/include/configs/el6x_common.h
+++ b/include/configs/el6x_common.h
@@ -56,7 +56,6 @@
 
 #define CONFIG_BOARD_NAME	EL6Q
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS                                               \
 	"board="__stringify(CONFIG_BOARD_NAME)"\0"                              \
 	"cma_size="__stringify(EL6Q_CMA_SIZE)"\0"                               \
diff --git a/include/configs/imx6_logic.h b/include/configs/imx6_logic.h
index 1bc7f2a..bfc9b33 100644
--- a/include/configs/imx6_logic.h
+++ b/include/configs/imx6_logic.h
@@ -28,8 +28,6 @@
 #define CONFIG_ETHPRIME                "FEC"
 #define CONFIG_FEC_MXC_PHYADDR         0
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"script=boot.scr\0" \
 	"image=zImage\0" \
diff --git a/include/configs/k2g_evm.h b/include/configs/k2g_evm.h
index f00ca1c..b14f6c5 100644
--- a/include/configs/k2g_evm.h
+++ b/include/configs/k2g_evm.h
@@ -16,8 +16,6 @@
 /* Platform type */
 #define CONFIG_SOC_K2G
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* U-Boot general configuration */
 #define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS				\
 	DEFAULT_MMC_TI_ARGS						\
diff --git a/include/configs/mccmon6.h b/include/configs/mccmon6.h
index 8eb248a..0aa797a 100644
--- a/include/configs/mccmon6.h
+++ b/include/configs/mccmon6.h
@@ -94,7 +94,6 @@
 #define CONFIG_ETHPRIME			"FEC"
 #define CONFIG_FEC_MXC_PHYADDR		1
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"console=ttymxc0,115200 quiet\0" \
 	"fdtfile=imx6q-mccmon6.dtb\0" \
diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h
index 0e1d18c..9fbd162 100644
--- a/include/configs/mx6cuboxi.h
+++ b/include/configs/mx6cuboxi.h
@@ -71,7 +71,6 @@
 #define CONFIG_SYS_FSL_USDHC_NUM	1
 #define CONFIG_SYS_MMC_ENV_DEV		0	/* SDHC2 */
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"fdtfile=undefined\0" \
diff --git a/include/configs/mx6sabre_common.h b/include/configs/mx6sabre_common.h
index d976e77..6f970a4 100644
--- a/include/configs/mx6sabre_common.h
+++ b/include/configs/mx6sabre_common.h
@@ -57,8 +57,6 @@
 #define EMMC_ENV ""
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"script=boot.scr\0" \
 	"image=zImage\0" \
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index 1eaaf01..713ebf6 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -43,7 +43,6 @@
 #define UPDATE_M4_ENV ""
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	UPDATE_M4_ENV \
 	"script=boot.scr\0" \
diff --git a/include/configs/mx6ul_14x14_evk.h b/include/configs/mx6ul_14x14_evk.h
index 1c1671e..733538f 100644
--- a/include/configs/mx6ul_14x14_evk.h
+++ b/include/configs/mx6ul_14x14_evk.h
@@ -18,8 +18,6 @@
 /* SPL options */
 #include "imx6_spl.h"
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(16 * SZ_1M)
 
diff --git a/include/configs/mx6ullevk.h b/include/configs/mx6ullevk.h
index 2142913..cf9f8ab 100644
--- a/include/configs/mx6ullevk.h
+++ b/include/configs/mx6ullevk.h
@@ -22,8 +22,6 @@
 
 #define PHYS_SDRAM_SIZE	SZ_512M
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(16 * SZ_1M)
 
diff --git a/include/configs/odroid.h b/include/configs/odroid.h
index 2c8ee7a..8faa7a3 100644
--- a/include/configs/odroid.h
+++ b/include/configs/odroid.h
@@ -185,7 +185,6 @@
  * TODO: Add Odroid X support
  */
 #define CONFIG_MISC_COMMON
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_BOARD_TYPES
 #define CONFIG_MISC_INIT_R
 
diff --git a/include/configs/odroid_xu3.h b/include/configs/odroid_xu3.h
index 9067ba6..53edd23 100644
--- a/include/configs/odroid_xu3.h
+++ b/include/configs/odroid_xu3.h
@@ -88,7 +88,6 @@
 #define CONFIG_SET_DFU_ALT_BUF_LEN	(SZ_1K)
 
 /* Set soc_rev, soc_id, board_rev, boardname, fdtfile */
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_ODROID_REV_AIN			9
 #define CONFIG_REVISION_TAG
 #define CONFIG_BOARD_TYPES
diff --git a/include/configs/omap4_panda.h b/include/configs/omap4_panda.h
index 75203b2..8cded99 100644
--- a/include/configs/omap4_panda.h
+++ b/include/configs/omap4_panda.h
@@ -30,7 +30,6 @@
 
 /* ENV related config options */
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_ENV_OVERWRITE
 
 #endif /* __CONFIG_PANDA_H */
diff --git a/include/configs/pcm051.h b/include/configs/pcm051.h
index 411403e..4f72350 100644
--- a/include/configs/pcm051.h
+++ b/include/configs/pcm051.h
@@ -25,7 +25,6 @@
 #define CONFIG_MACH_TYPE		MACH_TYPE_PCM051
 
 /* set to negative value for no autoboot */
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x80007fc0\0" \
 	"fdtaddr=0x80000000\0" \
diff --git a/include/configs/pengwyn.h b/include/configs/pengwyn.h
index 74bfde7..545f859 100644
--- a/include/configs/pengwyn.h
+++ b/include/configs/pengwyn.h
@@ -22,8 +22,6 @@
 /* set env size */
 #define CONFIG_ENV_SIZE			0x4000
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #ifndef CONFIG_SPL_BUILD
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x80200000\0" \
diff --git a/include/configs/pepper.h b/include/configs/pepper.h
index f0ffc51..44dcfba 100644
--- a/include/configs/pepper.h
+++ b/include/configs/pepper.h
@@ -20,7 +20,6 @@
 
 #define CONFIG_ENV_SIZE			(128 << 10)	/* 128 KiB */
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	DEFAULT_LINUX_BOOT_ENV \
 	"bootdir=/boot\0" \
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index 17cdecd..325e52a 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -86,7 +86,6 @@
 #define CONFIG_INITRD_TAG
 
 /* Environment */
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define ENV_DEVICE_SETTINGS \
 	"stdin=serial,usbkbd\0" \
 	"stdout=serial,vidconsole\0" \
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index 1b40c29..40f037e 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -103,7 +103,6 @@
 #define CONFIG_MISC_INIT_R
 
 #define CONFIG_ENV_OVERWRITE
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS					\
 	CONFIG_UPDATEB \
 	"updatek=" \
diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h
index 841dedd..410d20b 100644
--- a/include/configs/s5pc210_universal.h
+++ b/include/configs/s5pc210_universal.h
@@ -71,8 +71,6 @@
 
 #define CONFIG_ENV_COMMON_BOOT	"${console} ${meminfo}"
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #define CONFIG_EXTRA_ENV_SETTINGS					\
 	"updateb=" \
 		"onenand erase 0x0 0x100000;" \
diff --git a/include/configs/sama5d3xek.h b/include/configs/sama5d3xek.h
index 843aaa6..be19d8d 100644
--- a/include/configs/sama5d3xek.h
+++ b/include/configs/sama5d3xek.h
@@ -15,8 +15,6 @@
 
 #include "at91-sama5_common.h"
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /*
  * This needs to be defined for the OHCI code to work but it is defined as
  * ATMEL_ID_UHPHS in the CPU specific header files.
diff --git a/include/configs/siemens-am33x-common.h b/include/configs/siemens-am33x-common.h
index b23e20a..dfa7114 100644
--- a/include/configs/siemens-am33x-common.h
+++ b/include/configs/siemens-am33x-common.h
@@ -192,7 +192,6 @@
 # define CONFIG_ENV_SECT_SIZE		(4 << 10) /* 4 KB sectors */
 #endif /* SPI support */
 
-#define CONFIG_DRIVER_TI_CPSW
 #define CONFIG_MII
 #define CONFIG_BOOTP_DEFAULT
 #define CONFIG_BOOTP_DNS2
diff --git a/include/configs/ti814x_evm.h b/include/configs/ti814x_evm.h
index 2f9056c..a81f3b8 100644
--- a/include/configs/ti814x_evm.h
+++ b/include/configs/ti814x_evm.h
@@ -28,7 +28,6 @@
 
 /* commands to include */
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x80200000\0" \
 	"fdtaddr=0x80F80000\0" \
@@ -155,7 +154,6 @@
 #endif
 
 /* Ethernet */
-#define CONFIG_DRIVER_TI_CPSW
 #define CONFIG_MII
 #define CONFIG_BOOTP_DNS2
 #define CONFIG_BOOTP_SEND_HOSTNAME
diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h
index 9832e09..83e26db 100644
--- a/include/configs/ti_am335x_common.h
+++ b/include/configs/ti_am335x_common.h
@@ -35,7 +35,6 @@
 #define CONFIG_MII			/* Required in net/eth.c */
 #endif
 
-#define CONFIG_DRIVER_TI_CPSW		/* Driver for IP block */
 /*
  * SPL related defines.  The Public RAM memory map the ROM defines the
  * area between 0x402F0400 and 0x4030B800 as a download area and
diff --git a/include/configs/ti_omap5_common.h b/include/configs/ti_omap5_common.h
index 5391641..d6ea17b 100644
--- a/include/configs/ti_omap5_common.h
+++ b/include/configs/ti_omap5_common.h
@@ -58,7 +58,6 @@
 #include <environment/ti/boot.h>
 #include <environment/ti/mmc.h>
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	DEFAULT_LINUX_BOOT_ENV \
 	DEFAULT_MMC_TI_ARGS \
diff --git a/include/configs/trats.h b/include/configs/trats.h
index e6649ff..e892b59 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -57,8 +57,6 @@
 
 #define CONFIG_ENV_OVERWRITE
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* Tizen - partitions definitions */
 #define PARTS_CSA		"csa-mmc"
 #define PARTS_BOOT		"boot"
diff --git a/include/configs/trats2.h b/include/configs/trats2.h
index c3eb7c9..aecac07 100644
--- a/include/configs/trats2.h
+++ b/include/configs/trats2.h
@@ -52,8 +52,6 @@
 
 #define CONFIG_ENV_OVERWRITE
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 /* Tizen - partitions definitions */
 #define PARTS_CSA		"csa-mmc"
 #define PARTS_BOOT		"boot"
diff --git a/include/configs/udoo.h b/include/configs/udoo.h
index 989014a..dd86dee 100644
--- a/include/configs/udoo.h
+++ b/include/configs/udoo.h
@@ -46,8 +46,6 @@
 /* MMC Configuration */
 #define CONFIG_SYS_FSL_ESDHC_ADDR	0
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"script=boot.scr\0" \
 	"image=zImage\0" \
diff --git a/include/configs/udoo_neo.h b/include/configs/udoo_neo.h
index 35a6eca..7e6b980 100644
--- a/include/configs/udoo_neo.h
+++ b/include/configs/udoo_neo.h
@@ -27,7 +27,6 @@
 #define CONFIG_SYS_MMC_ENV_DEV		0  /*USDHC2*/
 
 /* Linux only */
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"console=ttymxc0,115200\0" \
 	"fdt_high=0xffffffff\0" \
diff --git a/include/configs/vining_2000.h b/include/configs/vining_2000.h
index f054c99..45d1c35 100644
--- a/include/configs/vining_2000.h
+++ b/include/configs/vining_2000.h
@@ -92,7 +92,6 @@
 #define CONFIG_PWM_IMX
 #define CONFIG_IMX6_PWM_PER_CLK 66000000
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_ENV_OFFSET		(8 * SZ_64K)
 #define CONFIG_ENV_SIZE			SZ_8K
 #define CONFIG_ENV_OFFSET_REDUND	(9 * SZ_64K)
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index bc2d269..7b50284 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -78,7 +78,6 @@
 #define CONFIG_IMX_VIDEO_SKIP
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"console=ttymxc0,115200\0" \
 	"splashpos=m,m\0" \
diff --git a/include/configs/wb50n.h b/include/configs/wb50n.h
index df27523..028e3ff 100644
--- a/include/configs/wb50n.h
+++ b/include/configs/wb50n.h
@@ -23,7 +23,6 @@
 #define CONFIG_SKIP_LOWLEVEL_INIT
 #endif
 
-#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 #define CONFIG_IMAGE_FORMAT_LEGACY
 
 /* general purpose I/O */
diff --git a/include/efi_api.h b/include/efi_api.h
index 3ba650e..ae93061 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -107,7 +107,7 @@
 	efi_status_t (EFIAPI *load_image)(bool boot_policiy,
 			efi_handle_t parent_image,
 			struct efi_device_path *file_path, void *source_buffer,
-			unsigned long source_size, efi_handle_t *image);
+			efi_uintn_t source_size, efi_handle_t *image);
 	efi_status_t (EFIAPI *start_image)(efi_handle_t handle,
 					   unsigned long *exitdata_size,
 					   s16 **exitdata);
@@ -180,7 +180,8 @@
 enum efi_reset_type {
 	EFI_RESET_COLD = 0,
 	EFI_RESET_WARM = 1,
-	EFI_RESET_SHUTDOWN = 2
+	EFI_RESET_SHUTDOWN = 2,
+	EFI_RESET_PLATFORM_SPECIFIC = 3,
 };
 
 /* EFI Runtime Services table */
@@ -243,6 +244,27 @@
 			u64 maximum_variable_size);
 };
 
+/* EFI event group GUID definitions */
+#define EFI_EVENT_GROUP_EXIT_BOOT_SERVICES \
+	EFI_GUID(0x27abf055, 0xb1b8, 0x4c26, 0x80, 0x48, \
+		 0x74, 0x8f, 0x37, 0xba, 0xa2, 0xdf)
+
+#define EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE \
+	EFI_GUID(0x13fa7698, 0xc831, 0x49c7, 0x87, 0xea, \
+		 0x8f, 0x43, 0xfc, 0xc2, 0x51, 0x96)
+
+#define EFI_EVENT_GROUP_MEMORY_MAP_CHANGE \
+	EFI_GUID(0x78bee926, 0x692f, 0x48fd, 0x9e, 0xdb, \
+		 0x01, 0x42, 0x2e, 0xf0, 0xd7, 0xab)
+
+#define EFI_EVENT_GROUP_READY_TO_BOOT \
+	EFI_GUID(0x7ce88fb3, 0x4bd7, 0x4679, 0x87, 0xa8, \
+		 0xa8, 0xd8, 0xde, 0xe5, 0x0d, 0x2b)
+
+#define EFI_EVENT_GROUP_RESET_SYSTEM \
+	EFI_GUID(0x62da6a56, 0x13fb, 0x485a, 0xa8, 0xda, \
+		 0xa3, 0xdd, 0x79, 0x12, 0xcb, 0x6b)
+
 /* EFI Configuration Table and GUID definitions */
 #define NULL_GUID \
 	EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
@@ -296,8 +318,8 @@
 	u32 revision;
 	void *parent_handle;
 	struct efi_system_table *system_table;
-	void *device_handle;
-	void *file_path;
+	efi_handle_t device_handle;
+	struct efi_device_path *file_path;
 	void *reserved;
 	u32 load_options_size;
 	void *load_options;
@@ -309,6 +331,8 @@
 
 	/* Below are efi loader private fields */
 #ifdef CONFIG_EFI_LOADER
+	void *reloc_base;
+	aligned_u64 reloc_size;
 	efi_status_t exit_status;
 	struct jmp_buf_data exit_jmp;
 #endif
@@ -571,24 +595,6 @@
 	struct efi_event *wait_for_key;
 };
 
-#define CONSOLE_CONTROL_GUID \
-	EFI_GUID(0xf42f7782, 0x12e, 0x4c12, \
-		 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21)
-#define EFI_CONSOLE_MODE_TEXT	0
-#define EFI_CONSOLE_MODE_GFX	1
-
-struct efi_console_control_protocol
-{
-	efi_status_t (EFIAPI *get_mode)(
-			struct efi_console_control_protocol *this, int *mode,
-			char *uga_exists, char *std_in_locked);
-	efi_status_t (EFIAPI *set_mode)(
-			struct efi_console_control_protocol *this, int mode);
-	efi_status_t (EFIAPI *lock_std_in)(
-			struct efi_console_control_protocol *this,
-			uint16_t *password);
-};
-
 #define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
 	EFI_GUID(0x8b843e20, 0x8132, 0x4852, \
 		 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c)
@@ -605,6 +611,35 @@
 			bool allow_shortcuts);
 };
 
+#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \
+	EFI_GUID(0x0379be4e, 0xd706, 0x437d, \
+		 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4)
+
+struct efi_device_path_utilities_protocol {
+	efi_uintn_t (EFIAPI *get_device_path_size)(
+		const struct efi_device_path *device_path);
+	struct efi_device_path *(EFIAPI *duplicate_device_path)(
+		const struct efi_device_path *device_path);
+	struct efi_device_path *(EFIAPI *append_device_path)(
+		const struct efi_device_path *src1,
+		const struct efi_device_path *src2);
+	struct efi_device_path *(EFIAPI *append_device_node)(
+		const struct efi_device_path *device_path,
+		const struct efi_device_path *device_node);
+	struct efi_device_path *(EFIAPI *append_device_path_instance)(
+		const struct efi_device_path *device_path,
+		const struct efi_device_path *device_path_instance);
+	struct efi_device_path *(EFIAPI *get_next_device_path_instance)(
+		struct efi_device_path **device_path_instance,
+		efi_uintn_t *device_path_instance_size);
+	bool (EFIAPI *is_device_path_multi_instance)(
+		const struct efi_device_path *device_path);
+	struct efi_device_path *(EFIAPI *create_device_node)(
+		uint8_t node_type,
+		uint8_t node_sub_type,
+		uint16_t node_length);
+};
+
 #define EFI_GOP_GUID \
 	EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \
 		 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a)
@@ -633,6 +668,13 @@
 	unsigned long fb_size;
 };
 
+struct efi_gop_pixel {
+	u8 blue;
+	u8 green;
+	u8 red;
+	u8 reserved;
+};
+
 #define EFI_BLT_VIDEO_FILL		0
 #define EFI_BLT_VIDEO_TO_BLT_BUFFER	1
 #define EFI_BLT_BUFFER_TO_VIDEO		2
@@ -644,7 +686,8 @@
 					  efi_uintn_t *size_of_info,
 					  struct efi_gop_mode_info **info);
 	efi_status_t (EFIAPI *set_mode)(struct efi_gop *this, u32 mode_number);
-	efi_status_t (EFIAPI *blt)(struct efi_gop *this, void *buffer,
+	efi_status_t (EFIAPI *blt)(struct efi_gop *this,
+				   struct efi_gop_pixel *buffer,
 				   u32 operation, efi_uintn_t sx,
 				   efi_uintn_t sy, efi_uintn_t dx,
 				   efi_uintn_t dy, efi_uintn_t width,
@@ -662,7 +705,7 @@
 
 struct efi_ip_address {
 	u8 ip_addr[16];
-};
+} __attribute__((aligned(4)));
 
 enum efi_simple_network_state {
 	EFI_NETWORK_STOPPED,
@@ -756,7 +799,28 @@
 
 struct efi_pxe_mode
 {
-	u8 unused[52];
+	u8 started;
+	u8 ipv6_available;
+	u8 ipv6_supported;
+	u8 using_ipv6;
+	u8 bis_supported;
+	u8 bis_detected;
+	u8 auto_arp;
+	u8 send_guid;
+	u8 dhcp_discover_valid;
+	u8 dhcp_ack_received;
+	u8 proxy_offer_received;
+	u8 pxe_discover_valid;
+	u8 pxe_reply_received;
+	u8 pxe_bis_reply_received;
+	u8 icmp_error_received;
+	u8 tftp_error_received;
+	u8 make_callbacks;
+	u8 ttl;
+	u8 tos;
+	u8 pad;
+	struct efi_ip_address station_ip;
+	struct efi_ip_address subnet_mask;
 	struct efi_pxe_packet dhcp_discover;
 	struct efi_pxe_packet dhcp_ack;
 	struct efi_pxe_packet proxy_offer;
@@ -794,17 +858,19 @@
 	efi_status_t (EFIAPI *close)(struct efi_file_handle *file);
 	efi_status_t (EFIAPI *delete)(struct efi_file_handle *file);
 	efi_status_t (EFIAPI *read)(struct efi_file_handle *file,
-			u64 *buffer_size, void *buffer);
+			efi_uintn_t *buffer_size, void *buffer);
 	efi_status_t (EFIAPI *write)(struct efi_file_handle *file,
-			u64 *buffer_size, void *buffer);
+			efi_uintn_t *buffer_size, void *buffer);
 	efi_status_t (EFIAPI *getpos)(struct efi_file_handle *file,
-			u64 *pos);
+			efi_uintn_t *pos);
 	efi_status_t (EFIAPI *setpos)(struct efi_file_handle *file,
-			u64 pos);
+			efi_uintn_t pos);
 	efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *file,
-			efi_guid_t *info_type, u64 *buffer_size, void *buffer);
+			const efi_guid_t *info_type, efi_uintn_t *buffer_size,
+			void *buffer);
 	efi_status_t (EFIAPI *setinfo)(struct efi_file_handle *file,
-			efi_guid_t *info_type, u64 buffer_size, void *buffer);
+			const efi_guid_t *info_type, efi_uintn_t buffer_size,
+			void *buffer);
 	efi_status_t (EFIAPI *flush)(struct efi_file_handle *file);
 };
 
@@ -823,6 +889,10 @@
 	EFI_GUID(0x9576e92, 0x6d3f, 0x11d2, \
 		 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
 
+#define EFI_FILE_SYSTEM_INFO_GUID \
+	EFI_GUID(0x09576e93, 0x6d3f, 0x11d2, \
+		 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+
 #define EFI_FILE_MODE_READ	0x0000000000000001
 #define EFI_FILE_MODE_WRITE	0x0000000000000002
 #define EFI_FILE_MODE_CREATE	0x8000000000000000
@@ -846,6 +916,15 @@
 	s16 file_name[0];
 };
 
+struct efi_file_system_info {
+	u64 size;
+	u8 read_only;
+	u64 volume_size;
+	u64 free_space;
+	u32 block_size;
+	u16 volume_label[0];
+};
+
 #define EFI_DRIVER_BINDING_PROTOCOL_GUID \
 	EFI_GUID(0x18a031ab, 0xb443, 0x4d1a,\
 		 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 07730c3..17f9d3d 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -83,6 +83,9 @@
 extern struct efi_simple_input_interface efi_con_in;
 extern struct efi_console_control_protocol efi_console_control;
 extern const struct efi_device_path_to_text_protocol efi_device_path_to_text;
+/* implementation of the EFI_DEVICE_PATH_UTILITIES_PROTOCOL */
+extern const struct efi_device_path_utilities_protocol
+					efi_device_path_utilities;
 
 uint16_t *efi_dp_str(struct efi_device_path *dp);
 
@@ -93,10 +96,25 @@
 extern const efi_guid_t efi_guid_device_path;
 /* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
 extern const efi_guid_t efi_guid_driver_binding_protocol;
+/* event group ExitBootServices() invoked */
+extern const efi_guid_t efi_guid_event_group_exit_boot_services;
+/* event group SetVirtualAddressMap() invoked */
+extern const efi_guid_t efi_guid_event_group_virtual_address_change;
+/* event group memory map changed */
+extern const efi_guid_t efi_guid_event_group_memory_map_change;
+/* event group boot manager about to boot */
+extern const efi_guid_t efi_guid_event_group_ready_to_boot;
+/* event group ResetSystem() invoked (before ExitBootServices) */
+extern const efi_guid_t efi_guid_event_group_reset_system;
+/* GUID of the device tree table */
+extern const efi_guid_t efi_guid_fdt;
 extern const efi_guid_t efi_guid_loaded_image;
 extern const efi_guid_t efi_guid_device_path_to_text_protocol;
 extern const efi_guid_t efi_simple_file_system_protocol_guid;
 extern const efi_guid_t efi_file_info_guid;
+/* GUID for file system information */
+extern const efi_guid_t efi_file_system_info_guid;
+extern const efi_guid_t efi_guid_device_path_utilities_protocol;
 
 extern unsigned int __efi_runtime_start, __efi_runtime_stop;
 extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
@@ -144,21 +162,25 @@
 /**
  * struct efi_event
  *
+ * @link:		Link to list of all events
  * @type:		Type of event, see efi_create_event
  * @notify_tpl:		Task priority level of notifications
- * @trigger_time:	Period of the timer
- * @trigger_next:	Next time to trigger the timer
  * @nofify_function:	Function to call when the event is triggered
  * @notify_context:	Data to be passed to the notify function
+ * @group:		Event group
+ * @trigger_time:	Period of the timer
+ * @trigger_next:	Next time to trigger the timer
  * @trigger_type:	Type of timer, see efi_set_timer
- * @queued:		The notification function is queued
- * @signaled:		The event occurred. The event is in the signaled state.
+ * @is_queued:		The notification function is queued
+ * @is_signaled:	The event occurred. The event is in the signaled state.
  */
 struct efi_event {
+	struct list_head link;
 	uint32_t type;
 	efi_uintn_t notify_tpl;
 	void (EFIAPI *notify_function)(struct efi_event *event, void *context);
 	void *notify_context;
+	const efi_guid_t *group;
 	u64 trigger_next;
 	u64 trigger_time;
 	enum efi_timer_delay trigger_type;
@@ -166,9 +188,10 @@
 	bool is_signaled;
 };
 
-
 /* This list contains all UEFI objects we know of */
 extern struct list_head efi_obj_list;
+/* List of all events */
+extern struct list_head efi_events;
 
 /* Called by bootefi to make console interface available */
 int efi_console_register(void);
@@ -179,13 +202,13 @@
 			       const char *if_typename, int diskid,
 			       const char *pdevname);
 /* Called by bootefi to make GOP (graphical) interface available */
-int efi_gop_register(void);
+efi_status_t efi_gop_register(void);
 /* Called by bootefi to make the network interface available */
-int efi_net_register(void);
+efi_status_t efi_net_register(void);
 /* Called by bootefi to make the watchdog available */
-int efi_watchdog_register(void);
+efi_status_t efi_watchdog_register(void);
 /* Called by bootefi to make SMBIOS tables available */
-void efi_smbios_register(void);
+efi_status_t efi_smbios_register(void);
 
 struct efi_simple_file_system_protocol *
 efi_fs_from_path(struct efi_device_path *fp);
@@ -235,7 +258,8 @@
 			      void (EFIAPI *notify_function) (
 					struct efi_event *event,
 					void *context),
-			      void *notify_context, struct efi_event **event);
+			      void *notify_context, efi_guid_t *group,
+			      struct efi_event **event);
 /* Call this to set a timer */
 efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
 			   uint64_t trigger_time);
@@ -284,6 +308,10 @@
 			struct efi_device_path *file_path);
 efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,
 				      void **buffer);
+/* Print information about a loaded image */
+efi_status_t efi_print_image_info(struct efi_loaded_image *image, void *pc);
+/* Print information about all loaded images */
+void efi_print_image_infos(void *pc);
 
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
 extern void *efi_bounce_buffer;
@@ -330,6 +358,7 @@
 {
 	while (*ascii)
 		*(unicode++) = *(ascii++);
+	*unicode = 0;
 }
 
 static inline int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2)
@@ -346,7 +375,7 @@
 
 /* Call this with mmio_ptr as the _pointer_ to a pointer to an MMIO region
  * to make it available at runtime */
-void efi_add_runtime_mmio(void *mmio_ptr, u64 len);
+efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len);
 
 /* Boards may provide the functions below to implement RTS functionality */
 
@@ -354,12 +383,14 @@
 			enum efi_reset_type reset_type,
 			efi_status_t reset_status,
 			unsigned long data_size, void *reset_data);
-void efi_reset_system_init(void);
+
+/* Architecture specific initialization of the EFI subsystem */
+efi_status_t efi_reset_system_init(void);
 
 efi_status_t __efi_runtime EFIAPI efi_get_time(
 			struct efi_time *time,
 			struct efi_time_cap *capabilities);
-void efi_get_time_init(void);
+efi_status_t efi_get_time_init(void);
 
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
 /*
@@ -388,13 +419,17 @@
 /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */
 #define __efi_runtime_data
 #define __efi_runtime
-static inline void efi_add_runtime_mmio(void *mmio_ptr, u64 len) { }
+static inline efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len)
+{
+	return EFI_SUCCESS;
+}
 
 /* No loader configured, stub out EFI_ENTRY */
 static inline void efi_restore_gd(void) { }
 static inline void efi_set_bootdev(const char *dev, const char *devnr,
 				   const char *path) { }
 static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
+static inline void efi_print_image_infos(void *pc) { }
 
 #endif /* CONFIG_EFI_LOADER && !CONFIG_SPL_BUILD */
 
diff --git a/include/environment.h b/include/environment.h
index 7986a24..1b52353 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -314,6 +314,10 @@
  */
 int env_save(void);
 
+void eth_parse_enetaddr(const char *addr, uint8_t *enetaddr);
+int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr);
+int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr);
+
 #endif /* DO_DEPS_ONLY */
 
 #endif /* _ENVIRONMENT_H_ */
diff --git a/include/net.h b/include/net.h
index 3101096..3469811 100644
--- a/include/net.h
+++ b/include/net.h
@@ -238,9 +238,6 @@
 void eth_set_current(void);		/* set nterface to ethcur var */
 
 int eth_get_dev_index(void);		/* get the device index */
-void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
-int eth_env_get_enetaddr(const char *name, uchar *enetaddr);
-int eth_env_set_enetaddr(const char *name, const uchar *enetaddr);
 
 /**
  * eth_env_set_enetaddr_by_index() - set the MAC address environment variable
diff --git a/include/pe.h b/include/pe.h
index c3a19ce..e7845bb 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -38,11 +38,15 @@
 #define IMAGE_DOS_SIGNATURE		0x5A4D     /* MZ   */
 #define IMAGE_NT_SIGNATURE		0x00004550 /* PE00 */
 
+#define IMAGE_FILE_MACHINE_I386		0x014c
 #define IMAGE_FILE_MACHINE_ARM		0x01c0
 #define IMAGE_FILE_MACHINE_THUMB	0x01c2
 #define IMAGE_FILE_MACHINE_ARMNT	0x01c4
 #define IMAGE_FILE_MACHINE_AMD64	0x8664
 #define IMAGE_FILE_MACHINE_ARM64	0xaa64
+#define IMAGE_FILE_MACHINE_RISCV32	0x5032
+#define IMAGE_FILE_MACHINE_RISCV64	0x5064
+
 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC	0x10b
 #define IMAGE_NT_OPTIONAL_HDR64_MAGIC	0x20b
 #define IMAGE_SUBSYSTEM_EFI_APPLICATION	10
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 2a87d9e..d2ce897 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -17,7 +17,8 @@
 obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
 obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o
 obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o
-obj-y += efi_file.o efi_variable.o efi_bootmgr.o efi_watchdog.o
+obj-y += efi_device_path_utilities.o efi_file.o efi_variable.o efi_bootmgr.o
+obj-y += efi_watchdog.o
 obj-$(CONFIG_LCD) += efi_gop.o
 obj-$(CONFIG_DM_VIDEO) += efi_gop.o
 obj-$(CONFIG_PARTITIONS) += efi_disk.o
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 66e26fd..7a9449f 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -26,6 +26,9 @@
 /* This list contains all the EFI objects our payload has access to */
 LIST_HEAD(efi_obj_list);
 
+/* List of all events */
+LIST_HEAD(efi_events);
+
 /*
  * If we're running on nasty systems (32bit ARM booting into non-EFI Linux)
  * we need to do trickery with caches. Since we don't want to break the EFI
@@ -56,10 +59,28 @@
 
 static int entry_count;
 static int nesting_level;
+/* GUID of the device tree table */
+const efi_guid_t efi_guid_fdt = EFI_FDT_GUID;
 /* GUID of the EFI_DRIVER_BINDING_PROTOCOL */
 const efi_guid_t efi_guid_driver_binding_protocol =
 			EFI_DRIVER_BINDING_PROTOCOL_GUID;
 
+/* event group ExitBootServices() invoked */
+const efi_guid_t efi_guid_event_group_exit_boot_services =
+			EFI_EVENT_GROUP_EXIT_BOOT_SERVICES;
+/* event group SetVirtualAddressMap() invoked */
+const efi_guid_t efi_guid_event_group_virtual_address_change =
+			EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE;
+/* event group memory map changed */
+const efi_guid_t efi_guid_event_group_memory_map_change =
+			EFI_EVENT_GROUP_MEMORY_MAP_CHANGE;
+/* event group boot manager about to boot */
+const efi_guid_t efi_guid_event_group_ready_to_boot =
+			EFI_EVENT_GROUP_READY_TO_BOOT;
+/* event group ResetSystem() invoked (before ExitBootServices) */
+const efi_guid_t efi_guid_event_group_reset_system =
+			EFI_EVENT_GROUP_RESET_SYSTEM;
+
 static efi_status_t EFIAPI efi_disconnect_controller(
 					efi_handle_t controller_handle,
 					efi_handle_t driver_image_handle,
@@ -121,6 +142,7 @@
 {
 	const char *indent = "                    ";
 	const int max = strlen(indent);
+
 	level = min(max, level * 2);
 	return &indent[max - level];
 }
@@ -154,7 +176,7 @@
  * @event	event to signal
  * @check_tpl	check the TPL level
  */
-void efi_signal_event(struct efi_event *event, bool check_tpl)
+static void efi_queue_event(struct efi_event *event, bool check_tpl)
 {
 	if (event->notify_function) {
 		event->is_queued = true;
@@ -168,6 +190,50 @@
 }
 
 /*
+ * Signal an EFI event.
+ *
+ * This function signals an event. If the event belongs to an event group
+ * all events of the group are signaled. If they are of type EVT_NOTIFY_SIGNAL
+ * their notification function is queued.
+ *
+ * For the SignalEvent service see efi_signal_event_ext.
+ *
+ * @event	event to signal
+ * @check_tpl	check the TPL level
+ */
+void efi_signal_event(struct efi_event *event, bool check_tpl)
+{
+	if (event->group) {
+		struct efi_event *evt;
+
+		/*
+		 * The signaled state has to set before executing any
+		 * notification function
+		 */
+		list_for_each_entry(evt, &efi_events, link) {
+			if (!evt->group || guidcmp(evt->group, event->group))
+				continue;
+			if (evt->is_signaled)
+				continue;
+			evt->is_signaled = true;
+			if (evt->type & EVT_NOTIFY_SIGNAL &&
+			    evt->notify_function)
+				evt->is_queued = true;
+		}
+		list_for_each_entry(evt, &efi_events, link) {
+			if (!evt->group || guidcmp(evt->group, event->group))
+				continue;
+			if (evt->is_queued)
+				efi_queue_event(evt, check_tpl);
+		}
+	} else if (!event->is_signaled) {
+		event->is_signaled = true;
+		if (event->type & EVT_NOTIFY_SIGNAL)
+			efi_queue_event(event, check_tpl);
+	}
+}
+
+/*
  * Raise the task priority level.
  *
  * This function implements the RaiseTpl service.
@@ -212,6 +278,11 @@
 	if (efi_tpl > TPL_HIGH_LEVEL)
 		efi_tpl = TPL_HIGH_LEVEL;
 
+	/*
+	 * Lowering the TPL may have made queued events eligible for execution.
+	 */
+	efi_timer_check();
+
 	EFI_EXIT(EFI_SUCCESS);
 }
 
@@ -255,7 +326,7 @@
 {
 	efi_status_t r;
 
-	EFI_ENTRY("%"PRIx64", 0x%zx", memory, pages);
+	EFI_ENTRY("%" PRIx64 ", 0x%zx", memory, pages);
 	r = efi_free_pages(memory, pages);
 	return EFI_EXIT(r);
 }
@@ -470,10 +541,23 @@
 }
 
 /*
- * Our event capabilities are very limited. Only a small limited
- * number of events is allowed to coexist.
+ * Check if a pointer is a valid event.
+ *
+ * @event		pointer to check
+ * @return		status code
  */
-static struct efi_event efi_events[16];
+static efi_status_t efi_is_event(const struct efi_event *event)
+{
+	const struct efi_event *evt;
+
+	if (!event)
+		return EFI_INVALID_PARAMETER;
+	list_for_each_entry(evt, &efi_events, link) {
+		if (evt == event)
+			return EFI_SUCCESS;
+	}
+	return EFI_INVALID_PARAMETER;
+}
 
 /*
  * Create an event.
@@ -494,9 +578,10 @@
 			      void (EFIAPI *notify_function) (
 					struct efi_event *event,
 					void *context),
-			      void *notify_context, struct efi_event **event)
+			      void *notify_context, efi_guid_t *group,
+			      struct efi_event **event)
 {
-	int i;
+	struct efi_event *evt;
 
 	if (event == NULL)
 		return EFI_INVALID_PARAMETER;
@@ -504,25 +589,25 @@
 	if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
 		return EFI_INVALID_PARAMETER;
 
-	if ((type & (EVT_NOTIFY_SIGNAL|EVT_NOTIFY_WAIT)) &&
+	if ((type & (EVT_NOTIFY_SIGNAL | EVT_NOTIFY_WAIT)) &&
 	    notify_function == NULL)
 		return EFI_INVALID_PARAMETER;
 
-	for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
-		if (efi_events[i].type)
-			continue;
-		efi_events[i].type = type;
-		efi_events[i].notify_tpl = notify_tpl;
-		efi_events[i].notify_function = notify_function;
-		efi_events[i].notify_context = notify_context;
-		/* Disable timers on bootup */
-		efi_events[i].trigger_next = -1ULL;
-		efi_events[i].is_queued = false;
-		efi_events[i].is_signaled = false;
-		*event = &efi_events[i];
-		return EFI_SUCCESS;
-	}
-	return EFI_OUT_OF_RESOURCES;
+	evt = calloc(1, sizeof(struct efi_event));
+	if (!evt)
+		return EFI_OUT_OF_RESOURCES;
+	evt->type = type;
+	evt->notify_tpl = notify_tpl;
+	evt->notify_function = notify_function;
+	evt->notify_context = notify_context;
+	evt->group = group;
+	/* Disable timers on bootup */
+	evt->trigger_next = -1ULL;
+	evt->is_queued = false;
+	evt->is_signaled = false;
+	list_add_tail(&evt->link, &efi_events);
+	*event = evt;
+	return EFI_SUCCESS;
 }
 
 /*
@@ -551,10 +636,8 @@
 {
 	EFI_ENTRY("%d, 0x%zx, %p, %p, %pUl", type, notify_tpl, notify_function,
 		  notify_context, event_group);
-	if (event_group)
-		return EFI_EXIT(EFI_UNSUPPORTED);
 	return EFI_EXIT(efi_create_event(type, notify_tpl, notify_function,
-					 notify_context, event));
+					 notify_context, event_group, event));
 }
 
 /*
@@ -581,10 +664,9 @@
 	EFI_ENTRY("%d, 0x%zx, %p, %p", type, notify_tpl, notify_function,
 		  notify_context);
 	return EFI_EXIT(efi_create_event(type, notify_tpl, notify_function,
-					 notify_context, event));
+					 notify_context, NULL, event));
 }
 
-
 /*
  * Check if a timer event has occurred or a queued notification function should
  * be called.
@@ -594,30 +676,26 @@
  */
 void efi_timer_check(void)
 {
-	int i;
+	struct efi_event *evt;
 	u64 now = timer_get_us();
 
-	for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
-		if (!efi_events[i].type)
+	list_for_each_entry(evt, &efi_events, link) {
+		if (evt->is_queued)
+			efi_queue_event(evt, true);
+		if (!(evt->type & EVT_TIMER) || now < evt->trigger_next)
 			continue;
-		if (efi_events[i].is_queued)
-			efi_signal_event(&efi_events[i], true);
-		if (!(efi_events[i].type & EVT_TIMER) ||
-		    now < efi_events[i].trigger_next)
-			continue;
-		switch (efi_events[i].trigger_type) {
+		switch (evt->trigger_type) {
 		case EFI_TIMER_RELATIVE:
-			efi_events[i].trigger_type = EFI_TIMER_STOP;
+			evt->trigger_type = EFI_TIMER_STOP;
 			break;
 		case EFI_TIMER_PERIODIC:
-			efi_events[i].trigger_next +=
-				efi_events[i].trigger_time;
+			evt->trigger_next += evt->trigger_time;
 			break;
 		default:
 			continue;
 		}
-		efi_events[i].is_signaled = true;
-		efi_signal_event(&efi_events[i], true);
+		evt->is_signaled = false;
+		efi_signal_event(evt, true);
 	}
 	WATCHDOG_RESET();
 }
@@ -636,7 +714,9 @@
 efi_status_t efi_set_timer(struct efi_event *event, enum efi_timer_delay type,
 			   uint64_t trigger_time)
 {
-	int i;
+	/* Check that the event is valid */
+	if (efi_is_event(event) != EFI_SUCCESS || !(event->type & EVT_TIMER))
+		return EFI_INVALID_PARAMETER;
 
 	/*
 	 * The parameter defines a multiple of 100ns.
@@ -644,30 +724,21 @@
 	 */
 	do_div(trigger_time, 10);
 
-	for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
-		if (event != &efi_events[i])
-			continue;
-
-		if (!(event->type & EVT_TIMER))
-			break;
-		switch (type) {
-		case EFI_TIMER_STOP:
-			event->trigger_next = -1ULL;
-			break;
-		case EFI_TIMER_PERIODIC:
-		case EFI_TIMER_RELATIVE:
-			event->trigger_next =
-				timer_get_us() + trigger_time;
-			break;
-		default:
-			return EFI_INVALID_PARAMETER;
-		}
-		event->trigger_type = type;
-		event->trigger_time = trigger_time;
-		event->is_signaled = false;
-		return EFI_SUCCESS;
+	switch (type) {
+	case EFI_TIMER_STOP:
+		event->trigger_next = -1ULL;
+		break;
+	case EFI_TIMER_PERIODIC:
+	case EFI_TIMER_RELATIVE:
+		event->trigger_next = timer_get_us() + trigger_time;
+		break;
+	default:
+		return EFI_INVALID_PARAMETER;
 	}
-	return EFI_INVALID_PARAMETER;
+	event->trigger_type = type;
+	event->trigger_time = trigger_time;
+	event->is_signaled = false;
+	return EFI_SUCCESS;
 }
 
 /*
@@ -686,7 +757,7 @@
 					     enum efi_timer_delay type,
 					     uint64_t trigger_time)
 {
-	EFI_ENTRY("%p, %d, %"PRIx64, event, type, trigger_time);
+	EFI_ENTRY("%p, %d, %" PRIx64, event, type, trigger_time);
 	return EFI_EXIT(efi_set_timer(event, type, trigger_time));
 }
 
@@ -706,7 +777,7 @@
 					      struct efi_event **event,
 					      efi_uintn_t *index)
 {
-	int i, j;
+	int i;
 
 	EFI_ENTRY("%zd, %p, %p", num_events, event, index);
 
@@ -717,16 +788,12 @@
 	if (efi_tpl != TPL_APPLICATION)
 		return EFI_EXIT(EFI_UNSUPPORTED);
 	for (i = 0; i < num_events; ++i) {
-		for (j = 0; j < ARRAY_SIZE(efi_events); ++j) {
-			if (event[i] == &efi_events[j])
-				goto known_event;
-		}
-		return EFI_EXIT(EFI_INVALID_PARAMETER);
-known_event:
+		if (efi_is_event(event[i]) != EFI_SUCCESS)
+			return EFI_EXIT(EFI_INVALID_PARAMETER);
 		if (!event[i]->type || event[i]->type & EVT_NOTIFY_SIGNAL)
 			return EFI_EXIT(EFI_INVALID_PARAMETER);
 		if (!event[i]->is_signaled)
-			efi_signal_event(event[i], true);
+			efi_queue_event(event[i], true);
 	}
 
 	/* Wait for signal */
@@ -766,19 +833,10 @@
  */
 static efi_status_t EFIAPI efi_signal_event_ext(struct efi_event *event)
 {
-	int i;
-
 	EFI_ENTRY("%p", event);
-	for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
-		if (event != &efi_events[i])
-			continue;
-		if (event->is_signaled)
-			break;
-		event->is_signaled = true;
-		if (event->type & EVT_NOTIFY_SIGNAL)
-			efi_signal_event(event, true);
-		break;
-	}
+	if (efi_is_event(event) != EFI_SUCCESS)
+		return EFI_EXIT(EFI_INVALID_PARAMETER);
+	efi_signal_event(event, true);
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
@@ -794,19 +852,12 @@
  */
 static efi_status_t EFIAPI efi_close_event(struct efi_event *event)
 {
-	int i;
-
 	EFI_ENTRY("%p", event);
-	for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
-		if (event == &efi_events[i]) {
-			event->type = 0;
-			event->trigger_next = -1ULL;
-			event->is_queued = false;
-			event->is_signaled = false;
-			return EFI_EXIT(EFI_SUCCESS);
-		}
-	}
-	return EFI_EXIT(EFI_INVALID_PARAMETER);
+	if (efi_is_event(event) != EFI_SUCCESS)
+		return EFI_EXIT(EFI_INVALID_PARAMETER);
+	list_del(&event->link);
+	free(event);
+	return EFI_EXIT(EFI_SUCCESS);
 }
 
 /*
@@ -816,29 +867,26 @@
  * See the Unified Extensible Firmware Interface (UEFI) specification
  * for details.
  *
- * If an event is not signaled yet the notification function is queued.
+ * If an event is not signaled yet, the notification function is queued.
+ * The signaled state is cleared.
  *
  * @event	event to check
  * @return	status code
  */
 static efi_status_t EFIAPI efi_check_event(struct efi_event *event)
 {
-	int i;
-
 	EFI_ENTRY("%p", event);
 	efi_timer_check();
-	for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
-		if (event != &efi_events[i])
-			continue;
-		if (!event->type || event->type & EVT_NOTIFY_SIGNAL)
-			break;
-		if (!event->is_signaled)
-			efi_signal_event(event, true);
-		if (event->is_signaled)
-			return EFI_EXIT(EFI_SUCCESS);
-		return EFI_EXIT(EFI_NOT_READY);
+	if (efi_is_event(event) != EFI_SUCCESS ||
+	    event->type & EVT_NOTIFY_SIGNAL)
+		return EFI_EXIT(EFI_INVALID_PARAMETER);
+	if (!event->is_signaled)
+		efi_queue_event(event, true);
+	if (event->is_signaled) {
+		event->is_signaled = false;
+		return EFI_EXIT(EFI_SUCCESS);
 	}
-	return EFI_EXIT(EFI_INVALID_PARAMETER);
+	return EFI_EXIT(EFI_NOT_READY);
 }
 
 /*
@@ -1259,7 +1307,7 @@
 	/* Count how much space we need */
 	list_for_each_entry(efiobj, &efi_obj_list, link) {
 		if (!efi_search(search_type, protocol, search_key, efiobj))
-			size += sizeof(void*);
+			size += sizeof(void *);
 	}
 
 	if (*buffer_size < size) {
@@ -1310,7 +1358,7 @@
 static void efi_remove_configuration_table(int i)
 {
 	struct efi_configuration_table *this = &efi_conf_table[i];
-	struct efi_configuration_table *next = &efi_conf_table[i+1];
+	struct efi_configuration_table *next = &efi_conf_table[i + 1];
 	struct efi_configuration_table *end = &efi_conf_table[systab.nr_tables];
 
 	memmove(this, next, (ulong)end - (ulong)next);
@@ -1327,10 +1375,15 @@
  * @table		table to be installed
  * @return		status code
  */
-efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table)
+efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
+					     void *table)
 {
+	struct efi_event *evt;
 	int i;
 
+	if (!guid)
+		return EFI_INVALID_PARAMETER;
+
 	/* Check for guid override */
 	for (i = 0; i < systab.nr_tables; i++) {
 		if (!guidcmp(guid, &efi_conf_table[i].guid)) {
@@ -1338,7 +1391,7 @@
 				efi_conf_table[i].table = table;
 			else
 				efi_remove_configuration_table(i);
-			return EFI_SUCCESS;
+			goto out;
 		}
 	}
 
@@ -1354,6 +1407,15 @@
 	efi_conf_table[i].table = table;
 	systab.nr_tables = i + 1;
 
+out:
+	/* Notify that the configuration table was changed */
+	list_for_each_entry(evt, &efi_events, link) {
+		if (evt->group && !guidcmp(evt->group, guid)) {
+			efi_signal_event(evt, false);
+			break;
+		}
+	}
+
 	return EFI_SUCCESS;
 }
 
@@ -1420,14 +1482,15 @@
 	if (ret != EFI_SUCCESS)
 		goto failure;
 
-	ret = efi_add_protocol(obj->handle, &efi_guid_console_control,
-			       (void *)&efi_console_control);
+	ret = efi_add_protocol(obj->handle,
+			       &efi_guid_device_path_to_text_protocol,
+			       (void *)&efi_device_path_to_text);
 	if (ret != EFI_SUCCESS)
 		goto failure;
 
 	ret = efi_add_protocol(obj->handle,
-			       &efi_guid_device_path_to_text_protocol,
-			       (void *)&efi_device_path_to_text);
+			       &efi_guid_device_path_utilities_protocol,
+			       (void *)&efi_device_path_utilities);
 	if (ret != EFI_SUCCESS)
 		goto failure;
 
@@ -1450,7 +1513,7 @@
 	struct efi_file_info *info = NULL;
 	struct efi_file_handle *f;
 	static efi_status_t ret;
-	uint64_t bs;
+	efi_uintn_t bs;
 
 	f = efi_file_from_path(file_path);
 	if (!f)
@@ -1471,7 +1534,8 @@
 	if (ret)
 		goto error;
 
-	EFI_CALL(ret = f->read(f, &info->file_size, *buffer));
+	bs = info->file_size;
+	EFI_CALL(ret = f->read(f, &bs, *buffer));
 
 error:
 	free(info);
@@ -1505,18 +1569,37 @@
 					  efi_handle_t parent_image,
 					  struct efi_device_path *file_path,
 					  void *source_buffer,
-					  unsigned long source_size,
+					  efi_uintn_t source_size,
 					  efi_handle_t *image_handle)
 {
 	struct efi_loaded_image *info;
 	struct efi_object *obj;
 	efi_status_t ret;
 
-	EFI_ENTRY("%d, %p, %pD, %p, %ld, %p", boot_policy, parent_image,
+	EFI_ENTRY("%d, %p, %pD, %p, %zd, %p", boot_policy, parent_image,
 		  file_path, source_buffer, source_size, image_handle);
 
+	if (!image_handle || !parent_image) {
+		ret = EFI_INVALID_PARAMETER;
+		goto error;
+	}
+
+	if (!source_buffer && !file_path) {
+		ret = EFI_NOT_FOUND;
+		goto error;
+	}
+
 	info = calloc(1, sizeof(*info));
+	if (!info) {
+		ret = EFI_OUT_OF_RESOURCES;
+		goto error;
+	}
 	obj = calloc(1, sizeof(*obj));
+	if (!obj) {
+		free(info);
+		ret = EFI_OUT_OF_RESOURCES;
+		goto error;
+	}
 
 	if (!source_buffer) {
 		struct efi_device_path *dp, *fp;
@@ -1552,6 +1635,7 @@
 failure:
 	free(info);
 	efi_delete_handle(obj);
+error:
 	return EFI_EXIT(ret);
 }
 
@@ -1635,8 +1719,9 @@
  * @return		status code
  */
 static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
-			efi_status_t exit_status, unsigned long exit_data_size,
-			int16_t *exit_data)
+				    efi_status_t exit_status,
+				    unsigned long exit_data_size,
+				    int16_t *exit_data)
 {
 	/*
 	 * We require that the handle points to the original loaded
@@ -1649,7 +1734,7 @@
 	 * TODO: We should call the unload procedure of the loaded
 	 *	 image protocol.
 	 */
-	struct efi_loaded_image *loaded_image_info = (void*)image_handle;
+	struct efi_loaded_image *loaded_image_info = (void *)image_handle;
 
 	EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
 		  exit_data_size, exit_data);
@@ -1724,7 +1809,7 @@
 static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
 						  unsigned long map_key)
 {
-	int i;
+	struct efi_event *evt;
 
 	EFI_ENTRY("%p, %ld", image_handle, map_key);
 
@@ -1735,12 +1820,19 @@
 	if (!systab.boottime)
 		return EFI_EXIT(EFI_SUCCESS);
 
+	/* Add related events to the event group */
+	list_for_each_entry(evt, &efi_events, link) {
+		if (evt->type == EVT_SIGNAL_EXIT_BOOT_SERVICES)
+			evt->group = &efi_guid_event_group_exit_boot_services;
+	}
 	/* Notify that ExitBootServices is invoked. */
-	for (i = 0; i < ARRAY_SIZE(efi_events); ++i) {
-		if (efi_events[i].type != EVT_SIGNAL_EXIT_BOOT_SERVICES)
-			continue;
-		efi_events[i].is_signaled = true;
-		efi_signal_event(&efi_events[i], false);
+	list_for_each_entry(evt, &efi_events, link) {
+		if (evt->group &&
+		    !guidcmp(evt->group,
+			     &efi_guid_event_group_exit_boot_services)) {
+			efi_signal_event(evt, false);
+			break;
+		}
 	}
 
 	/* TODO Should persist EFI variables here */
@@ -1786,7 +1878,8 @@
  */
 static efi_status_t EFIAPI efi_get_next_monotonic_count(uint64_t *count)
 {
-	static uint64_t mono = 0;
+	static uint64_t mono;
+
 	EFI_ENTRY("%p", count);
 	*count = mono++;
 	return EFI_EXIT(EFI_SUCCESS);
@@ -1827,7 +1920,7 @@
 						  unsigned long data_size,
 						  uint16_t *watchdog_data)
 {
-	EFI_ENTRY("%ld, 0x%"PRIx64", %ld, %p", timeout, watchdog_code,
+	EFI_ENTRY("%ld, 0x%" PRIx64 ", %ld, %p", timeout, watchdog_code,
 		  data_size, watchdog_data);
 	return EFI_EXIT(efi_set_watchdog(timeout));
 }
@@ -1892,8 +1985,8 @@
  * @entry_count		number of entries available in the buffer
  * @return		status code
  */
-static efi_status_t EFIAPI efi_open_protocol_information(efi_handle_t handle,
-			const efi_guid_t *protocol,
+static efi_status_t EFIAPI efi_open_protocol_information(
+			efi_handle_t handle, const efi_guid_t *protocol,
 			struct efi_open_protocol_info_entry **entry_buffer,
 			efi_uintn_t *entry_count)
 {
@@ -2878,15 +2971,16 @@
 	.protocols_per_handle = efi_protocols_per_handle,
 	.locate_handle_buffer = efi_locate_handle_buffer,
 	.locate_protocol = efi_locate_protocol,
-	.install_multiple_protocol_interfaces = efi_install_multiple_protocol_interfaces,
-	.uninstall_multiple_protocol_interfaces = efi_uninstall_multiple_protocol_interfaces,
+	.install_multiple_protocol_interfaces =
+			efi_install_multiple_protocol_interfaces,
+	.uninstall_multiple_protocol_interfaces =
+			efi_uninstall_multiple_protocol_interfaces,
 	.calculate_crc32 = efi_calculate_crc32,
 	.copy_mem = efi_copy_mem,
 	.set_mem = efi_set_mem,
 	.create_event_ex = efi_create_event_ex,
 };
 
-
 static uint16_t __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
 
 struct efi_system_table __efi_runtime_data systab = {
@@ -2896,11 +2990,11 @@
 		.headersize = sizeof(struct efi_table_hdr),
 	},
 	.fw_vendor = (long)firmware_vendor,
-	.con_in = (void*)&efi_con_in,
-	.con_out = (void*)&efi_con_out,
-	.std_err = (void*)&efi_con_out,
-	.runtime = (void*)&efi_runtime_services,
-	.boottime = (void*)&efi_boot_services,
+	.con_in = (void *)&efi_con_in,
+	.con_out = (void *)&efi_con_out,
+	.std_err = (void *)&efi_con_out,
+	.runtime = (void *)&efi_runtime_services,
+	.boottime = (void *)&efi_boot_services,
 	.nr_tables = 0,
-	.tables = (void*)efi_conf_table,
+	.tables = (void *)efi_conf_table,
 };
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 28d6363..5d1a9a8 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -45,7 +45,6 @@
 	},
 };
 
-const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID;
 const efi_guid_t efi_guid_text_output_protocol =
 			EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
 const efi_guid_t efi_guid_text_input_protocol =
@@ -54,43 +53,6 @@
 #define cESC '\x1b'
 #define ESC "\x1b"
 
-static efi_status_t EFIAPI efi_cin_get_mode(
-			struct efi_console_control_protocol *this,
-			int *mode, char *uga_exists, char *std_in_locked)
-{
-	EFI_ENTRY("%p, %p, %p, %p", this, mode, uga_exists, std_in_locked);
-
-	if (mode)
-		*mode = EFI_CONSOLE_MODE_TEXT;
-	if (uga_exists)
-		*uga_exists = 0;
-	if (std_in_locked)
-		*std_in_locked = 0;
-
-	return EFI_EXIT(EFI_SUCCESS);
-}
-
-static efi_status_t EFIAPI efi_cin_set_mode(
-			struct efi_console_control_protocol *this, int mode)
-{
-	EFI_ENTRY("%p, %d", this, mode);
-	return EFI_EXIT(EFI_UNSUPPORTED);
-}
-
-static efi_status_t EFIAPI efi_cin_lock_std_in(
-			struct efi_console_control_protocol *this,
-			uint16_t *password)
-{
-	EFI_ENTRY("%p, %p", this, password);
-	return EFI_EXIT(EFI_UNSUPPORTED);
-}
-
-struct efi_console_control_protocol efi_console_control = {
-	.get_mode = efi_cin_get_mode,
-	.set_mode = efi_cin_set_mode,
-	.lock_std_in = efi_cin_lock_std_in,
-};
-
 /* Default to mode 0 */
 static struct simple_text_output_mode efi_con_mode = {
 	.max_mode = 1,
@@ -399,6 +361,48 @@
 	return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
+/*
+ * Analyze modifiers (shift, alt, ctrl) for function keys.
+ * This gets called when we have already parsed CSI.
+ *
+ * @modifiers:  bitmask (shift, alt, ctrl)
+ * @return:	the unmodified code
+ */
+static char skip_modifiers(int *modifiers)
+{
+	char c, mod = 0, ret = 0;
+
+	c = getc();
+
+	if (c != ';') {
+		ret = c;
+		if (c == '~')
+			goto out;
+		c = getc();
+	}
+	for (;;) {
+		switch (c) {
+		case '0'...'9':
+			mod *= 10;
+			mod += c - '0';
+		/* fall through */
+		case ';':
+			c = getc();
+			break;
+		default:
+			goto out;
+		}
+	}
+out:
+	if (mod)
+		--mod;
+	if (modifiers)
+		*modifiers = mod;
+	if (!ret)
+		ret = c;
+	return ret;
+}
+
 static efi_status_t EFIAPI efi_cin_read_key_stroke(
 			struct efi_simple_input_interface *this,
 			struct efi_input_key *key)
@@ -421,14 +425,21 @@
 
 	ch = getc();
 	if (ch == cESC) {
-		/* Escape Sequence */
+		/*
+		 * Xterm Control Sequences
+		 * https://www.xfree86.org/4.8.0/ctlseqs.html
+		 */
 		ch = getc();
 		switch (ch) {
 		case cESC: /* ESC */
 			pressed_key.scan_code = 23;
 			break;
 		case 'O': /* F1 - F4 */
-			pressed_key.scan_code = getc() - 'P' + 11;
+			ch = getc();
+			/* skip modifiers */
+			if (ch <= '9')
+				ch = getc();
+			pressed_key.scan_code = ch - 'P' + 11;
 			break;
 		case 'a'...'z':
 			ch = ch - 'a';
@@ -445,17 +456,51 @@
 			case 'H': /* Home */
 				pressed_key.scan_code = 5;
 				break;
-			case '1': /* F5 - F8 */
-				pressed_key.scan_code = getc() - '0' + 11;
-				getc();
+			case '1':
+				ch = skip_modifiers(NULL);
+				switch (ch) {
+				case '1'...'5': /* F1 - F5 */
+					pressed_key.scan_code = ch - '1' + 11;
+					break;
+				case '7'...'9': /* F6 - F8 */
+					pressed_key.scan_code = ch - '7' + 16;
+					break;
+				case 'A'...'D': /* up, down right, left */
+					pressed_key.scan_code = ch - 'A' + 1;
+					break;
+				case 'F':
+					pressed_key.scan_code = 6; /* End */
+					break;
+				case 'H':
+					pressed_key.scan_code = 5; /* Home */
+					break;
+				}
 				break;
-			case '2': /* F9 - F12 */
-				pressed_key.scan_code = getc() - '0' + 19;
-				getc();
+			case '2':
+				ch = skip_modifiers(NULL);
+				switch (ch) {
+				case '0'...'1': /* F9 - F10 */
+					pressed_key.scan_code = ch - '0' + 19;
+					break;
+				case '3'...'4': /* F11 - F12 */
+					pressed_key.scan_code = ch - '3' + 21;
+					break;
+				case '~': /* INS */
+					pressed_key.scan_code = 7;
+					break;
+				}
 				break;
 			case '3': /* DEL */
 				pressed_key.scan_code = 8;
-				getc();
+				skip_modifiers(NULL);
+				break;
+			case '5': /* PG UP */
+				pressed_key.scan_code = 9;
+				skip_modifiers(NULL);
+				break;
+			case '6': /* PG DOWN */
+				pressed_key.scan_code = 10;
+				skip_modifiers(NULL);
 				break;
 			}
 			break;
@@ -464,7 +509,8 @@
 		/* Backspace */
 		ch = 0x08;
 	}
-	pressed_key.unicode_char = ch;
+	if (!pressed_key.scan_code)
+		pressed_key.unicode_char = ch;
 	*key = pressed_key;
 
 	return EFI_EXIT(EFI_SUCCESS);
@@ -506,18 +552,10 @@
 int efi_console_register(void)
 {
 	efi_status_t r;
-	struct efi_object *efi_console_control_obj;
 	struct efi_object *efi_console_output_obj;
 	struct efi_object *efi_console_input_obj;
 
 	/* Create handles */
-	r = efi_create_handle((efi_handle_t *)&efi_console_control_obj);
-	if (r != EFI_SUCCESS)
-		goto out_of_memory;
-	r = efi_add_protocol(efi_console_control_obj->handle,
-			     &efi_guid_console_control, &efi_console_control);
-	if (r != EFI_SUCCESS)
-		goto out_of_memory;
 	r = efi_create_handle((efi_handle_t *)&efi_console_output_obj);
 	if (r != EFI_SUCCESS)
 		goto out_of_memory;
@@ -534,14 +572,14 @@
 		goto out_of_memory;
 
 	/* Create console events */
-	r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK,
-			     efi_key_notify, NULL, &efi_con_in.wait_for_key);
+	r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_key_notify,
+			     NULL, NULL, &efi_con_in.wait_for_key);
 	if (r != EFI_SUCCESS) {
 		printf("ERROR: Failed to register WaitForKey event\n");
 		return r;
 	}
 	r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
-			     efi_console_timer_notify, NULL,
+			     efi_console_timer_notify, NULL, NULL,
 			     &console_timer_event);
 	if (r != EFI_SUCCESS) {
 		printf("ERROR: Failed to register console event\n");
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 3c735e6..ab28b2f 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -66,6 +66,7 @@
 		return NULL;
 	}
 
+	memset(buf, 0, sz);
 	return buf;
 }
 
@@ -749,7 +750,9 @@
 #ifdef CONFIG_CMD_NET
 struct efi_device_path *efi_dp_from_eth(void)
 {
+#ifndef CONFIG_DM_ETH
 	struct efi_device_path_mac_addr *ndp;
+#endif
 	void *buf, *start;
 	unsigned dpsize = 0;
 
@@ -759,8 +762,8 @@
 	dpsize += dp_size(eth_get_dev());
 #else
 	dpsize += sizeof(ROOT);
-#endif
 	dpsize += sizeof(*ndp);
+#endif
 
 	start = buf = dp_alloc(dpsize + sizeof(END));
 	if (!buf)
@@ -771,14 +774,15 @@
 #else
 	memcpy(buf, &ROOT, sizeof(ROOT));
 	buf += sizeof(ROOT);
-#endif
 
 	ndp = buf;
 	ndp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
 	ndp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
 	ndp->dp.length = sizeof(*ndp);
+	ndp->if_type = 1; /* Ethernet */
 	memcpy(ndp->mac.addr, eth_get_ethaddr(), ARP_HLEN);
 	buf = &ndp[1];
+#endif
 
 	*((struct efi_device_path *)buf) = END;
 
diff --git a/lib/efi_loader/efi_device_path_utilities.c b/lib/efi_loader/efi_device_path_utilities.c
new file mode 100644
index 0000000..bc97eee
--- /dev/null
+++ b/lib/efi_loader/efi_device_path_utilities.c
@@ -0,0 +1,89 @@
+/*
+ *  EFI device path interface
+ *
+ *  Copyright (c) 2017 Leif Lindholm
+ *
+ *  SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <efi_loader.h>
+
+const efi_guid_t efi_guid_device_path_utilities_protocol =
+		EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
+
+static efi_uintn_t EFIAPI get_device_path_size(
+	const struct efi_device_path *device_path)
+{
+	efi_uintn_t sz = 0;
+
+	EFI_ENTRY("%p", device_path);
+	/* size includes the END node: */
+	if (device_path)
+		sz = efi_dp_size(device_path) + sizeof(struct efi_device_path);
+	return EFI_EXIT(sz);
+}
+
+static struct efi_device_path * EFIAPI duplicate_device_path(
+	const struct efi_device_path *device_path)
+{
+	EFI_ENTRY("%p", device_path);
+	return EFI_EXIT(efi_dp_dup(device_path));
+}
+
+static struct efi_device_path * EFIAPI append_device_path(
+	const struct efi_device_path *src1,
+	const struct efi_device_path *src2)
+{
+	EFI_ENTRY("%p, %p", src1, src2);
+	return EFI_EXIT(efi_dp_append(src1, src2));
+}
+
+static struct efi_device_path * EFIAPI append_device_node(
+	const struct efi_device_path *device_path,
+	const struct efi_device_path *device_node)
+{
+	EFI_ENTRY("%p, %p", device_path, device_node);
+	return EFI_EXIT(efi_dp_append_node(device_path, device_node));
+}
+
+static struct efi_device_path * EFIAPI append_device_path_instance(
+	const struct efi_device_path *device_path,
+	const struct efi_device_path *device_path_instance)
+{
+	EFI_ENTRY("%p, %p", device_path, device_path_instance);
+	return EFI_EXIT(NULL);
+}
+
+static struct efi_device_path * EFIAPI get_next_device_path_instance(
+	struct efi_device_path **device_path_instance,
+	efi_uintn_t *device_path_instance_size)
+{
+	EFI_ENTRY("%p, %p", device_path_instance, device_path_instance_size);
+	return EFI_EXIT(NULL);
+}
+
+static bool EFIAPI is_device_path_multi_instance(
+	const struct efi_device_path *device_path)
+{
+	EFI_ENTRY("%p", device_path);
+	return EFI_EXIT(false);
+}
+
+static struct efi_device_path * EFIAPI create_device_node(
+	uint8_t node_type, uint8_t node_sub_type, uint16_t node_length)
+{
+	EFI_ENTRY("%u, %u, %u", node_type, node_sub_type, node_length);
+	return EFI_EXIT(NULL);
+}
+
+const struct efi_device_path_utilities_protocol efi_device_path_utilities = {
+	.get_device_path_size = get_device_path_size,
+	.duplicate_device_path = duplicate_device_path,
+	.append_device_path = append_device_path,
+	.append_device_node = append_device_node,
+	.append_device_path_instance = append_device_path_instance,
+	.get_next_device_path_instance = get_next_device_path_instance,
+	.is_device_path_multi_instance = is_device_path_multi_instance,
+	.create_device_node = create_device_node,
+};
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index 52a4e74..cec8347 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -12,6 +12,9 @@
 #include <malloc.h>
 #include <fs.h>
 
+/* GUID for file system information */
+const efi_guid_t efi_file_system_info_guid = EFI_FILE_SYSTEM_INFO_GUID;
+
 struct file_system {
 	struct efi_simple_file_system_protocol base;
 	struct efi_device_path *dp;
@@ -314,29 +317,41 @@
 }
 
 static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *file,
-		u64 *buffer_size, void *buffer)
+					 efi_uintn_t *buffer_size, void *buffer)
 {
 	struct file_handle *fh = to_fh(file);
 	efi_status_t ret = EFI_SUCCESS;
+	u64 bs;
 
 	EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer);
 
+	if (!buffer_size || !buffer) {
+		ret = EFI_INVALID_PARAMETER;
+		goto error;
+	}
+
 	if (set_blk_dev(fh)) {
 		ret = EFI_DEVICE_ERROR;
 		goto error;
 	}
 
+	bs = *buffer_size;
 	if (fh->isdir)
-		ret = dir_read(fh, buffer_size, buffer);
+		ret = dir_read(fh, &bs, buffer);
 	else
-		ret = file_read(fh, buffer_size, buffer);
+		ret = file_read(fh, &bs, buffer);
+	if (bs <= SIZE_MAX)
+		*buffer_size = bs;
+	else
+		*buffer_size = SIZE_MAX;
 
 error:
 	return EFI_EXIT(ret);
 }
 
 static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file,
-		u64 *buffer_size, void *buffer)
+					  efi_uintn_t *buffer_size,
+					  void *buffer)
 {
 	struct file_handle *fh = to_fh(file);
 	efi_status_t ret = EFI_SUCCESS;
@@ -363,21 +378,27 @@
 }
 
 static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file,
-		u64 *pos)
+					   efi_uintn_t *pos)
 {
 	struct file_handle *fh = to_fh(file);
+
 	EFI_ENTRY("%p, %p", file, pos);
-	*pos = fh->offset;
-	return EFI_EXIT(EFI_SUCCESS);
+
+	if (fh->offset <= SIZE_MAX) {
+		*pos = fh->offset;
+		return EFI_EXIT(EFI_SUCCESS);
+	} else {
+		return EFI_EXIT(EFI_DEVICE_ERROR);
+	}
 }
 
 static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file,
-		u64 pos)
+		efi_uintn_t pos)
 {
 	struct file_handle *fh = to_fh(file);
 	efi_status_t ret = EFI_SUCCESS;
 
-	EFI_ENTRY("%p, %llu", file, pos);
+	EFI_ENTRY("%p, %zu", file, pos);
 
 	if (fh->isdir) {
 		if (pos != 0) {
@@ -411,7 +432,9 @@
 }
 
 static efi_status_t EFIAPI efi_file_getinfo(struct efi_file_handle *file,
-		efi_guid_t *info_type, u64 *buffer_size, void *buffer)
+					    const efi_guid_t *info_type,
+					    efi_uintn_t *buffer_size,
+					    void *buffer)
 {
 	struct file_handle *fh = to_fh(file);
 	efi_status_t ret = EFI_SUCCESS;
@@ -452,6 +475,41 @@
 			info->attribute |= EFI_FILE_DIRECTORY;
 
 		ascii2unicode((u16 *)info->file_name, filename);
+	} else if (!guidcmp(info_type, &efi_file_system_info_guid)) {
+		struct efi_file_system_info *info = buffer;
+		disk_partition_t part;
+		efi_uintn_t required_size;
+		int r;
+
+		if (fh->fs->part >= 1)
+			r = part_get_info(fh->fs->desc, fh->fs->part, &part);
+		else
+			r = part_get_info_whole_disk(fh->fs->desc, &part);
+		if (r < 0) {
+			ret = EFI_DEVICE_ERROR;
+			goto error;
+		}
+		required_size = sizeof(info) + 2 *
+				(strlen((const char *)part.name) + 1);
+		if (*buffer_size < required_size) {
+			*buffer_size = required_size;
+			ret = EFI_BUFFER_TOO_SMALL;
+			goto error;
+		}
+
+		memset(info, 0, required_size);
+
+		info->size = required_size;
+		info->read_only = true;
+		info->volume_size = part.size * part.blksz;
+		info->free_space = 0;
+		info->block_size = part.blksz;
+		/*
+		 * TODO: The volume label is not available in U-Boot.
+		 * Use the partition name as substitute.
+		 */
+		ascii2unicode((u16 *)info->volume_label,
+			      (const char *)part.name);
 	} else {
 		ret = EFI_UNSUPPORTED;
 	}
@@ -461,9 +519,12 @@
 }
 
 static efi_status_t EFIAPI efi_file_setinfo(struct efi_file_handle *file,
-		efi_guid_t *info_type, u64 buffer_size, void *buffer)
+					    const efi_guid_t *info_type,
+					    efi_uintn_t buffer_size,
+					    void *buffer)
 {
-	EFI_ENTRY("%p, %p, %llu, %p", file, info_type, buffer_size, buffer);
+	EFI_ENTRY("%p, %p, %zu, %p", file, info_type, buffer_size, buffer);
+
 	return EFI_EXIT(EFI_UNSUPPORTED);
 }
 
diff --git a/lib/efi_loader/efi_gop.c b/lib/efi_loader/efi_gop.c
index 3caddd5..363ccbb 100644
--- a/lib/efi_loader/efi_gop.c
+++ b/lib/efi_loader/efi_gop.c
@@ -56,27 +56,166 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-efi_status_t EFIAPI gop_blt(struct efi_gop *this, void *buffer,
-			    u32 operation, efi_uintn_t sx,
-			    efi_uintn_t sy, efi_uintn_t dx,
-			    efi_uintn_t dy, efi_uintn_t width,
-			    efi_uintn_t height, efi_uintn_t delta)
+static __always_inline struct efi_gop_pixel efi_vid16_to_blt_col(u16 vid)
+{
+	struct efi_gop_pixel blt = {
+		.reserved = 0,
+	};
+
+	blt.blue  = (vid & 0x1f) << 3;
+	vid >>= 5;
+	blt.green = (vid & 0x3f) << 2;
+	vid >>= 6;
+	blt.red   = (vid & 0x1f) << 3;
+	return blt;
+}
+
+static __always_inline u16 efi_blt_col_to_vid16(struct efi_gop_pixel *blt)
+{
+	return (u16)(blt->red   >> 3) << 11 |
+	       (u16)(blt->green >> 2) <<  5 |
+	       (u16)(blt->blue  >> 3);
+}
+
+static __always_inline efi_status_t gop_blt_int(struct efi_gop *this,
+						struct efi_gop_pixel *bufferp,
+						u32 operation, efi_uintn_t sx,
+						efi_uintn_t sy, efi_uintn_t dx,
+						efi_uintn_t dy,
+						efi_uintn_t width,
+						efi_uintn_t height,
+						efi_uintn_t delta,
+						efi_uintn_t vid_bpp)
 {
 	struct efi_gop_obj *gopobj = container_of(this, struct efi_gop_obj, ops);
-	int i, j, line_len16, line_len32;
-	void *fb;
+	efi_uintn_t i, j, linelen, slineoff = 0, dlineoff, swidth, dwidth;
+	u32 *fb32 = gopobj->fb;
+	u16 *fb16 = gopobj->fb;
+	struct efi_gop_pixel *buffer = __builtin_assume_aligned(bufferp, 4);
 
-	EFI_ENTRY("%p, %p, %u, %zu, %zu, %zu, %zu, %zu, %zu, %zu", this,
-		  buffer, operation, sx, sy, dx, dy, width, height, delta);
+	if (delta) {
+		/* Check for 4 byte alignment */
+		if (delta & 3)
+			return EFI_INVALID_PARAMETER;
+		linelen = delta >> 2;
+	} else {
+		linelen = width;
+	}
 
-	if (operation != EFI_BLT_BUFFER_TO_VIDEO)
-		return EFI_EXIT(EFI_INVALID_PARAMETER);
+	/* Check source rectangle */
+	switch (operation) {
+	case EFI_BLT_VIDEO_FILL:
+		break;
+	case EFI_BLT_BUFFER_TO_VIDEO:
+		if (sx + width > linelen)
+			return EFI_INVALID_PARAMETER;
+		break;
+	case EFI_BLT_VIDEO_TO_BLT_BUFFER:
+	case EFI_BLT_VIDEO_TO_VIDEO:
+		if (sx + width > gopobj->info.width ||
+		    sy + height > gopobj->info.height)
+			return EFI_INVALID_PARAMETER;
+		break;
+	default:
+		return EFI_INVALID_PARAMETER;
+	}
 
-	fb = gopobj->fb;
-	line_len16 = gopobj->info.width * sizeof(u16);
-	line_len32 = gopobj->info.width * sizeof(u32);
+	/* Check destination rectangle */
+	switch (operation) {
+	case EFI_BLT_VIDEO_FILL:
+	case EFI_BLT_BUFFER_TO_VIDEO:
+	case EFI_BLT_VIDEO_TO_VIDEO:
+		if (dx + width > gopobj->info.width ||
+		    dy + height > gopobj->info.height)
+			return EFI_INVALID_PARAMETER;
+		break;
+	case EFI_BLT_VIDEO_TO_BLT_BUFFER:
+		if (dx + width > linelen)
+			return EFI_INVALID_PARAMETER;
+		break;
+	}
 
-	/* Copy the contents line by line */
+	/* Calculate line width */
+	switch (operation) {
+	case EFI_BLT_BUFFER_TO_VIDEO:
+		swidth = linelen;
+		break;
+	case EFI_BLT_VIDEO_TO_BLT_BUFFER:
+	case EFI_BLT_VIDEO_TO_VIDEO:
+		swidth = gopobj->info.width;
+		if (!vid_bpp)
+			return EFI_UNSUPPORTED;
+		break;
+	case EFI_BLT_VIDEO_FILL:
+		swidth = 0;
+		break;
+	}
+
+	switch (operation) {
+	case EFI_BLT_BUFFER_TO_VIDEO:
+	case EFI_BLT_VIDEO_FILL:
+	case EFI_BLT_VIDEO_TO_VIDEO:
+		dwidth = gopobj->info.width;
+		if (!vid_bpp)
+			return EFI_UNSUPPORTED;
+		break;
+	case EFI_BLT_VIDEO_TO_BLT_BUFFER:
+		dwidth = linelen;
+		break;
+	}
+
+	slineoff = swidth * sy;
+	dlineoff = dwidth * dy;
+	for (i = 0; i < height; i++) {
+		for (j = 0; j < width; j++) {
+			struct efi_gop_pixel pix;
+
+			/* Read source pixel */
+			switch (operation) {
+			case EFI_BLT_VIDEO_FILL:
+				pix = *buffer;
+				break;
+			case EFI_BLT_BUFFER_TO_VIDEO:
+				pix = buffer[slineoff + j + sx];
+				break;
+			case EFI_BLT_VIDEO_TO_BLT_BUFFER:
+			case EFI_BLT_VIDEO_TO_VIDEO:
+				if (vid_bpp == 32)
+					pix = *(struct efi_gop_pixel *)&fb32[
+						slineoff + j + sx];
+				else
+					pix = efi_vid16_to_blt_col(fb16[
+						slineoff + j + sx]);
+				break;
+			}
+
+			/* Write destination pixel */
+			switch (operation) {
+			case EFI_BLT_VIDEO_TO_BLT_BUFFER:
+				buffer[dlineoff + j + dx] = pix;
+				break;
+			case EFI_BLT_BUFFER_TO_VIDEO:
+			case EFI_BLT_VIDEO_FILL:
+			case EFI_BLT_VIDEO_TO_VIDEO:
+				if (vid_bpp == 32)
+					fb32[dlineoff + j + dx] = *(u32 *)&pix;
+				else
+					fb16[dlineoff + j + dx] =
+						efi_blt_col_to_vid16(&pix);
+				break;
+			}
+		}
+		slineoff += swidth;
+		dlineoff += dwidth;
+	}
+
+	return EFI_SUCCESS;
+}
+
+static efi_uintn_t gop_get_bpp(struct efi_gop *this)
+{
+	struct efi_gop_obj *gopobj = container_of(this, struct efi_gop_obj, ops);
+	efi_uintn_t vid_bpp = 0;
 
 	switch (gopobj->bpix) {
 #ifdef CONFIG_DM_VIDEO
@@ -84,38 +223,151 @@
 #else
 	case LCD_COLOR32:
 #endif
-		for (i = 0; i < height; i++) {
-			u32 *dest = fb + ((i + dy)  * line_len32) +
-					 (dx * sizeof(u32));
-			u32 *src = buffer + ((i + sy)  * line_len32) +
-					 (sx * sizeof(u32));
-
-			/* Same color format, just memcpy */
-			memcpy(dest, src, width * sizeof(u32));
-		}
+		vid_bpp = 32;
 		break;
 #ifdef CONFIG_DM_VIDEO
 	case VIDEO_BPP16:
 #else
 	case LCD_COLOR16:
 #endif
-		for (i = 0; i < height; i++) {
-			u16 *dest = fb + ((i + dy)  * line_len16) +
-					 (dx * sizeof(u16));
-			u32 *src = buffer + ((i + sy)  * line_len32) +
-					 (sx * sizeof(u32));
-
-			/* Convert from rgb888 to rgb565 */
-			for (j = 0; j < width; j++) {
-				u32 rgb888 = src[j];
-				dest[j] = ((((rgb888 >> (16 + 3)) & 0x1f) << 11) |
-					   (((rgb888 >> (8 + 2)) & 0x3f) << 5) |
-					   (((rgb888 >> (0 + 3)) & 0x1f) << 0));
-			}
-		}
+		vid_bpp = 16;
 		break;
 	}
 
+	return vid_bpp;
+}
+
+/*
+ * Gcc can't optimize our BLT function well, but we need to make sure that
+ * our 2-dimensional loop gets executed very quickly, otherwise the system
+ * will feel slow.
+ *
+ * By manually putting all obvious branch targets into functions which call
+ * our generic blt function with constants, the compiler can successfully
+ * optimize for speed.
+ */
+static efi_status_t gop_blt_video_fill(struct efi_gop *this,
+				       struct efi_gop_pixel *buffer,
+				       u32 foo, efi_uintn_t sx,
+				       efi_uintn_t sy, efi_uintn_t dx,
+				       efi_uintn_t dy, efi_uintn_t width,
+				       efi_uintn_t height, efi_uintn_t delta,
+				       efi_uintn_t vid_bpp)
+{
+	return gop_blt_int(this, buffer, EFI_BLT_VIDEO_FILL, sx, sy, dx,
+			   dy, width, height, delta, vid_bpp);
+}
+
+static efi_status_t gop_blt_buf_to_vid16(struct efi_gop *this,
+					 struct efi_gop_pixel *buffer,
+					 u32 foo, efi_uintn_t sx,
+					 efi_uintn_t sy, efi_uintn_t dx,
+					 efi_uintn_t dy, efi_uintn_t width,
+					 efi_uintn_t height, efi_uintn_t delta)
+{
+	return gop_blt_int(this, buffer, EFI_BLT_BUFFER_TO_VIDEO, sx, sy, dx,
+			   dy, width, height, delta, 16);
+}
+
+static efi_status_t gop_blt_buf_to_vid32(struct efi_gop *this,
+					 struct efi_gop_pixel *buffer,
+					 u32 foo, efi_uintn_t sx,
+					 efi_uintn_t sy, efi_uintn_t dx,
+					 efi_uintn_t dy, efi_uintn_t width,
+					 efi_uintn_t height, efi_uintn_t delta)
+{
+	return gop_blt_int(this, buffer, EFI_BLT_BUFFER_TO_VIDEO, sx, sy, dx,
+			   dy, width, height, delta, 32);
+}
+
+static efi_status_t gop_blt_vid_to_vid(struct efi_gop *this,
+				       struct efi_gop_pixel *buffer,
+				       u32 foo, efi_uintn_t sx,
+				       efi_uintn_t sy, efi_uintn_t dx,
+				       efi_uintn_t dy, efi_uintn_t width,
+				       efi_uintn_t height, efi_uintn_t delta,
+				       efi_uintn_t vid_bpp)
+{
+	return gop_blt_int(this, buffer, EFI_BLT_VIDEO_TO_VIDEO, sx, sy, dx,
+			   dy, width, height, delta, vid_bpp);
+}
+
+static efi_status_t gop_blt_vid_to_buf(struct efi_gop *this,
+				       struct efi_gop_pixel *buffer,
+				       u32 foo, efi_uintn_t sx,
+				       efi_uintn_t sy, efi_uintn_t dx,
+				       efi_uintn_t dy, efi_uintn_t width,
+				       efi_uintn_t height, efi_uintn_t delta,
+				       efi_uintn_t vid_bpp)
+{
+	return gop_blt_int(this, buffer, EFI_BLT_VIDEO_TO_BLT_BUFFER, sx, sy,
+			   dx, dy, width, height, delta, vid_bpp);
+}
+
+/*
+ * Copy rectangle.
+ *
+ * This function implements the Blt service of the EFI_GRAPHICS_OUTPUT_PROTOCOL.
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @this:	EFI_GRAPHICS_OUTPUT_PROTOCOL
+ * @buffer:	pixel buffer
+ * @sx:		source x-coordinate
+ * @sy:		source y-coordinate
+ * @dx:		destination x-coordinate
+ * @dy:		destination y-coordinate
+ * @width:	width of rectangle
+ * @height:	height of rectangle
+ * @delta:	length in bytes of a line in the pixel buffer (optional)
+ * @return:	status code
+ */
+efi_status_t EFIAPI gop_blt(struct efi_gop *this, struct efi_gop_pixel *buffer,
+			    u32 operation, efi_uintn_t sx,
+			    efi_uintn_t sy, efi_uintn_t dx,
+			    efi_uintn_t dy, efi_uintn_t width,
+			    efi_uintn_t height, efi_uintn_t delta)
+{
+	efi_status_t ret = EFI_INVALID_PARAMETER;
+	efi_uintn_t vid_bpp;
+
+	EFI_ENTRY("%p, %p, %u, %zu, %zu, %zu, %zu, %zu, %zu, %zu", this,
+		  buffer, operation, sx, sy, dx, dy, width, height, delta);
+
+	vid_bpp = gop_get_bpp(this);
+
+	/* Allow for compiler optimization */
+	switch (operation) {
+	case EFI_BLT_VIDEO_FILL:
+		ret = gop_blt_video_fill(this, buffer, operation, sx, sy, dx,
+					 dy, width, height, delta, vid_bpp);
+		break;
+	case EFI_BLT_BUFFER_TO_VIDEO:
+		/* This needs to be super-fast, so duplicate for 16/32bpp */
+		if (vid_bpp == 32)
+			ret = gop_blt_buf_to_vid32(this, buffer, operation, sx,
+						   sy, dx, dy, width, height,
+						   delta);
+		else
+			ret = gop_blt_buf_to_vid16(this, buffer, operation, sx,
+						   sy, dx, dy, width, height,
+						   delta);
+		break;
+	case EFI_BLT_VIDEO_TO_VIDEO:
+		ret = gop_blt_vid_to_vid(this, buffer, operation, sx, sy, dx,
+					 dy, width, height, delta, vid_bpp);
+		break;
+	case EFI_BLT_VIDEO_TO_BLT_BUFFER:
+		ret = gop_blt_vid_to_buf(this, buffer, operation, sx, sy, dx,
+					 dy, width, height, delta, vid_bpp);
+		break;
+	default:
+		ret = EFI_UNSUPPORTED;
+	}
+
+	if (ret != EFI_SUCCESS)
+		return EFI_EXIT(ret);
+
 #ifdef CONFIG_DM_VIDEO
 	video_sync_all();
 #else
@@ -125,8 +377,13 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
-/* This gets called from do_bootefi_exec(). */
-int efi_gop_register(void)
+/*
+ * Install graphical output protocol.
+ *
+ * If no supported video device exists this is not considered as an
+ * error.
+ */
+efi_status_t efi_gop_register(void)
 {
 	struct efi_gop_obj *gopobj;
 	u32 bpix, col, row;
@@ -136,12 +393,15 @@
 
 #ifdef CONFIG_DM_VIDEO
 	struct udevice *vdev;
+	struct video_priv *priv;
 
 	/* We only support a single video output device for now */
-	if (uclass_first_device(UCLASS_VIDEO, &vdev) || !vdev)
-		return -1;
+	if (uclass_first_device(UCLASS_VIDEO, &vdev) || !vdev) {
+		debug("WARNING: No video device\n");
+		return EFI_SUCCESS;
+	}
 
-	struct video_priv *priv = dev_get_uclass_priv(vdev);
+	priv = dev_get_uclass_priv(vdev);
 	bpix = priv->bpix;
 	col = video_get_xsize(vdev);
 	row = video_get_ysize(vdev);
@@ -170,13 +430,14 @@
 		break;
 	default:
 		/* So far, we only work in 16 or 32 bit mode */
-		return -1;
+		debug("WARNING: Unsupported video mode\n");
+		return EFI_SUCCESS;
 	}
 
 	gopobj = calloc(1, sizeof(*gopobj));
 	if (!gopobj) {
 		printf("ERROR: Out of memory\n");
-		return 1;
+		return EFI_OUT_OF_RESOURCES;
 	}
 
 	/* Hook up to the device list */
@@ -186,8 +447,8 @@
 	ret = efi_add_protocol(gopobj->parent.handle, &efi_gop_guid,
 			       &gopobj->ops);
 	if (ret != EFI_SUCCESS) {
-		printf("ERROR: Out of memory\n");
-		return 1;
+		printf("ERROR: Failure adding gop protocol\n");
+		return ret;
 	}
 	gopobj->ops.query_mode = gop_query_mode;
 	gopobj->ops.set_mode = gop_set_mode;
@@ -199,10 +460,11 @@
 	gopobj->mode.info_size = sizeof(gopobj->info);
 
 #ifdef CONFIG_DM_VIDEO
-	if (bpix == VIDEO_BPP32) {
+	if (bpix == VIDEO_BPP32)
 #else
-	if (bpix == LCD_COLOR32) {
+	if (bpix == LCD_COLOR32)
 #endif
+	{
 		/* With 32bit color space we can directly expose the fb */
 		gopobj->mode.fb_base = fb_base;
 		gopobj->mode.fb_size = fb_size;
@@ -217,5 +479,5 @@
 	gopobj->bpix = bpix;
 	gopobj->fb = fb;
 
-	return 0;
+	return EFI_SUCCESS;
 }
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index cac64ba..d5fbba3 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -22,6 +22,76 @@
 		EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
 const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
 
+static int machines[] = {
+#if defined(CONFIG_ARM64)
+	IMAGE_FILE_MACHINE_ARM64,
+#elif defined(CONFIG_ARM)
+	IMAGE_FILE_MACHINE_ARM,
+	IMAGE_FILE_MACHINE_THUMB,
+	IMAGE_FILE_MACHINE_ARMNT,
+#endif
+
+#if defined(CONFIG_X86_64)
+	IMAGE_FILE_MACHINE_AMD64,
+#elif defined(CONFIG_X86)
+	IMAGE_FILE_MACHINE_I386,
+#endif
+
+#if defined(CONFIG_CPU_RISCV_32)
+	IMAGE_FILE_MACHINE_RISCV32,
+#endif
+
+#if defined(CONFIG_CPU_RISCV_64)
+	IMAGE_FILE_MACHINE_RISCV64,
+#endif
+	0 };
+
+/*
+ * Print information about a loaded image.
+ *
+ * If the program counter is located within the image the offset to the base
+ * address is shown.
+ *
+ * @image:	loaded image
+ * @pc:		program counter (use NULL to suppress offset output)
+ * @return:	status code
+ */
+efi_status_t efi_print_image_info(struct efi_loaded_image *image, void *pc)
+{
+	if (!image)
+		return EFI_INVALID_PARAMETER;
+	printf("UEFI image");
+	printf(" [0x%p:0x%p]",
+	       image->reloc_base, image->reloc_base + image->reloc_size - 1);
+	if (pc && pc >= image->reloc_base &&
+	    pc < image->reloc_base + image->reloc_size)
+		printf(" pc=0x%zx", pc - image->reloc_base);
+	if (image->file_path)
+		printf(" '%pD'", image->file_path);
+	printf("\n");
+	return EFI_SUCCESS;
+}
+
+/*
+ * Print information about all loaded images.
+ *
+ * @pc:		program counter (use NULL to suppress offset output)
+ */
+void efi_print_image_infos(void *pc)
+{
+	struct efi_object *efiobj;
+	struct efi_handler *handler;
+
+	list_for_each_entry(efiobj, &efi_obj_list, link) {
+		list_for_each_entry(handler, &efiobj->protocols, link) {
+			if (!guidcmp(handler->guid, &efi_guid_loaded_image)) {
+				efi_print_image_info(
+					handler->protocol_interface, pc);
+			}
+		}
+	}
+}
+
 static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
 			unsigned long rel_size, void *efi_reloc)
 {
@@ -126,14 +196,7 @@
 	void *entry;
 	uint64_t image_size;
 	unsigned long virt_size = 0;
-	bool can_run_nt64 = true;
-	bool can_run_nt32 = true;
-
-#if defined(CONFIG_ARM64)
-	can_run_nt32 = false;
-#elif defined(CONFIG_ARM)
-	can_run_nt64 = false;
-#endif
+	int supported = 0;
 
 	dos = efi;
 	if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
@@ -147,6 +210,18 @@
 		return NULL;
 	}
 
+	for (i = 0; machines[i]; i++)
+		if (machines[i] == nt->FileHeader.Machine) {
+			supported = 1;
+			break;
+		}
+
+	if (!supported) {
+		printf("%s: Machine type 0x%04x is not supported\n",
+		       __func__, nt->FileHeader.Machine);
+		return NULL;
+	}
+
 	/* Calculate upper virtual address boundary */
 	num_sections = nt->FileHeader.NumberOfSections;
 	sections = (void *)&nt->OptionalHeader +
@@ -159,8 +234,7 @@
 	}
 
 	/* Read 32/64bit specific header bits */
-	if (can_run_nt64 &&
-	    (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)) {
+	if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
 		IMAGE_NT_HEADERS64 *nt64 = (void *)nt;
 		IMAGE_OPTIONAL_HEADER64 *opt = &nt64->OptionalHeader;
 		image_size = opt->SizeOfImage;
@@ -175,8 +249,8 @@
 		entry = efi_reloc + opt->AddressOfEntryPoint;
 		rel_size = opt->DataDirectory[rel_idx].Size;
 		rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
-	} else if (can_run_nt32 &&
-		   (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)) {
+		virt_size = ALIGN(virt_size, opt->SectionAlignment);
+	} else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
 		IMAGE_OPTIONAL_HEADER32 *opt = &nt->OptionalHeader;
 		image_size = opt->SizeOfImage;
 		efi_set_code_and_data_type(loaded_image_info, opt->Subsystem);
@@ -190,6 +264,7 @@
 		entry = efi_reloc + opt->AddressOfEntryPoint;
 		rel_size = opt->DataDirectory[rel_idx].Size;
 		rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
+		virt_size = ALIGN(virt_size, opt->SectionAlignment);
 	} else {
 		printf("%s: Invalid optional header magic %x\n", __func__,
 		       nt->OptionalHeader.Magic);
@@ -221,6 +296,8 @@
 	/* Populate the loaded image interface bits */
 	loaded_image_info->image_base = efi;
 	loaded_image_info->image_size = image_size;
+	loaded_image_info->reloc_base = efi_reloc;
+	loaded_image_info->reloc_size = virt_size;
 
 	return entry;
 }
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index ff0edf3..95f9ff0 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -8,12 +8,11 @@
 
 #include <common.h>
 #include <efi_loader.h>
-#include <malloc.h>
-#include <asm/global_data.h>
-#include <linux/libfdt_env.h>
-#include <linux/list_sort.h>
 #include <inttypes.h>
+#include <malloc.h>
 #include <watchdog.h>
+#include <asm/global_data.h>
+#include <linux/list_sort.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -292,7 +291,7 @@
 	uint64_t addr;
 
 	switch (type) {
-	case 0:
+	case EFI_ALLOCATE_ANY_PAGES:
 		/* Any page */
 		addr = efi_find_free_memory(len, gd->start_addr_sp);
 		if (!addr) {
@@ -300,7 +299,7 @@
 			break;
 		}
 		break;
-	case 1:
+	case EFI_ALLOCATE_MAX_ADDRESS:
 		/* Max address */
 		addr = efi_find_free_memory(len, *memory);
 		if (!addr) {
@@ -308,7 +307,7 @@
 			break;
 		}
 		break;
-	case 2:
+	case EFI_ALLOCATE_ADDRESS:
 		/* Exact address, reserve it. The addr is already in *memory. */
 		addr = *memory;
 		break;
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 8c5d5b4..9afe76c 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -54,14 +54,46 @@
 	return EFI_EXIT(EFI_SUCCESS);
 }
 
+/*
+ * Initialize network adapter and allocate transmit and receive buffers.
+ *
+ * This function implements the Initialize service of the
+ * EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
+ * (UEFI) specification for details.
+ *
+ * @this:	pointer to the protocol instance
+ * @extra_rx:	extra receive buffer to be allocated
+ * @extra_tx:	extra transmit buffer to be allocated
+ * @return:	status code
+ */
 static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
 					      ulong extra_rx, ulong extra_tx)
 {
+	int ret;
+	efi_status_t r = EFI_SUCCESS;
+
 	EFI_ENTRY("%p, %lx, %lx", this, extra_rx, extra_tx);
 
-	eth_init();
+	if (!this) {
+		r = EFI_INVALID_PARAMETER;
+		goto error;
+	}
 
-	return EFI_EXIT(EFI_SUCCESS);
+	/* Setup packet buffers */
+	net_init();
+	/* Disable hardware and put it into the reset state */
+	eth_halt();
+	/* Set current device according to environment variables */
+	eth_set_current();
+	/* Get hardware ready for send and receive operations */
+	ret = eth_init();
+	if (ret < 0) {
+		eth_halt();
+		r = EFI_DEVICE_ERROR;
+	}
+
+error:
+	return EFI_EXIT(r);
 }
 
 static efi_status_t EFIAPI efi_net_reset(struct efi_simple_network *this,
@@ -280,20 +312,22 @@
 }
 
 /* This gets called from do_bootefi_exec(). */
-int efi_net_register(void)
+efi_status_t efi_net_register(void)
 {
 	struct efi_net_obj *netobj;
 	efi_status_t r;
 
 	if (!eth_get_dev()) {
 		/* No eth device active, don't expose any */
-		return 0;
+		return EFI_SUCCESS;
 	}
 
 	/* We only expose the "active" eth device, so one is enough */
 	netobj = calloc(1, sizeof(*netobj));
-	if (!netobj)
-		goto out_of_memory;
+	if (!netobj) {
+		printf("ERROR: Out of memory\n");
+		return EFI_OUT_OF_RESOURCES;
+	}
 
 	/* Hook net up to the device list */
 	efi_add_handle(&netobj->parent);
@@ -302,15 +336,15 @@
 	r = efi_add_protocol(netobj->parent.handle, &efi_net_guid,
 			     &netobj->net);
 	if (r != EFI_SUCCESS)
-		goto out_of_memory;
+		goto failure_to_add_protocol;
 	r = efi_add_protocol(netobj->parent.handle, &efi_guid_device_path,
 			     efi_dp_from_eth());
 	if (r != EFI_SUCCESS)
-		goto out_of_memory;
+		goto failure_to_add_protocol;
 	r = efi_add_protocol(netobj->parent.handle, &efi_pxe_guid,
 			     &netobj->pxe);
 	if (r != EFI_SUCCESS)
-		goto out_of_memory;
+		goto failure_to_add_protocol;
 	netobj->net.revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
 	netobj->net.start = efi_net_start;
 	netobj->net.stop = efi_net_stop;
@@ -339,7 +373,7 @@
 	 * Create WaitForPacket event.
 	 */
 	r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK,
-			     efi_network_timer_notify, NULL,
+			     efi_network_timer_notify, NULL, NULL,
 			     &wait_for_packet);
 	if (r != EFI_SUCCESS) {
 		printf("ERROR: Failed to register network event\n");
@@ -351,9 +385,11 @@
 	 *
 	 * The notification function is used to check if a new network packet
 	 * has been received.
+	 *
+	 * iPXE is running at TPL_CALLBACK most of the time. Use a higher TPL.
 	 */
-	r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
-			     efi_network_timer_notify, NULL,
+	r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY,
+			     efi_network_timer_notify, NULL, NULL,
 			     &network_timer_event);
 	if (r != EFI_SUCCESS) {
 		printf("ERROR: Failed to register network event\n");
@@ -366,8 +402,8 @@
 		return r;
 	}
 
-	return 0;
-out_of_memory:
-	printf("ERROR: Out of memory\n");
-	return 1;
+	return EFI_SUCCESS;
+failure_to_add_protocol:
+	printf("ERROR: Failure to add protocol\n");
+	return r;
 }
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index ccb4fc6..8558124 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -74,12 +74,24 @@
 			efi_status_t reset_status,
 			unsigned long data_size, void *reset_data)
 {
+	struct efi_event *evt;
+
 	EFI_ENTRY("%d %lx %lx %p", reset_type, reset_status, data_size,
 		  reset_data);
 
+	/* Notify reset */
+	list_for_each_entry(evt, &efi_events, link) {
+		if (evt->group &&
+		    !guidcmp(evt->group,
+			     &efi_guid_event_group_reset_system)) {
+			efi_signal_event(evt, false);
+			break;
+		}
+	}
 	switch (reset_type) {
 	case EFI_RESET_COLD:
 	case EFI_RESET_WARM:
+	case EFI_RESET_PLATFORM_SPECIFIC:
 		do_reset(NULL, 0, 0, NULL);
 		break;
 	case EFI_RESET_SHUTDOWN:
@@ -134,8 +146,9 @@
 	while (1) { }
 }
 
-void __weak efi_reset_system_init(void)
+efi_status_t __weak efi_reset_system_init(void)
 {
+	return EFI_SUCCESS;
 }
 
 efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
@@ -146,8 +159,9 @@
 	return EFI_DEVICE_ERROR;
 }
 
-void __weak efi_get_time_init(void)
+efi_status_t __weak efi_get_time_init(void)
 {
+	return EFI_SUCCESS;
 }
 
 struct efi_runtime_detach_list_struct {
@@ -332,18 +346,26 @@
 	return EFI_EXIT(EFI_INVALID_PARAMETER);
 }
 
-void efi_add_runtime_mmio(void *mmio_ptr, u64 len)
+efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len)
 {
 	struct efi_runtime_mmio_list *newmmio;
-
 	u64 pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
-	efi_add_memory_map(*(uintptr_t *)mmio_ptr, pages, EFI_MMAP_IO, false);
+	uint64_t addr = *(uintptr_t *)mmio_ptr;
+	uint64_t retaddr;
+
+	retaddr = efi_add_memory_map(addr, pages, EFI_MMAP_IO, false);
+	if (retaddr != addr)
+		return EFI_OUT_OF_RESOURCES;
 
 	newmmio = calloc(1, sizeof(*newmmio));
+	if (!newmmio)
+		return EFI_OUT_OF_RESOURCES;
 	newmmio->ptr = mmio_ptr;
 	newmmio->paddr = *(uintptr_t *)mmio_ptr;
 	newmmio->len = len;
 	list_add_tail(&newmmio->link, &efi_runtime_mmio);
+
+	return EFI_SUCCESS;
 }
 
 /*
diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c
index ac412e7..62e9697 100644
--- a/lib/efi_loader/efi_smbios.c
+++ b/lib/efi_loader/efi_smbios.c
@@ -13,20 +13,27 @@
 
 static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
 
-void efi_smbios_register(void)
+/*
+ * Install the SMBIOS table as a configuration table.
+ *
+ * @return	status code
+ */
+efi_status_t efi_smbios_register(void)
 {
 	/* Map within the low 32 bits, to allow for 32bit SMBIOS tables */
-	uint64_t dmi = 0xffffffff;
-	/* Reserve 4kb for SMBIOS */
-	uint64_t pages = 1;
-	int memtype = EFI_RUNTIME_SERVICES_DATA;
+	u64 dmi = U32_MAX;
+	efi_status_t ret;
 
-	if (efi_allocate_pages(1, memtype, pages, &dmi) != EFI_SUCCESS)
-		return;
+	/* Reserve 4kiB page for SMBIOS */
+	ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+				 EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
+	if (ret != EFI_SUCCESS)
+		return ret;
 
 	/* Generate SMBIOS tables */
 	write_smbios_table(dmi);
 
 	/* And expose them to our EFI payload */
-	efi_install_configuration_table(&smbios_guid, (void*)(uintptr_t)dmi);
+	return efi_install_configuration_table(&smbios_guid,
+					       (void *)(uintptr_t)dmi);
 }
diff --git a/lib/efi_loader/efi_watchdog.c b/lib/efi_loader/efi_watchdog.c
index 35a45de..d12e51d 100644
--- a/lib/efi_loader/efi_watchdog.c
+++ b/lib/efi_loader/efi_watchdog.c
@@ -59,7 +59,7 @@
  *
  * This function is called by efi_init_obj_list()
  */
-int efi_watchdog_register(void)
+efi_status_t efi_watchdog_register(void)
 {
 	efi_status_t r;
 
@@ -67,7 +67,7 @@
 	 * Create a timer event.
 	 */
 	r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
-			     efi_watchdog_timer_notify, NULL,
+			     efi_watchdog_timer_notify, NULL, NULL,
 			     &watchdog_timer_event);
 	if (r != EFI_SUCCESS) {
 		printf("ERROR: Failed to register watchdog event\n");
@@ -85,5 +85,5 @@
 		printf("ERROR: Failed to set watchdog timer\n");
 		return r;
 	}
-	return 0;
+	return EFI_SUCCESS;
 }
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index 1ec0179..6c539ba 100644
--- a/lib/efi_loader/helloworld.c
+++ b/lib/efi_loader/helloworld.c
@@ -46,9 +46,27 @@
 	struct efi_loaded_image *loaded_image;
 	efi_status_t ret;
 	efi_uintn_t i;
+	u16 rev[] = L"0.0.0";
 
 	con_out->output_string(con_out, L"Hello, world!\n");
 
+	/* Print the revision number */
+	rev[0] = (systable->hdr.revision >> 16) + '0';
+	rev[4] = systable->hdr.revision & 0xffff;
+	for (; rev[4] >= 10;) {
+		rev[4] -= 10;
+		++rev[2];
+	}
+	/* Third digit is only to be shown if non-zero */
+	if (rev[4])
+		rev[4] += '0';
+	else
+		rev[3] = 0;
+
+	con_out->output_string(con_out, L"Running on UEFI ");
+	con_out->output_string(con_out, rev);
+	con_out->output_string(con_out, L"\n");
+
 	/* Get the loaded image protocol */
 	ret = boottime->handle_protocol(handle, &loaded_image_guid,
 					(void **)&loaded_image);
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index c4bdbdf..31b444f 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -14,14 +14,18 @@
 
 obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
 efi_selftest.o \
+efi_selftest_bitblt.o \
 efi_selftest_controllers.o \
 efi_selftest_console.o \
 efi_selftest_devicepath.o \
 efi_selftest_events.o \
+efi_selftest_event_groups.o \
 efi_selftest_exitbootservices.o \
+efi_selftest_fdt.o \
 efi_selftest_gop.o \
 efi_selftest_manageprotocols.o \
 efi_selftest_snp.o \
+efi_selftest_textinput.o \
 efi_selftest_textoutput.o \
 efi_selftest_tpl.o \
 efi_selftest_util.o \
diff --git a/lib/efi_selftest/efi_selftest_bitblt.c b/lib/efi_selftest/efi_selftest_bitblt.c
new file mode 100644
index 0000000..0fb76cc7
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_bitblt.c
@@ -0,0 +1,311 @@
+/*
+ * efi_selftest_bitblt
+ *
+ * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * Test the block image transfer in the graphical output protocol.
+ * An animated submarine is shown.
+ */
+
+#include <efi_selftest.h>
+
+#define WIDTH	200
+#define HEIGHT	120
+#define DEPTH	 60
+
+static const struct efi_gop_pixel BLACK =	{  0,   0,   0, 0};
+static const struct efi_gop_pixel RED =		{  0,   0, 255, 0};
+static const struct efi_gop_pixel ORANGE =	{  0, 128, 255, 0};
+static const struct efi_gop_pixel YELLOW =	{  0, 255, 255, 0};
+static const struct efi_gop_pixel GREEN =	{  0, 255,   0, 0};
+static const struct efi_gop_pixel DARK_BLUE =	{128,   0,   0, 0};
+static const struct efi_gop_pixel LIGHT_BLUE =	{255, 192, 192, 0};
+
+static struct efi_boot_services *boottime;
+static efi_guid_t efi_gop_guid = EFI_GOP_GUID;
+static struct efi_gop *gop;
+static struct efi_gop_pixel *bitmap;
+static struct efi_event *event;
+static efi_uintn_t xpos;
+
+static void ellipse(efi_uintn_t x, efi_uintn_t y,
+		    efi_uintn_t x0, efi_uintn_t y0,
+		    efi_uintn_t x1, efi_uintn_t y1,
+		    const struct efi_gop_pixel col, struct efi_gop_pixel *pix)
+{
+	efi_uintn_t xm = x0 + x1;
+	efi_uintn_t ym = y0 + y1;
+	efi_uintn_t dx = x1 - x0 + 1;
+	efi_uintn_t dy = y1 - y0 + 1;
+
+	if (dy * dy * (2 * x - xm) * (2 * x - xm) +
+	    dx * dx * (2 * y - ym) * (2 * y - ym) <= dx * dx * dy * dy)
+		*pix = col;
+}
+
+static void rectangle(efi_uintn_t x, efi_uintn_t y,
+		      efi_uintn_t x0, efi_uintn_t y0,
+		      efi_uintn_t x1, efi_uintn_t y1,
+		      const struct efi_gop_pixel col, struct efi_gop_pixel *pix)
+{
+	if (x >= x0 && y >= y0 && x <= x1 && y <= y1)
+		*pix = col;
+}
+
+/*
+ * Notification function, copies image to video.
+ * The position is incremented in each call.
+ *
+ * @event	notified event
+ * @context	pointer to the notification count
+ */
+static void EFIAPI notify(struct efi_event *event, void *context)
+{
+	efi_uintn_t *pos = context;
+	efi_uintn_t dx, sx, width;
+
+	if (!pos)
+		return;
+
+	/* Increment position */
+	*pos += 5;
+	if (*pos >= WIDTH + gop->mode->info->width)
+		*pos = 0;
+
+	width = WIDTH;
+	dx = *pos - WIDTH;
+	sx = 0;
+	if (*pos >= gop->mode->info->width) {
+		width = WIDTH +  gop->mode->info->width - *pos;
+	} else if (*pos < WIDTH) {
+		dx = 0;
+		sx = WIDTH - *pos;
+		width = *pos;
+	}
+
+	/* Copy image to video */
+	gop->blt(gop, bitmap, EFI_BLT_BUFFER_TO_VIDEO, sx, 0, dx, DEPTH,
+		 width, HEIGHT, WIDTH * sizeof(struct efi_gop_pixel));
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+		 const struct efi_system_table *systable)
+{
+	efi_status_t ret;
+	struct efi_gop_pixel pix;
+	efi_uintn_t x, y;
+
+	boottime = systable->boottime;
+
+	/* Create event */
+	ret = boottime->create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL,
+				     TPL_CALLBACK, notify, (void *)&xpos,
+				     &event);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("could not create event\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Get graphical output protocol */
+	ret = boottime->locate_protocol(&efi_gop_guid, NULL, (void **)&gop);
+	if (ret != EFI_SUCCESS) {
+		gop = NULL;
+		efi_st_printf("Graphical output protocol is not available.\n");
+		return EFI_ST_SUCCESS;
+	}
+
+	/* Prepare image of submarine */
+	ret = boottime->allocate_pool(EFI_LOADER_DATA,
+				      sizeof(struct efi_gop_pixel) *
+				      WIDTH * HEIGHT, (void **)&bitmap);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Out of memory\n");
+		return EFI_ST_FAILURE;
+	}
+	for (y = 0; y < HEIGHT; ++y) {
+		for (x = 0; x < WIDTH; ++x) {
+			pix = DARK_BLUE;
+
+			/* Propeller */
+			ellipse(x, y, 35, 55, 43, 75, BLACK, &pix);
+			ellipse(x, y, 36, 56, 42, 74, LIGHT_BLUE, &pix);
+
+			ellipse(x, y, 35, 75, 43, 95, BLACK, &pix);
+			ellipse(x, y, 36, 76, 42, 94, LIGHT_BLUE, &pix);
+
+			/* Shaft */
+			rectangle(x, y, 35, 73, 100, 77, BLACK, &pix);
+
+			/* Periscope */
+			ellipse(x, y, 120, 10, 160, 50, BLACK, &pix);
+			ellipse(x, y, 121, 11, 159, 59, YELLOW, &pix);
+			ellipse(x, y, 130, 20, 150, 40, BLACK, &pix);
+			ellipse(x, y, 131, 21, 149, 49, DARK_BLUE, &pix);
+			rectangle(x, y, 135, 10, 160, 50, DARK_BLUE, &pix);
+			ellipse(x, y, 132, 10, 138, 20, BLACK, &pix);
+			ellipse(x, y, 133, 11, 139, 19, RED, &pix);
+
+			/* Rudder */
+			ellipse(x, y, 45, 40, 75, 70, BLACK, &pix);
+			ellipse(x, y, 46, 41, 74, 69, ORANGE, &pix);
+			ellipse(x, y, 45, 80, 75, 109, BLACK, &pix);
+			ellipse(x, y, 46, 81, 74, 108, RED, &pix);
+
+			/* Bridge */
+			ellipse(x, y, 100, 30, 120, 50, BLACK, &pix);
+			ellipse(x, y, 101, 31, 119, 49, GREEN, &pix);
+			ellipse(x, y, 140, 30, 160, 50, BLACK, &pix);
+			ellipse(x, y, 141, 31, 159, 49, GREEN, &pix);
+			rectangle(x, y, 110, 30, 150, 50, BLACK, &pix);
+			rectangle(x, y, 110, 31, 150, 50, GREEN, &pix);
+
+			/* Hull */
+			ellipse(x, y, 50, 40, 199, 109, BLACK, &pix);
+			ellipse(x, y, 51, 41, 198, 108, LIGHT_BLUE, &pix);
+
+			/* Port holes */
+			ellipse(x, y, 79, 57, 109, 82, BLACK, &pix);
+			ellipse(x, y, 80, 58, 108, 81, LIGHT_BLUE, &pix);
+			ellipse(x, y, 83, 61, 105, 78, BLACK, &pix);
+			ellipse(x, y, 84, 62, 104, 77, YELLOW, &pix);
+			/*
+			 * This port hole is created by copying
+			 * ellipse(x, y, 119, 57, 149, 82, BLACK, &pix);
+			 * ellipse(x, y, 120, 58, 148, 81, LIGHT_BLUE, &pix);
+			 * ellipse(x, y, 123, 61, 145, 78, BLACK, &pix);
+			 * ellipse(x, y, 124, 62, 144, 77, YELLOW, &pix);
+			 */
+			ellipse(x, y, 159, 57, 189, 82, BLACK, &pix);
+			ellipse(x, y, 160, 58, 188, 81, LIGHT_BLUE, &pix);
+			ellipse(x, y, 163, 61, 185, 78, BLACK, &pix);
+			ellipse(x, y, 164, 62, 184, 77, YELLOW, &pix);
+
+			bitmap[WIDTH * y + x] = pix;
+		}
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Tear down unit test.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int teardown(void)
+{
+	efi_status_t ret;
+
+	if (bitmap) {
+		ret = boottime->free_pool(bitmap);
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("FreePool failed\n");
+			return EFI_ST_FAILURE;
+		}
+	}
+	if (event) {
+		ret = boottime->close_event(event);
+		event = NULL;
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("could not close event\n");
+			return EFI_ST_FAILURE;
+		}
+	}
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	u32 max_mode;
+	efi_status_t ret;
+	struct efi_gop_mode_info *info;
+
+	if (!gop)
+		return EFI_ST_SUCCESS;
+
+	if (!gop->mode) {
+		efi_st_error("EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE missing\n");
+		return EFI_ST_FAILURE;
+	}
+	info = gop->mode->info;
+	max_mode = gop->mode->max_mode;
+	if (!max_mode) {
+		efi_st_error("No graphical mode available\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Fill background */
+	ret = gop->blt(gop, bitmap, EFI_BLT_VIDEO_FILL, 0, 0, 0, 0,
+		       info->width, info->height, 0);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("EFI_BLT_VIDEO_FILL failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Copy image to video */
+	ret = gop->blt(gop, bitmap, EFI_BLT_BUFFER_TO_VIDEO, 0, 0, 0, DEPTH,
+		       WIDTH, HEIGHT, 0);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("EFI_BLT_BUFFER_TO_VIDEO failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Copy left port hole */
+	ret = gop->blt(gop, bitmap, EFI_BLT_VIDEO_TO_VIDEO,
+		       79, 57 + DEPTH, 119, 57 + DEPTH,
+		       31, 26, 0);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("EFI_BLT_VIDEO_TO_VIDEO failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Copy port holes back to buffer */
+	ret = gop->blt(gop, bitmap, EFI_BLT_VIDEO_TO_BLT_BUFFER,
+		       94, 57 + DEPTH, 94, 57,
+		       90, 26, WIDTH * sizeof(struct efi_gop_pixel));
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("EFI_BLT_VIDEO_TO_BLT_BUFFER failed\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/* Set 250ms timer */
+	xpos = WIDTH;
+	ret = boottime->set_timer(event, EFI_TIMER_PERIODIC, 250000);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Could not set timer\n");
+		return EFI_ST_FAILURE;
+	}
+
+	con_out->set_cursor_position(con_out, 0, 0);
+	con_out->set_attribute(con_out, EFI_WHITE | EFI_BACKGROUND_BLUE);
+	efi_st_printf("The submarine should have three yellow port holes.\n");
+	efi_st_printf("Press any key to continue");
+	efi_st_get_key();
+	con_out->set_attribute(con_out, EFI_LIGHTGRAY);
+	efi_st_printf("\n");
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(bitblt) = {
+	.name = "block image transfer",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+	.teardown = teardown,
+	.on_request = true,
+};
diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c
index 9e4b93d..a8979ed 100644
--- a/lib/efi_selftest/efi_selftest_block_device.c
+++ b/lib/efi_selftest/efi_selftest_block_device.c
@@ -29,6 +29,7 @@
 static const efi_guid_t guid_device_path = DEVICE_PATH_GUID;
 static const efi_guid_t guid_simple_file_system_protocol =
 					EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
+static const efi_guid_t guid_file_system_info = EFI_FILE_SYSTEM_INFO_GUID;
 static efi_guid_t guid_vendor =
 	EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d,
 		 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xb7, 0xb8);
@@ -302,7 +303,11 @@
 	struct efi_device_path *dp_partition;
 	struct efi_simple_file_system_protocol *file_system;
 	struct efi_file_handle *root, *file;
-	u64 buf_size;
+	struct {
+		struct efi_file_system_info info;
+		u16 label[12];
+	} system_info;
+	efi_uintn_t buf_size;
 	char buf[16] __aligned(ARCH_DMA_MINALIGN);
 
 	ret = boottime->connect_controller(disk_handle, NULL, NULL, 1);
@@ -356,6 +361,23 @@
 		efi_st_error("Failed to open volume\n");
 		return EFI_ST_FAILURE;
 	}
+	buf_size = sizeof(system_info);
+	ret = root->getinfo(root, &guid_file_system_info, &buf_size,
+			    &system_info);
+	if (ret != EFI_SUCCESS) {
+		efi_st_error("Failed to get file system info\n");
+		return EFI_ST_FAILURE;
+	}
+	if (system_info.info.block_size != 512) {
+		efi_st_error("Wrong block size %u, expected 512\n",
+			     system_info.info.block_size);
+		return EFI_ST_FAILURE;
+	}
+	if (efi_st_strcmp_16_8(system_info.info.volume_label, "U-BOOT TEST")) {
+		efi_st_todo(
+			"Wrong volume label '%ps', expected 'U-BOOT TEST'\n",
+			system_info.info.volume_label);
+	}
 	ret = root->open(root, &file, (s16 *)L"hello.txt", EFI_FILE_MODE_READ,
 			 0);
 	if (ret != EFI_SUCCESS) {
diff --git a/lib/efi_selftest/efi_selftest_disk_image.h b/lib/efi_selftest/efi_selftest_disk_image.h
index 4775dac..9c741ce 100644
--- a/lib/efi_selftest/efi_selftest_disk_image.h
+++ b/lib/efi_selftest/efi_selftest_disk_image.h
@@ -3,21 +3,21 @@
  *
  *  Generated with tools/file2include
  *
- *  SPDX-License-Identifier:     GPL-2.0+
+ *  SPDX-License-Identifier:	GPL-2.0+
  */
 
 #define EFI_ST_DISK_IMG { 0x00010000, { \
-	{0x000001b8, "\x94\x37\x69\xfc\x00\x00\x00\x00"}, /* .7i..... */ \
-	{0x000001c0, "\x02\x00\x83\x02\x02\x00\x01\x00"}, /* ........ */ \
+	{0x000001b8, "\x21\x5d\x53\xd1\x00\x00\x00\x00"}, /* !]S..... */ \
+	{0x000001c0, "\x02\x00\x01\x02\x02\x00\x01\x00"}, /* ........ */ \
 	{0x000001c8, "\x00\x00\x7f\x00\x00\x00\x00\x00"}, /* ........ */ \
 	{0x000001f8, "\x00\x00\x00\x00\x00\x00\x55\xaa"}, /* ......U. */ \
 	{0x00000200, "\xeb\x3c\x90\x6d\x6b\x66\x73\x2e"}, /* .<.mkfs. */ \
 	{0x00000208, "\x66\x61\x74\x00\x02\x04\x01\x00"}, /* fat..... */ \
 	{0x00000210, "\x02\x00\x02\x7f\x00\xf8\x01\x00"}, /* ........ */ \
 	{0x00000218, "\x20\x00\x40\x00\x00\x00\x00\x00"}, /*  .@..... */ \
-	{0x00000220, "\x00\x00\x00\x00\x80\x00\x29\x86"}, /* ......). */ \
-	{0x00000228, "\xe8\x82\x80\x4e\x4f\x20\x4e\x41"}, /* ...NO NA */ \
-	{0x00000230, "\x4d\x45\x20\x20\x20\x20\x46\x41"}, /* ME    FA */ \
+	{0x00000220, "\x00\x00\x00\x00\x80\x00\x29\xc4"}, /* ......). */ \
+	{0x00000228, "\xc4\x88\x11\x55\x2d\x42\x4f\x4f"}, /* ...U-BOO */ \
+	{0x00000230, "\x54\x20\x54\x45\x53\x54\x46\x41"}, /* T TESTFA */ \
 	{0x00000238, "\x54\x31\x32\x20\x20\x20\x0e\x1f"}, /* T12   .. */ \
 	{0x00000240, "\xbe\x5b\x7c\xac\x22\xc0\x74\x0b"}, /* .[|.".t. */ \
 	{0x00000248, "\x56\xb4\x0e\xbb\x07\x00\xcd\x10"}, /* V....... */ \
@@ -36,34 +36,20 @@
 	{0x000002b0, "\x72\x79\x20\x61\x67\x61\x69\x6e"}, /* ry again */ \
 	{0x000002b8, "\x20\x2e\x2e\x2e\x20\x0d\x0a\x00"}, /*  ... ... */ \
 	{0x000003f8, "\x00\x00\x00\x00\x00\x00\x55\xaa"}, /* ......U. */ \
-	{0x00000400, "\xf8\xff\xff\x00\x00\x00\x00\xf0"}, /* ........ */ \
-	{0x00000408, "\xff\x00\x00\x00\x00\x00\x00\x00"}, /* ........ */ \
-	{0x00000600, "\xf8\xff\xff\x00\x00\x00\x00\xf0"}, /* ........ */ \
-	{0x00000608, "\xff\x00\x00\x00\x00\x00\x00\x00"}, /* ........ */ \
-	{0x00000800, "\xe5\x70\x00\x00\x00\xff\xff\xff"}, /* .p...... */ \
-	{0x00000808, "\xff\xff\xff\x0f\x00\x0e\xff\xff"}, /* ........ */ \
-	{0x00000810, "\xff\xff\xff\xff\xff\xff\xff\xff"}, /* ........ */ \
-	{0x00000818, "\xff\xff\x00\x00\xff\xff\xff\xff"}, /* ........ */ \
-	{0x00000820, "\xe5\x2e\x00\x68\x00\x65\x00\x6c"}, /* ...h.e.l */ \
-	{0x00000828, "\x00\x6c\x00\x0f\x00\x0e\x6f\x00"}, /* .l....o. */ \
-	{0x00000830, "\x2e\x00\x74\x00\x78\x00\x74\x00"}, /* ..t.x.t. */ \
-	{0x00000838, "\x2e\x00\x00\x00\x73\x00\x77\x00"}, /* ....s.w. */ \
-	{0x00000840, "\xe5\x45\x4c\x4c\x4f\x54\x7e\x31"}, /* .ELLOT~1 */ \
-	{0x00000848, "\x53\x57\x50\x20\x00\x64\xd0\x8a"}, /* SWP .d.. */ \
-	{0x00000850, "\x92\x4b\x92\x4b\x00\x00\xd0\x8a"}, /* .K.K.... */ \
-	{0x00000858, "\x92\x4b\x00\x00\x00\x00\x00\x00"}, /* .K...... */ \
-	{0x00000860, "\x41\x68\x00\x65\x00\x6c\x00\x6c"}, /* Ah.e.l.l */ \
-	{0x00000868, "\x00\x6f\x00\x0f\x00\xf1\x2e\x00"}, /* .o...... */ \
-	{0x00000870, "\x74\x00\x78\x00\x74\x00\x00\x00"}, /* t.x.t... */ \
-	{0x00000878, "\xff\xff\x00\x00\xff\xff\xff\xff"}, /* ........ */ \
-	{0x00000880, "\x48\x45\x4c\x4c\x4f\x20\x20\x20"}, /* HELLO    */ \
-	{0x00000888, "\x54\x58\x54\x20\x00\x64\xd4\x8a"}, /* TXT .d.. */ \
-	{0x00000890, "\x92\x4b\x92\x4b\x00\x00\xd4\x8a"}, /* .K.K.... */ \
-	{0x00000898, "\x92\x4b\x05\x00\x0d\x00\x00\x00"}, /* .K...... */ \
-	{0x000008a0, "\xe5\x45\x4c\x4c\x4f\x54\x7e\x31"}, /* .ELLOT~1 */ \
-	{0x000008a8, "\x53\x57\x58\x20\x00\x64\xd0\x8a"}, /* SWX .d.. */ \
-	{0x000008b0, "\x92\x4b\x92\x4b\x00\x00\xd0\x8a"}, /* .K.K.... */ \
-	{0x000008b8, "\x92\x4b\x00\x00\x00\x00\x00\x00"}, /* .K...... */ \
-	{0x00006000, "\x48\x65\x6c\x6c\x6f\x20\x77\x6f"}, /* Hello wo */ \
-	{0x00006008, "\x72\x6c\x64\x21\x0a\x00\x00\x00"}, /* rld!.... */ \
+	{0x00000400, "\xf8\xff\xff\x00\xf0\xff\x00\x00"}, /* ........ */ \
+	{0x00000600, "\xf8\xff\xff\x00\xf0\xff\x00\x00"}, /* ........ */ \
+	{0x00000800, "\x55\x2d\x42\x4f\x4f\x54\x20\x54"}, /* U-BOOT T */ \
+	{0x00000808, "\x45\x53\x54\x08\x00\x00\xaa\x56"}, /* EST....V */ \
+	{0x00000810, "\x84\x4c\x84\x4c\x00\x00\xaa\x56"}, /* .L.L...V */ \
+	{0x00000818, "\x84\x4c\x00\x00\x00\x00\x00\x00"}, /* .L...... */ \
+	{0x00000820, "\x41\x68\x00\x65\x00\x6c\x00\x6c"}, /* Ah.e.l.l */ \
+	{0x00000828, "\x00\x6f\x00\x0f\x00\xf1\x2e\x00"}, /* .o...... */ \
+	{0x00000830, "\x74\x00\x78\x00\x74\x00\x00\x00"}, /* t.x.t... */ \
+	{0x00000838, "\xff\xff\x00\x00\xff\xff\xff\xff"}, /* ........ */ \
+	{0x00000840, "\x48\x45\x4c\x4c\x4f\x20\x20\x20"}, /* HELLO    */ \
+	{0x00000848, "\x54\x58\x54\x20\x00\x64\xd7\x46"}, /* TXT .d.F */ \
+	{0x00000850, "\x84\x4c\x84\x4c\x00\x00\xd7\x46"}, /* .L.L...F */ \
+	{0x00000858, "\x84\x4c\x03\x00\x0d\x00\x00\x00"}, /* .L...... */ \
+	{0x00005000, "\x48\x65\x6c\x6c\x6f\x20\x77\x6f"}, /* Hello wo */ \
+	{0x00005008, "\x72\x6c\x64\x21\x0a\x00\x00\x00"}, /* rld!.... */ \
 	{0, NULL} } }
diff --git a/lib/efi_selftest/efi_selftest_event_groups.c b/lib/efi_selftest/efi_selftest_event_groups.c
new file mode 100644
index 0000000..79e4ea1
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_event_groups.c
@@ -0,0 +1,140 @@
+/*
+ * efi_selftest_event_groups
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * This test checks the notification of group events and the
+ * following services:
+ * CreateEventEx, CloseEvent, SignalEvent, CheckEvent.
+ */
+
+#include <efi_selftest.h>
+
+#define GROUP_SIZE 16
+
+static struct efi_boot_services *boottime;
+static efi_guid_t event_group =
+	EFI_GUID(0x2335905b, 0xc3b9, 0x4221, 0xa3, 0x71,
+		 0x0e, 0x5b, 0x45, 0xc0, 0x56, 0x91);
+
+/*
+ * Notification function, increments the notfication count if parameter
+ * context is provided.
+ *
+ * @event	notified event
+ * @context	pointer to the notification count
+ */
+static void EFIAPI notify(struct efi_event *event, void *context)
+{
+	unsigned int *count = context;
+
+	if (count)
+		++*count;
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+		 const struct efi_system_table *systable)
+{
+	boottime = systable->boottime;
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * Create multiple events in an event group. Signal each event once and check
+ * that all events are notified once in each round.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	unsigned int counter[GROUP_SIZE] = {0};
+	struct efi_event *events[GROUP_SIZE];
+	size_t i, j;
+	efi_status_t ret;
+
+	for (i = 0; i < GROUP_SIZE; ++i) {
+		ret = boottime->create_event_ex(0, TPL_NOTIFY,
+						notify, (void *)&counter[i],
+						&event_group, &events[i]);
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("Failed to create event\n");
+			return EFI_ST_FAILURE;
+		}
+	}
+
+	for (i = 0; i < GROUP_SIZE; ++i) {
+		ret = boottime->signal_event(events[i]);
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("Failed to signal event\n");
+			return EFI_ST_FAILURE;
+		}
+		for (j = 0; j < GROUP_SIZE; ++j) {
+			if (counter[j] != i) {
+				efi_st_printf("i %u, j %u, count %u\n",
+					      (unsigned int)i, (unsigned int)j,
+					      (unsigned int)counter[j]);
+				efi_st_error(
+					"Notification function was called\n");
+				return EFI_ST_FAILURE;
+			}
+			/* Clear signaled state */
+			ret = boottime->check_event(events[j]);
+			if (ret != EFI_SUCCESS) {
+				efi_st_error("Event was not signaled\n");
+				return EFI_ST_FAILURE;
+			}
+			if (counter[j] != i) {
+				efi_st_printf("i %u, j %u, count %u\n",
+					      (unsigned int)i, (unsigned int)j,
+					      (unsigned int)counter[j]);
+				efi_st_error(
+					"Notification function was called\n");
+				return EFI_ST_FAILURE;
+			}
+			/* Call notification function  */
+			ret = boottime->check_event(events[j]);
+			if (ret != EFI_NOT_READY) {
+				efi_st_error(
+					"Signaled state not cleared\n");
+				return EFI_ST_FAILURE;
+			}
+			if (counter[j] != i + 1) {
+				efi_st_printf("i %u, j %u, count %u\n",
+					      (unsigned int)i, (unsigned int)j,
+					      (unsigned int)counter[j]);
+				efi_st_error(
+					"Nofification function not called\n");
+				return EFI_ST_FAILURE;
+			}
+		}
+	}
+
+	for (i = 0; i < GROUP_SIZE; ++i) {
+		ret = boottime->close_event(events[i]);
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("Failed to close event\n");
+			return EFI_ST_FAILURE;
+		}
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(eventgoups) = {
+	.name = "event groups",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+};
diff --git a/lib/efi_selftest/efi_selftest_fdt.c b/lib/efi_selftest/efi_selftest_fdt.c
new file mode 100644
index 0000000..e5a8d6a
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_fdt.c
@@ -0,0 +1,188 @@
+/*
+ * efi_selftest_pos
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * Test the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
+ *
+ * The following services are tested:
+ * OutputString, TestString, SetAttribute.
+ */
+
+#include <efi_selftest.h>
+#include <linux/libfdt.h>
+
+static struct efi_boot_services *boottime;
+static const char *fdt;
+
+/* This should be sufficent for */
+#define BUFFERSIZE 0x100000
+
+static efi_guid_t fdt_guid = EFI_FDT_GUID;
+
+/*
+ * Convert FDT value to host endianness.
+ *
+ * @val		FDT value
+ * @return	converted value
+ */
+static uint32_t f2h(fdt32_t val)
+{
+	char *buf = (char *)&val;
+	char i;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+	/* Swap the bytes */
+	i = buf[0]; buf[0] = buf[3]; buf[3] = i;
+	i = buf[1]; buf[1] = buf[2]; buf[2] = i;
+#endif
+	return *(uint32_t *)buf;
+}
+
+/*
+ * Return the value of a property of the FDT root node.
+ *
+ * @name	name of the property
+ * @return	value of the property
+ */
+static char *get_property(const u16 *property)
+{
+	struct fdt_header *header = (struct fdt_header *)fdt;
+	const fdt32_t *pos;
+	const char *strings;
+
+	if (!header)
+		return NULL;
+
+	if (f2h(header->magic) != FDT_MAGIC) {
+		printf("Wrong magic\n");
+		return NULL;
+	}
+
+	pos = (fdt32_t *)(fdt + f2h(header->off_dt_struct));
+	strings = fdt + f2h(header->off_dt_strings);
+
+	for (;;) {
+		switch (f2h(pos[0])) {
+		case FDT_BEGIN_NODE: {
+			char *c = (char *)&pos[1];
+			size_t i;
+
+			for (i = 0; c[i]; ++i)
+				;
+			pos = &pos[2 + (i >> 2)];
+			break;
+		}
+		case FDT_PROP: {
+			struct fdt_property *prop = (struct fdt_property *)pos;
+			const char *label = &strings[f2h(prop->nameoff)];
+			efi_status_t ret;
+
+			/* Check if this is the property to be returned */
+			if (!efi_st_strcmp_16_8(property, label)) {
+				char *str;
+				efi_uintn_t len = f2h(prop->len);
+
+				if (!len)
+					return NULL;
+				/*
+				 * The string might not be 0 terminated.
+				 * It is safer to make a copy.
+				 */
+				ret = boottime->allocate_pool(
+					EFI_LOADER_DATA, len + 1,
+					(void **)&str);
+				if (ret != EFI_SUCCESS) {
+					efi_st_printf("AllocatePool failed\n");
+					return NULL;
+				}
+				boottime->copy_mem(str, &pos[3], len);
+				str[len] = 0;
+
+				return str;
+			}
+
+			pos = &pos[3 + ((f2h(prop->len) + 3) >> 2)];
+			break;
+		}
+		case FDT_NOP:
+			pos = &pos[1];
+			break;
+		default:
+			return NULL;
+		}
+	}
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t img_handle,
+		 const struct efi_system_table *systable)
+{
+	efi_uintn_t i;
+
+	boottime = systable->boottime;
+
+	/* Find configuration tables */
+	for (i = 0; i < systable->nr_tables; ++i) {
+		if (!efi_st_memcmp(&systable->tables[i].guid, &fdt_guid,
+				   sizeof(efi_guid_t)))
+			fdt = systable->tables[i].table;
+	}
+	if (!fdt) {
+		efi_st_error("Missing device tree\n");
+		return EFI_ST_FAILURE;
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	char *str;
+	efi_status_t ret;
+
+	str = get_property(L"compatible");
+	if (str) {
+		efi_st_printf("compatible: %s\n", str);
+		ret = boottime->free_pool(str);
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("FreePool failed\n");
+			return EFI_ST_FAILURE;
+		}
+	} else {
+		efi_st_printf("Missing property 'compatible'\n");
+		return EFI_ST_FAILURE;
+	}
+	str = get_property(L"serial-number");
+	if (str) {
+		efi_st_printf("serial-number: %s\n", str);
+		ret = boottime->free_pool(str);
+		if (ret != EFI_SUCCESS) {
+			efi_st_error("FreePool failed\n");
+			return EFI_ST_FAILURE;
+		}
+	}
+
+	return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(fdt) = {
+	.name = "device tree",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+	.on_request = true,
+};
diff --git a/lib/efi_selftest/efi_selftest_textinput.c b/lib/efi_selftest/efi_selftest_textinput.c
new file mode 100644
index 0000000..c890ff8
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_textinput.c
@@ -0,0 +1,182 @@
+/*
+ * efi_selftest_textinput
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ *
+ * Provides a unit test for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
+ * The unicode character and the scan code are printed for text
+ * input. To run the test:
+ *
+ *	setenv efi_selftest text input
+ *	bootefi selftest
+ */
+
+#include <efi_selftest.h>
+
+struct translate {
+	u16 code;
+	u16 *text;
+};
+
+static struct efi_boot_services *boottime;
+
+static struct translate control_characters[] = {
+	{0, L"Null"},
+	{8, L"BS"},
+	{9, L"TAB"},
+	{10, L"LF"},
+	{13, L"CR"},
+	{0, NULL},
+};
+
+static u16 ch[] = L"' '";
+static u16 unknown[] = L"unknown";
+
+static struct translate scan_codes[] = {
+	{0x00, L"Null"},
+	{0x01, L"Up"},
+	{0x02, L"Down"},
+	{0x03, L"Right"},
+	{0x04, L"Left"},
+	{0x05, L"Home"},
+	{0x06, L"End"},
+	{0x07, L"Insert"},
+	{0x08, L"Delete"},
+	{0x09, L"Page Up"},
+	{0x0a, L"Page Down"},
+	{0x0b, L"FN 1"},
+	{0x0c, L"FN 2"},
+	{0x0d, L"FN 3"},
+	{0x0e, L"FN 4"},
+	{0x0f, L"FN 5"},
+	{0x10, L"FN 6"},
+	{0x11, L"FN 7"},
+	{0x12, L"FN 8"},
+	{0x13, L"FN 9"},
+	{0x14, L"FN 10"},
+	{0x15, L"FN 11"},
+	{0x16, L"FN 12"},
+	{0x17, L"Escape"},
+	{0x68, L"FN 13"},
+	{0x69, L"FN 14"},
+	{0x6a, L"FN 15"},
+	{0x6b, L"FN 16"},
+	{0x6c, L"FN 17"},
+	{0x6d, L"FN 18"},
+	{0x6e, L"FN 19"},
+	{0x6f, L"FN 20"},
+	{0x70, L"FN 21"},
+	{0x71, L"FN 22"},
+	{0x72, L"FN 23"},
+	{0x73, L"FN 24"},
+	{0x7f, L"Mute"},
+	{0x80, L"Volume Up"},
+	{0x81, L"Volume Down"},
+	{0x100, L"Brightness Up"},
+	{0x101, L"Brightness Down"},
+	{0x102, L"Suspend"},
+	{0x103, L"Hibernate"},
+	{0x104, L"Toggle Display"},
+	{0x105, L"Recovery"},
+	{0x106, L"Reject"},
+	{0x0, NULL},
+};
+
+/*
+ * Translate a unicode character to a string.
+ *
+ * @code	unicode character
+ * @return	string
+ */
+static u16 *translate_char(u16 code)
+{
+	struct translate *tr;
+
+	if (code >= ' ') {
+		ch[1] = code;
+		return ch;
+	}
+	for (tr = control_characters; tr->text; ++tr) {
+		if (tr->code == code)
+			return tr->text;
+	}
+	return unknown;
+}
+
+/*
+ * Translate a scan code to a human readable string.
+ *
+ * @code	unicode character
+ * @return	string
+ */
+static u16 *translate_code(u16 code)
+{
+	struct translate *tr;
+
+	for (tr = scan_codes; tr->text; ++tr) {
+		if (tr->code == code)
+			return tr->text;
+	}
+	return unknown;
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle:	handle of the loaded image
+ * @systable:	system table
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+		 const struct efi_system_table *systable)
+{
+	boottime = systable->boottime;
+
+	return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * @return:	EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+	struct efi_input_key input_key = {0};
+	efi_status_t ret;
+
+	efi_st_printf("Waiting for your input\n");
+	efi_st_printf("To terminate type 'x'\n");
+
+	for (;;) {
+		/* Wait for next key */
+		do {
+			ret = con_in->read_key_stroke(con_in, &input_key);
+		} while (ret == EFI_NOT_READY);
+
+		/* Allow 5 minutes until time out */
+		boottime->set_watchdog_timer(300, 0, 0, NULL);
+
+		efi_st_printf("Unicode char %u (%ps), scan code %u (%ps)\n",
+			      (unsigned int)input_key.unicode_char,
+			      translate_char(input_key.unicode_char),
+			      (unsigned int)input_key.scan_code,
+			      translate_code(input_key.scan_code));
+
+		switch (input_key.unicode_char) {
+		case 'x':
+		case 'X':
+			return EFI_ST_SUCCESS;
+		}
+	}
+}
+
+EFI_UNIT_TEST(textinput) = {
+	.name = "text input",
+	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+	.setup = setup,
+	.execute = execute,
+	.on_request = true,
+};
diff --git a/net/eth_common.c b/net/eth_common.c
index 66d0d22..0af91a9 100644
--- a/net/eth_common.c
+++ b/net/eth_common.c
@@ -8,40 +8,11 @@
 
 #include <common.h>
 #include <dm.h>
+#include <environment.h>
 #include <miiphy.h>
 #include <net.h>
 #include "eth_internal.h"
 
-void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
-{
-	char *end;
-	int i;
-
-	for (i = 0; i < 6; ++i) {
-		enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
-		if (addr)
-			addr = (*end) ? end + 1 : end;
-	}
-}
-
-int eth_env_get_enetaddr(const char *name, uchar *enetaddr)
-{
-	eth_parse_enetaddr(env_get(name), enetaddr);
-	return is_valid_ethaddr(enetaddr);
-}
-
-int eth_env_set_enetaddr(const char *name, const uchar *enetaddr)
-{
-	char buf[ARP_HLEN_ASCII + 1];
-
-	if (eth_env_get_enetaddr(name, (uchar *)buf))
-		return -EEXIST;
-
-	sprintf(buf, "%pM", enetaddr);
-
-	return env_set(name, buf);
-}
-
 int eth_env_get_enetaddr_by_index(const char *base_name, int index,
 				 uchar *enetaddr)
 {
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 23a1dc9..9d86725 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -409,7 +409,6 @@
 CONFIG_DRIVER_NE2000_CCR
 CONFIG_DRIVER_NE2000_VAL
 CONFIG_DRIVER_SMC911X_BASE
-CONFIG_DRIVER_TI_CPSW
 CONFIG_DRIVER_TI_EMAC
 CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE
 CONFIG_DRIVER_TI_EMAC_USE_RMII
@@ -536,7 +535,6 @@
 CONFIG_ENV_UBIFS_OPTION
 CONFIG_ENV_UBI_MTD
 CONFIG_ENV_UBI_VOLUME_REDUND
-CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 CONFIG_ENV_VERSION
 CONFIG_EP9302
 CONFIG_EP9307
diff --git a/test/py/tests/test_efi_selftest.py b/test/py/tests/test_efi_selftest.py
index 66b799b..b1ef6bd 100644
--- a/test/py/tests/test_efi_selftest.py
+++ b/test/py/tests/test_efi_selftest.py
@@ -25,6 +25,20 @@
 	u_boot_console.restart_uboot();
 
 @pytest.mark.buildconfigspec('cmd_bootefi_selftest')
+@pytest.mark.buildconfigspec('of_control')
+def test_efi_selftest_device_tree(u_boot_console):
+	u_boot_console.run_command(cmd='setenv efi_selftest list')
+	output = u_boot_console.run_command('bootefi selftest')
+	assert '\'device tree\'' in output
+	u_boot_console.run_command(cmd='setenv efi_selftest device tree')
+	u_boot_console.run_command(cmd='setenv -f serial# Testing DT')
+	u_boot_console.run_command(cmd='bootefi selftest ${fdtcontroladdr}', wait_for_prompt=False)
+	m = u_boot_console.p.expect(['serial-number: Testing DT', 'U-Boot'])
+	if m != 0:
+		raise Exception('Reset failed in \'device tree\' test')
+	u_boot_console.restart_uboot();
+
+@pytest.mark.buildconfigspec('cmd_bootefi_selftest')
 def test_efi_selftest_watchdog_reboot(u_boot_console):
 	u_boot_console.run_command(cmd='setenv efi_selftest list')
 	output = u_boot_console.run_command('bootefi selftest')