efi: Create a 64-bit app

Most modern platforms use 64-bit EFI so it is useful to have a U-Boot app
that runs under that. Add a (non-functional) build for this.

Note that --whole-archive causes the gcc 9.2 linker to crash, so disable
this for now. Once this is resolved, things should work.

For now, avoid mentioning the documentation for the 64-bit app, since it
does not work.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
diff --git a/MAINTAINERS b/MAINTAINERS
index fa7fe90..00ff572 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -709,6 +709,9 @@
 M:	Heinrich Schuchardt <xypron.glpk@gmx.de>
 S:	Maintained
 W:	https://u-boot.readthedocs.io/en/latest/develop/uefi/u-boot_on_efi.html
+F:	board/efi/efi-x86_app
+F:	configs/efi-x86_app*
+F:	doc/develop/uefi/u-boot_on_efi.rst
 F:	lib/efi/efi_app.c
 F:	scripts/build-efi.sh
 
diff --git a/Makefile b/Makefile
index bf78009..ea884fe 100644
--- a/Makefile
+++ b/Makefile
@@ -1756,12 +1756,16 @@
 		-Wl,-Map,u-boot.map;						\
 		$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
 else
+# Note: Linking efi-x86_app64 causes a segfault in the linker at present
+# when using x86_64-linux-gnu-ld.bfd
+# For now, disable --whole-archive which makes things link, although not
+# correctly
 quiet_cmd_u-boot__ ?= LD      $@
       cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@		\
 		-T u-boot.lds $(u-boot-init)					\
-		--whole-archive							\
+		$(if $(CONFIG_EFI_APP_64BIT),,--whole-archive)			\
 			$(u-boot-main)						\
-		--no-whole-archive						\
+		$(if $(CONFIG_EFI_APP_64BIT),,--no-whole-archive)		\
 		$(PLATFORM_LIBS) -Map u-boot.map;				\
 		$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
 endif
diff --git a/arch/x86/cpu/u-boot-64.lds b/arch/x86/cpu/u-boot-64.lds
index ee0812a..92a30c2 100644
--- a/arch/x86/cpu/u-boot-64.lds
+++ b/arch/x86/cpu/u-boot-64.lds
@@ -15,7 +15,9 @@
 	/DISCARD/ : { *(.u_boot_list_2_cmd_*) }
 #endif
 
+#ifdef CONFIG_SYS_TEXT_BASE
 	. = CONFIG_SYS_TEXT_BASE;	/* Location of bootcode in flash */
+#endif
 	__text_start = .;
 
 	.text.start : { *(.text.start); }
diff --git a/arch/x86/cpu/x86_64/Makefile b/arch/x86/cpu/x86_64/Makefile
index 400f0ff..e929563 100644
--- a/arch/x86/cpu/x86_64/Makefile
+++ b/arch/x86/cpu/x86_64/Makefile
@@ -4,3 +4,7 @@
 #
 
 obj-y += cpu.o interrupts.o setjmp.o
+
+ifndef CONFIG_EFI
+obj-y += misc.o
+endif
diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c
index 90a766c..8f72c99 100644
--- a/arch/x86/cpu/x86_64/cpu.c
+++ b/arch/x86/cpu/x86_64/cpu.c
@@ -49,23 +49,6 @@
 	return 0;
 }
 
-int misc_init_r(void)
-{
-	return 0;
-}
-
-#ifndef CONFIG_SYS_COREBOOT
-int checkcpu(void)
-{
-	return 0;
-}
-
-int print_cpuinfo(void)
-{
-	return 0;
-}
-#endif
-
 int x86_cpu_reinit_f(void)
 {
 	return 0;
diff --git a/arch/x86/cpu/x86_64/misc.c b/arch/x86/cpu/x86_64/misc.c
new file mode 100644
index 0000000..02587ff
--- /dev/null
+++ b/arch/x86/cpu/x86_64/misc.c
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <init.h>
+
+int misc_init_r(void)
+{
+	return 0;
+}
+
+#ifndef CONFIG_SYS_COREBOOT
+int checkcpu(void)
+{
+	return 0;
+}
+
+int print_cpuinfo(void)
+{
+	return 0;
+}
+#endif
diff --git a/board/efi/Kconfig b/board/efi/Kconfig
index 291bd2c..3df6e31 100644
--- a/board/efi/Kconfig
+++ b/board/efi/Kconfig
@@ -4,14 +4,25 @@
 	prompt "Mainboard model"
 	optional
 
-config TARGET_EFI_APP
-	bool "efi application"
+config TARGET_EFI_APP32
+	bool "32-bit efi application"
+	select EFI_APP
 	help
 	  This target is used for running U-Boot on top of EFI. In
 	  this case EFI does the early initialisation, and U-Boot
 	  takes over once the RAM, video and CPU are fully running.
 	  U-Boot is loaded as an application from EFI.
 
+config TARGET_EFI_APP64
+	bool "64-bit efi application"
+	select EFI_APP
+	select X86_64
+	help
+	  This target is used for running U-Boot on top of EFI in 64-bit mode.
+	  In this case EFI does the early initialisation, and U-Boot
+	  takes over once the RAM, video and CPU are fully running.
+	  U-Boot is loaded as an application from EFI.
+
 config TARGET_EFI_PAYLOAD
 	bool "efi payload"
 	help
diff --git a/board/efi/efi-x86_app/Kconfig b/board/efi/efi-x86_app/Kconfig
index ae87bf3..e412702 100644
--- a/board/efi/efi-x86_app/Kconfig
+++ b/board/efi/efi-x86_app/Kconfig
@@ -1,4 +1,4 @@
-if TARGET_EFI_APP
+if EFI_APP
 
 config SYS_BOARD
 	default "efi-x86_app"
diff --git a/board/efi/efi-x86_app/MAINTAINERS b/board/efi/efi-x86_app/MAINTAINERS
index fb8a6b1..b292811 100644
--- a/board/efi/efi-x86_app/MAINTAINERS
+++ b/board/efi/efi-x86_app/MAINTAINERS
@@ -1,6 +1,13 @@
-EFI-X86_APP BOARD
+EFI-X86_APP32 BOARD
 M:	Simon Glass <sjg@chromium.org>
 S:	Maintained
 F:	board/efi/efi-x86_app/
 F:	include/configs/efi-x86_app.h
-F:	configs/efi-x86_app_defconfig
+F:	configs/efi-x86_app32_defconfig
+
+EFI-X86_APP64 BOARD
+M:	Simon Glass <sjg@chromium.org>
+S:	Maintained
+F:	board/efi/efi-x86_app/
+F:	include/configs/efi-x86_app.h
+F:	configs/efi-x86_app64_defconfig
diff --git a/configs/efi-x86_app_defconfig b/configs/efi-x86_app32_defconfig
similarity index 96%
rename from configs/efi-x86_app_defconfig
rename to configs/efi-x86_app32_defconfig
index f0bc877..480ef64 100644
--- a/configs/efi-x86_app_defconfig
+++ b/configs/efi-x86_app32_defconfig
@@ -5,7 +5,7 @@
 CONFIG_DEBUG_UART_BASE=0
 CONFIG_DEBUG_UART_CLOCK=0
 CONFIG_VENDOR_EFI=y
-CONFIG_TARGET_EFI_APP=y
+CONFIG_TARGET_EFI_APP32=y
 CONFIG_DEBUG_UART=y
 CONFIG_FIT=y
 CONFIG_SHOW_BOOT_PROGRESS=y
diff --git a/configs/efi-x86_app_defconfig b/configs/efi-x86_app64_defconfig
similarity index 94%
copy from configs/efi-x86_app_defconfig
copy to configs/efi-x86_app64_defconfig
index f0bc877..bffbf69 100644
--- a/configs/efi-x86_app_defconfig
+++ b/configs/efi-x86_app64_defconfig
@@ -5,7 +5,7 @@
 CONFIG_DEBUG_UART_BASE=0
 CONFIG_DEBUG_UART_CLOCK=0
 CONFIG_VENDOR_EFI=y
-CONFIG_TARGET_EFI_APP=y
+CONFIG_TARGET_EFI_APP64=y
 CONFIG_DEBUG_UART=y
 CONFIG_FIT=y
 CONFIG_SHOW_BOOT_PROGRESS=y
@@ -35,3 +35,4 @@
 # CONFIG_REGEX is not set
 # CONFIG_GZIP is not set
 CONFIG_EFI=y
+CONFIG_EFI_APP_64BIT=y
diff --git a/doc/develop/uefi/u-boot_on_efi.rst b/doc/develop/uefi/u-boot_on_efi.rst
index 8856af3..f275a52 100644
--- a/doc/develop/uefi/u-boot_on_efi.rst
+++ b/doc/develop/uefi/u-boot_on_efi.rst
@@ -48,10 +48,10 @@
 opt for using QEMU [1] and the OVMF [2], as detailed below.
 
 To build U-Boot as an EFI application (32-bit EFI required), enable CONFIG_EFI
-and CONFIG_EFI_APP. The efi-x86_app config (efi-x86_app_defconfig) is set up
+and CONFIG_EFI_APP. The efi-x86_app config (efi-x86_app32_defconfig) is set up
 for this. Just build U-Boot as normal, e.g.::
 
-   make efi-x86_app_defconfig
+   make efi-x86_app32_defconfig
    make
 
 To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), enable
@@ -261,7 +261,7 @@
 
 - Add ARM support
 
-- Add 64-bit application support
+- Add 64-bit application support (in progress)
 
 - Figure out how to solve the interrupt problem
 
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 52f71c0..700dc83 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -12,6 +12,7 @@
 	depends on !EFI_STUB || !X86 || X86_64 || EFI_STUB_32BIT
 	depends on BLK
 	depends on DM_ETH || !NET
+	depends on !EFI_APP
 	default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8
 	select LIB_UUID
 	select PARTITION_UUIDS