Browse Source

Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot

Patch queue for efi - 2016-11-17

Highlights this time around:

  - x86 efi_loader support
  - hello world efi test case
  - network device name is now representative
  - terminal output reports modes correctly
  - fix psci reset for ls1043/ls1046
  - fix efi_add_runtime_mmio definition for x86
  - efi_loader support for ls2080
Tom Rini 8 years ago
parent
commit
9e40ea04e9
54 changed files with 1021 additions and 86 deletions
  1. 1 0
      Kconfig
  2. 10 1
      Makefile
  3. 7 0
      arch/arm/config.mk
  4. 3 2
      arch/arm/cpu/armv8/Kconfig
  5. 4 0
      arch/arm/cpu/armv8/config.mk
  6. 31 2
      arch/arm/cpu/armv8/fsl-layerscape/cpu.c
  7. 6 0
      arch/arm/cpu/armv8/fsl-layerscape/fdt.c
  8. 1 0
      arch/arm/include/asm/u-boot-arm.h
  9. 10 0
      arch/arm/lib/Makefile
  10. 7 0
      arch/arm/lib/bootm.c
  11. 135 0
      arch/arm/lib/crt0_aarch64_efi.S
  12. 138 0
      arch/arm/lib/crt0_arm_efi.S
  13. 70 0
      arch/arm/lib/elf_aarch64_efi.lds
  14. 70 0
      arch/arm/lib/elf_arm_efi.lds
  15. 87 0
      arch/arm/lib/reloc_aarch64_efi.c
  16. 66 0
      arch/arm/lib/reloc_arm_efi.c
  17. 2 1
      arch/arm/lib/relocate.S
  18. 2 1
      arch/arm/lib/relocate_64.S
  19. 18 2
      arch/x86/config.mk
  20. 1 0
      arch/x86/include/asm/u-boot-x86.h
  21. 23 0
      arch/x86/lib/Makefile
  22. 4 0
      arch/x86/lib/bootm.c
  23. 0 0
      arch/x86/lib/crt0_ia32_efi.S
  24. 0 0
      arch/x86/lib/crt0_x86_64_efi.S
  25. 0 18
      arch/x86/lib/efi/Makefile
  26. 0 2
      arch/x86/lib/elf_ia32_efi.lds
  27. 0 2
      arch/x86/lib/elf_x86_64_efi.lds
  28. 0 0
      arch/x86/lib/reloc_ia32_efi.c
  29. 0 0
      arch/x86/lib/reloc_x86_64_efi.c
  30. 2 0
      arch/x86/lib/tables.c
  31. 5 1
      board/freescale/ls2080a/ls2080a.c
  32. 5 6
      board/freescale/ls2080aqds/ls2080aqds.c
  33. 14 6
      board/freescale/ls2080ardb/ls2080ardb.c
  34. 9 0
      cmd/Kconfig
  35. 33 7
      cmd/bootefi.c
  36. 1 0
      configs/efi-x86_defconfig
  37. 14 0
      doc/README.efi
  38. 0 1
      doc/README.x86
  39. 22 2
      drivers/net/fsl-mc/mc.c
  40. 2 0
      include/asm-generic/sections.h
  41. 25 1
      include/configs/ls2080ardb.h
  42. 5 2
      include/efi.h
  43. 13 0
      include/efi_api.h
  44. 1 1
      include/efi_loader.h
  45. 13 0
      include/elf.h
  46. 2 2
      lib/efi/Makefile
  47. 1 1
      lib/efi_loader/Kconfig
  48. 4 0
      lib/efi_loader/Makefile
  49. 2 0
      lib/efi_loader/efi_boottime.c
  50. 84 16
      lib/efi_loader/efi_console.c
  51. 2 1
      lib/efi_loader/efi_image_loader.c
  52. 9 8
      lib/efi_loader/efi_net.c
  53. 24 0
      lib/efi_loader/helloworld.c
  54. 33 0
      scripts/Makefile.lib

+ 1 - 0
Kconfig

@@ -56,6 +56,7 @@ config CC_OPTIMIZE_FOR_SIZE
 config DISTRO_DEFAULTS
 config DISTRO_DEFAULTS
 	bool "Select defaults suitable for booting general purpose Linux distributions"
 	bool "Select defaults suitable for booting general purpose Linux distributions"
 	default y if ARCH_SUNXI
 	default y if ARCH_SUNXI
+	default y if ARCH_LS2080A
 	default n
 	default n
 	select CMD_BOOTZ if ARM && !ARM64
 	select CMD_BOOTZ if ARM && !ARM64
 	select CMD_BOOTI if ARM64
 	select CMD_BOOTI if ARM64

+ 10 - 1
Makefile

@@ -527,6 +527,15 @@ endif
 endif
 endif
 endif
 endif
 
 
+# These are set by the arch-specific config.mk. Make sure they are exported
+# so they can be used when building an EFI application.
+export EFI_LDS		# Filename of EFI link script in arch/$(ARCH)/lib
+export EFI_CRT0		# Filename of EFI CRT0 in arch/$(ARCH)/lib
+export EFI_RELOC	# Filename of EFU relocation code in arch/$(ARCH)/lib
+export CFLAGS_EFI	# Compiler flags to add when building EFI app
+export CFLAGS_NON_EFI	# Compiler flags to remove when building EFI app
+export EFI_TARGET	# binutils target if EFI is natively supported
+
 # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
 # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
 # that (or fail if absent).  Otherwise, search for a linker script in a
 # that (or fail if absent).  Otherwise, search for a linker script in a
 # standard location.
 # standard location.
@@ -1131,7 +1140,7 @@ quiet_cmd_u-boot_payload ?= LD      $@
       cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
       cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
       -T u-boot-payload.lds arch/x86/cpu/call32.o \
       -T u-boot-payload.lds arch/x86/cpu/call32.o \
       lib/efi/efi.o lib/efi/efi_stub.o u-boot.bin.o \
       lib/efi/efi.o lib/efi/efi_stub.o u-boot.bin.o \
-      $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
+      $(addprefix arch/$(ARCH)/lib/,$(EFISTUB))
 
 
 u-boot-payload: u-boot.bin.o u-boot-payload.lds FORCE
 u-boot-payload: u-boot.bin.o u-boot-payload.lds FORCE
 	$(call if_changed,u-boot_payload)
 	$(call if_changed,u-boot_payload)

+ 7 - 0
arch/arm/config.mk

@@ -13,6 +13,9 @@ CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
 endif
 endif
 endif
 endif
 
 
+CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections
+CFLAGS_EFI := -fpic -fshort-wchar
+
 LDFLAGS_FINAL += --gc-sections
 LDFLAGS_FINAL += --gc-sections
 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \
 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \
 		     -fno-common -ffixed-r9
 		     -fno-common -ffixed-r9
@@ -148,3 +151,7 @@ ifneq ($(CONFIG_VF610),)
 ALL-y += u-boot.vyb
 ALL-y += u-boot.vyb
 endif
 endif
 endif
 endif
+
+EFI_LDS := elf_arm_efi.lds
+EFI_CRT0 := crt0_arm_efi.o
+EFI_RELOC := reloc_arm_efi.o

+ 3 - 2
arch/arm/cpu/armv8/Kconfig

@@ -28,8 +28,9 @@ config PSCI_RESET
 		   !TARGET_LS2080A_SIMU && !TARGET_LS2080AQDS && \
 		   !TARGET_LS2080A_SIMU && !TARGET_LS2080AQDS && \
 		   !TARGET_LS2080ARDB && !TARGET_LS1012AQDS && \
 		   !TARGET_LS2080ARDB && !TARGET_LS1012AQDS && \
 		   !TARGET_LS1012ARDB && !TARGET_LS1012AFRDM && \
 		   !TARGET_LS1012ARDB && !TARGET_LS1012AFRDM && \
-		   !TARGET_LS1043ARDB && !ARCH_UNIPHIER && !ARCH_SNAPDRAGON && \
-		   !TARGET_S32V234EVB
+		   !TARGET_LS1043ARDB && !TARGET_LS1043AQDS && \
+		   !TARGET_LS1046ARDB && !TARGET_LS1046AQDS && \
+		   !ARCH_UNIPHIER && !ARCH_SNAPDRAGON && !TARGET_S32V234EVB
 	help
 	help
 	  Most armv8 systems have PSCI support enabled in EL3, either through
 	  Most armv8 systems have PSCI support enabled in EL3, either through
 	  ARM Trusted Firmware or other firmware.
 	  ARM Trusted Firmware or other firmware.

+ 4 - 0
arch/arm/cpu/armv8/config.mk

@@ -8,3 +8,7 @@ PLATFORM_RELFLAGS += -fno-common -ffixed-x18
 
 
 PF_NO_UNALIGNED := $(call cc-option, -mstrict-align)
 PF_NO_UNALIGNED := $(call cc-option, -mstrict-align)
 PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
 PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
+
+EFI_LDS := elf_aarch64_efi.lds
+EFI_CRT0 := crt0_aarch64_efi.o
+EFI_RELOC := reloc_aarch64_efi.o

+ 31 - 2
arch/arm/cpu/armv8/fsl-layerscape/cpu.c

@@ -17,6 +17,7 @@
 #ifdef CONFIG_MP
 #ifdef CONFIG_MP
 #include <asm/arch/mp.h>
 #include <asm/arch/mp.h>
 #endif
 #endif
+#include <efi_loader.h>
 #include <fm_eth.h>
 #include <fm_eth.h>
 #include <fsl-mc/fsl_mc.h>
 #include <fsl-mc/fsl_mc.h>
 #ifdef CONFIG_FSL_ESDHC
 #ifdef CONFIG_FSL_ESDHC
@@ -462,9 +463,10 @@ int timer_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
-void reset_cpu(ulong addr)
+__efi_runtime_data u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
+
+void __efi_runtime reset_cpu(ulong addr)
 {
 {
-	u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
 	u32 val;
 	u32 val;
 
 
 	/* Raise RESET_REQ_B */
 	/* Raise RESET_REQ_B */
@@ -473,6 +475,33 @@ void reset_cpu(ulong addr)
 	scfg_out32(rstcr, val);
 	scfg_out32(rstcr, val);
 }
 }
 
 
+#ifdef CONFIG_EFI_LOADER
+
+void __efi_runtime EFIAPI efi_reset_system(
+		       enum efi_reset_type reset_type,
+		       efi_status_t reset_status,
+		       unsigned long data_size, void *reset_data)
+{
+	switch (reset_type) {
+	case EFI_RESET_COLD:
+	case EFI_RESET_WARM:
+		reset_cpu(0);
+		break;
+	case EFI_RESET_SHUTDOWN:
+		/* Nothing we can do */
+		break;
+	}
+
+	while (1) { }
+}
+
+void efi_reset_system_init(void)
+{
+       efi_add_runtime_mmio(&rstcr, sizeof(*rstcr));
+}
+
+#endif
+
 phys_size_t board_reserve_ram_top(phys_size_t ram_size)
 phys_size_t board_reserve_ram_top(phys_size_t ram_size)
 {
 {
 	phys_size_t ram_top = ram_size;
 	phys_size_t ram_top = ram_size;

+ 6 - 0
arch/arm/cpu/armv8/fsl-layerscape/fdt.c

@@ -5,6 +5,7 @@
  */
  */
 
 
 #include <common.h>
 #include <common.h>
+#include <efi_loader.h>
 #include <libfdt.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <fdt_support.h>
 #include <phy.h>
 #include <phy.h>
@@ -105,6 +106,11 @@ remove_psci_node:
 
 
 	fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
 	fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
 			*boot_code_size);
 			*boot_code_size);
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
+	efi_add_memory_map((uintptr_t)&secondary_boot_code,
+			   ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+			   EFI_RESERVED_MEMORY_TYPE, false);
+#endif
 }
 }
 #endif
 #endif
 
 

+ 1 - 0
arch/arm/include/asm/u-boot-arm.h

@@ -37,6 +37,7 @@ int	arch_early_init_r(void);
 /* board/.../... */
 /* board/.../... */
 int	board_init(void);
 int	board_init(void);
 void	dram_init_banksize (void);
 void	dram_init_banksize (void);
+void	board_quiesce_devices(void);
 
 
 /* cpu/.../interrupt.c */
 /* cpu/.../interrupt.c */
 int	arch_interrupt_init	(void);
 int	arch_interrupt_init	(void);

+ 10 - 0
arch/arm/lib/Makefile

@@ -92,3 +92,13 @@ AFLAGS_memset.o := -DMEMSET_NO_THUMB_BUILD
 AFLAGS_memcpy.o := -DMEMCPY_NO_THUMB_BUILD
 AFLAGS_memcpy.o := -DMEMCPY_NO_THUMB_BUILD
 endif
 endif
 endif
 endif
+
+# For building EFI apps
+CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
+CFLAGS_REMOVE_$(EFI_CRT0) := $(CFLAGS_NON_EFI)
+
+CFLAGS_$(EFI_RELOC) := $(CFLAGS_EFI)
+CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI)
+
+extra-$(CONFIG_CMD_BOOTEFI_HELLO) += $(EFI_CRT0) $(EFI_RELOC)
+extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC)

+ 7 - 0
arch/arm/lib/bootm.c

@@ -64,6 +64,10 @@ void arch_lmb_reserve(struct lmb *lmb)
 		    gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
 		    gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
 }
 }
 
 
+__weak void board_quiesce_devices(void)
+{
+}
+
 /**
 /**
  * announce_and_cleanup() - Print message and prepare for kernel boot
  * announce_and_cleanup() - Print message and prepare for kernel boot
  *
  *
@@ -84,6 +88,9 @@ static void announce_and_cleanup(int fake)
 #ifdef CONFIG_USB_DEVICE
 #ifdef CONFIG_USB_DEVICE
 	udc_disconnect();
 	udc_disconnect();
 #endif
 #endif
+
+	board_quiesce_devices();
+
 	cleanup_before_linux();
 	cleanup_before_linux();
 }
 }
 
 

+ 135 - 0
arch/arm/lib/crt0_aarch64_efi.S

@@ -0,0 +1,135 @@
+/*
+ * crt0-efi-aarch64.S - PE/COFF header for aarch64 EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+     BSD-2-Clause
+ *
+ * This file is taken and modified from the gnu-efi project.
+ */
+
+	.section	.text.head
+
+	/*
+	 * Magic "MZ" signature for PE/COFF
+	 */
+	.globl	ImageBase
+ImageBase:
+	.ascii	"MZ"
+	.skip	58				/* 'MZ' + pad + offset == 64 */
+	.long	pe_header - ImageBase		/* Offset to the PE header */
+pe_header:
+	.ascii	"PE"
+	.short	0
+coff_header:
+	.short	0xaa64				/* AArch64 */
+	.short	2				/* nr_sections */
+	.long	0				/* TimeDateStamp */
+	.long	0				/* PointerToSymbolTable */
+	.long	1				/* NumberOfSymbols */
+	.short	section_table - optional_header	/* SizeOfOptionalHeader */
+	/*
+	 * Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
+	 * IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
+	 */
+	.short	0x206
+optional_header:
+	.short	0x20b				/* PE32+ format */
+	.byte	0x02				/* MajorLinkerVersion */
+	.byte	0x14				/* MinorLinkerVersion */
+	.long	_edata - _start			/* SizeOfCode */
+	.long	0				/* SizeOfInitializedData */
+	.long	0				/* SizeOfUninitializedData */
+	.long	_start - ImageBase		/* AddressOfEntryPoint */
+	.long	_start - ImageBase		/* BaseOfCode */
+
+extra_header_fields:
+	.quad	0				/* ImageBase */
+	.long	0x20				/* SectionAlignment */
+	.long	0x8				/* FileAlignment */
+	.short	0				/* MajorOperatingSystemVersion */
+	.short	0				/* MinorOperatingSystemVersion */
+	.short	0				/* MajorImageVersion */
+	.short	0				/* MinorImageVersion */
+	.short	0				/* MajorSubsystemVersion */
+	.short	0				/* MinorSubsystemVersion */
+	.long	0				/* Win32VersionValue */
+
+	.long	_edata - ImageBase		/* SizeOfImage */
+
+	/*
+	 * Everything before the kernel image is considered part of the header
+	 */
+	.long	_start - ImageBase		/* SizeOfHeaders */
+	.long	0				/* CheckSum */
+	.short	EFI_SUBSYSTEM			/* Subsystem */
+	.short	0				/* DllCharacteristics */
+	.quad	0				/* SizeOfStackReserve */
+	.quad	0				/* SizeOfStackCommit */
+	.quad	0				/* SizeOfHeapReserve */
+	.quad	0				/* SizeOfHeapCommit */
+	.long	0				/* LoaderFlags */
+	.long	0x6				/* NumberOfRvaAndSizes */
+
+	.quad	0				/* ExportTable */
+	.quad	0				/* ImportTable */
+	.quad	0				/* ResourceTable */
+	.quad	0				/* ExceptionTable */
+	.quad	0				/* CertificationTable */
+	.quad	0				/* BaseRelocationTable */
+
+	/* Section table */
+section_table:
+
+	/*
+	 * The EFI application loader requires a relocation section
+	 * because EFI applications must be relocatable.  This is a
+	 * dummy section as far as we are concerned.
+	 */
+	.ascii	".reloc"
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	0
+	.long	0
+	.long	0			/* SizeOfRawData */
+	.long	0			/* PointerToRawData */
+	.long	0			/* PointerToRelocations */
+	.long	0			/* PointerToLineNumbers */
+	.short	0			/* NumberOfRelocations */
+	.short	0			/* NumberOfLineNumbers */
+	.long	0x42100040		/* Characteristics (section flags) */
+
+
+	.ascii	".text"
+	.byte	0
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	_edata - _start		/* VirtualSize */
+	.long	_start - ImageBase	/* VirtualAddress */
+	.long	_edata - _start		/* SizeOfRawData */
+	.long	_start - ImageBase	/* PointerToRawData */
+
+	.long	0		/* PointerToRelocations (0 for executables) */
+	.long	0		/* PointerToLineNumbers (0 for executables) */
+	.short	0		/* NumberOfRelocations  (0 for executables) */
+	.short	0		/* NumberOfLineNumbers  (0 for executables) */
+	.long	0xe0500020	/* Characteristics (section flags) */
+
+_start:
+	stp		x29, x30, [sp, #-32]!
+	mov		x29, sp
+
+	stp		x0, x1, [sp, #16]
+	mov		x2, x0
+	mov		x3, x1
+	adr		x0, ImageBase
+	adrp		x1, _DYNAMIC
+	add		x1, x1, #:lo12:_DYNAMIC
+	bl		_relocate
+	cbnz		x0, 0f
+
+	ldp		x0, x1, [sp, #16]
+	bl		efi_main
+
+0:	ldp		x29, x30, [sp], #32
+	ret

+ 138 - 0
arch/arm/lib/crt0_arm_efi.S

@@ -0,0 +1,138 @@
+/*
+ * crt0-efi-arm.S - PE/COFF header for ARM EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+     BSD-2-Clause
+ *
+ * This file is taken and modified from the gnu-efi project.
+ */
+
+	.section	.text.head
+
+	/*
+	 * Magic "MZ" signature for PE/COFF
+	 */
+	.globl	image_base
+image_base:
+	.ascii	"MZ"
+	.skip	58				/* 'MZ' + pad + offset == 64 */
+	.long	pe_header - image_base		/* Offset to the PE header */
+pe_header:
+	.ascii	"PE"
+	.short	0
+coff_header:
+	.short	0x1c2				/* Mixed ARM/Thumb */
+	.short	2				/* nr_sections */
+	.long	0				/* TimeDateStamp */
+	.long	0				/* PointerToSymbolTable */
+	.long	1				/* NumberOfSymbols */
+	.short	section_table - optional_header	/* SizeOfOptionalHeader */
+	/*
+	 * Characteristics: IMAGE_FILE_32BIT_MACHINE |
+	 * IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
+	 * IMAGE_FILE_LINE_NUMS_STRIPPED
+	 */
+	.short	0x306
+optional_header:
+	.short	0x10b				/* PE32+ format */
+	.byte	0x02				/* MajorLinkerVersion */
+	.byte	0x14				/* MinorLinkerVersion */
+	.long	_edata - _start			/* SizeOfCode */
+	.long	0				/* SizeOfInitializedData */
+	.long	0				/* SizeOfUninitializedData */
+	.long	_start - image_base		/* AddressOfEntryPoint */
+	.long	_start - image_base		/* BaseOfCode */
+	.long	0				/* BaseOfData */
+
+extra_header_fields:
+	.long	0				/* image_base */
+	.long	0x20				/* SectionAlignment */
+	.long	0x8				/* FileAlignment */
+	.short	0				/* MajorOperatingSystemVersion */
+	.short	0				/* MinorOperatingSystemVersion */
+	.short	0				/* MajorImageVersion */
+	.short	0				/* MinorImageVersion */
+	.short	0				/* MajorSubsystemVersion */
+	.short	0				/* MinorSubsystemVersion */
+	.long	0				/* Win32VersionValue */
+
+	.long	_edata - image_base		/* SizeOfImage */
+
+	/*
+	 * Everything before the kernel image is considered part of the header
+	 */
+	.long	_start - image_base		/* SizeOfHeaders */
+	.long	0				/* CheckSum */
+	.short	EFI_SUBSYSTEM			/* Subsystem */
+	.short	0				/* DllCharacteristics */
+	.long	0				/* SizeOfStackReserve */
+	.long	0				/* SizeOfStackCommit */
+	.long	0				/* SizeOfHeapReserve */
+	.long	0				/* SizeOfHeapCommit */
+	.long	0				/* LoaderFlags */
+	.long	0x6				/* NumberOfRvaAndSizes */
+
+	.quad	0				/* ExportTable */
+	.quad	0				/* ImportTable */
+	.quad	0				/* ResourceTable */
+	.quad	0				/* ExceptionTable */
+	.quad	0				/* CertificationTable */
+	.quad	0				/* BaseRelocationTable */
+
+section_table:
+
+	/*
+	 * The EFI application loader requires a relocation section
+	 * because EFI applications must be relocatable.  This is a
+	 * dummy section as far as we are concerned.
+	 */
+	.ascii	".reloc"
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	0
+	.long	0
+	.long	0			/* SizeOfRawData */
+	.long	0			/* PointerToRawData */
+	.long	0			/* PointerToRelocations */
+	.long	0			/* PointerToLineNumbers */
+	.short	0			/* NumberOfRelocations */
+	.short	0			/* NumberOfLineNumbers */
+	.long	0x42100040		/* Characteristics (section flags) */
+
+	.ascii	".text"
+	.byte	0
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	_edata - _start		/* VirtualSize */
+	.long	_start - image_base	/* VirtualAddress */
+	.long	_edata - _start		/* SizeOfRawData */
+	.long	_start - image_base	/* PointerToRawData */
+
+	.long	0		/* PointerToRelocations (0 for executables) */
+	.long	0		/* PointerToLineNumbers (0 for executables) */
+	.short	0		/* NumberOfRelocations  (0 for executables) */
+	.short	0		/* NumberOfLineNumbers  (0 for executables) */
+	.long	0xe0500020	/* Characteristics (section flags) */
+
+_start:
+	stmfd		sp!, {r0-r2, lr}
+
+	mov		r2, r0
+	mov		r3, r1
+	adr		r1, .L_DYNAMIC
+	ldr		r0, [r1]
+	add		r1, r0, r1
+	adr		r0, image_base
+	bl		_relocate
+	teq		r0, #0
+	bne		0f
+
+	ldmfd		sp, {r0-r1}
+	bl		efi_main
+
+0:	add		sp, sp, #12
+	ldr		pc, [sp], #4
+
+.L_DYNAMIC:
+	.word		_DYNAMIC - .

+ 70 - 0
arch/arm/lib/elf_aarch64_efi.lds

@@ -0,0 +1,70 @@
+/*
+ * U-Boot aarch64 EFI linker script
+ *
+ * SPDX-License-Identifier:	BSD-2-Clause
+ *
+ * Modified from elf_aarch64_efi.lds in gnu-efi
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+	.text 0x0 : {
+		_text = .;
+		*(.text.head)
+		*(.text)
+		*(.text.*)
+		*(.gnu.linkonce.t.*)
+		*(.srodata)
+		*(.rodata*)
+		. = ALIGN(16);
+	}
+	_etext = .;
+	_text_size = . - _text;
+	.dynamic  : { *(.dynamic) }
+	.data : {
+		_data = .;
+		*(.sdata)
+		*(.data)
+		*(.data1)
+		*(.data.*)
+		*(.got.plt)
+		*(.got)
+
+		/*
+		 * The EFI loader doesn't seem to like a .bss section, so we
+		 * stick it all into .data:
+		 */
+		. = ALIGN(16);
+		_bss = .;
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(16);
+		_bss_end = .;
+		_edata = .;
+	}
+	.rela.dyn : { *(.rela.dyn) }
+	.rela.plt : { *(.rela.plt) }
+	.rela.got : { *(.rela.got) }
+	.rela.data : { *(.rela.data) *(.rela.data*) }
+	_data_size = . - _etext;
+
+	. = ALIGN(4096);
+	.dynsym   : { *(.dynsym) }
+	. = ALIGN(4096);
+	.dynstr   : { *(.dynstr) }
+	. = ALIGN(4096);
+	.note.gnu.build-id : { *(.note.gnu.build-id) }
+	/DISCARD/ : {
+		*(.rel.reloc)
+		*(.eh_frame)
+		*(.note.GNU-stack)
+	}
+	.comment 0 : { *(.comment) }
+}

+ 70 - 0
arch/arm/lib/elf_arm_efi.lds

@@ -0,0 +1,70 @@
+/*
+ * U-Boot ARM EFI linker script
+ *
+ * SPDX-License-Identifier:	BSD-2-Clause
+ *
+ * Modified from elf_arm_efi.lds in gnu-efi
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	.text 0x0 : {
+		_text = .;
+		*(.text.head)
+		*(.text)
+		*(.text.*)
+		*(.gnu.linkonce.t.*)
+		*(.srodata)
+		*(.rodata*)
+		. = ALIGN(16);
+	}
+	_etext = .;
+	_text_size = . - _text;
+	.dynamic  : { *(.dynamic) }
+	.data : {
+		_data = .;
+		*(.sdata)
+		*(.data)
+		*(.data1)
+		*(.data.*)
+		*(.got.plt)
+		*(.got)
+
+		/*
+		 * The EFI loader doesn't seem to like a .bss section, so we
+		 * stick it all into .data:
+		 */
+		. = ALIGN(16);
+		_bss = .;
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(.bss.*)
+		*(COMMON)
+		. = ALIGN(16);
+		_bss_end = .;
+		_edata = .;
+	}
+	.rel.dyn : { *(.rel.dyn) }
+	.rel.plt : { *(.rel.plt) }
+	.rel.got : { *(.rel.got) }
+	.rel.data : { *(.rel.data) *(.rel.data*) }
+	_data_size = . - _etext;
+
+	. = ALIGN(4096);
+	.dynsym   : { *(.dynsym) }
+	. = ALIGN(4096);
+	.dynstr   : { *(.dynstr) }
+	. = ALIGN(4096);
+	.note.gnu.build-id : { *(.note.gnu.build-id) }
+	/DISCARD/ : {
+		*(.rel.reloc)
+		*(.eh_frame)
+		*(.note.GNU-stack)
+	}
+	.comment 0 : { *(.comment) }
+}

+ 87 - 0
arch/arm/lib/reloc_aarch64_efi.c

@@ -0,0 +1,87 @@
+/* reloc_aarch64.c - position independent x86 ELF shared object relocator
+   Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+   Copyright (C) 1999 Hewlett-Packard Co.
+	Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials
+      provided with the distribution.
+    * Neither the name of Hewlett-Packard Co. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+    BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+#include <efi.h>
+
+#include <elf.h>
+
+efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
+		       struct efi_system_table *systab)
+{
+	long relsz = 0, relent = 0;
+	Elf64_Rela *rel = 0;
+	unsigned long *addr;
+	int i;
+
+	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+		switch (dyn[i].d_tag) {
+		case DT_RELA:
+			rel = (Elf64_Rela *)((ulong)dyn[i].d_un.d_ptr + ldbase);
+			break;
+		case DT_RELASZ:
+			relsz = dyn[i].d_un.d_val;
+			break;
+		case DT_RELAENT:
+			relent = dyn[i].d_un.d_val;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (!rel && relent == 0)
+		return EFI_SUCCESS;
+
+	if (!rel || relent == 0)
+		return EFI_LOAD_ERROR;
+
+	while (relsz > 0) {
+		/* apply the relocs */
+		switch (ELF64_R_TYPE(rel->r_info)) {
+		case R_AARCH64_NONE:
+			break;
+		case R_AARCH64_RELATIVE:
+			addr = (ulong *)(ldbase + rel->r_offset);
+			*addr = ldbase + rel->r_addend;
+			break;
+		default:
+			break;
+		}
+		rel = (Elf64_Rela *)((char *)rel + relent);
+		relsz -= relent;
+	}
+	return EFI_SUCCESS;
+}

+ 66 - 0
arch/arm/lib/reloc_arm_efi.c

@@ -0,0 +1,66 @@
+/*
+ * reloc_arm.c - position-independent ARM ELF shared object relocator
+ *
+ * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ *
+ * This file is taken and modified from the gnu-efi project.
+ */
+
+#include <efi.h>
+#include <elf.h>
+
+efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
+		       struct efi_system_table *systab)
+{
+	long relsz = 0, relent = 0;
+	Elf32_Rel *rel = 0;
+	ulong *addr;
+	int i;
+
+	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+		switch (dyn[i].d_tag) {
+		case DT_REL:
+			rel = (Elf32_Rel *)((ulong)dyn[i].d_un.d_ptr
+					+ ldbase);
+			break;
+		case DT_RELSZ:
+			relsz = dyn[i].d_un.d_val;
+			break;
+		case DT_RELENT:
+			relent = dyn[i].d_un.d_val;
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (!rel && relent == 0)
+		return EFI_SUCCESS;
+
+	if (!rel || relent == 0)
+		return EFI_LOAD_ERROR;
+
+	while (relsz > 0) {
+		/* apply the relocs */
+		switch (ELF32_R_TYPE(rel->r_info)) {
+		case R_ARM_NONE:
+			break;
+		case R_ARM_RELATIVE:
+			addr = (ulong *)(ldbase + rel->r_offset);
+			*addr += ldbase;
+			break;
+		default:
+			break;
+		}
+		rel = (Elf32_Rel *)((char *)rel + relent);
+		relsz -= relent;
+	}
+
+	return EFI_SUCCESS;
+}

+ 2 - 1
arch/arm/lib/relocate.S

@@ -8,6 +8,7 @@
 
 
 #include <asm-offsets.h>
 #include <asm-offsets.h>
 #include <config.h>
 #include <config.h>
+#include <elf.h>
 #include <linux/linkage.h>
 #include <linux/linkage.h>
 #ifdef CONFIG_CPU_V7M
 #ifdef CONFIG_CPU_V7M
 #include <asm/armv7m.h>
 #include <asm/armv7m.h>
@@ -96,7 +97,7 @@ copy_loop:
 fixloop:
 fixloop:
 	ldmia	r2!, {r0-r1}		/* (r0,r1) <- (SRC location,fixup) */
 	ldmia	r2!, {r0-r1}		/* (r0,r1) <- (SRC location,fixup) */
 	and	r1, r1, #0xff
 	and	r1, r1, #0xff
-	cmp	r1, #23			/* relative fixup? */
+	cmp	r1, #R_ARM_RELATIVE
 	bne	fixnext
 	bne	fixnext
 
 
 	/* relative fix: increase location by offset */
 	/* relative fix: increase location by offset */

+ 2 - 1
arch/arm/lib/relocate_64.S

@@ -10,6 +10,7 @@
 
 
 #include <asm-offsets.h>
 #include <asm-offsets.h>
 #include <config.h>
 #include <config.h>
+#include <elf.h>
 #include <linux/linkage.h>
 #include <linux/linkage.h>
 #include <asm/macro.h>
 #include <asm/macro.h>
 
 
@@ -47,7 +48,7 @@ fixloop:
 	ldp	x0, x1, [x2], #16	/* (x0,x1) <- (SRC location, fixup) */
 	ldp	x0, x1, [x2], #16	/* (x0,x1) <- (SRC location, fixup) */
 	ldr	x4, [x2], #8		/* x4 <- addend */
 	ldr	x4, [x2], #8		/* x4 <- addend */
 	and	x1, x1, #0xffffffff
 	and	x1, x1, #0xffffffff
-	cmp	x1, #1027		/* relative fixup? */
+	cmp	x1, #R_AARCH64_RELATIVE
 	bne	fixnext
 	bne	fixnext
 
 
 	/* relative fix: store addend plus offset at dest location */
 	/* relative fix: store addend plus offset at dest location */

+ 18 - 2
arch/x86/config.mk

@@ -45,8 +45,8 @@ endif
 
 
 EFIPAYLOAD_BFDARCH = i386
 EFIPAYLOAD_BFDARCH = i386
 
 
-LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
-EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o
+LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds
+EFISTUB := crt0_$(EFIARCH)_efi.o reloc_$(EFIARCH)_efi.o
 OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
 OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
 
 
 CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
 CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
@@ -65,3 +65,19 @@ PLATFORM_LDFLAGS += --emit-relocs
 LDFLAGS_FINAL += --gc-sections -pie
 LDFLAGS_FINAL += --gc-sections -pie
 
 
 endif
 endif
+
+ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),)
+
+ifneq ($(CONFIG_EFI_STUB_64BIT),)
+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
+EFI_TARGET := --target=efi-app-x86_64
+endif
+
+endif

+ 1 - 0
arch/x86/include/asm/u-boot-x86.h

@@ -74,6 +74,7 @@ static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void)
 /* board/... */
 /* board/... */
 void timer_set_tsc_base(uint64_t new_base);
 void timer_set_tsc_base(uint64_t new_base);
 uint64_t timer_get_tsc(void);
 uint64_t timer_get_tsc(void);
+void board_quiesce_devices(void);
 
 
 void quick_ram_check(void);
 void quick_ram_check(void);
 
 

+ 23 - 0
arch/x86/lib/Makefile

@@ -44,3 +44,26 @@ NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
 OBJCOPYFLAGS := --prefix-symbols=__normal_
 OBJCOPYFLAGS := --prefix-symbols=__normal_
 $(obj)/lib.a: $(NORMAL_LIBGCC) FORCE
 $(obj)/lib.a: $(NORMAL_LIBGCC) FORCE
 	$(call if_changed,objcopy)
 	$(call if_changed,objcopy)
+
+obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o
+
+ifneq ($(CONFIG_EFI_STUB),)
+
+CFLAGS_REMOVE_reloc_ia32_efi.o += -mregparm=3
+CFLAGS_reloc_ia32_efi.o += -fpic -fshort-wchar
+
+# When building for 64-bit we must remove the i386-specific flags
+CFLAGS_REMOVE_reloc_x86_64_efi.o += -mregparm=3 -march=i386 -m32
+CFLAGS_reloc_x86_64_efi.o += -fpic -fshort-wchar
+
+AFLAGS_REMOVE_crt0_x86_64_efi.o += -mregparm=3 -march=i386 -m32
+AFLAGS_crt0_x86_64_efi.o += -fpic -fshort-wchar
+
+extra-$(CONFIG_EFI_STUB_32BIT) += crt0_ia32_efi.o reloc_ia32_efi.o
+extra-$(CONFIG_EFI_STUB_64BIT) += crt0_x86_64_efi.o reloc_x86_64_efi.o
+
+endif
+
+ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),)
+extra-y += $(EFI_CRT0) $(EFI_RELOC)
+endif

+ 4 - 0
arch/x86/lib/bootm.c

@@ -26,6 +26,10 @@ DECLARE_GLOBAL_DATA_PTR;
 
 
 #define COMMAND_LINE_OFFSET 0x9000
 #define COMMAND_LINE_OFFSET 0x9000
 
 
+__weak void board_quiesce_devices(void)
+{
+}
+
 void bootm_announce_and_cleanup(void)
 void bootm_announce_and_cleanup(void)
 {
 {
 	printf("\nStarting kernel ...\n\n");
 	printf("\nStarting kernel ...\n\n");

+ 0 - 0
arch/x86/lib/efi/crt0-efi-ia32.S → arch/x86/lib/crt0_ia32_efi.S


+ 0 - 0
arch/x86/lib/efi/crt0-efi-x86_64.S → arch/x86/lib/crt0_x86_64_efi.S


+ 0 - 18
arch/x86/lib/efi/Makefile

@@ -7,21 +7,3 @@
 
 
 obj-$(CONFIG_EFI_STUB) += car.o
 obj-$(CONFIG_EFI_STUB) += car.o
 obj-$(CONFIG_EFI_STUB) += efi.o
 obj-$(CONFIG_EFI_STUB) += efi.o
-
-obj-$(CONFIG_EFI_APP) += crt0-efi-ia32.o reloc_ia32.o
-
-ifneq ($(CONFIG_EFI_STUB),)
-
-CFLAGS_REMOVE_reloc_ia32.o += -mregparm=3
-CFLAGS_reloc_ia32.o += -fpic -fshort-wchar
-
-# When building for 64-bit we must remove the i386-specific flags
-CFLAGS_REMOVE_reloc_x86_64.o += -mregparm=3 -march=i386 -m32
-CFLAGS_reloc_x86_64.o += -fpic -fshort-wchar
-
-AFLAGS_REMOVE_crt0-efi-x86_64.o += -mregparm=3 -march=i386 -m32
-AFLAGS_crt0-efi-x86_64.o += -fpic -fshort-wchar
-
-extra-$(CONFIG_EFI_STUB_32BIT) += crt0-efi-ia32.o reloc_ia32.o
-extra-$(CONFIG_EFI_STUB_64BIT) += crt0-efi-x86_64.o reloc_x86_64.o
-endif

+ 0 - 2
arch/x86/cpu/efi/elf_ia32_efi.lds → arch/x86/lib/elf_ia32_efi.lds

@@ -6,8 +6,6 @@
  * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
  * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
  */
  */
 
 
-#include <config.h>
-
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
 OUTPUT_ARCH(i386)
 ENTRY(_start)
 ENTRY(_start)

+ 0 - 2
arch/x86/cpu/efi/elf_x86_64_efi.lds → arch/x86/lib/elf_x86_64_efi.lds

@@ -6,8 +6,6 @@
  * Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi
  * Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi
  */
  */
 
 
-#include <config.h>
-
 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
 OUTPUT_ARCH(i386:x86-64)
 OUTPUT_ARCH(i386:x86-64)
 ENTRY(_start)
 ENTRY(_start)

+ 0 - 0
arch/x86/lib/efi/reloc_ia32.c → arch/x86/lib/reloc_ia32_efi.c


+ 0 - 0
arch/x86/lib/efi/reloc_x86_64.c → arch/x86/lib/reloc_x86_64_efi.c


+ 2 - 0
arch/x86/lib/tables.c

@@ -12,10 +12,12 @@
 #include <asm/acpi_table.h>
 #include <asm/acpi_table.h>
 #include <asm/coreboot_tables.h>
 #include <asm/coreboot_tables.h>
 
 
+#ifdef CONFIG_GENERATE_SMBIOS_TABLE
 static u32 write_smbios_table_wrapper(u32 addr)
 static u32 write_smbios_table_wrapper(u32 addr)
 {
 {
 	return write_smbios_table(addr);
 	return write_smbios_table(addr);
 }
 }
+#endif
 
 
 /**
 /**
  * Function prototype to write a specific configuration table
  * Function prototype to write a specific configuration table

+ 5 - 1
board/freescale/ls2080a/ls2080a.c

@@ -102,6 +102,11 @@ void fdt_fixup_board_enet(void *fdt)
 	else
 	else
 		fdt_status_fail(fdt, offset);
 		fdt_status_fail(fdt, offset);
 }
 }
+
+void board_quiesce_devices(void)
+{
+	fsl_mc_ldpaa_exit(gd->bd);
+}
 #endif
 #endif
 
 
 #ifdef CONFIG_OF_BOARD_SETUP
 #ifdef CONFIG_OF_BOARD_SETUP
@@ -122,7 +127,6 @@ int ft_board_setup(void *blob, bd_t *bd)
 
 
 #ifdef CONFIG_FSL_MC_ENET
 #ifdef CONFIG_FSL_MC_ENET
 	fdt_fixup_board_enet(blob);
 	fdt_fixup_board_enet(blob);
-	fsl_mc_ldpaa_exit(bd);
 #endif
 #endif
 
 
 	return 0;
 	return 0;

+ 5 - 6
board/freescale/ls2080aqds/ls2080aqds.c

@@ -292,14 +292,16 @@ void fdt_fixup_board_enet(void *fdt)
 	else
 	else
 		fdt_status_fail(fdt, offset);
 		fdt_status_fail(fdt, offset);
 }
 }
+
+void board_quiesce_devices(void)
+{
+	fsl_mc_ldpaa_exit(gd->bd);
+}
 #endif
 #endif
 
 
 #ifdef CONFIG_OF_BOARD_SETUP
 #ifdef CONFIG_OF_BOARD_SETUP
 int ft_board_setup(void *blob, bd_t *bd)
 int ft_board_setup(void *blob, bd_t *bd)
 {
 {
-#ifdef CONFIG_FSL_MC_ENET
-	int err;
-#endif
 	u64 base[CONFIG_NR_DRAM_BANKS];
 	u64 base[CONFIG_NR_DRAM_BANKS];
 	u64 size[CONFIG_NR_DRAM_BANKS];
 	u64 size[CONFIG_NR_DRAM_BANKS];
 
 
@@ -317,9 +319,6 @@ int ft_board_setup(void *blob, bd_t *bd)
 
 
 #ifdef CONFIG_FSL_MC_ENET
 #ifdef CONFIG_FSL_MC_ENET
 	fdt_fixup_board_enet(blob);
 	fdt_fixup_board_enet(blob);
-	err = fsl_mc_ldpaa_exit(bd);
-	if (err)
-		return err;
 #endif
 #endif
 
 
 	return 0;
 	return 0;

+ 14 - 6
board/freescale/ls2080ardb/ls2080ardb.c

@@ -15,6 +15,7 @@
 #include <libfdt.h>
 #include <libfdt.h>
 #include <fsl-mc/fsl_mc.h>
 #include <fsl-mc/fsl_mc.h>
 #include <environment.h>
 #include <environment.h>
+#include <efi_loader.h>
 #include <i2c.h>
 #include <i2c.h>
 #include <asm/arch/soc.h>
 #include <asm/arch/soc.h>
 #include <fsl_sec.h>
 #include <fsl_sec.h>
@@ -201,6 +202,14 @@ int misc_init_r(void)
 	if (adjust_vdd(0))
 	if (adjust_vdd(0))
 		printf("Warning: Adjusting core voltage failed.\n");
 		printf("Warning: Adjusting core voltage failed.\n");
 
 
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
+	if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) {
+		efi_add_memory_map(gd->bd->bi_dram[2].start,
+				   gd->bd->bi_dram[2].size >> EFI_PAGE_SHIFT,
+				   EFI_RESERVED_MEMORY_TYPE, false);
+	}
+#endif
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -256,14 +265,16 @@ void fdt_fixup_board_enet(void *fdt)
 	else
 	else
 		fdt_status_fail(fdt, offset);
 		fdt_status_fail(fdt, offset);
 }
 }
+
+void board_quiesce_devices(void)
+{
+	fsl_mc_ldpaa_exit(gd->bd);
+}
 #endif
 #endif
 
 
 #ifdef CONFIG_OF_BOARD_SETUP
 #ifdef CONFIG_OF_BOARD_SETUP
 int ft_board_setup(void *blob, bd_t *bd)
 int ft_board_setup(void *blob, bd_t *bd)
 {
 {
-#ifdef CONFIG_FSL_MC_ENET
-	int err;
-#endif
 	u64 base[CONFIG_NR_DRAM_BANKS];
 	u64 base[CONFIG_NR_DRAM_BANKS];
 	u64 size[CONFIG_NR_DRAM_BANKS];
 	u64 size[CONFIG_NR_DRAM_BANKS];
 
 
@@ -281,9 +292,6 @@ int ft_board_setup(void *blob, bd_t *bd)
 
 
 #ifdef CONFIG_FSL_MC_ENET
 #ifdef CONFIG_FSL_MC_ENET
 	fdt_fixup_board_enet(blob);
 	fdt_fixup_board_enet(blob);
-	err = fsl_mc_ldpaa_exit(bd);
-	if (err)
-		return err;
 #endif
 #endif
 
 
 	return 0;
 	return 0;

+ 9 - 0
cmd/Kconfig

@@ -181,6 +181,15 @@ config CMD_BOOTEFI
 	help
 	help
 	  Boot an EFI image from memory.
 	  Boot an EFI image from memory.
 
 
+config CMD_BOOTEFI_HELLO
+	bool "Allow booting a standard EFI hello world for testing"
+	depends on CMD_BOOTEFI && (ARM || X86)
+	help
+	  This adds a standard EFI hello world application to U-Boot so that
+	  it can be used with the 'bootefi hello' command. This is useful
+	  for testing that EFI is working at a basic level, and for bringing
+	  up EFI support on a new architecture.
+
 config CMD_ELF
 config CMD_ELF
 	bool "bootelf, bootvx"
 	bool "bootelf, bootvx"
 	default y
 	default y

+ 33 - 7
cmd/bootefi.c

@@ -226,6 +226,17 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
 		return status == EFI_SUCCESS ? 0 : -EINVAL;
 		return status == EFI_SUCCESS ? 0 : -EINVAL;
 	}
 	}
 
 
+#ifdef CONFIG_ARM64
+	/* On AArch64 we need to make sure we call our payload in < EL3 */
+	if (current_el() == 3) {
+		smp_kick_all_cpus();
+		dcache_disable();	/* flush cache before switch to EL2 */
+		armv8_switch_to_el2();
+		/* Enable caches again */
+		dcache_enable();
+	}
+#endif
+
 	return entry(&loaded_image_info, &systab);
 	return entry(&loaded_image_info, &systab);
 }
 }
 
 
@@ -239,16 +250,26 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 
 	if (argc < 2)
 	if (argc < 2)
 		return CMD_RET_USAGE;
 		return CMD_RET_USAGE;
-	saddr = argv[1];
+#ifdef CONFIG_CMD_BOOTEFI_HELLO
+	if (!strcmp(argv[1], "hello")) {
+		ulong size = __efi_hello_world_end - __efi_hello_world_begin;
 
 
-	addr = simple_strtoul(saddr, NULL, 16);
+		addr = CONFIG_SYS_LOAD_ADDR;
+		memcpy((char *)addr, __efi_hello_world_begin, size);
+	} else
+#endif
+	{
+		saddr = argv[1];
+
+		addr = simple_strtoul(saddr, NULL, 16);
 
 
-	if (argc > 2) {
-		sfdt = argv[2];
-		fdt_addr = simple_strtoul(sfdt, NULL, 16);
+		if (argc > 2) {
+			sfdt = argv[2];
+			fdt_addr = simple_strtoul(sfdt, NULL, 16);
+		}
 	}
 	}
 
 
-	printf("## Starting EFI application at 0x%08lx ...\n", addr);
+	printf("## Starting EFI application at %08lx ...\n", addr);
 	r = do_bootefi_exec((void *)addr, (void*)fdt_addr);
 	r = do_bootefi_exec((void *)addr, (void*)fdt_addr);
 	printf("## Application terminated, r = %d\n", r);
 	printf("## Application terminated, r = %d\n", r);
 
 
@@ -263,7 +284,12 @@ static char bootefi_help_text[] =
 	"<image address> [fdt address]\n"
 	"<image address> [fdt address]\n"
 	"  - boot EFI payload stored at address <image address>.\n"
 	"  - boot EFI payload stored at address <image address>.\n"
 	"    If specified, the device tree located at <fdt address> gets\n"
 	"    If specified, the device tree located at <fdt address> gets\n"
-	"    exposed as EFI configuration table.\n";
+	"    exposed as EFI configuration table.\n"
+#ifdef CONFIG_CMD_BOOTEFI_HELLO
+	"hello\n"
+	"  - boot a sample Hello World application stored within U-Boot"
+#endif
+	;
 #endif
 #endif
 
 
 U_BOOT_CMD(
 U_BOOT_CMD(

+ 1 - 0
configs/efi-x86_defconfig

@@ -34,3 +34,4 @@ CONFIG_USB=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_EFI=y
 CONFIG_EFI=y
+# CONFIG_EFI_LOADER is not set

+ 14 - 0
doc/README.efi

@@ -310,6 +310,20 @@ 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
 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.
 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
 Future work
 -----------
 -----------
 
 

+ 0 - 1
doc/README.x86

@@ -1077,7 +1077,6 @@ TODO List
 ---------
 ---------
 - Audio
 - Audio
 - Chrome OS verified boot
 - Chrome OS verified boot
-- Support for CONFIG_EFI_LOADER
 - Building U-Boot to run in 64-bit mode
 - Building U-Boot to run in 64-bit mode
 
 
 References
 References

+ 22 - 2
drivers/net/fsl-mc/mc.c

@@ -40,6 +40,7 @@ int child_dprc_id;
 struct fsl_dpbp_obj *dflt_dpbp = NULL;
 struct fsl_dpbp_obj *dflt_dpbp = NULL;
 struct fsl_dpio_obj *dflt_dpio = NULL;
 struct fsl_dpio_obj *dflt_dpio = NULL;
 struct fsl_dpni_obj *dflt_dpni = NULL;
 struct fsl_dpni_obj *dflt_dpni = NULL;
+static u64 mc_lazy_dpl_addr;
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 void dump_ram_words(const char *title, void *addr)
 void dump_ram_words(const char *title, void *addr)
@@ -572,6 +573,9 @@ int mc_apply_dpl(u64 mc_dpl_addr)
 	u64 mc_ram_addr = mc_get_dram_addr();
 	u64 mc_ram_addr = mc_get_dram_addr();
 	size_t mc_ram_size = mc_get_dram_block_size();
 	size_t mc_ram_size = mc_get_dram_block_size();
 
 
+	if (!mc_dpl_addr)
+		return -1;
+
 	error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr);
 	error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr);
 	if (error != 0)
 	if (error != 0)
 		return error;
 		return error;
@@ -1156,6 +1160,11 @@ int fsl_mc_ldpaa_exit(bd_t *bd)
 {
 {
 	int err = 0;
 	int err = 0;
 
 
+	if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) {
+		mc_apply_dpl(mc_lazy_dpl_addr);
+		mc_lazy_dpl_addr = 0;
+	}
+
 	/* MC is not loaded intentionally, So return success. */
 	/* MC is not loaded intentionally, So return success. */
 	if (bd && get_mc_boot_status() != 0)
 	if (bd && get_mc_boot_status() != 0)
 		return 0;
 		return 0;
@@ -1259,6 +1268,7 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		}
 		}
 		break;
 		break;
 
 
+	case 'l':
 	case 'a': {
 	case 'a': {
 			u64 mc_dpl_addr;
 			u64 mc_dpl_addr;
 
 
@@ -1279,8 +1289,17 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 				return -ENODEV;
 				return -ENODEV;
 			}
 			}
 
 
-			if (!fsl_mc_ldpaa_exit(NULL))
-				err = mc_apply_dpl(mc_dpl_addr);
+			if (argv[1][0] == 'l') {
+				/*
+				 * We will do the actual dpaa exit and dpl apply
+				 * later from announce_and_cleanup().
+				 */
+				mc_lazy_dpl_addr = mc_dpl_addr;
+			} else {
+				/* The user wants it applied now */
+				if (!fsl_mc_ldpaa_exit(NULL))
+					err = mc_apply_dpl(mc_dpl_addr);
+			}
 			break;
 			break;
 		}
 		}
 	default:
 	default:
@@ -1298,5 +1317,6 @@ U_BOOT_CMD(
 	"DPAA2 command to manage Management Complex (MC)",
 	"DPAA2 command to manage Management Complex (MC)",
 	"start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
 	"start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
 	"fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
 	"fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
+	"fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
 	"fsl_mc start aiop [FW_addr] - Start AIOP\n"
 	"fsl_mc start aiop [FW_addr] - Start AIOP\n"
 );
 );

+ 2 - 0
include/asm-generic/sections.h

@@ -22,6 +22,8 @@ extern char __kprobes_text_start[], __kprobes_text_end[];
 extern char __entry_text_start[], __entry_text_end[];
 extern char __entry_text_start[], __entry_text_end[];
 extern char __initdata_begin[], __initdata_end[];
 extern char __initdata_begin[], __initdata_end[];
 extern char __start_rodata[], __end_rodata[];
 extern char __start_rodata[], __end_rodata[];
+extern char __efi_hello_world_begin[];
+extern char __efi_hello_world_end[];
 
 
 /* Start and end of .ctors section - used for constructor calls. */
 /* Start and end of .ctors section - used for constructor calls. */
 extern char __ctors_start[], __ctors_end[];
 extern char __ctors_start[], __ctors_end[];

+ 25 - 1
include/configs/ls2080ardb.h

@@ -316,10 +316,25 @@ unsigned long get_board_sys_clk(void);
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         2
 #define CONFIG_USB_MAX_CONTROLLER_COUNT         2
 #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS      2
 
 
+#undef CONFIG_CMDLINE_EDITING
+#include <config_distro_defaults.h>
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(USB, usb, 0) \
+	func(MMC, mmc, 0) \
+	func(SCSI, scsi, 0) \
+	func(DHCP, dhcp, na)
+#include <config_distro_bootcmd.h>
+
 /* Initial environment variables */
 /* Initial environment variables */
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #undef CONFIG_EXTRA_ENV_SETTINGS
 #define CONFIG_EXTRA_ENV_SETTINGS		\
 #define CONFIG_EXTRA_ENV_SETTINGS		\
 	"hwconfig=fsl_ddr:bank_intlv=auto\0"	\
 	"hwconfig=fsl_ddr:bank_intlv=auto\0"	\
+	"scriptaddr=0x80800000\0"		\
+	"kernel_addr_r=0x81000000\0"		\
+	"pxefile_addr_r=0x81000000\0"		\
+	"fdt_addr_r=0x88000000\0"		\
+	"ramdisk_addr_r=0x89000000\0"		\
 	"loadaddr=0x80100000\0"			\
 	"loadaddr=0x80100000\0"			\
 	"kernel_addr=0x100000\0"		\
 	"kernel_addr=0x100000\0"		\
 	"ramdisk_addr=0x800000\0"		\
 	"ramdisk_addr=0x800000\0"		\
@@ -329,8 +344,10 @@ unsigned long get_board_sys_clk(void);
 	"kernel_start=0x581100000\0"		\
 	"kernel_start=0x581100000\0"		\
 	"kernel_load=0xa0000000\0"		\
 	"kernel_load=0xa0000000\0"		\
 	"kernel_size=0x2800000\0"		\
 	"kernel_size=0x2800000\0"		\
+	"fdtfile=fsl-ls2080a-rdb.dtb\0"		\
 	"mcinitcmd=fsl_mc start mc 0x580300000"	\
 	"mcinitcmd=fsl_mc start mc 0x580300000"	\
-	" 0x580800000 \0"
+	" 0x580800000 \0"			\
+	BOOTENV
 
 
 #undef CONFIG_BOOTARGS
 #undef CONFIG_BOOTARGS
 #define CONFIG_BOOTARGS		"console=ttyS1,115200 root=/dev/ram0 " \
 #define CONFIG_BOOTARGS		"console=ttyS1,115200 root=/dev/ram0 " \
@@ -338,6 +355,13 @@ unsigned long get_board_sys_clk(void);
 				"ramdisk_size=0x2000000 default_hugepagesz=2m" \
 				"ramdisk_size=0x2000000 default_hugepagesz=2m" \
 				" hugepagesz=2m hugepages=256"
 				" hugepagesz=2m hugepages=256"
 
 
+#undef CONFIG_BOOTCOMMAND
+/* Try to boot an on-NOR kernel first, then do normal distro boot */
+#define CONFIG_BOOTCOMMAND "run mcinitcmd && fsl_mc lazyapply dpl 0x580700000" \
+			   " && cp.b $kernel_start $kernel_load $kernel_size" \
+			   " && bootm $kernel_load" \
+			   " || run distro_bootcmd"
+
 /* MAC/PHY configuration */
 /* MAC/PHY configuration */
 #ifdef CONFIG_FSL_MC_ENET
 #ifdef CONFIG_FSL_MC_ENET
 #define CONFIG_PHYLIB_10G
 #define CONFIG_PHYLIB_10G

+ 5 - 2
include/efi.h

@@ -30,8 +30,11 @@ struct efi_device_path;
 
 
 #define EFI_BITS_PER_LONG	BITS_PER_LONG
 #define EFI_BITS_PER_LONG	BITS_PER_LONG
 
 
-/* With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64 */
-#ifdef CONFIG_EFI_STUB_64BIT
+/*
+ * With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64. EFI_STUB is set
+ * in lib/efi/Makefile, when building the stub.
+ */
+#if defined(CONFIG_EFI_STUB_64BIT) && defined(EFI_STUB)
 #undef EFI_BITS_PER_LONG
 #undef EFI_BITS_PER_LONG
 #define EFI_BITS_PER_LONG	64
 #define EFI_BITS_PER_LONG	64
 #endif
 #endif

+ 13 - 0
include/efi_api.h

@@ -268,6 +268,19 @@ struct efi_device_path {
 	u16 length;
 	u16 length;
 };
 };
 
 
+struct efi_mac_addr {
+	u8 addr[32];
+};
+
+#define DEVICE_PATH_TYPE_MESSAGING_DEVICE	0x03
+#  define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR	0x0b
+
+struct efi_device_path_mac_addr {
+	struct efi_device_path dp;
+	struct efi_mac_addr mac;
+	u8 if_type;
+};
+
 #define DEVICE_PATH_TYPE_MEDIA_DEVICE		0x04
 #define DEVICE_PATH_TYPE_MEDIA_DEVICE		0x04
 #  define DEVICE_PATH_SUB_TYPE_FILE_PATH	0x04
 #  define DEVICE_PATH_SUB_TYPE_FILE_PATH	0x04
 
 

+ 1 - 1
include/efi_loader.h

@@ -181,7 +181,7 @@ void efi_get_time_init(void);
 /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */
 /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */
 #define __efi_runtime_data
 #define __efi_runtime_data
 #define __efi_runtime
 #define __efi_runtime
-static inline void efi_add_runtime_mmio(void **mmio_ptr, u64 len) { }
+static inline void efi_add_runtime_mmio(void *mmio_ptr, u64 len) { }
 
 
 /* No loader configured, stub out EFI_ENTRY */
 /* No loader configured, stub out EFI_ENTRY */
 static inline void efi_restore_gd(void) { }
 static inline void efi_restore_gd(void) { }

+ 13 - 0
include/elf.h

@@ -13,6 +13,7 @@
 #ifndef _ELF_H
 #ifndef _ELF_H
 #define _ELF_H
 #define _ELF_H
 
 
+#ifndef __ASSEMBLER__
 #include "compiler.h"
 #include "compiler.h"
 
 
 /*
 /*
@@ -517,6 +518,8 @@ unsigned long elf_hash(const unsigned char *name);
 
 
 #define ELF_TARG_VER	1	/* The ver for which this code is intended */
 #define ELF_TARG_VER	1	/* The ver for which this code is intended */
 
 
+#endif /* __ASSEMBLER */
+
 /*
 /*
  * XXX - PowerPC defines really don't belong in here,
  * XXX - PowerPC defines really don't belong in here,
  * but we'll put them in for simplicity.
  * but we'll put them in for simplicity.
@@ -602,6 +605,16 @@ unsigned long elf_hash(const unsigned char *name);
    that may still be in object files.  */
    that may still be in object files.  */
 #define R_PPC_TOC16             255
 #define R_PPC_TOC16             255
 
 
+ /* ARM relocs */
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_RELATIVE		23	/* Adjust by program base */
+
+/* AArch64 relocs */
+#define R_AARCH64_NONE		0	/* No relocation.  */
+#define R_AARCH64_RELATIVE	1027	/* Adjust by program base.  */
+
+#ifndef __ASSEMBLER__
 int valid_elf_image(unsigned long addr);
 int valid_elf_image(unsigned long addr);
+#endif
 
 
 #endif /* _ELF_H */
 #endif /* _ELF_H */

+ 2 - 2
lib/efi/Makefile

@@ -9,9 +9,9 @@ obj-$(CONFIG_EFI_STUB) += efi_info.o
 
 
 CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
 CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
 	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
 	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
-CFLAGS_efi_stub.o := -fpic -fshort-wchar
+CFLAGS_efi_stub.o := -fpic -fshort-wchar -DEFI_STUB
 CFLAGS_REMOVE_efi.o := -mregparm=3 \
 CFLAGS_REMOVE_efi.o := -mregparm=3 \
 	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
 	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
-CFLAGS_efi.o := -fpic -fshort-wchar
+CFLAGS_efi.o := -fpic -fshort-wchar -DEFI_STUB
 
 
 extra-$(CONFIG_EFI_STUB) += efi_stub.o efi.o
 extra-$(CONFIG_EFI_STUB) += efi_stub.o efi.o

+ 1 - 1
lib/efi_loader/Kconfig

@@ -1,6 +1,6 @@
 config EFI_LOADER
 config EFI_LOADER
 	bool "Support running EFI Applications in U-Boot"
 	bool "Support running EFI Applications in U-Boot"
-	depends on (ARM64 || ARM) && OF_LIBFDT
+	depends on (ARM || X86) && OF_LIBFDT
 	default y
 	default y
 	help
 	help
 	  Select this option if you want to run EFI applications (like grub2)
 	  Select this option if you want to run EFI applications (like grub2)

+ 4 - 0
lib/efi_loader/Makefile

@@ -7,6 +7,10 @@
 # This file only gets included with CONFIG_EFI_LOADER set, so all
 # This file only gets included with CONFIG_EFI_LOADER set, so all
 # object inclusion implicitly depends on it
 # object inclusion implicitly depends on it
 
 
+CFLAGS_helloworld.o := $(CFLAGS_EFI)
+CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI)
+
+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_image_loader.o efi_boottime.o efi_runtime.o efi_console.o
 obj-y += efi_memory.o
 obj-y += efi_memory.o
 obj-$(CONFIG_LCD) += efi_gop.o
 obj-$(CONFIG_LCD) += efi_gop.o

+ 2 - 0
lib/efi_loader/efi_boottime.c

@@ -538,6 +538,8 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
 {
 {
 	EFI_ENTRY("%p, %ld", image_handle, map_key);
 	EFI_ENTRY("%p, %ld", image_handle, map_key);
 
 
+	board_quiesce_devices();
+
 	/* Fix up caches for EFI payloads if necessary */
 	/* Fix up caches for EFI payloads if necessary */
 	efi_exit_caches();
 	efi_exit_caches();
 
 

+ 84 - 16
lib/efi_loader/efi_console.c

@@ -9,11 +9,38 @@
 #include <common.h>
 #include <common.h>
 #include <efi_loader.h>
 #include <efi_loader.h>
 
 
-/* If we can't determine the console size, default to 80x24 */
-static int console_columns = 80;
-static int console_rows = 24;
 static bool console_size_queried;
 static bool console_size_queried;
 
 
+#define EFI_COUT_MODE_2 2
+#define EFI_MAX_COUT_MODE 3
+
+struct cout_mode {
+	unsigned long columns;
+	unsigned long rows;
+	int present;
+};
+
+static struct cout_mode efi_cout_modes[] = {
+	/* EFI Mode 0 is 80x25 and always present */
+	{
+		.columns = 80,
+		.rows = 25,
+		.present = 1,
+	},
+	/* EFI Mode 1 is always 80x50 */
+	{
+		.columns = 80,
+		.rows = 50,
+		.present = 0,
+	},
+	/* Value are unknown until we query the console */
+	{
+		.columns = 0,
+		.rows = 0,
+		.present = 0,
+	},
+};
+
 const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID;
 const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID;
 
 
 #define cESC '\x1b'
 #define cESC '\x1b'
@@ -56,8 +83,9 @@ const struct efi_console_control_protocol efi_console_control = {
 	.lock_std_in = efi_cin_lock_std_in,
 	.lock_std_in = efi_cin_lock_std_in,
 };
 };
 
 
+/* Default to mode 0 */
 static struct simple_text_output_mode efi_con_mode = {
 static struct simple_text_output_mode efi_con_mode = {
-	.max_mode = 0,
+	.max_mode = 1,
 	.mode = 0,
 	.mode = 0,
 	.attribute = 0,
 	.attribute = 0,
 	.cursor_column = 0,
 	.cursor_column = 0,
@@ -131,8 +159,10 @@ static efi_status_t EFIAPI efi_cout_output_string(
 			struct efi_simple_text_output_protocol *this,
 			struct efi_simple_text_output_protocol *this,
 			const unsigned short *string)
 			const unsigned short *string)
 {
 {
+	struct cout_mode *mode;
 	u16 ch;
 	u16 ch;
 
 
+	mode = &efi_cout_modes[efi_con_mode.mode];
 	EFI_ENTRY("%p, %p", this, string);
 	EFI_ENTRY("%p, %p", this, string);
 	for (;(ch = *string); string++) {
 	for (;(ch = *string); string++) {
 		print_unicode_in_utf8(ch);
 		print_unicode_in_utf8(ch);
@@ -140,13 +170,12 @@ static efi_status_t EFIAPI efi_cout_output_string(
 		if (ch == '\n') {
 		if (ch == '\n') {
 			efi_con_mode.cursor_column = 1;
 			efi_con_mode.cursor_column = 1;
 			efi_con_mode.cursor_row++;
 			efi_con_mode.cursor_row++;
-		} else if (efi_con_mode.cursor_column > console_columns) {
+		} else if (efi_con_mode.cursor_column > mode->columns) {
 			efi_con_mode.cursor_column = 1;
 			efi_con_mode.cursor_column = 1;
 			efi_con_mode.cursor_row++;
 			efi_con_mode.cursor_row++;
 		}
 		}
-		if (efi_con_mode.cursor_row > console_rows) {
-			efi_con_mode.cursor_row = console_rows;
-		}
+		if (efi_con_mode.cursor_row > mode->rows)
+			efi_con_mode.cursor_row = mode->rows;
 	}
 	}
 
 
 	return EFI_EXIT(EFI_SUCCESS);
 	return EFI_EXIT(EFI_SUCCESS);
@@ -160,6 +189,14 @@ static efi_status_t EFIAPI efi_cout_test_string(
 	return EFI_EXIT(EFI_SUCCESS);
 	return EFI_EXIT(EFI_SUCCESS);
 }
 }
 
 
+static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
+{
+	if (!mode->present)
+		return false;
+
+	return (mode->rows == rows) && (mode->columns == cols);
+}
+
 static efi_status_t EFIAPI efi_cout_query_mode(
 static efi_status_t EFIAPI efi_cout_query_mode(
 			struct efi_simple_text_output_protocol *this,
 			struct efi_simple_text_output_protocol *this,
 			unsigned long mode_number, unsigned long *columns,
 			unsigned long mode_number, unsigned long *columns,
@@ -170,6 +207,8 @@ static efi_status_t EFIAPI efi_cout_query_mode(
 	if (!console_size_queried) {
 	if (!console_size_queried) {
 		/* Ask the terminal about its size */
 		/* Ask the terminal about its size */
 		int n[3];
 		int n[3];
+		int cols;
+		int rows;
 		u64 timeout;
 		u64 timeout;
 
 
 		console_size_queried = true;
 		console_size_queried = true;
@@ -191,15 +230,40 @@ static efi_status_t EFIAPI efi_cout_query_mode(
 			goto out;
 			goto out;
 		}
 		}
 
 
-		console_columns = n[2];
-		console_rows = n[1];
+		cols = n[2];
+		rows = n[1];
+
+		/* Test if we can have Mode 1 */
+		if (cols >= 80 && rows >= 50) {
+			efi_cout_modes[1].present = 1;
+			efi_con_mode.max_mode = 2;
+		}
+
+		/*
+		 * Install our mode as mode 2 if it is different
+		 * than mode 0 or 1 and set it  as the currently selected mode
+		 */
+		if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
+		    !cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
+			efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
+			efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
+			efi_cout_modes[EFI_COUT_MODE_2].present = 1;
+			efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
+			efi_con_mode.mode = EFI_COUT_MODE_2;
+		}
 	}
 	}
 
 
+	if (mode_number >= efi_con_mode.max_mode)
+		return EFI_EXIT(EFI_UNSUPPORTED);
+
+	if (efi_cout_modes[mode_number].present != 1)
+		return EFI_EXIT(EFI_UNSUPPORTED);
+
 out:
 out:
 	if (columns)
 	if (columns)
-		*columns = console_columns;
+		*columns = efi_cout_modes[mode_number].columns;
 	if (rows)
 	if (rows)
-		*rows = console_rows;
+		*rows = efi_cout_modes[mode_number].rows;
 
 
 	return EFI_EXIT(EFI_SUCCESS);
 	return EFI_EXIT(EFI_SUCCESS);
 }
 }
@@ -210,11 +274,15 @@ static efi_status_t EFIAPI efi_cout_set_mode(
 {
 {
 	EFI_ENTRY("%p, %ld", this, mode_number);
 	EFI_ENTRY("%p, %ld", this, mode_number);
 
 
-	/* We only support text output for now */
-	if (mode_number == EFI_CONSOLE_MODE_TEXT)
-		return EFI_EXIT(EFI_SUCCESS);
 
 
-	return EFI_EXIT(EFI_UNSUPPORTED);
+	if (mode_number > efi_con_mode.max_mode)
+		return EFI_EXIT(EFI_UNSUPPORTED);
+
+	efi_con_mode.mode = mode_number;
+	efi_con_mode.cursor_column = 0;
+	efi_con_mode.cursor_row = 0;
+
+	return EFI_EXIT(EFI_SUCCESS);
 }
 }
 
 
 static efi_status_t EFIAPI efi_cout_set_attribute(
 static efi_status_t EFIAPI efi_cout_set_attribute(

+ 2 - 1
lib/efi_loader/efi_image_loader.c

@@ -174,7 +174,8 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
 	efi_loader_relocate(rel, rel_size, efi_reloc);
 	efi_loader_relocate(rel, rel_size, efi_reloc);
 
 
 	/* Flush cache */
 	/* Flush cache */
-	flush_cache((ulong)efi_reloc, virt_size);
+	flush_cache((ulong)efi_reloc,
+		    ALIGN(virt_size, CONFIG_SYS_CACHELINE_SIZE));
 	invalidate_icache_all();
 	invalidate_icache_all();
 
 
 	/* Populate the loaded image interface bits */
 	/* Populate the loaded image interface bits */

+ 9 - 8
lib/efi_loader/efi_net.c

@@ -27,7 +27,8 @@ struct efi_net_obj {
 	struct efi_simple_network net;
 	struct efi_simple_network net;
 	struct efi_simple_network_mode net_mode;
 	struct efi_simple_network_mode net_mode;
 	/* Device path to the network adapter */
 	/* Device path to the network adapter */
-	struct efi_device_path_file_path dp[2];
+	struct efi_device_path_mac_addr dp_mac;
+	struct efi_device_path_file_path dp_end;
 	/* PXE struct to transmit dhcp data */
 	/* PXE struct to transmit dhcp data */
 	struct efi_pxe pxe;
 	struct efi_pxe pxe;
 	struct efi_pxe_mode pxe_mode;
 	struct efi_pxe_mode pxe_mode;
@@ -205,7 +206,7 @@ static efi_status_t EFIAPI efi_net_open_dp(void *handle, efi_guid_t *protocol,
 	struct efi_simple_network *net = handle;
 	struct efi_simple_network *net = handle;
 	struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
 	struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
 
 
-	*protocol_interface = netobj->dp;
+	*protocol_interface = &netobj->dp_mac;
 
 
 	return EFI_SUCCESS;
 	return EFI_SUCCESS;
 }
 }
@@ -236,11 +237,10 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
 int efi_net_register(void **handle)
 int efi_net_register(void **handle)
 {
 {
 	struct efi_net_obj *netobj;
 	struct efi_net_obj *netobj;
-	struct efi_device_path_file_path dp_net = {
-		.dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE,
-		.dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH,
+	struct efi_device_path_mac_addr dp_net = {
+		.dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE,
+		.dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR,
 		.dp.length = sizeof(dp_net),
 		.dp.length = sizeof(dp_net),
-		.str = { 'N', 'e', 't' },
 	};
 	};
 	struct efi_device_path_file_path dp_end = {
 	struct efi_device_path_file_path dp_end = {
 		.dp.type = DEVICE_PATH_TYPE_END,
 		.dp.type = DEVICE_PATH_TYPE_END,
@@ -279,8 +279,9 @@ int efi_net_register(void **handle)
 	netobj->net.receive = efi_net_receive;
 	netobj->net.receive = efi_net_receive;
 	netobj->net.mode = &netobj->net_mode;
 	netobj->net.mode = &netobj->net_mode;
 	netobj->net_mode.state = EFI_NETWORK_STARTED;
 	netobj->net_mode.state = EFI_NETWORK_STARTED;
-	netobj->dp[0] = dp_net;
-	netobj->dp[1] = dp_end;
+	netobj->dp_mac = dp_net;
+	netobj->dp_end = dp_end;
+	memcpy(netobj->dp_mac.mac.addr, eth_get_ethaddr(), 6);
 	memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
 	memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
 	netobj->net_mode.max_packet_size = PKTSIZE;
 	netobj->net_mode.max_packet_size = PKTSIZE;
 
 

+ 24 - 0
lib/efi_loader/helloworld.c

@@ -0,0 +1,24 @@
+/*
+ * EFI hello world
+ *
+ * Copyright (c) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <part_efi.h>
+#include <efi_api.h>
+
+efi_status_t EFIAPI efi_main(efi_handle_t handle,
+			     struct efi_system_table *systable)
+{
+	struct efi_simple_text_output_protocol *con_out = systable->con_out;
+	struct efi_boot_services *boottime = systable->boottime;
+
+	con_out->output_string(con_out, L"Hello, world!\n");
+	boottime->exit(handle, 0, 0, NULL);
+
+	return EFI_SUCCESS;
+}

+ 33 - 0
scripts/Makefile.lib

@@ -321,6 +321,39 @@ cmd_S_ttf=						\
 $(obj)/%.S: $(src)/%.ttf
 $(obj)/%.S: $(src)/%.ttf
 	$(call cmd,S_ttf)
 	$(call cmd,S_ttf)
 
 
+# EFI Hello World application
+# ---------------------------------------------------------------------------
+
+# Generate an assembly file to wrap the EFI app
+cmd_S_efi=						\
+(							\
+	echo '.section .rodata.efi.init,"a"';		\
+	echo '.balign 16';				\
+	echo '.global __efi_hello_world_begin';		\
+	echo '__efi_hello_world_begin:';		\
+	echo '.incbin "$<" ';				\
+	echo '__efi_hello_world_end:';			\
+	echo '.global __efi_hello_world_end';		\
+	echo '.balign 16';				\
+) > $@
+
+$(obj)/%_efi.S: $(obj)/%.efi
+	$(call cmd,S_efi)
+
+$(obj)/%.efi: $(obj)/%.so
+	$(OBJCOPY) -j .header -j .text -j .sdata -j .data -j .dynamic \
+		-j .dynsym  -j .rel* -j .rela* -j .reloc \
+		$(if $(EFI_TARGET),$(EFI_TARGET),-O binary) $^ $@
+
+EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
+
+$(obj)/helloworld.so: $(EFI_LDS_PATH)
+
+$(obj)/helloworld.so: $(obj)/helloworld.o arch/$(ARCH)/lib/$(EFI_CRT0) \
+		arch/$(ARCH)/lib/$(EFI_RELOC)
+	$(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared -Bsymbolic \
+		$^ -o $@
+
 # ACPI
 # ACPI
 # ---------------------------------------------------------------------------
 # ---------------------------------------------------------------------------
 quiet_cmd_acpi_c_asl= ASL     $<
 quiet_cmd_acpi_c_asl= ASL     $<