All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application
@ 2015-08-04 18:33 Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 01/28] Add a way to skip relocation Simon Glass
                   ` (27 more replies)
  0 siblings, 28 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

This series allows U-Boot to be build as an EFI payload so that U-Boot
can be started on almost any x86 platform that supports EFI. This is
implemented as a stub which EFI can load plus a payload that is copied
to RAM. The payload contains a normal U-Boot binary image and device tree.

This allows U-Boot to run on platforms that have EFI support but are not
supported natively by U-Boot. It also allows testing and fiddling with the
board using U-Boots memory display and other commands.

In addition, U-Boot can be built as an EFI application. This should work
regardless of the board type since it only relies on EFI services. However
only 32-bit EFI is supported in this case. Again it can be used to snoop
around the platform.

A README provides further details of how this series operates.

Changes in v3:
- Add new patch to allow device tree relocation to be disabled
- Add spaces around EFIARCH=
- Drop LDFLAGS_EFI from this patch
- Fix calling convention to starting U-Boot in the 32-bit stub
- Move '-m elf_i386' into the common PLATFORM_LDFLAGS
- Move 64-bit comment to just above the 64-bit flag adjustments
- Move the rename to u-boot-app.efi into this patch
- Move u-boot-app.efi Makefile change to the earlier patch
- Rename LDFLAGS_EFI to LDFLAGS_EFI_PAYLOAD and move into this patch
- Update the patch subject
- Use "BSD-2-Clause" for the SPDX license
- Use CONFIG_SYS_MONITOR_LEN as a more accurate value for U-Boot's size
- Use quiet_cmd_xxx to link the payload

Changes in v2:
- Add -no-red-zone for 64-bit only
- Add ALIGN() before .dynamic in the linker script
- Add a blank line before return in the _relocate() function
- Add a comment about special handling for backspace
- Add a comment about the REX prefix
- Add a comment as to where LDFLAGS_EFI is used
- Add a comment as to why .hash has to be first in the linker script
- Add a comment as to why debug_uart_init() is empty
- Add a comment as to why interrupt_init() must be skipped for EFI
- Add a comment as to why the AFLAGS_REMOVE_.. lines are needed
- Add a comment as to why we must call exit_boot_services() twice
- Add a note that bootm does not work when running as an EFI app
- Add descriptor bits for the base and limit
- Change 'link script' to 'linker script'
- Check the GDT selector's base and limit against the target address
- Drop . = 0x0;
- Drop \n\t at the end of a one-line asm statement
- Drop a left-over debug printf()
- Drop duplicate OBJCOPYFLAGS_EFI
- Drop no-red-zone as it is not needed for i386
- Drop patch "Add a link script entry for U-Boot as a payload"
- Drop the REX prefix in 32-bit mode
- Drop unnecessary .section .text
- Drop unnecessary SYS_CAR_ADDR/SIZE Kconfig options
- Drop unneeded include of asm/ptrace.h
- Drop unused DECLARE_GLOBAL_DATA_INIT
- Drop unused DECLARE_GLOBAL_DATA_PTR
- Drop unused board_eth_init()
- Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application yet
- Fix alignment of region index field in the output
- Fix comment style
- Fix efi_mem_desc_VERSION typo
- Fix indenting in board/emulation/qemu-x86/Kconfig
- Fix indenting in board/intel/minnowmax/Kconfig
- Fix reference to elf_ia32_efi instead of elf_x86_64_efi
- Fix spacing around operators
- Fix text alignment in Kconfig files
- Merge in Bin's implementation of adding a U-Boot payload with objcopy
- Move 64-bit crt0 to a later patch
- Move EFI CAR settings to arch/x86/lib/efi/Kconfig
- Move crt0 and reloc files into arch/x86/lib/efi/
- Move the 64-bit crt and reloc code into this patch
- Move the 64-bit efi.h additions into this patch
- Move the crt and reloc files into arch/x86/lib/efi/
- Output the region index in decimal
- Remove CONFIG_SYS_EARLY_PCI_INIT and CONFIG_PCI_PNP
- Remove KEEP in the EFI linker script since garbage collection is not enabled
- Remove comment about reset_cpu() returning to EFI in the stub
- Remove extraneous '+' in comment
- Remove superfluous Kconfig options
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
- Rename CONFIG_DEBUG_UART_EFI to CONFIG_DEBUG_EFI_CONSOLE
- Rename EFI debug UART to EFI_CONSOLE
- Rename GDT_4GB to GDT_4KB
- Rename ImageBase to image_base
- Replace 'Coreboot' with 'coreboot'
- Replace serial_s5p with serial_efi
- Return early in copy_uboot_to_ram() and clear_bbs() when relocation disabled
- Set text_base to 0 to avoid possible compiler warning
- Update based on the elf.h changes
- Use "efi,app" instead of "efi,payload" for the compatible string
- Use CONFIG_EFI_APP instead of CONFIG_ARCH_EFI
- Use SPDX for the EFI start and relocation code
- Use toolchain instead of tool chain
- Use u-boot-app.efi instead of u-boot.efi
- Zero BIST when starting from EFI/coreboot

Ben Stoltz (5):
  efi: Drop CONFIG_SYS_TEXT_BASE for EFI
  x86: Set up toolchain flags for running as EFI application
  x86: Add support for U-Boot as an EFI application
  x86: Add EFI board code
  x86: Add definitions for the x86-efi board and plumb it in

Simon Glass (23):
  Add a way to skip relocation
  efi: Add a serial driver
  efi: Support building a u-boot-app.efi executable
  x86: Support skipping relocation for EFI
  x86: Add asm/elf.h for x86-specific ELF definitions
  x86: dts: Add a device tree file for EFI
  x86: Allow relocation code to build without text base
  x86: Add relocation and link script for a 64-bit EFI application
  efi: Add support for loading U-Boot through an EFI stub
  x86: Support building the EFI stub
  x86: Add an enum for some commonly-used GDT bits
  x86: Add a way to call 32-bit code from 64-bit mode
  efi: Add 64-bit payload support
  x86: Add support for passing tables into U-Boot
  efi: Add functions for decoding the EFI tables
  efi: Add a command to display the memory map
  x86: Handle running as EFI payload
  x86: Add helper code for running from EFI
  x86: baytrail: Support operation as an EFI payload
  x86: qemu: Support operation as an EFI payload
  x86: Gracefully disable the vesa driver when running from EFI
  efi: Add a README to explain how things work
  Allow device tree relocation to be disabled

 Kconfig                              |   1 +
 Makefile                             |  29 +++
 arch/x86/Kconfig                     |  10 +
 arch/x86/Makefile                    |   2 +
 arch/x86/config.mk                   |  47 ++++-
 arch/x86/cpu/Makefile                |   7 +
 arch/x86/cpu/baytrail/Kconfig        |   2 +-
 arch/x86/cpu/baytrail/cpu.c          |   2 +
 arch/x86/cpu/baytrail/valleyview.c   |   2 +
 arch/x86/cpu/call32.S                |  64 ++++++
 arch/x86/cpu/cpu.c                   |  21 +-
 arch/x86/cpu/efi/Makefile            |   8 +
 arch/x86/cpu/efi/efi.c               |  42 ++++
 arch/x86/cpu/efi/elf_ia32_efi.lds    |  94 +++++++++
 arch/x86/cpu/efi/elf_x86_64_efi.lds  |  83 ++++++++
 arch/x86/cpu/efi/sdram.c             |  29 +++
 arch/x86/cpu/interrupts.c            |  16 +-
 arch/x86/cpu/qemu/Makefile           |   5 +-
 arch/x86/cpu/qemu/qemu.c             |   2 +
 arch/x86/cpu/start.S                 |  19 +-
 arch/x86/dts/Makefile                |   1 +
 arch/x86/dts/efi.dts                 |  22 +++
 arch/x86/include/asm/arch-efi/gpio.h |  10 +
 arch/x86/include/asm/cpu.h           |  27 +++
 arch/x86/include/asm/elf.h           |  46 +++++
 arch/x86/include/asm/global_data.h   |   1 +
 arch/x86/include/asm/types.h         |   5 +-
 arch/x86/lib/Makefile                |   3 +-
 arch/x86/lib/asm-offsets.c           |   1 +
 arch/x86/lib/bootm.c                 |   5 +
 arch/x86/lib/efi/Kconfig             |  11 ++
 arch/x86/lib/efi/Makefile            |  27 +++
 arch/x86/lib/efi/car.S               |  10 +
 arch/x86/lib/efi/crt0-efi-ia32.S     |  52 +++++
 arch/x86/lib/efi/crt0-efi-x86_64.S   |  51 +++++
 arch/x86/lib/efi/efi.c               | 151 ++++++++++++++
 arch/x86/lib/efi/reloc_ia32.c        |  72 +++++++
 arch/x86/lib/efi/reloc_x86_64.c      |  66 +++++++
 arch/x86/lib/relocate.c              |  23 ++-
 board/efi/Kconfig                    |  19 ++
 board/efi/efi-x86/Kconfig            |  15 ++
 board/efi/efi-x86/MAINTAINERS        |   6 +
 board/efi/efi-x86/Makefile           |   7 +
 board/efi/efi-x86/efi.c              |  18 ++
 board/emulation/qemu-x86/Kconfig     |   5 +-
 board/intel/minnowmax/Kconfig        |   5 +-
 common/Makefile                      |   1 +
 common/board_f.c                     |   9 +
 common/cmd_efi.c                     | 257 ++++++++++++++++++++++++
 configs/efi-x86_defconfig            |  16 ++
 doc/README.efi                       | 237 ++++++++++++++++++++++
 drivers/serial/Kconfig               |   9 +
 drivers/serial/Makefile              |   1 +
 drivers/serial/serial_efi.c          | 157 +++++++++++++++
 drivers/video/vesa_fb.c              |   8 +
 include/asm-generic/global_data.h    |   1 +
 include/common.h                     |   7 +
 include/configs/efi-x86.h            |  34 ++++
 include/efi.h                        |  11 ++
 lib/efi/Kconfig                      |  21 ++
 lib/efi/Makefile                     |  10 +
 lib/efi/efi_info.c                   |  47 +++++
 lib/efi/efi_stub.c                   | 370 +++++++++++++++++++++++++++++++++++
 63 files changed, 2312 insertions(+), 28 deletions(-)
 create mode 100644 arch/x86/cpu/call32.S
 create mode 100644 arch/x86/cpu/efi/Makefile
 create mode 100644 arch/x86/cpu/efi/efi.c
 create mode 100644 arch/x86/cpu/efi/elf_ia32_efi.lds
 create mode 100644 arch/x86/cpu/efi/elf_x86_64_efi.lds
 create mode 100644 arch/x86/cpu/efi/sdram.c
 create mode 100644 arch/x86/dts/efi.dts
 create mode 100644 arch/x86/include/asm/arch-efi/gpio.h
 create mode 100644 arch/x86/include/asm/elf.h
 create mode 100644 arch/x86/lib/efi/Kconfig
 create mode 100644 arch/x86/lib/efi/Makefile
 create mode 100644 arch/x86/lib/efi/car.S
 create mode 100644 arch/x86/lib/efi/crt0-efi-ia32.S
 create mode 100644 arch/x86/lib/efi/crt0-efi-x86_64.S
 create mode 100644 arch/x86/lib/efi/efi.c
 create mode 100644 arch/x86/lib/efi/reloc_ia32.c
 create mode 100644 arch/x86/lib/efi/reloc_x86_64.c
 create mode 100644 board/efi/Kconfig
 create mode 100644 board/efi/efi-x86/Kconfig
 create mode 100644 board/efi/efi-x86/MAINTAINERS
 create mode 100644 board/efi/efi-x86/Makefile
 create mode 100644 board/efi/efi-x86/efi.c
 create mode 100644 common/cmd_efi.c
 create mode 100644 configs/efi-x86_defconfig
 create mode 100644 doc/README.efi
 create mode 100644 drivers/serial/serial_efi.c
 create mode 100644 include/configs/efi-x86.h
 create mode 100644 lib/efi/efi_info.c
 create mode 100644 lib/efi/efi_stub.c

-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 01/28] Add a way to skip relocation
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:41   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 02/28] efi: Add a serial driver Simon Glass
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

When running U-Boot as an EFI application we cannot relocate since we do not
have relocation information. U-Boot has already been relocated to a suitable
address.

Add a global_data flag to control skipping relocation.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2: None

 common/board_f.c                  | 7 +++++++
 include/asm-generic/global_data.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/common/board_f.c b/common/board_f.c
index 6d922b8..c596083 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -664,6 +664,11 @@ static int reloc_fdt(void)
 
 static int setup_reloc(void)
 {
+	if (gd->flags & GD_FLG_SKIP_RELOC) {
+		debug("Skipping relocation due to flag\n");
+		return 0;
+	}
+
 #ifdef CONFIG_SYS_TEXT_BASE
 	gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
 #ifdef CONFIG_M68K
@@ -689,6 +694,8 @@ static int setup_reloc(void)
 
 static int jump_to_copy(void)
 {
+	if (gd->flags & GD_FLG_SKIP_RELOC)
+		return 0;
 	/*
 	 * x86 is special, but in a nice way. It uses a trampoline which
 	 * enables the dcache if possible.
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 9f5db0f..2155265 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -117,5 +117,6 @@ typedef struct global_data {
 #define GD_FLG_SERIAL_READY	0x00100	/* Pre-reloc serial console ready  */
 #define GD_FLG_FULL_MALLOC_INIT	0x00200	/* Full malloc() is ready	   */
 #define GD_FLG_SPL_INIT		0x00400	/* spl_init() has been called	   */
+#define GD_FLG_SKIP_RELOC	0x00800	/* Don't relocate */
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 02/28] efi: Add a serial driver
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 01/28] Add a way to skip relocation Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:02   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 03/28] efi: Drop CONFIG_SYS_TEXT_BASE for EFI Simon Glass
                   ` (25 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

Add a serial driver which makes use of EFI's console in/out service.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested on Intel Crown Bay and QEMU
Tested-by: Bin Meng <bmeng.cn@gmail.com>

---

Changes in v3: None
Changes in v2:
- Add a comment about special handling for backspace
- Add a comment as to why debug_uart_init() is empty
- Drop unused DECLARE_GLOBAL_DATA_PTR
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
- Rename EFI debug UART to EFI_CONSOLE
- Replace serial_s5p with serial_efi

 drivers/serial/Kconfig      |   9 +++
 drivers/serial/Makefile     |   1 +
 drivers/serial/serial_efi.c | 157 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 167 insertions(+)
 create mode 100644 drivers/serial/serial_efi.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 078246d..b5a91b7 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -44,6 +44,15 @@ config DEBUG_UART_NS16550
 	  will need to provide parameters to make this work. The driver will
 	  be available until the real driver model serial is running.
 
+config DEBUG_EFI_CONSOLE
+	bool "EFI"
+	depends on EFI_APP
+	help
+	  Select this to enable a debug console which calls back to EFI to
+	  output to the console. This can be useful for early debugging of
+	  U-Boot when running on top of EFI (Extensive Firmware Interface).
+	  This is a type of BIOS used by PCs.
+
 endchoice
 
 config DEBUG_UART_BASE
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index d183eed..1d1f036 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
 obj-$(CONFIG_ARM_DCC) += arm_dcc.o
 obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
 obj-$(CONFIG_DW_SERIAL) += serial_dw.o
+obj-$(CONFIG_EFI_APP) += serial_efi.o
 obj-$(CONFIG_LPC32XX_HSUART) += lpc32xx_hsuart.o
 obj-$(CONFIG_MCFUART) += mcfuart.o
 obj-$(CONFIG_OPENCORES_YANU) += opencores_yanu.o
diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c
new file mode 100644
index 0000000..cf57d89
--- /dev/null
+++ b/drivers/serial/serial_efi.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <efi.h>
+#include <efi_api.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <linux/compiler.h>
+#include <asm/io.h>
+#include <serial.h>
+
+/* Information about the efi console */
+struct serial_efi_priv {
+	struct efi_simple_input_interface *con_in;
+	struct efi_simple_text_output_protocol *con_out;
+	struct efi_input_key key;
+	bool have_key;
+};
+
+int serial_efi_setbrg(struct udevice *dev, int baudrate)
+{
+	return 0;
+}
+
+static int serial_efi_get_key(struct serial_efi_priv *priv)
+{
+	int ret;
+
+	if (priv->have_key)
+		return 0;
+	ret = priv->con_in->read_key_stroke(priv->con_in, &priv->key);
+	if (ret == EFI_NOT_READY)
+		return -EAGAIN;
+	else if (ret != EFI_SUCCESS)
+		return -EIO;
+
+	priv->have_key = true;
+
+	return 0;
+}
+
+static int serial_efi_getc(struct udevice *dev)
+{
+	struct serial_efi_priv *priv = dev_get_priv(dev);
+	int ret, ch;
+
+	ret = serial_efi_get_key(priv);
+	if (ret)
+		return ret;
+
+	priv->have_key = false;
+	ch = priv->key.unicode_char;
+
+	/*
+	 * Unicode char 8 (for backspace) is never returned. Instead we get a
+	 * key scan code of 8. Handle this so that backspace works correctly
+	 * in the U-Boot command line.
+	 */
+	if (!ch && priv->key.scan_code == 8)
+		ch = 8;
+	debug(" [%x %x %x] ", ch, priv->key.unicode_char, priv->key.scan_code);
+
+	return ch;
+}
+
+static int serial_efi_putc(struct udevice *dev, const char ch)
+{
+	struct serial_efi_priv *priv = dev_get_priv(dev);
+	uint16_t ucode[2];
+	int ret;
+
+	ucode[0] = ch;
+	ucode[1] = '\0';
+	ret = priv->con_out->output_string(priv->con_out, ucode);
+	if (ret)
+		return -EIO;
+
+	return 0;
+}
+
+static int serial_efi_pending(struct udevice *dev, bool input)
+{
+	struct serial_efi_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	/* We assume that EFI will stall if its output buffer fills up */
+	if (!input)
+		return 0;
+
+	ret = serial_efi_get_key(priv);
+	if (ret == -EAGAIN)
+		return 0;
+	else if (ret)
+		return ret;
+
+	return 1;
+}
+
+/*
+ * There is nothing to init here since the EFI console is already running by
+ * the time we enter U-Boot.
+ */
+void debug_uart_init(void)
+{
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+	struct efi_system_table *sys_table = efi_get_sys_table();
+	uint16_t ucode[2];
+
+	ucode[0] = ch;
+	ucode[1] = '\0';
+	sys_table->con_out->output_string(sys_table->con_out, ucode);
+}
+
+DEBUG_UART_FUNCS
+
+static int serial_efi_probe(struct udevice *dev)
+{
+	struct efi_system_table *table = efi_get_sys_table();
+	struct serial_efi_priv *priv = dev_get_priv(dev);
+
+	priv->con_in = table->con_in;
+	priv->con_out = table->con_out;
+
+	return 0;
+}
+
+static const struct dm_serial_ops serial_efi_ops = {
+	.putc = serial_efi_putc,
+	.getc = serial_efi_getc,
+	.pending = serial_efi_pending,
+	.setbrg = serial_efi_setbrg,
+};
+
+static const struct udevice_id serial_efi_ids[] = {
+	{ .compatible = "efi,uart" },
+	{ }
+};
+
+U_BOOT_DRIVER(serial_efi) = {
+	.name	= "serial_efi",
+	.id	= UCLASS_SERIAL,
+	.of_match = serial_efi_ids,
+	.priv_auto_alloc_size = sizeof(struct serial_efi_priv),
+	.probe = serial_efi_probe,
+	.ops	= &serial_efi_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 03/28] efi: Drop CONFIG_SYS_TEXT_BASE for EFI
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 01/28] Add a way to skip relocation Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 02/28] efi: Add a serial driver Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:02   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 04/28] x86: Set up toolchain flags for running as EFI application Simon Glass
                   ` (24 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

From: Ben Stoltz <stoltz@google.com>

When U-Boot runs as an EFI application is does not have a definition of
CONFIG_SYS_TEXT_BASE. U-Boot is a relocatable application and the relocation
is done by EFI. U-Boot can be loaded at any address.

Ensure that this CONFIG option is not set in this case.

Signed-off-by: Ben Stoltz <stoltz@google.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP

 Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Kconfig b/Kconfig
index fc69189..05a34f7 100644
--- a/Kconfig
+++ b/Kconfig
@@ -179,6 +179,7 @@ config SYS_EXTRA_OPTIONS
 
 config SYS_TEXT_BASE
 	depends on SPARC || ARC || X86 || ARCH_UNIPHIER || ARCH_ZYNQMP
+	depends on !EFI_APP
 	hex "Text Base"
 	help
 	  TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 04/28] x86: Set up toolchain flags for running as EFI application
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (2 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 03/28] efi: Drop CONFIG_SYS_TEXT_BASE for EFI Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:41   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 05/28] efi: Support building a u-boot-app.efi executable Simon Glass
                   ` (23 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

From: Ben Stoltz <stoltz@google.com>

Adjust the toolchain flags to build U-Boot as a relocatable shared library,
as required by EFI.

Signed-off-by: Ben Stoltz <stoltz@google.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Add spaces around EFIARCH=
- Drop LDFLAGS_EFI from this patch
- Move '-m elf_i386' into the common PLATFORM_LDFLAGS

Changes in v2:
- Add a comment as to where LDFLAGS_EFI is used
- Drop duplicate OBJCOPYFLAGS_EFI
- Drop no-red-zone as it is not needed for i386
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
- Use toolchain instead of tool chain

 arch/x86/config.mk | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 999143e..e27f84a 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -8,19 +8,43 @@
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
 
 PLATFORM_CPPFLAGS += -fno-strict-aliasing
-PLATFORM_CPPFLAGS += -mregparm=3
 PLATFORM_CPPFLAGS += -fomit-frame-pointer
 PF_CPPFLAGS_X86   := $(call cc-option, -fno-toplevel-reorder, \
 		       $(call cc-option, -fno-unit-at-a-time)) \
 		     $(call cc-option, -mpreferred-stack-boundary=2)
+
 PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86)
 PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
 PLATFORM_CPPFLAGS += -march=i386 -m32
 
 PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
 
-PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions -m elf_i386
+PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions -m elf_i386
 
-LDFLAGS_FINAL += --gc-sections -pie
 LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
 LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
+
+OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
+	-j .rel -j .rela -j .reloc
+
+CFLAGS_NON_EFI := -mregparm=3
+CFLAGS_EFI := -fpic -fshort-wchar
+
+EFIARCH = ia32
+
+LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
+OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
+
+ifeq ($(CONFIG_EFI_APP),y)
+
+PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
+LDFLAGS_FINAL += -znocombreloc -shared
+LDSCRIPT := $(LDSCRIPT_EFI)
+
+else
+
+PLATFORM_CPPFLAGS += $(CFLAGS_NON_EFI)
+PLATFORM_LDFLAGS += --emit-relocs
+LDFLAGS_FINAL += --gc-sections -pie
+
+endif
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 05/28] efi: Support building a u-boot-app.efi executable
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (3 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 04/28] x86: Set up toolchain flags for running as EFI application Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:42   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 06/28] x86: Support skipping relocation for EFI Simon Glass
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

Add support for building U-Boot as an EFI application with a .efi suffix.
This can be loaded by EFI provided that EFI has the same bit width (32-
or 64-bit) as U-Boot. This unfortunate limitation is imposed by EFI.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Move the rename to u-boot-app.efi into this patch
- Update the patch subject

Changes in v2:
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP

 Makefile | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Makefile b/Makefile
index 1b03357..620c18f 100644
--- a/Makefile
+++ b/Makefile
@@ -754,6 +754,7 @@ ifneq ($(CONFIG_SPL_TARGET),)
 ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
 endif
 ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
+ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
 
 ifneq ($(BUILD_ROM),)
 ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
@@ -1082,6 +1083,10 @@ u-boot-dtb-tegra.bin: u-boot-nodtb-tegra.bin dts/dt.dtb FORCE
 endif
 endif
 
+OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)
+u-boot-app.efi: u-boot FORCE
+	$(call if_changed,zobjcopy)
+
 u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE
 	$(call if_changed,cat)
 
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 06/28] x86: Support skipping relocation for EFI
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (4 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 05/28] efi: Support building a u-boot-app.efi executable Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:42   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 07/28] x86: Add asm/elf.h for x86-specific ELF definitions Simon Glass
                   ` (21 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

When running as an EFI application we must skip relocation. Add support for
this in the x86 relocation code.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3: None
Changes in v2:
- Return early in copy_uboot_to_ram() and clear_bbs() when relocation disabled

 arch/x86/lib/relocate.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c
index 1a62142..9e748d2 100644
--- a/arch/x86/lib/relocate.c
+++ b/arch/x86/lib/relocate.c
@@ -28,6 +28,8 @@ int copy_uboot_to_ram(void)
 {
 	size_t len = (size_t)&__data_end - (size_t)&__text_start;
 
+	if (gd->flags & GD_FLG_SKIP_RELOC)
+		return 0;
 	memcpy((void *)gd->relocaddr, (void *)&__text_start, len);
 
 	return 0;
@@ -38,6 +40,8 @@ int clear_bss(void)
 	ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
 	size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
 
+	if (gd->flags & GD_FLG_SKIP_RELOC)
+		return 0;
 	memset((void *)dst_addr, 0x00, len);
 
 	return 0;
@@ -58,6 +62,8 @@ int do_elf_reloc_fixups(void)
 	/* The size of the region of u-boot that runs out of RAM. */
 	uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
 
+	if (gd->flags & GD_FLG_SKIP_RELOC)
+		return 0;
 	if (re_src == re_end)
 		panic("No relocation data");
 
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 07/28] x86: Add asm/elf.h for x86-specific ELF definitions
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (5 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 06/28] x86: Support skipping relocation for EFI Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:02   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 08/28] x86: Add support for U-Boot as an EFI application Simon Glass
                   ` (20 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

Bring in this file from Linux 4.1. It supports relocation features specific
to x86.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Drop unneeded include of asm/ptrace.h
- Fix comment style

 arch/x86/include/asm/elf.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 arch/x86/include/asm/elf.h

diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
new file mode 100644
index 0000000..3bdcdfe
--- /dev/null
+++ b/arch/x86/include/asm/elf.h
@@ -0,0 +1,46 @@
+/*
+ * Brought in from Linux 4.1, removed things not useful to U-Boot.
+ * The definitions perhaps came from the GNU Library which is GPL.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ASM_X86_ELF_H
+#define _ASM_X86_ELF_H
+
+/* ELF register definitions */
+#define R_386_NONE	0
+#define R_386_32	1
+#define R_386_PC32	2
+#define R_386_GOT32	3
+#define R_386_PLT32	4
+#define R_386_COPY	5
+#define R_386_GLOB_DAT	6
+#define R_386_JMP_SLOT	7
+#define R_386_RELATIVE	8
+#define R_386_GOTOFF	9
+#define R_386_GOTPC	10
+#define R_386_NUM	11
+
+/* x86-64 relocation types */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+/* 32 bit signed pc relative offset to GOT */
+#define R_X86_64_GOTPCREL	9
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+
+#define R_X86_64_NUM		16
+
+#endif
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 08/28] x86: Add support for U-Boot as an EFI application
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (6 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 07/28] x86: Add asm/elf.h for x86-specific ELF definitions Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:42   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 09/28] x86: Add EFI board code Simon Glass
                   ` (19 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

From: Ben Stoltz <stoltz@google.com>

Add the required x86 glue code. This includes the initial start-up,
relocation and jumping to efi_main(). We also need to avoid fiddling with
interrupts.

Signed-off-by: Ben Stoltz <stoltz@google.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Move u-boot-app.efi Makefile change to the earlier patch
- Use "BSD-2-Clause" for the SPDX license

Changes in v2:
- Add ALIGN() before .dynamic in the linker script
- Add a blank line before return in the _relocate() function
- Add a comment as to why .hash has to be first in the linker script
- Add a comment as to why interrupt_init() must be skipped for EFI
- Drop unused DECLARE_GLOBAL_DATA_INIT
- Drop unused board_eth_init()
- Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application yet
- Fix spacing around operators
- Move 64-bit crt0 to a later patch
- Move crt0 and reloc files into arch/x86/lib/efi/
- Remove KEEP in the EFI linker script since garbage collection is not enabled
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
- Rename ImageBase to image_base
- Use SPDX for the EFI start and relocation code
- Use u-boot-app.efi instead of u-boot.efi

 arch/x86/Kconfig                     |  3 ++
 arch/x86/Makefile                    |  2 +
 arch/x86/cpu/Makefile                |  1 +
 arch/x86/cpu/efi/Makefile            |  8 +++
 arch/x86/cpu/efi/efi.c               | 42 ++++++++++++++++
 arch/x86/cpu/efi/elf_ia32_efi.lds    | 94 ++++++++++++++++++++++++++++++++++++
 arch/x86/cpu/efi/sdram.c             | 29 +++++++++++
 arch/x86/cpu/interrupts.c            |  6 +++
 arch/x86/include/asm/arch-efi/gpio.h | 10 ++++
 arch/x86/lib/efi/crt0-efi-ia32.S     | 52 ++++++++++++++++++++
 arch/x86/lib/efi/reloc_ia32.c        | 72 +++++++++++++++++++++++++++
 11 files changed, 319 insertions(+)
 create mode 100644 arch/x86/cpu/efi/Makefile
 create mode 100644 arch/x86/cpu/efi/efi.c
 create mode 100644 arch/x86/cpu/efi/elf_ia32_efi.lds
 create mode 100644 arch/x86/cpu/efi/sdram.c
 create mode 100644 arch/x86/include/asm/arch-efi/gpio.h
 create mode 100644 arch/x86/lib/efi/crt0-efi-ia32.S
 create mode 100644 arch/x86/lib/efi/reloc_ia32.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e8968a7..7e6e89c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -11,6 +11,9 @@ choice
 config VENDOR_COREBOOT
 	bool "coreboot"
 
+config VENDOR_EFI
+	bool "efi"
+
 config VENDOR_EMULATION
 	bool "emulation"
 
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 36a6018..d104a49 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -2,7 +2,9 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+ifeq ($(CONFIG_EFI_APP),)
 head-y := arch/x86/cpu/start.o
+endif
 ifeq ($(CONFIG_SPL_BUILD),y)
 head-y += arch/x86/cpu/start16.o
 head-y += arch/x86/cpu/resetvec.o
diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 8a8e63e..5e058c0 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -14,6 +14,7 @@ obj-y	+= interrupts.o cpu.o cpu_x86.o call64.o
 
 obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
 obj-$(CONFIG_SYS_COREBOOT) += coreboot/
+obj-$(CONFIG_EFI_APP) += efi/
 obj-$(CONFIG_QEMU) += qemu/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
diff --git a/arch/x86/cpu/efi/Makefile b/arch/x86/cpu/efi/Makefile
new file mode 100644
index 0000000..e091637
--- /dev/null
+++ b/arch/x86/cpu/efi/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += efi.o
+obj-y += sdram.o
diff --git a/arch/x86/cpu/efi/efi.c b/arch/x86/cpu/efi/efi.c
new file mode 100644
index 0000000..75ba0d4
--- /dev/null
+++ b/arch/x86/cpu/efi/efi.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <netdev.h>
+
+int arch_cpu_init(void)
+{
+#ifdef CONFIG_SYS_X86_TSC_TIMER
+	timer_set_base(rdtsc());
+#endif
+
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	return 0;
+}
+
+int print_cpuinfo(void)
+{
+	return default_print_cpuinfo();
+}
+
+void board_final_cleanup(void)
+{
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
+
+int arch_misc_init(void)
+{
+	return 0;
+}
diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds b/arch/x86/cpu/efi/elf_ia32_efi.lds
new file mode 100644
index 0000000..cd3b0a9
--- /dev/null
+++ b/arch/x86/cpu/efi/elf_ia32_efi.lds
@@ -0,0 +1,94 @@
+/*
+ * U-Boot EFI linker script
+ *
+ * SPDX-License-Identifier:	BSD-2-Clause
+ *
+ * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
+ */
+
+#include <config.h>
+
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+	image_base = .;
+	.hash : { *(.hash) }	/* this MUST come first, EFI expects it */
+	. = ALIGN(4096);
+	.text :
+	{
+		*(.text)
+		*(.text.*)
+		*(.gnu.linkonce.t.*)
+	}
+	. = ALIGN(4096);
+	.sdata :
+	{
+		*(.got.plt)
+		*(.got)
+		*(.srodata)
+		*(.sdata)
+		*(.sbss)
+		*(.scommon)
+	}
+	. = ALIGN(4096);
+	.data :
+	{
+		*(.rodata*)
+		*(.data)
+		*(.data1)
+		*(.data.*)
+		*(.sdata)
+		*(.got.plt)
+		*(.got)
+		/*
+		 * the EFI loader doesn't seem to like a .bss section, so we
+		 * stick it all into .data:
+		 */
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(COMMON)
+
+		/* U-Boot lists and device tree */
+		. = ALIGN(8);
+		*(SORT(.u_boot_list*));
+		. = ALIGN(8);
+		*(.dtb*);
+	}
+
+	. = ALIGN(4096);
+	.dynamic  : { *(.dynamic) }
+	. = ALIGN(4096);
+	.rel :
+	{
+		*(.rel.data)
+		*(.rel.data.*)
+		*(.rel.got)
+		*(.rel.stab)
+		*(.data.rel.ro.local)
+		*(.data.rel.local)
+		*(.data.rel.ro)
+		*(.data.rel*)
+		*(.rel.u_boot_list*)
+	}
+	. = ALIGN(4096);
+		.reloc :	/* This is the PECOFF .reloc section! */
+	{
+	*(.reloc)
+	}
+	. = ALIGN(4096);
+	.dynsym   : { *(.dynsym) }
+	. = ALIGN(4096);
+	.dynstr   : { *(.dynstr) }
+	. = ALIGN(4096);
+	/DISCARD/ :
+	{
+		*(.rel.reloc)
+		*(.eh_frame)
+		*(.note.GNU-stack)
+	}
+	.comment 0 : { *(.comment) }
+}
diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c
new file mode 100644
index 0000000..5159944
--- /dev/null
+++ b/arch/x86/cpu/efi/sdram.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <asm/u-boot-x86.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	return (ulong)efi_get_ram_base() + gd->ram_size;
+}
+
+int dram_init(void)
+{
+	/* gd->ram_size is set as part of EFI init */
+
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = efi_get_ram_base();
+	gd->bd->bi_dram[0].size = CONFIG_EFI_RAM_SIZE;
+}
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index 3a9c2d4..a112938 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -242,6 +242,11 @@ int disable_interrupts(void)
 
 int interrupt_init(void)
 {
+	/*
+	 * When running as an EFI application we are not in control of
+	 * interrupts and should leave them alone.
+	 */
+#ifndef CONFIG_EFI_APP
 	/* Just in case... */
 	disable_interrupts();
 
@@ -255,6 +260,7 @@ int interrupt_init(void)
 
 	/* It is now safe to enable interrupts */
 	enable_interrupts();
+#endif
 
 	return 0;
 }
diff --git a/arch/x86/include/asm/arch-efi/gpio.h b/arch/x86/include/asm/arch-efi/gpio.h
new file mode 100644
index 0000000..f044f07
--- /dev/null
+++ b/arch/x86/include/asm/arch-efi/gpio.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2015 Google, Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _X86_ARCH_GPIO_H_
+#define _X86_ARCH_GPIO_H_
+
+#endif /* _X86_ARCH_GPIO_H_ */
diff --git a/arch/x86/lib/efi/crt0-efi-ia32.S b/arch/x86/lib/efi/crt0-efi-ia32.S
new file mode 100644
index 0000000..30e5eb0
--- /dev/null
+++ b/arch/x86/lib/efi/crt0-efi-ia32.S
@@ -0,0 +1,52 @@
+/*
+ * crt0-efi-ia32.S - x86 EFI startup code.
+ *
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+	.text
+	.align 4
+
+	.globl _start
+_start:
+	pushl %ebp
+	movl %esp,%ebp
+
+	pushl 12(%ebp)			# copy "image" argument
+	pushl  8(%ebp)			# copy "systab" argument
+
+	call 0f
+0:	popl %eax
+	movl %eax,%ebx
+
+	addl $image_base-0b,%eax	# %eax = ldbase
+	addl $_DYNAMIC-0b,%ebx		# %ebx = _DYNAMIC
+
+	pushl %ebx			# pass _DYNAMIC as second argument
+	pushl %eax			# pass ldbase as first argument
+	call _relocate
+	popl %ebx
+	popl %ebx
+	testl %eax,%eax
+	jne .exit
+	call efi_main		# call app with "image" and "systab" argument
+
+.exit:	leave
+	ret
+
+	/*
+	 * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+	 * executable:
+	 */
+	.data
+dummy:	.long	0
+
+#define IMAGE_REL_ABSOLUTE	0
+	.section .reloc
+	.long	dummy					/* Page RVA */
+	.long	10					/* Block Size (2*4+2) */
+	.word	(IMAGE_REL_ABSOLUTE << 12) +  0		/* reloc for dummy */
diff --git a/arch/x86/lib/efi/reloc_ia32.c b/arch/x86/lib/efi/reloc_ia32.c
new file mode 100644
index 0000000..4d68255
--- /dev/null
+++ b/arch/x86/lib/efi/reloc_ia32.c
@@ -0,0 +1,72 @@
+/*
+ * reloc_ia32.c - position independent x86 ELF shared object relocator
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <elf.h>
+#include <asm/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;
+	unsigned long *addr;
+	int i;
+
+	for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+		switch (dyn[i].d_tag) {
+		case DT_REL:
+			rel = (Elf32_Rel *)((unsigned long)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;
+
+		case DT_RELA:
+			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_386_NONE:
+			break;
+
+		case R_386_RELATIVE:
+			addr = (unsigned long *)(ldbase + rel->r_offset);
+			*addr += ldbase;
+			break;
+
+		default:
+			break;
+		}
+		rel = (Elf32_Rel *)((char *)rel + relent);
+		relsz -= relent;
+	}
+
+	return EFI_SUCCESS;
+}
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 09/28] x86: Add EFI board code
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (7 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 08/28] x86: Add support for U-Boot as an EFI application Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:41   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 10/28] x86: dts: Add a device tree file for EFI Simon Glass
                   ` (18 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

From: Ben Stoltz <stoltz@google.com>

Add support for the efi-x86 board, which supports running U-Boot as an
EFI 32-bit application.

Signed-off-by: Ben Stoltz <stoltz@google.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Drop unnecessary SYS_CAR_ADDR/SIZE Kconfig options
- Fix text alignment in Kconfig files

 arch/x86/Kconfig              |  1 +
 board/efi/Kconfig             | 19 +++++++++++++++++++
 board/efi/efi-x86/Kconfig     | 15 +++++++++++++++
 board/efi/efi-x86/MAINTAINERS |  6 ++++++
 board/efi/efi-x86/Makefile    |  7 +++++++
 board/efi/efi-x86/efi.c       | 18 ++++++++++++++++++
 6 files changed, 66 insertions(+)
 create mode 100644 board/efi/Kconfig
 create mode 100644 board/efi/efi-x86/Kconfig
 create mode 100644 board/efi/efi-x86/MAINTAINERS
 create mode 100644 board/efi/efi-x86/Makefile
 create mode 100644 board/efi/efi-x86/efi.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7e6e89c..f124d58 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -27,6 +27,7 @@ endchoice
 
 # board-specific options below
 source "board/coreboot/Kconfig"
+source "board/efi/Kconfig"
 source "board/emulation/Kconfig"
 source "board/google/Kconfig"
 source "board/intel/Kconfig"
diff --git a/board/efi/Kconfig b/board/efi/Kconfig
new file mode 100644
index 0000000..6f86a48
--- /dev/null
+++ b/board/efi/Kconfig
@@ -0,0 +1,19 @@
+if VENDOR_EFI
+
+choice
+	prompt "Mainboard model"
+	optional
+
+config TARGET_EFI
+	bool "efi"
+	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.
+
+endchoice
+
+source "board/efi/efi-x86/Kconfig"
+
+endif
diff --git a/board/efi/efi-x86/Kconfig b/board/efi/efi-x86/Kconfig
new file mode 100644
index 0000000..fa609ba
--- /dev/null
+++ b/board/efi/efi-x86/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EFI
+
+config SYS_BOARD
+	default "efi-x86"
+
+config SYS_VENDOR
+	default "efi"
+
+config SYS_SOC
+	default "efi"
+
+config SYS_CONFIG_NAME
+	default "efi-x86"
+
+endif
diff --git a/board/efi/efi-x86/MAINTAINERS b/board/efi/efi-x86/MAINTAINERS
new file mode 100644
index 0000000..a44c7c6
--- /dev/null
+++ b/board/efi/efi-x86/MAINTAINERS
@@ -0,0 +1,6 @@
+EFI-X86 BOARD
+M:	Simon Glass <sjg@chromium.org>
+S:	Maintained
+F:	board/efi/efi-x86/
+F:	include/configs/efi-x86.h
+F:	configs/efi-x86_defconfig
diff --git a/board/efi/efi-x86/Makefile b/board/efi/efi-x86/Makefile
new file mode 100644
index 0000000..9b1e0bd
--- /dev/null
+++ b/board/efi/efi-x86/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y	+= efi.o
diff --git a/board/efi/efi-x86/efi.c b/board/efi/efi-x86/efi.c
new file mode 100644
index 0000000..08958f9
--- /dev/null
+++ b/board/efi/efi-x86/efi.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/gpio.h>
+
+int arch_early_init_r(void)
+{
+	return 0;
+}
+
+void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio)
+{
+	return;
+}
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 10/28] x86: dts: Add a device tree file for EFI
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (8 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 09/28] x86: Add EFI board code Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:41   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 11/28] x86: Allow relocation code to build without text base Simon Glass
                   ` (17 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

This contains just enough to bring up the serial UART.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Remove extraneous '+' in comment
- Use "efi,app" instead of "efi,payload" for the compatible string

 arch/x86/dts/Makefile |  1 +
 arch/x86/dts/efi.dts  | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)
 create mode 100644 arch/x86/dts/efi.dts

diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
index 44e2829..71595c7 100644
--- a/arch/x86/dts/Makefile
+++ b/arch/x86/dts/Makefile
@@ -2,6 +2,7 @@ dtb-y += bayleybay.dtb \
 	chromebook_link.dtb \
 	chromebox_panther.dtb \
 	crownbay.dtb \
+	efi.dtb \
 	galileo.dtb \
 	minnowmax.dtb \
 	qemu-x86_i440fx.dtb \
diff --git a/arch/x86/dts/efi.dts b/arch/x86/dts/efi.dts
new file mode 100644
index 0000000..1f50428
--- /dev/null
+++ b/arch/x86/dts/efi.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "EFI";
+	compatible = "efi,app";
+
+	chosen {
+		stdout-path = &serial;
+	};
+
+	serial: serial {
+		compatible = "efi,uart";
+	};
+};
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 11/28] x86: Allow relocation code to build without text base
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (9 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 10/28] x86: dts: Add a device tree file for EFI Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:02   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 12/28] x86: Add definitions for the x86-efi board and plumb it in Simon Glass
                   ` (16 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

This code currently requires CONFIG_SYS_TEXT_BASE but this should be
unnecessary. As a first step, remove the build-time limitation and report an
error instead.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Set text_base to 0 to avoid possible compiler warning

 arch/x86/lib/relocate.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c
index 9e748d2..0d683bf 100644
--- a/arch/x86/lib/relocate.c
+++ b/arch/x86/lib/relocate.c
@@ -58,6 +58,7 @@ int do_elf_reloc_fixups(void)
 
 	Elf32_Addr *offset_ptr_rom, *last_offset = NULL;
 	Elf32_Addr *offset_ptr_ram;
+	unsigned int text_base = 0;
 
 	/* The size of the region of u-boot that runs out of RAM. */
 	uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
@@ -67,29 +68,33 @@ int do_elf_reloc_fixups(void)
 	if (re_src == re_end)
 		panic("No relocation data");
 
+#ifdef CONFIG_SYS_TEXT_BASE
+	text_base = CONFIG_SYS_TEXT_BASE;
+#else
+	panic("No CONFIG_SYS_TEXT_BASE");
+#endif
 	do {
 		/* Get the location from the relocation entry */
 		offset_ptr_rom = (Elf32_Addr *)re_src->r_offset;
 
 		/* Check that the location of the relocation is in .text */
-		if (offset_ptr_rom >= (Elf32_Addr *)CONFIG_SYS_TEXT_BASE &&
-				offset_ptr_rom > last_offset) {
+		if (offset_ptr_rom >= (Elf32_Addr *)text_base &&
+		    offset_ptr_rom > last_offset) {
 
 			/* Switch to the in-RAM version */
 			offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom +
 							gd->reloc_off);
 
 			/* Check that the target points into .text */
-			if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE &&
-					*offset_ptr_ram <=
-					(CONFIG_SYS_TEXT_BASE + size)) {
+			if (*offset_ptr_ram >= text_base &&
+			    *offset_ptr_ram <= text_base + size) {
 				*offset_ptr_ram += gd->reloc_off;
 			} else {
 				debug("   %p: rom reloc %x, ram %p, value %x,"
 					" limit %" PRIXPTR "\n", re_src,
 					re_src->r_offset, offset_ptr_ram,
 					*offset_ptr_ram,
-					CONFIG_SYS_TEXT_BASE + size);
+					text_base + size);
 			}
 		} else {
 			debug("   %p: rom reloc %x, last %p\n", re_src,
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 12/28] x86: Add definitions for the x86-efi board and plumb it in
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (10 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 11/28] x86: Allow relocation code to build without text base Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 13/28] x86: Add relocation and link script for a 64-bit EFI application Simon Glass
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

From: Ben Stoltz <stoltz@google.com>

Add configuration and Kconfig changes for this board.

Signed-off-by: Ben Stoltz <stoltz@google.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Remove CONFIG_SYS_EARLY_PCI_INIT and CONFIG_PCI_PNP
- Remove superfluous Kconfig options
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
- Rename CONFIG_DEBUG_UART_EFI to CONFIG_DEBUG_EFI_CONSOLE

 configs/efi-x86_defconfig | 16 ++++++++++++++++
 include/configs/efi-x86.h | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 configs/efi-x86_defconfig
 create mode 100644 include/configs/efi-x86.h

diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_defconfig
new file mode 100644
index 0000000..1aa0655
--- /dev/null
+++ b/configs/efi-x86_defconfig
@@ -0,0 +1,16 @@
+CONFIG_X86=y
+CONFIG_VENDOR_EFI=y
+CONFIG_TARGET_EFI=y
+CONFIG_TSC_CALIBRATION_BYPASS=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
+CONFIG_DM_PCI=y
+CONFIG_DEFAULT_DEVICE_TREE="efi"
+CONFIG_EFI=y
+CONFIG_EFI_APP=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_EFI_CONSOLE=y
+CONFIG_DEBUG_UART_BASE=0
+CONFIG_DEBUG_UART_CLOCK=0
+# CONFIG_CMD_NET is not set
+# CONFIG_CMD_BOOTM is not set
diff --git a/include/configs/efi-x86.h b/include/configs/efi-x86.h
new file mode 100644
index 0000000..5779cfd
--- /dev/null
+++ b/include/configs/efi-x86.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/x86-common.h>
+
+#undef CONFIG_CMD_SF_TEST
+
+#undef CONFIG_TPM
+#undef CONFIG_TPM_TIS_LPC
+#undef CONFIG_TPM_TIS_BASE_ADDRESS
+
+#undef CONFIG_CMD_IMLS
+
+#undef CONFIG_SYS_NS16550
+#undef CONFIG_X86_SERIAL
+#undef CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_IS_NOWHERE
+#undef CONFIG_VIDEO
+#undef CONFIG_CFB_CONSOLE
+#undef CONFIG_SCSI_AHCI
+#undef CONFIG_CMD_SCSI
+#undef CONFIG_INTEL_ICH6_GPIO
+
+#define CONFIG_STD_DEVICES_SETTINGS     "stdin=usbkbd,vga,serial\0" \
+					"stdout=vga,serial\0" \
+					"stderr=vga,serial\0"
+
+#endif
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 13/28] x86: Add relocation and link script for a 64-bit EFI application
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (11 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 12/28] x86: Add definitions for the x86-efi board and plumb it in Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 14/28] efi: Add support for loading U-Boot through an EFI stub Simon Glass
                   ` (14 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

Add a linker script and relocation code for building 64-bit EFI
applications. This can be used for the EFI stub.

Signed-off-by: Simon Glass <sjg@chromium.org>
Improvements to how the payload is built:
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3:
- Use "BSD-2-Clause" for the SPDX license

Changes in v2:
- Add a comment as to why .hash has to be first in the linker script
- Change 'link script' to 'linker script'
- Drop . = 0x0;
- Fix reference to elf_ia32_efi instead of elf_x86_64_efi
- Merge in Bin's implementation of adding a U-Boot payload with objcopy
- Remove KEEP in the EFI linker script since garbage collection is not enabled
- Rename ImageBase to image_base
- Update based on the elf.h changes

 arch/x86/cpu/efi/elf_x86_64_efi.lds | 83 +++++++++++++++++++++++++++++++++++++
 arch/x86/lib/efi/reloc_x86_64.c     | 66 +++++++++++++++++++++++++++++
 2 files changed, 149 insertions(+)
 create mode 100644 arch/x86/cpu/efi/elf_x86_64_efi.lds
 create mode 100644 arch/x86/lib/efi/reloc_x86_64.c

diff --git a/arch/x86/cpu/efi/elf_x86_64_efi.lds b/arch/x86/cpu/efi/elf_x86_64_efi.lds
new file mode 100644
index 0000000..9d9f057
--- /dev/null
+++ b/arch/x86/cpu/efi/elf_x86_64_efi.lds
@@ -0,0 +1,83 @@
+/*
+ * U-Boot EFI linker script
+ *
+ * SPDX-License-Identifier:	BSD-2-Clause
+ *
+ * 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_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+	image_base = .;
+	.hash : { *(.hash) }	/* this MUST come first, EFI expects it */
+	. = ALIGN(4096);
+	.eh_frame : {
+		*(.eh_frame)
+	}
+
+	. = ALIGN(4096);
+
+	.text : {
+		*(.text)
+		*(.text.*)
+		*(.gnu.linkonce.t.*)
+	}
+
+	. = ALIGN(4096);
+
+	.reloc : {
+		*(.reloc)
+	}
+
+	. = ALIGN(4096);
+
+	.data : {
+		*(.rodata*)
+		*(.got.plt)
+		*(.got)
+		*(.data*)
+		*(.sdata)
+		/* the EFI loader doesn't seem to like a .bss section, so we stick
+		 * it all into .data: */
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		*(COMMON)
+		*(.rel.local)
+
+		/* U-Boot lists and device tree */
+		. = ALIGN(8);
+		*(SORT(.u_boot_list*));
+		. = ALIGN(8);
+		*(.dtb*);
+	}
+
+	. = ALIGN(4096);
+	.dynamic : { *(.dynamic) }
+	. = ALIGN(4096);
+
+	.rela : {
+		*(.rela.data*)
+		*(.rela.got)
+		*(.rela.stab)
+	}
+
+	. = ALIGN(4096);
+	.dynsym : { *(.dynsym) }
+	. = ALIGN(4096);
+	.dynstr : { *(.dynstr) }
+	. = ALIGN(4096);
+	.ignored.reloc : {
+		*(.rela.reloc)
+		*(.eh_frame)
+		*(.note.GNU-stack)
+	}
+
+	.comment 0 : { *(.comment) }
+}
diff --git a/arch/x86/lib/efi/reloc_x86_64.c b/arch/x86/lib/efi/reloc_x86_64.c
new file mode 100644
index 0000000..5f71f2a
--- /dev/null
+++ b/arch/x86/lib/efi/reloc_x86_64.c
@@ -0,0 +1,66 @@
+/*
+ * reloc_x86_64.c - position independent x86_64 ELF shared object relocator
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ * Copyright (C) 2005 Intel Co.
+ * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
+ *
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <elf.h>
+#include <asm/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_Rel *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_Rel *)
+				((unsigned long)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_X86_64_NONE:
+			break;
+		case R_X86_64_RELATIVE:
+			addr = (unsigned long *)(ldbase + rel->r_offset);
+			*addr += ldbase;
+			break;
+		default:
+			break;
+		}
+		rel = (Elf64_Rel *)((char *)rel + relent);
+		relsz -= relent;
+	}
+
+	return EFI_SUCCESS;
+}
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 14/28] efi: Add support for loading U-Boot through an EFI stub
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (12 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 13/28] x86: Add relocation and link script for a 64-bit EFI application Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  7:59   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 15/28] x86: Support building the " Simon Glass
                   ` (13 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

It is useful to be able to load U-Boot onto a board even if is it already
running EFI. This can allow access to the U-Boot command interface, flexible
booting options and easier development.

The easiest way to do this is to build U-Boot as a binary blob and have an
EFI stub copy it into RAM. Add support for this feature, targeting 32-bit
initially.

Also add a way to detect when U-Boot has been loaded via a stub. This goes
in common.h since it needs to be widely available so that we avoid redoing
initialisation that should be skipped.

Signed-off-by: Simon Glass <sjg@chromium.org>
Improvements to how the payload is built:
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3:
- Fix calling convention to starting U-Boot in the 32-bit stub
- Rename LDFLAGS_EFI to LDFLAGS_EFI_PAYLOAD and move into this patch
- Use quiet_cmd_xxx to link the payload

Changes in v2:
- Add a comment as to why we must call exit_boot_services() twice
- Drop \n\t at the end of a one-line asm statement
- Merge in Bin's implementation of adding a U-Boot payload with objcopy
- Remove comment about reset_cpu() returning to EFI in the stub
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP

 Makefile           |  24 +++++
 arch/x86/config.mk |   7 ++
 include/common.h   |   7 ++
 include/efi.h      |   4 +
 lib/efi/Kconfig    |  21 ++++
 lib/efi/Makefile   |   9 ++
 lib/efi/efi_stub.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 376 insertions(+)
 create mode 100644 lib/efi/efi_stub.c

diff --git a/Makefile b/Makefile
index 620c18f..752ee0d 100644
--- a/Makefile
+++ b/Makefile
@@ -755,6 +755,7 @@ ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
 endif
 ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
 ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
+ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi
 
 ifneq ($(BUILD_ROM),)
 ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
@@ -790,6 +791,9 @@ cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
 quiet_cmd_zobjcopy = OBJCOPY $@
 cmd_zobjcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
 
+quiet_cmd_efipayload = OBJCOPY $@
+cmd_efipayload = $(OBJCOPY) -I binary -O $(EFIPAYLOAD_BFDTARGET) -B $(EFIPAYLOAD_BFDARCH) $< $@
+
 quiet_cmd_mkimage = MKIMAGE $@
 cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
 	$(if $(KBUILD_VERBOSE:1=), >/dev/null)
@@ -1087,6 +1091,26 @@ OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)
 u-boot-app.efi: u-boot FORCE
 	$(call if_changed,zobjcopy)
 
+u-boot-dtb.bin.o: u-boot-dtb.bin FORCE
+	$(call if_changed,efipayload)
+
+u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE
+	$(call if_changed_dep,cpp_lds)
+
+# Rule to link the EFI payload which contains a stub and a U-Boot binary
+quiet_cmd_u-boot_payload ?= LD      $@
+      cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
+      -T u-boot-payload.lds \
+      lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \
+      $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
+
+u-boot-payload: u-boot-dtb.bin.o u-boot-payload.lds FORCE
+	$(call if_changed,u-boot_payload)
+
+OBJCOPYFLAGS_u-boot-payload.efi := $(OBJCOPYFLAGS_EFI)
+u-boot-payload.efi: u-boot-payload FORCE
+	$(call if_changed,zobjcopy)
+
 u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE
 	$(call if_changed,cat)
 
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index e27f84a..334c10b 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -24,6 +24,10 @@ PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions -m elf_i386
 LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
 LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
 
+# This is used in the top-level Makefile which does not include
+# PLATFORM_LDFLAGS
+LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined
+
 OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
 	-j .rel -j .rela -j .reloc
 
@@ -31,6 +35,9 @@ CFLAGS_NON_EFI := -mregparm=3
 CFLAGS_EFI := -fpic -fshort-wchar
 
 EFIARCH = ia32
+EFIPAYLOAD_BFDTARGET = elf32-i386
+
+EFIPAYLOAD_BFDARCH = i386
 
 LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
 OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
diff --git a/include/common.h b/include/common.h
index 4566bd1..fcc9ae7 100644
--- a/include/common.h
+++ b/include/common.h
@@ -1021,6 +1021,13 @@ int cpu_release(int nr, int argc, char * const argv[]);
 	offsetof(struct structure, member) == offset, \
 	"`struct " #structure "` offset for `" #member "` is not " #offset)
 
+/* Avoid using CONFIG_EFI_STUB directly as we may boot from other loaders */
+#ifdef CONFIG_EFI_STUB
+#define ll_boot_init()	false
+#else
+#define ll_boot_init()	true
+#endif
+
 /* Pull in stuff for the build system */
 #ifdef DO_DEPS_ONLY
 # include <environment.h>
diff --git a/include/efi.h b/include/efi.h
index f009701..1470c08 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -268,11 +268,15 @@ struct efi_priv {
 /* Base address of the EFI image */
 extern char image_base[];
 
+/* Start and end of U-Boot image (for payload) */
+extern char _binary_u_boot_dtb_bin_start[], _binary_u_boot_dtb_bin_end[];
+
 /**
  * efi_get_sys_table() - Get access to the main EFI system table
  *
  * @return pointer to EFI system table
  */
+
 struct efi_system_table *efi_get_sys_table(void);
 
 /**
diff --git a/lib/efi/Kconfig b/lib/efi/Kconfig
index b23ba5b..919e314 100644
--- a/lib/efi/Kconfig
+++ b/lib/efi/Kconfig
@@ -20,6 +20,11 @@ config EFI_APP
 	  command prompt and memory and I/O functions. Use 'reset' to return
 	  to EFI.
 
+config EFI_STUB
+	bool "Support running as an EFI payload"
+
+endchoice
+
 config EFI_RAM_SIZE
 	hex "Amount of EFI RAM for U-Boot"
 	depends on EFI_APP
@@ -30,4 +35,20 @@ config EFI_RAM_SIZE
 	  other smaller amounts) and it can never be increased after that.
 	  It is used as the RAM size in with U-Boot.
 
+choice
+	prompt "EFI 32/64-bit selection"
+	depends on EFI_STUB
+	help
+	  EFI does not support mixing 32-bit and 64-bit modes. This is a
+	  significant problem because it means that you must build a stub with
+	  the correct type for EFI to load it correctly. If you are using
+	  32-bit EFI, select 32-bit here, else select 64-bit. Failure to do
+	  this may produce no error message - it just won't start!
+
+config EFI_STUB_32BIT
+	bool "Produce a stub for running with 32-bit EFI"
+
+config EFI_STUB_64BIT
+	bool "Produce a stub for running with 64-bit EFI"
+
 endchoice
diff --git a/lib/efi/Makefile b/lib/efi/Makefile
index 5ee344c..4bc67f0 100644
--- a/lib/efi/Makefile
+++ b/lib/efi/Makefile
@@ -5,3 +5,12 @@
 #
 
 obj-$(CONFIG_EFI_APP) += efi_app.o efi.o
+
+CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
+	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
+CFLAGS_efi_stub.o := -fpic -fshort-wchar
+CFLAGS_REMOVE_efi.o := -mregparm=3 \
+	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
+CFLAGS_efi.o := -fpic -fshort-wchar
+
+extra-$(CONFIG_EFI_STUB) += efi_stub.o efi.o
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
new file mode 100644
index 0000000..1e46f6e
--- /dev/null
+++ b/lib/efi/efi_stub.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * EFI information obtained here:
+ * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES
+ *
+ * Loads a payload (U-Boot) within the EFI environment. This is built as a
+ * 32-bit EFI application.
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <efi.h>
+#include <efi_api.h>
+#include <errno.h>
+#include <ns16550.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <linux/err.h>
+#include <linux/types.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_X86
+/*
+ * Problem areas:
+ * - putc() uses the ns16550 address directly and assumed I/O access. Many
+ *	platforms will use memory access
+ * get_codeseg32() is only meaningful on x86
+ */
+#error "This file needs to be ported for use on architectures"
+#endif
+
+static struct efi_priv *global_priv;
+static bool use_uart;
+
+struct __packed desctab_info {
+	uint16_t limit;
+	uint64_t addr;
+	uint16_t pad;
+};
+
+/*
+ * EFI uses Unicode and we don't. The easiest way to get a sensible output
+ * function is to use the U-Boot debug UART. We use EFI's console output
+ * function where available, and assume the built-in UART after that. We rely
+ * on EFI to set up the UART for us and just bring in the functions here.
+ * This last bit is a bit icky, but it's only for debugging anyway. We could
+ * build in ns16550.c with some effort, but this is a payload loader after
+ * all.
+ *
+ * Note: We avoid using printf() so we don't need to bring in lib/vsprintf.c.
+ * That would require some refactoring since we already build this for U-Boot.
+ * Building an EFI shared library version would have to be a separate stem.
+ * That might push us to using the SPL framework to build this stub. However
+ * that would involve a round of EFI-specific changes in SPL. Worth
+ * considering if we start needing more U-Boot functionality. Note that we
+ * could then move get_codeseg32() to arch/x86/cpu/cpu.c.
+ */
+void debug_uart_init(void)
+{
+}
+
+void putc(const char ch)
+{
+	if (use_uart) {
+		NS16550_t com_port = (NS16550_t)0x3f8;
+
+		while ((inb((ulong)&com_port->lsr) & UART_LSR_THRE) == 0)
+			;
+		outb(ch, (ulong)&com_port->thr);
+	} else {
+		efi_putc(global_priv, ch);
+	}
+	if (ch == '\n')
+		putc('\r');
+}
+
+void puts(const char *str)
+{
+	while (*str)
+		putc(*str++);
+}
+
+static void _debug_uart_putc(int ch)
+{
+	putc(ch);
+}
+
+DEBUG_UART_FUNCS
+
+void *memcpy(void *dest, const void *src, size_t size)
+{
+	unsigned char *dptr = dest;
+	const unsigned char *ptr = src;
+	const unsigned char *end = src + size;
+
+	while (ptr < end)
+		*dptr++ = *ptr++;
+
+	return dest;
+}
+
+void *memset(void *inptr, int ch, size_t size)
+{
+	char *ptr = inptr;
+	char *end = ptr + size;
+
+	while (ptr < end)
+		*ptr++ = ch;
+
+	return ptr;
+}
+
+static void jump_to_uboot(ulong cs32, ulong addr, ulong info)
+{
+#ifdef CONFIG_EFI_STUB_32BIT
+	/*
+	 * U-Boot requires these parameters in registers, not on the stack.
+	 * See _x86boot_start() for this code.
+	 */
+	typedef void (*func_t)(int bist, int unused, ulong info)
+		__attribute__((regparm(3)));
+
+	((func_t)addr)(0, 0, info);
+#else
+	/* TODO: Implement this */
+#endif
+}
+
+static void get_gdt(struct desctab_info *info)
+{
+	asm volatile ("sgdt %0" : : "m"(*info) : "memory");
+}
+
+static inline unsigned long read_cr3(void)
+{
+	unsigned long val;
+
+	asm volatile("mov %%cr3,%0" : "=r" (val) : : "memory");
+	return val;
+}
+
+/**
+ * get_codeseg32() - Find the code segment to use for 32-bit code
+ *
+ * U-Boot only works in 32-bit mode@present, so when booting from 64-bit
+ * EFI we must first change to 32-bit mode. To do this we need to find the
+ * correct code segment to use (an entry in the Global Descriptor Table).
+ *
+ * @return code segment GDT offset, or 0 for 32-bit EFI, -ENOENT if not found
+ */
+static int get_codeseg32(void)
+{
+	int cs32 = 0;
+
+	/* TODO(sjg): Implement this for 64-bit mode */
+	return cs32;
+}
+
+static int setup_info_table(struct efi_priv *priv, int size)
+{
+	struct efi_info_hdr *info;
+	efi_status_t ret;
+
+	/* Get some memory for our info table */
+	priv->info_size = size;
+	info = efi_malloc(priv, priv->info_size, &ret);
+	if (ret) {
+		printhex2(ret);
+		puts(" No memory for info table: ");
+		return ret;
+	}
+
+	memset(info, '\0', sizeof(*info));
+	info->version = EFI_TABLE_VERSION;
+	info->hdr_size = sizeof(*info);
+	priv->info = info;
+	priv->next_hdr = (char *)info + info->hdr_size;
+
+	return 0;
+}
+
+static void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type,
+			   void *ptr1, int size1, void *ptr2, int size2)
+{
+	struct efi_entry_hdr *hdr = priv->next_hdr;
+
+	hdr->type = type;
+	hdr->size = size1 + size2;
+	hdr->addr = 0;
+	hdr->link = ALIGN(sizeof(*hdr) + hdr->size, 16);
+	priv->next_hdr += hdr->link;
+	memcpy(hdr + 1, ptr1, size1);
+	memcpy((void *)(hdr + 1) + size1, ptr2, size2);
+	priv->info->total_size = (ulong)priv->next_hdr - (ulong)priv->info;
+}
+
+/**
+ * efi_main() - Start an EFI image
+ *
+ * This function is called by our EFI start-up code. It handles running
+ * U-Boot. If it returns, EFI will continue.
+ */
+efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
+{
+	struct efi_priv local_priv, *priv = &local_priv;
+	struct efi_boot_services *boot = sys_table->boottime;
+	struct efi_mem_desc *desc;
+	struct efi_entry_memmap map;
+	ulong key, desc_size, size;
+	efi_status_t ret;
+	u32 version;
+	int cs32;
+
+	ret = efi_init(priv, "Payload", image, sys_table);
+	if (ret) {
+		printhex2(ret); puts(" efi_init() failed\n");
+		return ret;
+	}
+	global_priv = priv;
+
+	cs32 = get_codeseg32();
+	if (cs32 < 0)
+		return EFI_UNSUPPORTED;
+
+	/* Get the memory map so we can switch off EFI */
+	size = 0;
+	ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version);
+	if (ret != EFI_BUFFER_TOO_SMALL) {
+		printhex2(BITS_PER_LONG);
+		printhex2(ret);
+		puts(" No memory map\n");
+		return ret;
+	}
+	size += 1024;	/* Since doing a malloc() may change the memory map! */
+	desc = efi_malloc(priv, size, &ret);
+	if (!desc) {
+		printhex2(ret);
+		puts(" No memory for memory descriptor: ");
+		return ret;
+	}
+	ret = setup_info_table(priv, size + 128);
+	if (ret)
+		return ret;
+
+	ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version);
+	if (ret) {
+		printhex2(ret);
+		puts(" Can't get memory map\n");
+		return ret;
+	}
+
+	ret = boot->exit_boot_services(image, key);
+	if (ret) {
+		/*
+		 * Unfortunately it happens that we cannot exit boot services
+		 * the first time. But the second time it work. I don't know
+		 * why but this seems to be a repeatable problem. To get
+		 * around it, just try again.
+		 */
+		printhex2(ret);
+		puts(" Can't exit boot services\n");
+		size = sizeof(desc);
+		ret = boot->get_memory_map(&size, desc, &key, &desc_size,
+					   &version);
+		if (ret) {
+			printhex2(ret);
+			puts(" Can't get memory map\n");
+			return ret;
+		}
+		ret = boot->exit_boot_services(image, key);
+		if (ret) {
+			printhex2(ret);
+			puts(" Can't exit boot services 2\n");
+			return ret;
+		}
+	}
+
+	map.version = version;
+	map.desc_size = desc_size;
+	add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), desc, size);
+	add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0);
+
+	/* The EFI UART won't work now, switch to a debug one */
+	use_uart = true;
+
+	memcpy((void *)CONFIG_SYS_TEXT_BASE, _binary_u_boot_dtb_bin_start,
+	       (ulong)_binary_u_boot_dtb_bin_end -
+	       (ulong)_binary_u_boot_dtb_bin_start);
+
+#ifdef DEBUG
+	puts("EFI table at ");
+	printhex8((ulong)priv->info);
+	puts(" size ");
+	printhex8(priv->info->total_size);
+#endif
+	putc('\n');
+	jump_to_uboot(cs32, CONFIG_SYS_TEXT_BASE, (ulong)priv->info);
+
+	return EFI_LOAD_ERROR;
+}
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 15/28] x86: Support building the EFI stub
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (13 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 14/28] efi: Add support for loading U-Boot through an EFI stub Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 12:20   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 16/28] x86: Add an enum for some commonly-used GDT bits Simon Glass
                   ` (12 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

Add support for building a 32/64-bit EFI stub for x86. This involves
building the startup and relocation code for either i386 or x86_64.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Move 64-bit comment to just above the 64-bit flag adjustments

Changes in v2:
- Add a comment as to why the AFLAGS_REMOVE_.. lines are needed
- Move the crt and reloc files into arch/x86/lib/efi/

 arch/x86/lib/Makefile     |  2 +-
 arch/x86/lib/efi/Makefile | 24 ++++++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/lib/efi/Makefile

diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 43489fd..09c236b 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_SYS_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_CMD_ZBOOT)	+= zimage.o
 obj-$(CONFIG_HAVE_FSP) += fsp/
 
-extra-$(CONFIG_USE_PRIVATE_LIBGCC) := lib.a
+extra-$(CONFIG_USE_PRIVATE_LIBGCC) += lib.a
 
 NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
 OBJCOPYFLAGS := --prefix-symbols=__normal_
diff --git a/arch/x86/lib/efi/Makefile b/arch/x86/lib/efi/Makefile
new file mode 100644
index 0000000..bb7b95b
--- /dev/null
+++ b/arch/x86/lib/efi/Makefile
@@ -0,0 +1,24 @@
+#
+# (C) Copyright 2002-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+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
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 16/28] x86: Add an enum for some commonly-used GDT bits
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (14 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 15/28] x86: Support building the " Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 17/28] x86: Add a way to call 32-bit code from 64-bit mode Simon Glass
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

Rather than add these as open-coded values, create an enum with the commonly
used flags.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Add descriptor bits for the base and limit
- Rename GDT_4GB to GDT_4KB

 arch/x86/include/asm/cpu.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 08284ee..5b89139 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -27,6 +27,24 @@ enum {
 	X86_VENDOR_UNKNOWN = 0xff
 };
 
+/* Global descriptor table (GDT) bits */
+enum {
+	GDT_4KB			= 1ULL << 55,
+	GDT_32BIT		= 1ULL << 54,
+	GDT_LONG		= 1ULL << 53,
+	GDT_PRESENT		= 1ULL << 47,
+	GDT_NOTSYS		= 1ULL << 44,
+	GDT_CODE		= 1ULL << 43,
+	GDT_LIMIT_LOW_SHIFT	= 0,
+	GDT_LIMIT_LOW_MASK	= 0xffff,
+	GDT_LIMIT_HIGH_SHIFT	= 48,
+	GDT_LIMIT_HIGH_MASK	= 0xf,
+	GDT_BASE_LOW_SHIFT	= 16,
+	GDT_BASE_LOW_MASK	= 0xffff,
+	GDT_BASE_HIGH_SHIFT	= 56,
+	GDT_BASE_HIGH_MASK	= 0xf,
+};
+
 struct cpuid_result {
 	uint32_t eax;
 	uint32_t ebx;
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 17/28] x86: Add a way to call 32-bit code from 64-bit mode
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (15 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 16/28] x86: Add an enum for some commonly-used GDT bits Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 18/28] efi: Add 64-bit payload support Simon Glass
                   ` (10 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

The procedure to drop from 64-bit mode to 32-bit is a bit messy. Add a
function to take care of it. It requires identity-mapped pages and that
the calling code is running below 4GB.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Add a comment about the REX prefix
- Drop the REX prefix in 32-bit mode

 arch/x86/cpu/Makefile      |  6 +++++
 arch/x86/cpu/call32.S      | 64 ++++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/cpu.h |  9 +++++++
 3 files changed, 79 insertions(+)
 create mode 100644 arch/x86/cpu/call32.S

diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
index 5e058c0..e797925 100644
--- a/arch/x86/cpu/Makefile
+++ b/arch/x86/cpu/Makefile
@@ -12,6 +12,12 @@ extra-y	= start.o
 obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
 obj-y	+= interrupts.o cpu.o cpu_x86.o call64.o
 
+AFLAGS_REMOVE_call32.o := -mregparm=3 \
+	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
+AFLAGS_call32.o := -fpic -fshort-wchar
+
+extra-y += call32.o
+
 obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
 obj-$(CONFIG_SYS_COREBOOT) += coreboot/
 obj-$(CONFIG_EFI_APP) += efi/
diff --git a/arch/x86/cpu/call32.S b/arch/x86/cpu/call32.S
new file mode 100644
index 0000000..c517e4a
--- /dev/null
+++ b/arch/x86/cpu/call32.S
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/global_data.h>
+#include <asm/msr-index.h>
+#include <asm/processor-flags.h>
+
+	/*
+	 * rdi - 32-bit code segment selector
+	 * rsi - target address
+	 * rdx - table address (0 if none)
+	 */
+.code64
+.globl cpu_call32
+cpu_call32:
+	cli
+
+	/* Save table pointer */
+	mov	%edx, %ebx
+
+	/*
+	 * Debugging option, this outputs characters to the console UART
+	 * mov	$0x3f8,%edx
+	 * mov	$'a',%al
+	 * out	%al,(%dx)
+	 */
+
+	pushf
+	push	%rdi	/* 32-bit code segment */
+	lea	compat(%rip), %rax
+	push	%rax
+	.byte	0x48	/* REX prefix to force 64-bit far return */
+	retf
+.code32
+compat:
+	/*
+	 * We are now in compatibility mode with a default operand size of
+	 * 32 bits. First disable paging.
+	 */
+	movl	%cr0, %eax
+	andl	$~X86_CR0_PG, %eax
+	movl	%eax, %cr0
+
+	/* Invalidate TLB */
+	xorl	%eax, %eax
+	movl	%eax, %cr3
+
+	/* Disable Long mode in EFER (Extended Feature Enable Register) */
+	movl	$MSR_EFER, %ecx
+	rdmsr
+	btr	$_EFER_LME, %eax
+	wrmsr
+
+	/* Set up table pointer for _x86boot_start */
+	mov	%ebx, %ecx
+
+	/* Jump to the required target */
+	pushl	%edi	/* 32-bit code segment */
+	pushl	%esi	/* 32-bit target address */
+	retf
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 5b89139..c70183c 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -230,6 +230,15 @@ char *cpu_get_name(char *name);
 void cpu_call64(ulong pgtable, ulong setup_base, ulong target);
 
 /**
+ * cpu_call32() - Jump to a 32-bit entry point
+ *
+ * @code_seg32:	32-bit code segment to use (GDT offset, e.g. 0x20)
+ * @target:	Pointer to the start of the 32-bit U-Boot image/entry point
+ * @table:	Pointer to start of info table to pass to U-Boot
+ */
+void cpu_call32(ulong code_seg32, ulong target, ulong table);
+
+/**
  * cpu_jump_to_64bit() - Jump to a 64-bit Linux kernel
  *
  * The kernel is uncompressed and the 64-bit entry point is expected to be
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 18/28] efi: Add 64-bit payload support
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (16 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 17/28] x86: Add a way to call 32-bit code from 64-bit mode Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05  8:02   ` Bin Meng
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 19/28] x86: Add support for passing tables into U-Boot Simon Glass
                   ` (9 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

Most EFI implementations use 64-bit. Add a way to build U-Boot as a 64-bit
EFI payload. The payload unpacks a (32-bit) U-Boot and starts it. This can
be enabled for x86 boards at present.

Signed-off-by: Simon Glass <sjg@chromium.org>
Improvements to how the payload is built:
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3:
- Add spaces around EFIARCH=
- Use CONFIG_SYS_MONITOR_LEN as a more accurate value for U-Boot's size

Changes in v2:
- Add -no-red-zone for 64-bit only
- Check the GDT selector's base and limit against the target address
- Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application yet
- Merge in Bin's implementation of adding a U-Boot payload with objcopy
- Move the 64-bit crt and reloc code into this patch
- Move the 64-bit efi.h additions into this patch
- Rename GDT_4GB to GDT_4KB

 Makefile                           |  2 +-
 arch/x86/config.mk                 | 10 ++++++
 arch/x86/include/asm/types.h       |  5 ++-
 arch/x86/lib/efi/crt0-efi-x86_64.S | 51 ++++++++++++++++++++++++++
 include/efi.h                      |  7 ++++
 lib/efi/efi_stub.c                 | 74 +++++++++++++++++++++++++++++++++++---
 6 files changed, 143 insertions(+), 6 deletions(-)
 create mode 100644 arch/x86/lib/efi/crt0-efi-x86_64.S

diff --git a/Makefile b/Makefile
index 752ee0d..bb0ba9f 100644
--- a/Makefile
+++ b/Makefile
@@ -1100,7 +1100,7 @@ u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE
 # Rule to link the EFI payload which contains a stub and a U-Boot binary
 quiet_cmd_u-boot_payload ?= LD      $@
       cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
-      -T u-boot-payload.lds \
+      -T u-boot-payload.lds arch/x86/cpu/call32.o \
       lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \
       $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
 
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 334c10b..d7addd8 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -34,14 +34,24 @@ OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
 CFLAGS_NON_EFI := -mregparm=3
 CFLAGS_EFI := -fpic -fshort-wchar
 
+ifeq ($(CONFIG_EFI_STUB_64BIT),)
+CFLAGS_EFI += $(call cc-option, -mno-red-zone)
 EFIARCH = ia32
 EFIPAYLOAD_BFDTARGET = elf32-i386
+else
+EFIARCH = x86_64
+EFIPAYLOAD_BFDTARGET = elf64-x86-64
+endif
 
 EFIPAYLOAD_BFDARCH = i386
 
 LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
+EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o
 OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
 
+CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
+CPPFLAGS_crt0-efi-$(EFIARCH).o += $(CFLAGS_EFI)
+
 ifeq ($(CONFIG_EFI_APP),y)
 
 PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index e272c90..766617f 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -44,8 +44,11 @@ typedef __INT64_TYPE__ s64;
 typedef __UINT64_TYPE__ u64;
 #endif
 
+#ifdef CONFIG_EFI_STUB_64BIT
+#define BITS_PER_LONG 64
+#else
 #define BITS_PER_LONG 32
-
+#endif
 /* Dma addresses are 32-bits wide.  */
 
 typedef u32 dma_addr_t;
diff --git a/arch/x86/lib/efi/crt0-efi-x86_64.S b/arch/x86/lib/efi/crt0-efi-x86_64.S
new file mode 100644
index 0000000..c5cbf41
--- /dev/null
+++ b/arch/x86/lib/efi/crt0-efi-x86_64.S
@@ -0,0 +1,51 @@
+/*
+ * crt0-efi-x86_64.S - x86_64 EFI startup code.
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ * Copyright (C) 2005 Intel Co.
+ * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
+ *
+ * All rights reserved.
+ * SPDX-License-Identifier:	BSD-3-Clause
+ */
+	.text
+	.align 4
+
+	.globl _start
+_start:
+	subq $8, %rsp
+	pushq %rcx
+	pushq %rdx
+
+0:
+	lea image_base(%rip), %rdi
+	lea _DYNAMIC(%rip), %rsi
+
+	popq %rcx
+	popq %rdx
+	pushq %rcx
+	pushq %rdx
+	call _relocate
+
+	popq %rdi
+	popq %rsi
+
+	call efi_main
+	addq $8, %rsp
+
+.exit:
+	ret
+
+	/*
+	 * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+	 * executable:
+	 */
+	.data
+dummy:	.long	0
+
+#define IMAGE_REL_ABSOLUTE	0
+	.section .reloc, "a"
+label1:
+	.long	dummy-label1				/* Page RVA */
+	.long	10					/* Block Size (2*4+2) */
+	.word	(IMAGE_REL_ABSOLUTE << 12) +  0		/* reloc for dummy */
diff --git a/include/efi.h b/include/efi.h
index 1470c08..fcafda0 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -18,6 +18,13 @@
 #include <linux/string.h>
 #include <linux/types.h>
 
+#ifdef CONFIG_EFI_STUB_64BIT
+/* EFI uses the Microsoft ABI which is not the default for GCC */
+#define EFIAPI __attribute__((ms_abi))
+#else
+#define EFIAPI
+#endif
+
 struct efi_device_path;
 
 #define EFI_SUCCESS		0
diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
index 1e46f6e..d4d3e49 100644
--- a/lib/efi/efi_stub.c
+++ b/lib/efi/efi_stub.c
@@ -6,8 +6,8 @@
  * EFI information obtained here:
  * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES
  *
- * Loads a payload (U-Boot) within the EFI environment. This is built as a
- * 32-bit EFI application.
+ * Loads a payload (U-Boot) within the EFI environment. This is built as an
+ * EFI application. It can be built either in 32-bit or 64-bit mode.
  */
 
 #include <common.h>
@@ -126,14 +126,16 @@ static void jump_to_uboot(ulong cs32, ulong addr, ulong info)
 
 	((func_t)addr)(0, 0, info);
 #else
-	/* TODO: Implement this */
+	cpu_call32(cs32, CONFIG_SYS_TEXT_BASE, info);
 #endif
 }
 
+#ifdef CONFIG_EFI_STUB_64BIT
 static void get_gdt(struct desctab_info *info)
 {
 	asm volatile ("sgdt %0" : : "m"(*info) : "memory");
 }
+#endif
 
 static inline unsigned long read_cr3(void)
 {
@@ -156,7 +158,71 @@ static int get_codeseg32(void)
 {
 	int cs32 = 0;
 
-	/* TODO(sjg): Implement this for 64-bit mode */
+#ifdef CONFIG_EFI_STUB_64BIT
+	struct desctab_info gdt;
+	uint64_t *ptr;
+	int i;
+
+	get_gdt(&gdt);
+	for (ptr = (uint64_t *)(unsigned long)gdt.addr, i = 0; i < gdt.limit;
+	     i += 8, ptr++) {
+		uint64_t desc = *ptr;
+		uint64_t base, limit;
+
+		/*
+		 * Check that the target U-Boot jump address is within the
+		 * selector and that the selector is of the right type.
+		 */
+		base = ((desc >> GDT_BASE_LOW_SHIFT) & GDT_BASE_LOW_MASK) |
+			((desc >> GDT_BASE_HIGH_SHIFT) & GDT_BASE_HIGH_MASK)
+				<< 16;
+		limit = ((desc >> GDT_LIMIT_LOW_SHIFT) & GDT_LIMIT_LOW_MASK) |
+			((desc >> GDT_LIMIT_HIGH_SHIFT) & GDT_LIMIT_HIGH_MASK)
+				<< 16;
+		base <<= 12;	/* 4KB granularity */
+		limit <<= 12;
+		if ((desc & GDT_PRESENT) && (desc && GDT_NOTSYS) &&
+		    !(desc & GDT_LONG) && (desc & GDT_4KB) &&
+		    (desc & GDT_32BIT) && (desc & GDT_CODE) &&
+		    CONFIG_SYS_TEXT_BASE > base &&
+		    CONFIG_SYS_TEXT_BASE + CONFIG_SYS_MONITOR_LEN < limit
+		) {
+			cs32 = i;
+			break;
+		}
+	}
+
+#ifdef DEBUG
+	puts("\ngdt: ");
+	printhex8(gdt.limit);
+	puts(", addr: ");
+	printhex8(gdt.addr >> 32);
+	printhex8(gdt.addr);
+	for (i = 0; i < gdt.limit; i += 8) {
+		uint32_t *ptr = (uint32_t *)((unsigned long)gdt.addr + i);
+
+		puts("\n");
+		printhex2(i);
+		puts(": ");
+		printhex8(ptr[1]);
+		puts("  ");
+		printhex8(ptr[0]);
+	}
+	puts("\n ");
+	puts("32-bit code segment: ");
+	printhex2(cs32);
+	puts("\n ");
+
+	puts("page_table: ");
+	printhex8(read_cr3());
+	puts("\n ");
+#endif
+	if (!cs32) {
+		puts("Can't find 32-bit code segment\n");
+		return -ENOENT;
+	}
+#endif
+
 	return cs32;
 }
 
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 19/28] x86: Add support for passing tables into U-Boot
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (17 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 18/28] efi: Add 64-bit payload support Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 20/28] efi: Add functions for decoding the EFI tables Simon Glass
                   ` (8 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

The EFI stub provides information to U-Boot in a table. This includes the
memory map which is needed to decide where to relocate U-Boot. Collect this
information in the early init code and store it in global_data.

Fix up the BIST code at the same time since we don't have it when booting
from EFI and can assume it is 0.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Zero BIST when starting from EFI/coreboot

 arch/x86/cpu/start.S               | 19 ++++++++++++++++++-
 arch/x86/include/asm/global_data.h |  1 +
 arch/x86/lib/asm-offsets.c         |  1 +
 3 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index a0dec39..e5c1733 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -42,6 +42,13 @@ _x86boot_start:
 
 	/* Tell 32-bit code it is being entered from an in-RAM copy */
 	movl	$GD_FLG_WARM_BOOT, %ebx
+
+	/*
+	 * Zero the BIST (Built-In Self Test) value since we don't have it.
+	 * It must be 0 or the previous loader would have reported an error.
+	 */
+	movl	$0, %ebp
+
 	jmp	1f
 
 	/* Add a way for tools to discover the _start entry point */
@@ -53,9 +60,13 @@ _start:
 	 * Set %ebx to GD_FLG_COLD_BOOT to indicate this.
 	 */
 	movl	$GD_FLG_COLD_BOOT, %ebx
-1:
+
 	/* Save BIST */
 	movl	%eax, %ebp
+1:
+
+	/* Save table pointer */
+	movl	%ecx, %esi
 
 	/* Load the segement registers to match the GDT loaded in start16.S */
 	movl	$(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax
@@ -133,7 +144,13 @@ car_init_ret:
 	movl	%esi, (%edx)
 
 skip_hob:
+#else
+	/* Store table pointer */
+	movl	%esp, %edx
+	addl	$GD_TABLE, %edx
+	movl	%esi, (%edx)
 #endif
+
 	/* Setup first parameter to setup_gdt, pointer to global_data */
 	movl	%esp, %eax
 
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 80ebe3e..f7e3889 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -69,6 +69,7 @@ struct arch_global_data {
 	char *mrc_output;
 	unsigned int mrc_output_len;
 	void *gdt;			/* Global descriptor table */
+	ulong table;			/* Table pointer from previous loader */
 };
 
 #endif
diff --git a/arch/x86/lib/asm-offsets.c b/arch/x86/lib/asm-offsets.c
index 70ccf1b..9da04dd 100644
--- a/arch/x86/lib/asm-offsets.c
+++ b/arch/x86/lib/asm-offsets.c
@@ -21,5 +21,6 @@ int main(void)
 #ifdef CONFIG_HAVE_FSP
 	DEFINE(GD_HOB_LIST, offsetof(gd_t, arch.hob_list));
 #endif
+	DEFINE(GD_TABLE, offsetof(gd_t, arch.table));
 	return 0;
 }
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 20/28] efi: Add functions for decoding the EFI tables
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (18 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 19/28] x86: Add support for passing tables into U-Boot Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 21/28] efi: Add a command to display the memory map Simon Glass
                   ` (7 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

The EFI stub can pass a table to U-Boot with information about the memory map
Potentially other things will follow. Add a way to access this table.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2: None

 lib/efi/Makefile   |  1 +
 lib/efi/efi_info.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 lib/efi/efi_info.c

diff --git a/lib/efi/Makefile b/lib/efi/Makefile
index 4bc67f0..e32dc14 100644
--- a/lib/efi/Makefile
+++ b/lib/efi/Makefile
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_EFI_APP) += efi_app.o efi.o
+obj-$(CONFIG_EFI_STUB) += efi_info.o
 
 CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
 	$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
diff --git a/lib/efi/efi_info.c b/lib/efi/efi_info.c
new file mode 100644
index 0000000..0cd9a7e
--- /dev/null
+++ b/lib/efi/efi_info.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ *
+ * Access to the EFI information table
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <errno.h>
+#include <mapmem.h>
+
+int efi_info_get(enum efi_entry_t type, void **datap, int *sizep)
+{
+	struct efi_entry_hdr *entry;
+	struct efi_info_hdr *info;
+	int ret;
+
+	if (!gd->arch.table)
+		return -ENODATA;
+
+	info = map_sysmem(gd->arch.table, 0);
+	if (info->version != EFI_TABLE_VERSION) {
+		ret = -EPROTONOSUPPORT;
+		goto err;
+	}
+
+	entry = (struct efi_entry_hdr *)((ulong)info + info->hdr_size);
+	while (entry->type != EFIET_END) {
+		if (entry->type == type) {
+			if (entry->addr)
+				*datap = map_sysmem(entry->addr, entry->size);
+			else
+				*datap = entry + 1;
+			*sizep = entry->size;
+			return 0;
+		}
+		entry = (struct efi_entry_hdr *)((ulong)entry + entry->link);
+	}
+
+	ret = -ENOENT;
+err:
+	unmap_sysmem(info);
+
+	return ret;
+}
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 21/28] efi: Add a command to display the memory map
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (19 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 20/28] efi: Add functions for decoding the EFI tables Simon Glass
@ 2015-08-04 18:33 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 22/28] x86: Handle running as EFI payload Simon Glass
                   ` (6 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:33 UTC (permalink / raw)
  To: u-boot

The EFI memory map is passed from the stub to U-Boot in a table. Add a
command to display it in a vaguely readable fashion.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested on QEMU
Tested-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Drop a left-over debug printf()
- Fix alignment of region index field in the output
- Fix efi_mem_desc_VERSION typo
- Output the region index in decimal

 common/Makefile  |   1 +
 common/cmd_efi.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 258 insertions(+)
 create mode 100644 common/cmd_efi.c

diff --git a/common/Makefile b/common/Makefile
index d6c1d48..6dc4c89 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_CMD_DTT) += cmd_dtt.o
 obj-$(CONFIG_CMD_ECHO) += cmd_echo.o
 obj-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o
 obj-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
+obj-$(CONFIG_EFI_STUB) += cmd_efi.o
 obj-$(CONFIG_CMD_ELF) += cmd_elf.o
 obj-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
 obj-$(CONFIG_CMD_EXT4) += cmd_ext4.o
diff --git a/common/cmd_efi.c b/common/cmd_efi.c
new file mode 100644
index 0000000..c76296e
--- /dev/null
+++ b/common/cmd_efi.c
@@ -0,0 +1,257 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <efi.h>
+#include <errno.h>
+#include <malloc.h>
+
+static const char *const type_name[] = {
+	"reserved",
+	"loader_code",
+	"loader_data",
+	"bs_code",
+	"bs_data",
+	"rt_code",
+	"rt_data",
+	"conv",
+	"unusable",
+	"acpi_reclaim",
+	"acpi_nvs",
+	"io",
+	"io_port",
+	"pal_code",
+};
+
+static struct attr_info {
+	int shift;
+	const char *name;
+} mem_attr[] = {
+	{ EFI_MEMORY_UC_SHIFT, "uncached" },
+	{ EFI_MEMORY_WC_SHIFT, "write-coalescing" },
+	{ EFI_MEMORY_WT_SHIFT, "write-through" },
+	{ EFI_MEMORY_WB_SHIFT, "write-back" },
+	{ EFI_MEMORY_UCE_SHIFT, "uncached & exported" },
+	{ EFI_MEMORY_WP_SHIFT, "write-protect" },
+	{ EFI_MEMORY_RP_SHIFT, "read-protect" },
+	{ EFI_MEMORY_XP_SHIFT, "execute-protect" },
+	{ EFI_MEMORY_RUNTIME_SHIFT, "needs runtime mapping" }
+};
+
+/* Maximum different attribute values we can track */
+#define ATTR_SEEN_MAX	30
+
+static inline bool is_boot_services(int type)
+{
+	return type == EFI_LOADER_CODE || type == EFI_LOADER_DATA ||
+		type == EFI_BOOT_SERVICES_CODE ||
+		type == EFI_BOOT_SERVICES_DATA;
+}
+
+static int h_cmp_entry(const void *v1, const void *v2)
+{
+	const struct efi_mem_desc *desc1 = v1;
+	const struct efi_mem_desc *desc2 = v2;
+	int64_t diff = desc1->physical_start - desc2->physical_start;
+
+	/*
+	 * Manually calculate the difference to avoid sign loss in the 64-bit
+	 * to 32-bit conversion
+	 */
+	return diff < 0 ? -1 : diff > 0 ? 1 : 0;
+}
+
+void *efi_build_mem_table(struct efi_entry_memmap *map, int size, bool skip_bs)
+{
+	struct efi_mem_desc *desc, *end, *base, *dest, *prev;
+	int count;
+	u64 addr;
+
+	base = malloc(size + sizeof(*desc));
+	if (!base) {
+		debug("%s: Cannot allocate %#x bytes\n", __func__, size);
+		return NULL;
+	}
+	end = (struct efi_mem_desc *)((ulong)map + size);
+	count = ((ulong)end - (ulong)map->desc) / map->desc_size;
+	memcpy(base, map->desc, (ulong)end - (ulong)map->desc);
+	qsort(base, count, map->desc_size, h_cmp_entry);
+	prev = NULL;
+	addr = 0;
+	dest = base;
+	end = base + count;
+	for (desc = base; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
+		bool merge = true;
+		int type = desc->type;
+
+		if (skip_bs && is_boot_services(desc->type))
+			type = EFI_CONVENTIONAL_MEMORY;
+
+		memcpy(dest, desc, map->desc_size);
+		dest->type = type;
+		if (!skip_bs || !prev)
+			merge = false;
+		else if (desc->physical_start != addr)
+			merge = false;
+		else if (type != EFI_CONVENTIONAL_MEMORY)
+			merge = false;
+		else if (prev->type != EFI_CONVENTIONAL_MEMORY)
+			merge = false;
+
+		if (merge) {
+			prev->num_pages += desc->num_pages;
+		} else {
+			prev = dest;
+			dest = efi_get_next_mem_desc(map, dest);
+		}
+		addr = desc->physical_start + (desc->num_pages <<
+				EFI_PAGE_SHIFT);
+	}
+
+	/* Mark the end */
+	dest->type = EFI_TABLE_END;
+
+	return base;
+}
+
+static void efi_print_mem_table(struct efi_entry_memmap *map,
+				struct efi_mem_desc *desc, bool skip_bs)
+{
+	u64 attr_seen[ATTR_SEEN_MAX];
+	int attr_seen_count;
+	int upto, i;
+	u64 addr;
+
+	printf(" #  %-14s  %10s  %10s  %10s  %s\n", "Type", "Physical",
+	       "Virtual", "Size", "Attributes");
+
+	/* Keep track of all the different attributes we have seen */
+	attr_seen_count = 0;
+	addr = 0;
+	for (upto = 0; desc->type != EFI_TABLE_END;
+	     upto++, desc = efi_get_next_mem_desc(map, desc)) {
+		const char *name;
+		u64 size;
+
+		if (skip_bs && is_boot_services(desc->type))
+			continue;
+		if (desc->physical_start != addr) {
+			printf("    %-14s  %010llx  %10s  %010llx\n", "<gap>",
+			       addr, "", desc->physical_start - addr);
+		}
+		size = desc->num_pages << EFI_PAGE_SHIFT;
+
+		name = desc->type < ARRAY_SIZE(type_name) ?
+				type_name[desc->type] : "<invalid>";
+		printf("%2d  %x:%-12s  %010llx  %010llx  %010llx  ", upto,
+		       desc->type, name, desc->physical_start,
+		       desc->virtual_start, size);
+		if (desc->attribute & EFI_MEMORY_RUNTIME)
+			putc('r');
+		printf("%llx", desc->attribute & ~EFI_MEMORY_RUNTIME);
+		putc('\n');
+
+		for (i = 0; i < attr_seen_count; i++) {
+			if (attr_seen[i] == desc->attribute)
+				break;
+		}
+		if (i == attr_seen_count && i < ATTR_SEEN_MAX)
+			attr_seen[attr_seen_count++] = desc->attribute;
+		addr = desc->physical_start + size;
+	}
+
+	printf("\nAttributes key:\n");
+	for (i = 0; i < attr_seen_count; i++) {
+		u64 attr = attr_seen[i];
+		bool first;
+		int j;
+
+		printf("%c%llx: ", attr & EFI_MEMORY_RUNTIME ? 'r' : ' ',
+		       attr & ~EFI_MEMORY_RUNTIME);
+		for (j = 0, first = true; j < ARRAY_SIZE(mem_attr); j++) {
+			if (attr & (1ULL << mem_attr[j].shift)) {
+				if (first)
+					first = false;
+				else
+					printf(", ");
+				printf("%s", mem_attr[j].name);
+			}
+		}
+		putc('\n');
+	}
+	if (skip_bs)
+		printf("*Some areas are merged (use 'all' to see)\n");
+}
+
+static int do_efi_mem(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct efi_mem_desc *desc;
+	struct efi_entry_memmap *map;
+	int size, ret;
+	bool skip_bs;
+
+	skip_bs = !argc || *argv[0] != 'a';
+	ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
+	switch (ret) {
+	case -ENOENT:
+		printf("No EFI table available\n");
+		goto done;
+	case -EPROTONOSUPPORT:
+		printf("Incorrect EFI table version\n");
+		goto done;
+	}
+	printf("EFI table@%lx, memory map %p, size %x, version %x, descr. size %#x\n",
+	       gd->arch.table, map, size, map->version, map->desc_size);
+	if (map->version != EFI_MEM_DESC_VERSION) {
+		printf("Incorrect memory map version\n");
+		ret = -EPROTONOSUPPORT;
+		goto done;
+	}
+
+	desc = efi_build_mem_table(map, size, skip_bs);
+	if (!desc) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	efi_print_mem_table(map, desc, skip_bs);
+	free(desc);
+done:
+	if (ret)
+		printf("Error: %d\n", ret);
+
+	return ret ? CMD_RET_FAILURE : 0;
+}
+
+static cmd_tbl_t efi_commands[] = {
+	U_BOOT_CMD_MKENT(mem, 1, 1, do_efi_mem, "", ""),
+};
+
+static int do_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *efi_cmd;
+	int ret;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+	efi_cmd = find_cmd_tbl(argv[1], efi_commands, ARRAY_SIZE(efi_commands));
+	argc -= 2;
+	argv += 2;
+	if (!efi_cmd || argc > efi_cmd->maxargs)
+		return CMD_RET_USAGE;
+
+	ret = efi_cmd->cmd(efi_cmd, flag, argc, argv);
+
+	return cmd_process_error(efi_cmd, ret);
+}
+
+U_BOOT_CMD(
+	efi,     3,      1,      do_efi,
+	"EFI access",
+	"mem [all]        Dump memory information [include boot services]"
+);
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 22/28] x86: Handle running as EFI payload
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (20 preceding siblings ...)
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 21/28] efi: Add a command to display the memory map Simon Glass
@ 2015-08-04 18:34 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 23/28] x86: Add helper code for running from EFI Simon Glass
                   ` (5 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:34 UTC (permalink / raw)
  To: u-boot

When U-Boot runs as an EFI payload it needs to avoid setting up the CPU
again. Also U-Boot currently does not handle interrupts for many devices, so
run with interrupts disabled.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Add a note that bootm does not work when running as an EFI app
- Move EFI CAR settings to arch/x86/lib/efi/Kconfig
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP

 arch/x86/Kconfig          |  6 ++++++
 arch/x86/cpu/cpu.c        | 21 +++++++++++++--------
 arch/x86/cpu/interrupts.c | 10 ++++++++--
 arch/x86/lib/bootm.c      |  5 +++++
 arch/x86/lib/efi/Kconfig  | 11 +++++++++++
 5 files changed, 43 insertions(+), 10 deletions(-)
 create mode 100644 arch/x86/lib/efi/Kconfig

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f124d58..01ed760 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -194,6 +194,7 @@ config X86_RAMTEST
 
 config HAVE_FSP
 	bool "Add an Firmware Support Package binary"
+	depends on !EFI
 	help
 	  Select this option to add an Firmware Support Package binary to
 	  the resulting U-Boot image. It is a binary blob which U-Boot uses
@@ -309,6 +310,7 @@ menu "System tables"
 
 config GENERATE_PIRQ_TABLE
 	bool "Generate a PIRQ table"
+	depends on !EFI
 	default n
 	help
 	  Generate a PIRQ routing table for this board. The PIRQ routing table
@@ -319,6 +321,7 @@ config GENERATE_PIRQ_TABLE
 
 config GENERATE_SFI_TABLE
 	bool "Generate a SFI (Simple Firmware Interface) table"
+	depends on !EFI
 	help
 	  The Simple Firmware Interface (SFI) provides a lightweight method
 	  for platform firmware to pass information to the operating system
@@ -333,6 +336,7 @@ config GENERATE_SFI_TABLE
 
 config GENERATE_MP_TABLE
 	bool "Generate an MP (Multi-Processor) table"
+	depends on !EFI
 	default n
 	help
 	  Generate an MP (Multi-Processor) table for this board. The MP table
@@ -383,4 +387,6 @@ config PCIE_ECAM_SIZE
 	  so a default 0x10000000 size covers all of the 256 buses which is the
 	  maximum number of PCI buses as defined by the PCI specification.
 
+source "arch/x86/lib/efi/Kconfig"
+
 endmenu
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index d233a45..129777c 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -330,13 +330,15 @@ int x86_cpu_init_f(void)
 	const u32 em_rst = ~X86_CR0_EM;
 	const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE;
 
-	/* initialize FPU, reset EM, set MP and NE */
-	asm ("fninit\n" \
-	     "movl %%cr0, %%eax\n" \
-	     "andl %0, %%eax\n" \
-	     "orl  %1, %%eax\n" \
-	     "movl %%eax, %%cr0\n" \
-	     : : "i" (em_rst), "i" (mp_ne_set) : "eax");
+	if (ll_boot_init()) {
+		/* initialize FPU, reset EM, set MP and NE */
+		asm ("fninit\n" \
+		"movl %%cr0, %%eax\n" \
+		"andl %0, %%eax\n" \
+		"orl  %1, %%eax\n" \
+		"movl %%eax, %%cr0\n" \
+		: : "i" (em_rst), "i" (mp_ne_set) : "eax");
+	}
 
 	/* identify CPU via cpuid and store the decoded info into gd->arch */
 	if (has_cpuid()) {
@@ -712,5 +714,8 @@ __weak int x86_init_cpus(void)
 
 int cpu_init_r(void)
 {
-	return x86_init_cpus();
+	if (ll_boot_init())
+		return x86_init_cpus();
+
+	return 0;
 }
diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
index a112938..9217307 100644
--- a/arch/x86/cpu/interrupts.c
+++ b/arch/x86/cpu/interrupts.c
@@ -258,8 +258,14 @@ int interrupt_init(void)
 	/* Initialize core interrupt and exception functionality of CPU */
 	cpu_init_interrupts();
 
-	/* It is now safe to enable interrupts */
-	enable_interrupts();
+	/*
+	 * It is now safe to enable interrupts.
+	 *
+	 * TODO(sjg at chromium.org): But we don't handle these correctly when
+	 * booted from EFI.
+	 */
+	if (ll_boot_init())
+		enable_interrupts();
 #endif
 
 	return 0;
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index 445ee6e..f441c84 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -164,7 +164,11 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
 		* the data segments are 0x18, 4GB flat, and read/write.
 		* U-boot is setting them up that way for itself in
 		* arch/i386/cpu/cpu.c.
+		*
+		* Note that we cannot currently boot a kernel while running as
+		* an EFI application. Please use the payload option for that.
 		*/
+#ifndef CONFIG_EFI_APP
 		__asm__ __volatile__ (
 		"movl $0, %%ebp\n"
 		"cli\n"
@@ -173,6 +177,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit)
 		[boot_params] "S"(setup_base),
 		"b"(0), "D"(0)
 		);
+#endif
 	}
 
 	/* We can't get to here */
diff --git a/arch/x86/lib/efi/Kconfig b/arch/x86/lib/efi/Kconfig
new file mode 100644
index 0000000..e0975d3
--- /dev/null
+++ b/arch/x86/lib/efi/Kconfig
@@ -0,0 +1,11 @@
+if EFI
+
+config SYS_CAR_ADDR
+	hex
+	default 0x100000
+
+config SYS_CAR_SIZE
+	hex
+	default 0x20000
+
+endif
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 23/28] x86: Add helper code for running from EFI
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (21 preceding siblings ...)
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 22/28] x86: Handle running as EFI payload Simon Glass
@ 2015-08-04 18:34 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 24/28] x86: baytrail: Support operation as an EFI payload Simon Glass
                   ` (4 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:34 UTC (permalink / raw)
  To: u-boot

When U-Boot is running from EFI some of the x86 init is replaced with
EFI-specific init. For example, since DRAM has already been set up, we only
need to find it, not init it. Add these functions so that boards can easily
allow booting from EFI if required.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Drop unnecessary .section .text

 arch/x86/lib/Makefile     |   1 +
 arch/x86/lib/efi/Makefile |   3 +
 arch/x86/lib/efi/car.S    |  10 +++
 arch/x86/lib/efi/efi.c    | 151 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 165 insertions(+)
 create mode 100644 arch/x86/lib/efi/car.S
 create mode 100644 arch/x86/lib/efi/efi.c

diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 09c236b..dcfe9ee 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -11,6 +11,7 @@ obj-y += bios_interrupts.o
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-y	+= cmd_boot.o
 obj-$(CONFIG_HAVE_FSP) += cmd_hob.o
+obj-$(CONFIG_EFI) += efi/
 obj-y	+= gcc.o
 obj-y	+= init_helpers.o
 obj-y	+= interrupts.o
diff --git a/arch/x86/lib/efi/Makefile b/arch/x86/lib/efi/Makefile
index bb7b95b..af4503e 100644
--- a/arch/x86/lib/efi/Makefile
+++ b/arch/x86/lib/efi/Makefile
@@ -5,6 +5,9 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-$(CONFIG_EFI_STUB) += car.o
+obj-$(CONFIG_EFI_STUB) += efi.o
+
 obj-$(CONFIG_EFI_APP) += crt0-efi-ia32.o reloc_ia32.o
 
 ifneq ($(CONFIG_EFI_STUB),)
diff --git a/arch/x86/lib/efi/car.S b/arch/x86/lib/efi/car.S
new file mode 100644
index 0000000..613af9a
--- /dev/null
+++ b/arch/x86/lib/efi/car.S
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+.globl car_init
+car_init:
+	jmp	car_init_ret
diff --git a/arch/x86/lib/efi/efi.c b/arch/x86/lib/efi/efi.c
new file mode 100644
index 0000000..ede5d56
--- /dev/null
+++ b/arch/x86/lib/efi/efi.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <efi.h>
+#include <errno.h>
+#include <linux/err.h>
+#include <linux/types.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This function looks for the highest region of memory lower than 4GB which
+ * has enough space for U-Boot where U-Boot is aligned on a page boundary.
+ * It overrides the default implementation found elsewhere which simply
+ * picks the end of ram, wherever that may be. The location of the stack,
+ * the relocation address, and how far U-Boot is moved by relocation are
+ * set in the global data structure.
+ */
+ulong board_get_usable_ram_top(ulong total_size)
+{
+	struct efi_mem_desc *desc, *end;
+	struct efi_entry_memmap *map;
+	int ret, size;
+	uintptr_t dest_addr = 0;
+	struct efi_mem_desc *largest = NULL;
+
+	/*
+	 * Find largest area of memory below 4GB. We could
+	 * call efi_build_mem_table() for a more accurate picture since it
+	 * merges areas together where possible. But that function uses more
+	 * pre-relocation memory, and it's not critical that we find the
+	 * absolute largest region.
+	 */
+	ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
+	if (ret) {
+		/* We should have stopped in dram_init(), something is wrong */
+		debug("%s: Missing memory map\n", __func__);
+		goto err;
+	}
+
+	end = (struct efi_mem_desc *)((ulong)map + size);
+	desc = map->desc;
+	for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
+		if (desc->type != EFI_CONVENTIONAL_MEMORY ||
+		    desc->physical_start >= 1ULL << 32)
+			continue;
+		if (!largest || desc->num_pages > largest->num_pages)
+			largest = desc;
+	}
+
+	/* If no suitable area was found, return an error. */
+	assert(largest);
+	if (!largest || (largest->num_pages << EFI_PAGE_SHIFT) < (2 << 20))
+		goto err;
+
+	dest_addr = largest->physical_start + (largest->num_pages <<
+			EFI_PAGE_SHIFT);
+
+	return (ulong)dest_addr;
+err:
+	panic("No available memory found for relocation");
+	return 0;
+}
+
+int dram_init(void)
+{
+	struct efi_mem_desc *desc, *end;
+	struct efi_entry_memmap *map;
+	int size, ret;
+
+	ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
+	if (ret) {
+		printf("Cannot find EFI memory map tables, ret=%d\n", ret);
+
+		return -ENODEV;
+	}
+
+	end = (struct efi_mem_desc *)((ulong)map + size);
+	gd->ram_size = 0;
+	desc = map->desc;
+	for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) {
+		if (desc->type < EFI_MMAP_IO)
+			gd->ram_size += desc->num_pages << EFI_PAGE_SHIFT;
+	}
+
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	struct efi_mem_desc *desc, *end;
+	struct efi_entry_memmap *map;
+	int ret, size;
+	int num_banks;
+
+	ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
+	if (ret) {
+		/* We should have stopped in dram_init(), something is wrong */
+		debug("%s: Missing memory map\n", __func__);
+		return;
+	}
+	end = (struct efi_mem_desc *)((ulong)map + size);
+	desc = map->desc;
+	for (num_banks = 0;
+	     desc < end && num_banks < CONFIG_NR_DRAM_BANKS;
+	     desc = efi_get_next_mem_desc(map, desc)) {
+		/*
+		 * We only use conventional memory below 4GB, and ignore
+		 * anything less than 1MB.
+		 */
+		if (desc->type != EFI_CONVENTIONAL_MEMORY ||
+		    desc->physical_start >= 1ULL << 32 ||
+		    (desc->num_pages << EFI_PAGE_SHIFT) < 1 << 20)
+			continue;
+		gd->bd->bi_dram[num_banks].start = desc->physical_start;
+		gd->bd->bi_dram[num_banks].size = desc->num_pages <<
+			EFI_PAGE_SHIFT;
+		num_banks++;
+	}
+}
+
+int print_cpuinfo(void)
+{
+	return default_print_cpuinfo();
+}
+
+/* Find any available tables and copy them to a safe place */
+int reserve_arch(void)
+{
+	struct efi_info_hdr *hdr;
+
+	debug("table=%lx\n", gd->arch.table);
+	if (!gd->arch.table)
+		return 0;
+
+	hdr = (struct efi_info_hdr *)gd->arch.table;
+
+	gd->start_addr_sp -= hdr->total_size;
+	memcpy((void *)gd->start_addr_sp, hdr, hdr->total_size);
+	debug("Stashing EFI table at %lx to %lx, size %x\n",
+	      gd->arch.table, gd->start_addr_sp, hdr->total_size);
+	gd->arch.table = gd->start_addr_sp;
+
+	return 0;
+}
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 24/28] x86: baytrail: Support operation as an EFI payload
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (22 preceding siblings ...)
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 23/28] x86: Add helper code for running from EFI Simon Glass
@ 2015-08-04 18:34 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 25/28] x86: qemu: " Simon Glass
                   ` (3 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:34 UTC (permalink / raw)
  To: u-boot

Disable a few things which interfere with the EFI init. This allows the
Minnowboard MAX to boot into EFI, load a U-Boot payload then boot to the
U-Boot prompt.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Fix indenting in board/intel/minnowmax/Kconfig
- Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP

 arch/x86/cpu/baytrail/Kconfig      | 2 +-
 arch/x86/cpu/baytrail/cpu.c        | 2 ++
 arch/x86/cpu/baytrail/valleyview.c | 2 ++
 board/intel/minnowmax/Kconfig      | 5 +++--
 4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/baytrail/Kconfig b/arch/x86/cpu/baytrail/Kconfig
index e86cc01..407feb2 100644
--- a/arch/x86/cpu/baytrail/Kconfig
+++ b/arch/x86/cpu/baytrail/Kconfig
@@ -6,4 +6,4 @@
 
 config INTEL_BAYTRAIL
 	bool
-	select HAVE_FSP
+	select HAVE_FSP if !EFI
diff --git a/arch/x86/cpu/baytrail/cpu.c b/arch/x86/cpu/baytrail/cpu.c
index a011730..b1faf8c 100644
--- a/arch/x86/cpu/baytrail/cpu.c
+++ b/arch/x86/cpu/baytrail/cpu.c
@@ -45,6 +45,8 @@ static void set_max_freq(void)
 
 static int cpu_x86_baytrail_probe(struct udevice *dev)
 {
+	if (!ll_boot_init())
+		return 0;
 	debug("Init BayTrail core\n");
 
 	/*
diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c
index d8d2b8d..610e9d9 100644
--- a/arch/x86/cpu/baytrail/valleyview.c
+++ b/arch/x86/cpu/baytrail/valleyview.c
@@ -21,6 +21,7 @@ int cpu_mmc_init(bd_t *bis)
 			    ARRAY_SIZE(mmc_supported));
 }
 
+#ifndef CONFIG_EFI_APP
 int arch_cpu_init(void)
 {
 	int ret;
@@ -43,3 +44,4 @@ int arch_misc_init(void)
 
 	return 0;
 }
+#endif
diff --git a/board/intel/minnowmax/Kconfig b/board/intel/minnowmax/Kconfig
index f2a0b71..7e975f9 100644
--- a/board/intel/minnowmax/Kconfig
+++ b/board/intel/minnowmax/Kconfig
@@ -13,11 +13,12 @@ config SYS_CONFIG_NAME
 	default "minnowmax"
 
 config SYS_TEXT_BASE
-	default 0xfff00000
+	default 0xfff00000 if !EFI_STUB
+	default 0x01110000 if EFI_STUB
 
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
-	select X86_RESET_VECTOR
+	select X86_RESET_VECTOR if !EFI_STUB
 	select INTEL_BAYTRAIL
 	select BOARD_ROMSIZE_KB_8192
 
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 25/28] x86: qemu: Support operation as an EFI payload
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (23 preceding siblings ...)
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 24/28] x86: baytrail: Support operation as an EFI payload Simon Glass
@ 2015-08-04 18:34 ` Simon Glass
  2015-08-05  8:19   ` Bin Meng
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 26/28] x86: Gracefully disable the vesa driver when running from EFI Simon Glass
                   ` (2 subsequent siblings)
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:34 UTC (permalink / raw)
  To: u-boot

Disable a few things which interfere with the EFI init. This allows QEMU to
to boot into EFI, load a U-Boot payload then boot to the U-Boot prompt.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Fix indenting in board/emulation/qemu-x86/Kconfig

 arch/x86/cpu/qemu/Makefile       | 5 ++++-
 arch/x86/cpu/qemu/qemu.c         | 2 ++
 board/emulation/qemu-x86/Kconfig | 5 +++--
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile
index be79723..9a66b16 100644
--- a/arch/x86/cpu/qemu/Makefile
+++ b/arch/x86/cpu/qemu/Makefile
@@ -4,5 +4,8 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += car.o dram.o qemu.o
+ifndef CONFIG_EFI_STUB
+obj-y += car.o dram.o
+endif
+obj-y += qemu.o
 obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
index 930d2b6..64634a9 100644
--- a/arch/x86/cpu/qemu/qemu.c
+++ b/arch/x86/cpu/qemu/qemu.c
@@ -25,11 +25,13 @@ int arch_cpu_init(void)
 	return 0;
 }
 
+#ifndef CONFIG_EFI_STUB
 int print_cpuinfo(void)
 {
 	post_code(POST_CPU_INFO);
 	return default_print_cpuinfo();
 }
+#endif
 
 void reset_cpu(ulong addr)
 {
diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
index e777ef4..c9181fc 100644
--- a/board/emulation/qemu-x86/Kconfig
+++ b/board/emulation/qemu-x86/Kconfig
@@ -13,11 +13,12 @@ config SYS_CONFIG_NAME
 	default "qemu-x86"
 
 config SYS_TEXT_BASE
-	default 0xfff00000
+	default 0xfff00000 if !EFI_STUB
+	default 0x01110000 if EFI_STUB
 
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
-	select X86_RESET_VECTOR
+	select X86_RESET_VECTOR if !EFI_STUB
 	select QEMU
 	select BOARD_ROMSIZE_KB_1024
 
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 26/28] x86: Gracefully disable the vesa driver when running from EFI
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (24 preceding siblings ...)
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 25/28] x86: qemu: " Simon Glass
@ 2015-08-04 18:34 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 27/28] efi: Add a README to explain how things work Simon Glass
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled Simon Glass
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:34 UTC (permalink / raw)
  To: u-boot

We cannot use this driver when running from EFI as we have no direct hardware
access. In fact coreboot uses a different driver which uses tables provided
by coreboot. So far it does not seem possible to use a normal video driver
when booting from EFI.

Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Anatolij Gustschin <agust@denx.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Replace 'Coreboot' with 'coreboot'

 drivers/video/vesa_fb.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c
index 909f8e8..4e6d070 100644
--- a/drivers/video/vesa_fb.c
+++ b/drivers/video/vesa_fb.c
@@ -24,6 +24,14 @@ void *video_hw_init(void)
 	int ret;
 
 	printf("Video: ");
+	if (!ll_boot_init()) {
+		/*
+		 * If we are running from EFI or coreboot, this driver can't
+		 * work.
+		 */
+		printf("Not available (previous bootloader prevents it)\n");
+		return NULL;
+	}
 	if (vbe_get_video_info(gdev)) {
 		dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0);
 		if (dev == -1) {
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 27/28] efi: Add a README to explain how things work
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (25 preceding siblings ...)
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 26/28] x86: Gracefully disable the vesa driver when running from EFI Simon Glass
@ 2015-08-04 18:34 ` Simon Glass
  2015-08-05 18:03   ` Simon Glass
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled Simon Glass
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:34 UTC (permalink / raw)
  To: u-boot

Add some documentation on the EFI implementation in U-Boot.

Signed-off-by: Ben Stoltz <stoltz@google.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---

Changes in v3: None
Changes in v2:
- Drop patch "Add a link script entry for U-Boot as a payload"
- Replace 'Coreboot' with 'coreboot'
- Use CONFIG_EFI_APP instead of CONFIG_ARCH_EFI
- Use u-boot-app.efi instead of u-boot.efi

 doc/README.efi | 237 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)
 create mode 100644 doc/README.efi

diff --git a/doc/README.efi b/doc/README.efi
new file mode 100644
index 0000000..7c95579
--- /dev/null
+++ b/doc/README.efi
@@ -0,0 +1,237 @@
+#
+# Copyright (C) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+U-Boot on EFI
+=============
+This document provides information about U-Boot running on top of EFI, either
+as an application or just as a means of getting U-Boot onto a new platform.
+
+
+In God's Name, Why?
+-------------------
+This is useful in several situations:
+
+- You have EFI running on a board but U-Boot does not natively support it
+fully yet. You can boot into U-Boot from EFI and use that until U-Boot is
+fully ported
+
+- You need to use an EFI implementation (e.g. UEFI) because your vendor
+requires it in order to provide support
+
+- You plan to use coreboot to boot into U-Boot but coreboot support does
+not currently exist for your platform. In the meantime you can use U-Boot
+on EFI and then move to U-Boot on coreboot when ready
+
+- You use EFI but want to experiment with a simpler alternative like U-Boot
+
+
+Status
+------
+Only x86 is supported at present. If you are using EFI on another architecture
+you may want to reconsider. However, much of the code is generic so could be
+ported.
+
+U-Boot supports running as an EFI application for 32-bit EFI only. This is
+not very useful since only a serial port is provided. You can look around at
+memory and type 'help' but that is about it.
+
+More usefully, U-Boot supports building itself as a payload for either 32-bit
+or 64-bit EFI. U-Boot is packaged up and loaded in its entirety by EFI. Once
+started, U-Boot changes to 32-bit mode (currently) and takes over the
+machine. You can use devices, boot a kernel, etc.
+
+
+Build Instructions
+------------------
+First choose a board that has EFI support and obtain an EFI implementation
+for that board. It will be either 32-bit or 64-bit.
+
+To build U-Boot as an EFI application (32-bit EFI required), enable
+CONFIG_EFI and CONFIG_EFI_APP. The efi-x86 config is set up for this.
+
+To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust
+an existing config to enable CONFIG_EFI, CONFIG_EFI_STUB and either
+CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT.
+
+Then build U-Boot as normal, e.g.
+
+   make qemu-x86_defconfig
+   make menuconfig    (or make xconfig if you prefer)
+   # change the settings as above
+   make
+
+You will end up with one of these files:
+
+   u-boot-app.efi      - U-Boot EFI application
+   u-boot-payload.efi  - U-Boot EFI payload application
+
+
+Trying it out
+-------------
+Qemu is an emulator and it can emulate an x86 machine. You can run the
+payload with something like this:
+
+   mkdir /tmp/efi
+   cp /path/to/u-boot*.efi /tmp/efi
+   qemu-system-x86_64 -bios bios.bin -hda fat:/tmp/efi/
+
+Add -nographic if you want to use the terminal for output. Once it starts
+type 'fs0:u-boot-payload.efi' to run the payload or 'fs0:u-boot-app.efi' to
+run the application. 'bios.bin' is the EFI 'BIOS'.
+
+To try it on real hardware, put u-boot-app.efi on a suitable boot medium,
+such as a USB stick. Then you can type something like this to start it:
+
+   fs0:u-boot-payload.efi
+
+(or fs0:u-boot-app.efi for the application)
+
+This will start the payload, copy U-Boot into RAM and start U-Boot. Note
+that EFI does not support booting a 64-bit application from a 32-bit
+EFI (or vice versa). Also it will often fail to print an error message if
+you get this wrong.
+
+
+Inner workings
+==============
+Here follow a few implementation notes for those who want to fiddle with
+this and perhaps contribute patches.
+
+The application and payload approaches sound similar but are in fact
+implemented completely differently.
+
+EFI Application
+---------------
+For the application the whole of U-Boot is built as a shared library. The
+efi_main() function is in lib/efi/efi_app.c. It sets up some basic EFI
+functions with efi_init(), sets up U-Boot global_data, allocates memory for
+U-Boot's malloc(), etc. and enters the normal init sequence (board_init_f()
+and board_init_r()).
+
+Since U-Boot limits its memory access to the allocated regions very little
+special code is needed. The CONFIG_EFI_APP option controls a few things
+that need to change so 'git grep CONFIG_EFI_APP' may be instructive.
+The CONFIG_EFI option controls more general EFI adjustments.
+
+The only available driver is the serial driver. This calls back into EFI
+'boot services' to send and receive characters. Although it is implemented
+as a serial driver the console device is not necessarilly serial. If you
+boot EFI with video output then the 'serial' device will operate on your
+target devices's display instead and the device's USB keyboard will also
+work if connected. If you have both serial and video output, then both
+consoles will be active. Even though U-Boot does the same thing normally,
+These are features of EFI, not U-Boot.
+
+Very little code is involved in implementing the EFI application feature.
+U-Boot is highly portable. Most of the difficulty is in modifying the
+Makefile settings to pass the right build flags. In particular there is very
+little x86-specific code involved - you can find most of it in
+arch/x86/cpu. Porting to ARM (which can also use EFI if you are brave
+enough) should be straightforward.
+
+Use the 'reset' command to get back to EFI.
+
+EFI Payload
+-----------
+The payload approach is a different kettle of fish. It works by building
+U-Boot exactly as normal for your target board, then adding the entire
+image (including device tree) into a small EFI stub application responsible
+for booting it. The stub application is built as a normal EFI application
+except that it has a lot of data attached to it.
+
+The stub application is implemented in lib/efi/efi_stub.c. The efi_main()
+function is called by EFI. It is responsible for copying U-Boot from its
+original location into memory, disabling EFI boot services and starting
+U-Boot. U-Boot then starts as normal, relocates, starts all drivers, etc.
+
+The stub application is architecture-dependent. At present it has some
+x86-specific code and a comment at the top of efi_stub.c describes this.
+
+While the stub application does allocate some memory from EFI this is not
+used by U-Boot (the payload). In fact when U-Boot starts it has all of the
+memory available to it and can operate as it pleases (but see the next
+section).
+
+Tables
+------
+The payload can pass information to U-Boot in the form of EFI tables. At
+present this feature is used to pass the EFI memory map, an inordinately
+large list of memory regions. You can use the 'efi mem all' command to
+display this list. U-Boot uses the list to work out where to relocate
+itself.
+
+Although U-Boot can use any memory it likes, EFI marks some memory as used
+by 'run-time services', code that hangs around while U-Boot is running and
+is even present when Linux is running. This is common on x86 and provides
+a way for Linux to call back into the firmware to control things like CPU
+fan speed. U-Boot uses only 'conventional' memory, in EFI terminology. It
+will relocate itself to the top of the largest block of memory it can find
+below 4GB.
+
+Interrupts
+----------
+U-Boot drivers typically don't use interrupts. Since EFI enables interrupts
+it is possible that an interrupt will fire that U-Boot cannot handle. This
+seems to cause problems. For this reason the U-Boot payload runs with
+interrupts disabled at present.
+
+32/64-bit
+---------
+While the EFI application can in principle be built as either 32- or 64-bit,
+only 32-bit is currently supported. This means that the application can only
+be used with 32-bit EFI.
+
+The payload stub can be build as either 32- or 64-bits. Only a small amount
+of code is built this way (see the extra- line in lib/efi/Makefile).
+Everything else is built as a normal U-Boot, so is always 32-bit on x86 at
+present.
+
+Future work
+-----------
+This work could be extended in a number of ways:
+
+- Add a generic x86 EFI payload configuration. At present you need to modify
+an existing one, but mostly the low-level x86 code is disabled when booting
+on EFI anyway, so a generic 'EFI' board could be created with a suitable set
+of drivers enabled.
+
+- Add ARM support
+
+- Add 64-bit application support
+
+- Figure out how to solve the interrupt problem
+
+- Add more drivers to the application side (e.g. video, block devices, USB,
+environment access). This would mostly be an academic exercise as a strong
+use case is not readily apparent, but it might be fun.
+
+- Avoid turning off boot services in the stub. Instead allow U-Boot to make
+use of boot services in case it wants to. It is unclear what it might want
+though.
+
+Where is the code?
+------------------
+lib/efi
+	payload stub, application, support code. Mostly arch-neutral
+
+arch/x86/lib/efi
+	helper functions for the fake DRAM init, etc. These can be used by
+	any board that runs as a payload.
+
+arch/x86/cpu/efi
+	x86 support code for running as an EFI application
+
+board/efi/efi-x86/efi.c
+	x86 board code for running as an EFI application
+
+common/cmd_efi.c
+	the 'efi' command
+
+
+--
+Ben Stoltz, Simon Glass
+Google, Inc
+July 2015
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled
  2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
                   ` (26 preceding siblings ...)
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 27/28] efi: Add a README to explain how things work Simon Glass
@ 2015-08-04 18:34 ` Simon Glass
  2015-08-05  3:38   ` Simon Glass
  27 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-04 18:34 UTC (permalink / raw)
  To: u-boot

This was missed in the patch 'Add a way to skip relocation'. Add it in now.

I hope to squash this patch into the earlier one before sending to mainline.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v3:
- Add new patch to allow device tree relocation to be disabled

Changes in v2: None

 common/board_f.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/common/board_f.c b/common/board_f.c
index c596083..c7cc67c 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -654,6 +654,8 @@ static int setup_dram_config(void)
 
 static int reloc_fdt(void)
 {
+	if (gd->flags & GD_FLG_SKIP_RELOC)
+		return 0;
 	if (gd->new_fdt) {
 		memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
 		gd->fdt_blob = gd->new_fdt;
-- 
2.5.0.rc2.392.g76e840b

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled Simon Glass
@ 2015-08-05  3:38   ` Simon Glass
  2015-08-05  8:07     ` Bin Meng
  0 siblings, 1 reply; 69+ messages in thread
From: Simon Glass @ 2015-08-05  3:38 UTC (permalink / raw)
  To: u-boot

Hi Bin,

On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
> This was missed in the patch 'Add a way to skip relocation'. Add it in now.
>
> I hope to squash this patch into the earlier one before sending to mainline.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Add new patch to allow device tree relocation to be disabled
>
> Changes in v2: None
>
>  common/board_f.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/common/board_f.c b/common/board_f.c
> index c596083..c7cc67c 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -654,6 +654,8 @@ static int setup_dram_config(void)
>
>  static int reloc_fdt(void)
>  {
> +       if (gd->flags & GD_FLG_SKIP_RELOC)
> +               return 0;
>         if (gd->new_fdt) {
>                 memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
>                 gd->fdt_blob = gd->new_fdt;
> --
> 2.5.0.rc2.392.g76e840b
>

I should have just squashed this in before sending the series. Anyway,
I can do it either in the next version, or when applying.

Regards,
Simon

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 09/28] x86: Add EFI board code
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 09/28] x86: Add EFI board code Simon Glass
@ 2015-08-05  7:41   ` Bin Meng
  2015-08-05 18:02     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:41 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> From: Ben Stoltz <stoltz@google.com>
>
> Add support for the efi-x86 board, which supports running U-Boot as an
> EFI 32-bit application.
>
> Signed-off-by: Ben Stoltz <stoltz@google.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Drop unnecessary SYS_CAR_ADDR/SIZE Kconfig options
> - Fix text alignment in Kconfig files
>
>  arch/x86/Kconfig              |  1 +
>  board/efi/Kconfig             | 19 +++++++++++++++++++
>  board/efi/efi-x86/Kconfig     | 15 +++++++++++++++
>  board/efi/efi-x86/MAINTAINERS |  6 ++++++
>  board/efi/efi-x86/Makefile    |  7 +++++++
>  board/efi/efi-x86/efi.c       | 18 ++++++++++++++++++
>  6 files changed, 66 insertions(+)
>  create mode 100644 board/efi/Kconfig
>  create mode 100644 board/efi/efi-x86/Kconfig
>  create mode 100644 board/efi/efi-x86/MAINTAINERS
>  create mode 100644 board/efi/efi-x86/Makefile
>  create mode 100644 board/efi/efi-x86/efi.c
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 7e6e89c..f124d58 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -27,6 +27,7 @@ endchoice
>
>  # board-specific options below
>  source "board/coreboot/Kconfig"
> +source "board/efi/Kconfig"
>  source "board/emulation/Kconfig"
>  source "board/google/Kconfig"
>  source "board/intel/Kconfig"
> diff --git a/board/efi/Kconfig b/board/efi/Kconfig
> new file mode 100644
> index 0000000..6f86a48
> --- /dev/null
> +++ b/board/efi/Kconfig
> @@ -0,0 +1,19 @@
> +if VENDOR_EFI
> +
> +choice
> +       prompt "Mainboard model"
> +       optional
> +
> +config TARGET_EFI
> +       bool "efi"
> +       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.
> +
> +endchoice
> +
> +source "board/efi/efi-x86/Kconfig"
> +
> +endif
> diff --git a/board/efi/efi-x86/Kconfig b/board/efi/efi-x86/Kconfig
> new file mode 100644
> index 0000000..fa609ba
> --- /dev/null
> +++ b/board/efi/efi-x86/Kconfig
> @@ -0,0 +1,15 @@
> +if TARGET_EFI
> +
> +config SYS_BOARD
> +       default "efi-x86"
> +
> +config SYS_VENDOR
> +       default "efi"
> +
> +config SYS_SOC
> +       default "efi"
> +
> +config SYS_CONFIG_NAME
> +       default "efi-x86"
> +
> +endif
> diff --git a/board/efi/efi-x86/MAINTAINERS b/board/efi/efi-x86/MAINTAINERS
> new file mode 100644
> index 0000000..a44c7c6
> --- /dev/null
> +++ b/board/efi/efi-x86/MAINTAINERS
> @@ -0,0 +1,6 @@
> +EFI-X86 BOARD
> +M:     Simon Glass <sjg@chromium.org>
> +S:     Maintained
> +F:     board/efi/efi-x86/
> +F:     include/configs/efi-x86.h
> +F:     configs/efi-x86_defconfig
> diff --git a/board/efi/efi-x86/Makefile b/board/efi/efi-x86/Makefile
> new file mode 100644
> index 0000000..9b1e0bd
> --- /dev/null
> +++ b/board/efi/efi-x86/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# Copyright (c) 2015 Google, Inc
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y  += efi.o
> diff --git a/board/efi/efi-x86/efi.c b/board/efi/efi-x86/efi.c
> new file mode 100644
> index 0000000..08958f9
> --- /dev/null
> +++ b/board/efi/efi-x86/efi.c
> @@ -0,0 +1,18 @@
> +/*
> + * Copyright (C) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/gpio.h>
> +
> +int arch_early_init_r(void)
> +{
> +       return 0;
> +}
> +
> +void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio)
> +{
> +       return;
> +}
> --

Tested on Intel Crown Bay and QEMU
Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 10/28] x86: dts: Add a device tree file for EFI
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 10/28] x86: dts: Add a device tree file for EFI Simon Glass
@ 2015-08-05  7:41   ` Bin Meng
  2015-08-05 18:02     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:41 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> This contains just enough to bring up the serial UART.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Remove extraneous '+' in comment
> - Use "efi,app" instead of "efi,payload" for the compatible string
>
>  arch/x86/dts/Makefile |  1 +
>  arch/x86/dts/efi.dts  | 22 ++++++++++++++++++++++
>  2 files changed, 23 insertions(+)
>  create mode 100644 arch/x86/dts/efi.dts
>
> diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
> index 44e2829..71595c7 100644
> --- a/arch/x86/dts/Makefile
> +++ b/arch/x86/dts/Makefile
> @@ -2,6 +2,7 @@ dtb-y += bayleybay.dtb \
>         chromebook_link.dtb \
>         chromebox_panther.dtb \
>         crownbay.dtb \
> +       efi.dtb \
>         galileo.dtb \
>         minnowmax.dtb \
>         qemu-x86_i440fx.dtb \
> diff --git a/arch/x86/dts/efi.dts b/arch/x86/dts/efi.dts
> new file mode 100644
> index 0000000..1f50428
> --- /dev/null
> +++ b/arch/x86/dts/efi.dts
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +/dts-v1/;
> +
> +/include/ "skeleton.dtsi"
> +
> +/ {
> +       model = "EFI";
> +       compatible = "efi,app";
> +
> +       chosen {
> +               stdout-path = &serial;
> +       };
> +
> +       serial: serial {
> +               compatible = "efi,uart";
> +       };
> +};
> --

Tested on Intel Crown Bay and QEMU
Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 01/28] Add a way to skip relocation
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 01/28] Add a way to skip relocation Simon Glass
@ 2015-08-05  7:41   ` Bin Meng
  2015-08-05 18:02     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:41 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> When running U-Boot as an EFI application we cannot relocate since we do not
> have relocation information. U-Boot has already been relocated to a suitable
> address.
>
> Add a global_data flag to control skipping relocation.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  common/board_f.c                  | 7 +++++++
>  include/asm-generic/global_data.h | 1 +
>  2 files changed, 8 insertions(+)
>
> diff --git a/common/board_f.c b/common/board_f.c
> index 6d922b8..c596083 100644
> --- a/common/board_f.c
> +++ b/common/board_f.c
> @@ -664,6 +664,11 @@ static int reloc_fdt(void)
>
>  static int setup_reloc(void)
>  {
> +       if (gd->flags & GD_FLG_SKIP_RELOC) {
> +               debug("Skipping relocation due to flag\n");
> +               return 0;
> +       }
> +
>  #ifdef CONFIG_SYS_TEXT_BASE
>         gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
>  #ifdef CONFIG_M68K
> @@ -689,6 +694,8 @@ static int setup_reloc(void)
>
>  static int jump_to_copy(void)
>  {
> +       if (gd->flags & GD_FLG_SKIP_RELOC)
> +               return 0;
>         /*
>          * x86 is special, but in a nice way. It uses a trampoline which
>          * enables the dcache if possible.
> diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
> index 9f5db0f..2155265 100644
> --- a/include/asm-generic/global_data.h
> +++ b/include/asm-generic/global_data.h
> @@ -117,5 +117,6 @@ typedef struct global_data {
>  #define GD_FLG_SERIAL_READY    0x00100 /* Pre-reloc serial console ready  */
>  #define GD_FLG_FULL_MALLOC_INIT        0x00200 /* Full malloc() is ready          */
>  #define GD_FLG_SPL_INIT                0x00400 /* spl_init() has been called      */
> +#define GD_FLG_SKIP_RELOC      0x00800 /* Don't relocate */
>
>  #endif /* __ASM_GENERIC_GBL_DATA_H */
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 04/28] x86: Set up toolchain flags for running as EFI application
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 04/28] x86: Set up toolchain flags for running as EFI application Simon Glass
@ 2015-08-05  7:41   ` Bin Meng
  2015-08-05 18:02     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:41 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> From: Ben Stoltz <stoltz@google.com>
>
> Adjust the toolchain flags to build U-Boot as a relocatable shared library,
> as required by EFI.
>
> Signed-off-by: Ben Stoltz <stoltz@google.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Add spaces around EFIARCH=
> - Drop LDFLAGS_EFI from this patch
> - Move '-m elf_i386' into the common PLATFORM_LDFLAGS
>
> Changes in v2:
> - Add a comment as to where LDFLAGS_EFI is used
> - Drop duplicate OBJCOPYFLAGS_EFI
> - Drop no-red-zone as it is not needed for i386
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
> - Use toolchain instead of tool chain
>
>  arch/x86/config.mk | 30 +++++++++++++++++++++++++++---
>  1 file changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/config.mk b/arch/x86/config.mk
> index 999143e..e27f84a 100644
> --- a/arch/x86/config.mk
> +++ b/arch/x86/config.mk
> @@ -8,19 +8,43 @@
>  CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
>
>  PLATFORM_CPPFLAGS += -fno-strict-aliasing
> -PLATFORM_CPPFLAGS += -mregparm=3
>  PLATFORM_CPPFLAGS += -fomit-frame-pointer
>  PF_CPPFLAGS_X86   := $(call cc-option, -fno-toplevel-reorder, \
>                        $(call cc-option, -fno-unit-at-a-time)) \
>                      $(call cc-option, -mpreferred-stack-boundary=2)
> +
>  PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86)
>  PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
>  PLATFORM_CPPFLAGS += -march=i386 -m32
>
>  PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
>
> -PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions -m elf_i386
> +PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions -m elf_i386
>
> -LDFLAGS_FINAL += --gc-sections -pie
>  LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
>  LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
> +
> +OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
> +       -j .rel -j .rela -j .reloc
> +
> +CFLAGS_NON_EFI := -mregparm=3
> +CFLAGS_EFI := -fpic -fshort-wchar
> +
> +EFIARCH = ia32
> +
> +LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
> +OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
> +
> +ifeq ($(CONFIG_EFI_APP),y)
> +
> +PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
> +LDFLAGS_FINAL += -znocombreloc -shared
> +LDSCRIPT := $(LDSCRIPT_EFI)
> +
> +else
> +
> +PLATFORM_CPPFLAGS += $(CFLAGS_NON_EFI)
> +PLATFORM_LDFLAGS += --emit-relocs
> +LDFLAGS_FINAL += --gc-sections -pie
> +
> +endif
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 05/28] efi: Support building a u-boot-app.efi executable
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 05/28] efi: Support building a u-boot-app.efi executable Simon Glass
@ 2015-08-05  7:42   ` Bin Meng
  2015-08-05 18:02     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:42 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> Add support for building U-Boot as an EFI application with a .efi suffix.
> This can be loaded by EFI provided that EFI has the same bit width (32-
> or 64-bit) as U-Boot. This unfortunate limitation is imposed by EFI.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Move the rename to u-boot-app.efi into this patch
> - Update the patch subject
>
> Changes in v2:
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>
>  Makefile | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/Makefile b/Makefile
> index 1b03357..620c18f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -754,6 +754,7 @@ ifneq ($(CONFIG_SPL_TARGET),)
>  ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
>  endif
>  ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
> +ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
>
>  ifneq ($(BUILD_ROM),)
>  ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
> @@ -1082,6 +1083,10 @@ u-boot-dtb-tegra.bin: u-boot-nodtb-tegra.bin dts/dt.dtb FORCE
>  endif
>  endif
>
> +OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)
> +u-boot-app.efi: u-boot FORCE
> +       $(call if_changed,zobjcopy)
> +
>  u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE
>         $(call if_changed,cat)
>
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 06/28] x86: Support skipping relocation for EFI
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 06/28] x86: Support skipping relocation for EFI Simon Glass
@ 2015-08-05  7:42   ` Bin Meng
  2015-08-05 18:02     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:42 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> When running as an EFI application we must skip relocation. Add support for
> this in the x86 relocation code.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Return early in copy_uboot_to_ram() and clear_bbs() when relocation disabled
>
>  arch/x86/lib/relocate.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c
> index 1a62142..9e748d2 100644
> --- a/arch/x86/lib/relocate.c
> +++ b/arch/x86/lib/relocate.c
> @@ -28,6 +28,8 @@ int copy_uboot_to_ram(void)
>  {
>         size_t len = (size_t)&__data_end - (size_t)&__text_start;
>
> +       if (gd->flags & GD_FLG_SKIP_RELOC)
> +               return 0;
>         memcpy((void *)gd->relocaddr, (void *)&__text_start, len);
>
>         return 0;
> @@ -38,6 +40,8 @@ int clear_bss(void)
>         ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
>         size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
>
> +       if (gd->flags & GD_FLG_SKIP_RELOC)
> +               return 0;
>         memset((void *)dst_addr, 0x00, len);
>
>         return 0;
> @@ -58,6 +62,8 @@ int do_elf_reloc_fixups(void)
>         /* The size of the region of u-boot that runs out of RAM. */
>         uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
>
> +       if (gd->flags & GD_FLG_SKIP_RELOC)
> +               return 0;
>         if (re_src == re_end)
>                 panic("No relocation data");
>
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 08/28] x86: Add support for U-Boot as an EFI application
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 08/28] x86: Add support for U-Boot as an EFI application Simon Glass
@ 2015-08-05  7:42   ` Bin Meng
  2015-08-05 18:02     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:42 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> From: Ben Stoltz <stoltz@google.com>
>
> Add the required x86 glue code. This includes the initial start-up,
> relocation and jumping to efi_main(). We also need to avoid fiddling with
> interrupts.
>
> Signed-off-by: Ben Stoltz <stoltz@google.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Move u-boot-app.efi Makefile change to the earlier patch
> - Use "BSD-2-Clause" for the SPDX license
>
> Changes in v2:
> - Add ALIGN() before .dynamic in the linker script
> - Add a blank line before return in the _relocate() function
> - Add a comment as to why .hash has to be first in the linker script
> - Add a comment as to why interrupt_init() must be skipped for EFI
> - Drop unused DECLARE_GLOBAL_DATA_INIT
> - Drop unused board_eth_init()
> - Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application yet
> - Fix spacing around operators
> - Move 64-bit crt0 to a later patch
> - Move crt0 and reloc files into arch/x86/lib/efi/
> - Remove KEEP in the EFI linker script since garbage collection is not enabled
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
> - Rename ImageBase to image_base
> - Use SPDX for the EFI start and relocation code
> - Use u-boot-app.efi instead of u-boot.efi
>
>  arch/x86/Kconfig                     |  3 ++
>  arch/x86/Makefile                    |  2 +
>  arch/x86/cpu/Makefile                |  1 +
>  arch/x86/cpu/efi/Makefile            |  8 +++
>  arch/x86/cpu/efi/efi.c               | 42 ++++++++++++++++
>  arch/x86/cpu/efi/elf_ia32_efi.lds    | 94 ++++++++++++++++++++++++++++++++++++
>  arch/x86/cpu/efi/sdram.c             | 29 +++++++++++
>  arch/x86/cpu/interrupts.c            |  6 +++
>  arch/x86/include/asm/arch-efi/gpio.h | 10 ++++
>  arch/x86/lib/efi/crt0-efi-ia32.S     | 52 ++++++++++++++++++++
>  arch/x86/lib/efi/reloc_ia32.c        | 72 +++++++++++++++++++++++++++
>  11 files changed, 319 insertions(+)
>  create mode 100644 arch/x86/cpu/efi/Makefile
>  create mode 100644 arch/x86/cpu/efi/efi.c
>  create mode 100644 arch/x86/cpu/efi/elf_ia32_efi.lds
>  create mode 100644 arch/x86/cpu/efi/sdram.c
>  create mode 100644 arch/x86/include/asm/arch-efi/gpio.h
>  create mode 100644 arch/x86/lib/efi/crt0-efi-ia32.S
>  create mode 100644 arch/x86/lib/efi/reloc_ia32.c
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index e8968a7..7e6e89c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -11,6 +11,9 @@ choice
>  config VENDOR_COREBOOT
>         bool "coreboot"
>
> +config VENDOR_EFI
> +       bool "efi"
> +
>  config VENDOR_EMULATION
>         bool "emulation"
>
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index 36a6018..d104a49 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -2,7 +2,9 @@
>  # SPDX-License-Identifier:     GPL-2.0+
>  #
>
> +ifeq ($(CONFIG_EFI_APP),)
>  head-y := arch/x86/cpu/start.o
> +endif
>  ifeq ($(CONFIG_SPL_BUILD),y)
>  head-y += arch/x86/cpu/start16.o
>  head-y += arch/x86/cpu/resetvec.o
> diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
> index 8a8e63e..5e058c0 100644
> --- a/arch/x86/cpu/Makefile
> +++ b/arch/x86/cpu/Makefile
> @@ -14,6 +14,7 @@ obj-y += interrupts.o cpu.o cpu_x86.o call64.o
>
>  obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
>  obj-$(CONFIG_SYS_COREBOOT) += coreboot/
> +obj-$(CONFIG_EFI_APP) += efi/
>  obj-$(CONFIG_QEMU) += qemu/
>  obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
>  obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
> diff --git a/arch/x86/cpu/efi/Makefile b/arch/x86/cpu/efi/Makefile
> new file mode 100644
> index 0000000..e091637
> --- /dev/null
> +++ b/arch/x86/cpu/efi/Makefile
> @@ -0,0 +1,8 @@
> +#
> +# Copyright (c) 2015 Google, Inc
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y += efi.o
> +obj-y += sdram.o
> diff --git a/arch/x86/cpu/efi/efi.c b/arch/x86/cpu/efi/efi.c
> new file mode 100644
> index 0000000..75ba0d4
> --- /dev/null
> +++ b/arch/x86/cpu/efi/efi.c
> @@ -0,0 +1,42 @@
> +/*
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <fdtdec.h>
> +#include <netdev.h>
> +
> +int arch_cpu_init(void)
> +{
> +#ifdef CONFIG_SYS_X86_TSC_TIMER
> +       timer_set_base(rdtsc());
> +#endif
> +
> +       return 0;
> +}
> +
> +int board_early_init_f(void)
> +{
> +       return 0;
> +}
> +
> +int print_cpuinfo(void)
> +{
> +       return default_print_cpuinfo();
> +}
> +
> +void board_final_cleanup(void)
> +{
> +}
> +
> +int misc_init_r(void)
> +{
> +       return 0;
> +}
> +
> +int arch_misc_init(void)
> +{
> +       return 0;
> +}
> diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds b/arch/x86/cpu/efi/elf_ia32_efi.lds
> new file mode 100644
> index 0000000..cd3b0a9
> --- /dev/null
> +++ b/arch/x86/cpu/efi/elf_ia32_efi.lds
> @@ -0,0 +1,94 @@
> +/*
> + * U-Boot EFI linker script
> + *
> + * SPDX-License-Identifier:    BSD-2-Clause
> + *
> + * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
> + */
> +
> +#include <config.h>
> +
> +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
> +OUTPUT_ARCH(i386)
> +ENTRY(_start)
> +SECTIONS
> +{
> +       image_base = .;
> +       .hash : { *(.hash) }    /* this MUST come first, EFI expects it */
> +       . = ALIGN(4096);
> +       .text :
> +       {
> +               *(.text)
> +               *(.text.*)
> +               *(.gnu.linkonce.t.*)
> +       }
> +       . = ALIGN(4096);
> +       .sdata :
> +       {
> +               *(.got.plt)
> +               *(.got)
> +               *(.srodata)
> +               *(.sdata)
> +               *(.sbss)
> +               *(.scommon)
> +       }
> +       . = ALIGN(4096);
> +       .data :
> +       {
> +               *(.rodata*)
> +               *(.data)
> +               *(.data1)
> +               *(.data.*)
> +               *(.sdata)
> +               *(.got.plt)
> +               *(.got)
> +               /*
> +                * the EFI loader doesn't seem to like a .bss section, so we
> +                * stick it all into .data:
> +                */
> +               *(.sbss)
> +               *(.scommon)
> +               *(.dynbss)
> +               *(.bss)
> +               *(COMMON)
> +
> +               /* U-Boot lists and device tree */
> +               . = ALIGN(8);
> +               *(SORT(.u_boot_list*));
> +               . = ALIGN(8);
> +               *(.dtb*);
> +       }
> +
> +       . = ALIGN(4096);
> +       .dynamic  : { *(.dynamic) }
> +       . = ALIGN(4096);
> +       .rel :
> +       {
> +               *(.rel.data)
> +               *(.rel.data.*)
> +               *(.rel.got)
> +               *(.rel.stab)
> +               *(.data.rel.ro.local)
> +               *(.data.rel.local)
> +               *(.data.rel.ro)
> +               *(.data.rel*)
> +               *(.rel.u_boot_list*)
> +       }
> +       . = ALIGN(4096);
> +               .reloc :        /* This is the PECOFF .reloc section! */
> +       {
> +       *(.reloc)
> +       }
> +       . = ALIGN(4096);
> +       .dynsym   : { *(.dynsym) }
> +       . = ALIGN(4096);
> +       .dynstr   : { *(.dynstr) }
> +       . = ALIGN(4096);
> +       /DISCARD/ :
> +       {
> +               *(.rel.reloc)
> +               *(.eh_frame)
> +               *(.note.GNU-stack)
> +       }
> +       .comment 0 : { *(.comment) }
> +}
> diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c
> new file mode 100644
> index 0000000..5159944
> --- /dev/null
> +++ b/arch/x86/cpu/efi/sdram.c
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <efi.h>
> +#include <asm/u-boot-x86.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +ulong board_get_usable_ram_top(ulong total_size)
> +{
> +       return (ulong)efi_get_ram_base() + gd->ram_size;
> +}
> +
> +int dram_init(void)
> +{
> +       /* gd->ram_size is set as part of EFI init */
> +
> +       return 0;
> +}
> +
> +void dram_init_banksize(void)
> +{
> +       gd->bd->bi_dram[0].start = efi_get_ram_base();
> +       gd->bd->bi_dram[0].size = CONFIG_EFI_RAM_SIZE;
> +}
> diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
> index 3a9c2d4..a112938 100644
> --- a/arch/x86/cpu/interrupts.c
> +++ b/arch/x86/cpu/interrupts.c
> @@ -242,6 +242,11 @@ int disable_interrupts(void)
>
>  int interrupt_init(void)
>  {
> +       /*
> +        * When running as an EFI application we are not in control of
> +        * interrupts and should leave them alone.
> +        */
> +#ifndef CONFIG_EFI_APP
>         /* Just in case... */
>         disable_interrupts();
>
> @@ -255,6 +260,7 @@ int interrupt_init(void)
>
>         /* It is now safe to enable interrupts */
>         enable_interrupts();
> +#endif
>
>         return 0;
>  }
> diff --git a/arch/x86/include/asm/arch-efi/gpio.h b/arch/x86/include/asm/arch-efi/gpio.h
> new file mode 100644
> index 0000000..f044f07
> --- /dev/null
> +++ b/arch/x86/include/asm/arch-efi/gpio.h
> @@ -0,0 +1,10 @@
> +/*
> + * Copyright (c) 2015 Google, Inc.
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _X86_ARCH_GPIO_H_
> +#define _X86_ARCH_GPIO_H_
> +
> +#endif /* _X86_ARCH_GPIO_H_ */
> diff --git a/arch/x86/lib/efi/crt0-efi-ia32.S b/arch/x86/lib/efi/crt0-efi-ia32.S
> new file mode 100644
> index 0000000..30e5eb0
> --- /dev/null
> +++ b/arch/x86/lib/efi/crt0-efi-ia32.S
> @@ -0,0 +1,52 @@
> +/*
> + * crt0-efi-ia32.S - x86 EFI startup code.
> + *
> + * Copyright (C) 1999 Hewlett-Packard Co.
> + * Contributed by David Mosberger <davidm@hpl.hp.com>.
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +
> +       .text
> +       .align 4
> +
> +       .globl _start
> +_start:
> +       pushl %ebp
> +       movl %esp,%ebp
> +
> +       pushl 12(%ebp)                  # copy "image" argument
> +       pushl  8(%ebp)                  # copy "systab" argument
> +
> +       call 0f
> +0:     popl %eax
> +       movl %eax,%ebx
> +
> +       addl $image_base-0b,%eax        # %eax = ldbase
> +       addl $_DYNAMIC-0b,%ebx          # %ebx = _DYNAMIC
> +
> +       pushl %ebx                      # pass _DYNAMIC as second argument
> +       pushl %eax                      # pass ldbase as first argument
> +       call _relocate
> +       popl %ebx
> +       popl %ebx
> +       testl %eax,%eax
> +       jne .exit
> +       call efi_main           # call app with "image" and "systab" argument
> +
> +.exit: leave
> +       ret
> +
> +       /*
> +        * hand-craft a dummy .reloc section so EFI knows it's a relocatable
> +        * executable:
> +        */
> +       .data
> +dummy: .long   0
> +
> +#define IMAGE_REL_ABSOLUTE     0
> +       .section .reloc
> +       .long   dummy                                   /* Page RVA */
> +       .long   10                                      /* Block Size (2*4+2) */
> +       .word   (IMAGE_REL_ABSOLUTE << 12) +  0         /* reloc for dummy */
> diff --git a/arch/x86/lib/efi/reloc_ia32.c b/arch/x86/lib/efi/reloc_ia32.c
> new file mode 100644
> index 0000000..4d68255
> --- /dev/null
> +++ b/arch/x86/lib/efi/reloc_ia32.c
> @@ -0,0 +1,72 @@
> +/*
> + * reloc_ia32.c - position independent x86 ELF shared object relocator
> + * Copyright (C) 1999 Hewlett-Packard Co.
> + * Contributed by David Mosberger <davidm@hpl.hp.com>.
> + *
> + * All rights reserved.
> + *
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +
> +#include <common.h>
> +#include <efi.h>
> +#include <elf.h>
> +#include <asm/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;
> +       unsigned long *addr;
> +       int i;
> +
> +       for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
> +               switch (dyn[i].d_tag) {
> +               case DT_REL:
> +                       rel = (Elf32_Rel *)((unsigned long)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;
> +
> +               case DT_RELA:
> +                       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_386_NONE:
> +                       break;
> +
> +               case R_386_RELATIVE:
> +                       addr = (unsigned long *)(ldbase + rel->r_offset);
> +                       *addr += ldbase;
> +                       break;
> +
> +               default:
> +                       break;
> +               }
> +               rel = (Elf32_Rel *)((char *)rel + relent);
> +               relsz -= relent;
> +       }
> +
> +       return EFI_SUCCESS;
> +}
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 14/28] efi: Add support for loading U-Boot through an EFI stub
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 14/28] efi: Add support for loading U-Boot through an EFI stub Simon Glass
@ 2015-08-05  7:59   ` Bin Meng
  2015-08-05 18:03     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  7:59 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> It is useful to be able to load U-Boot onto a board even if is it already
> running EFI. This can allow access to the U-Boot command interface, flexible
> booting options and easier development.
>
> The easiest way to do this is to build U-Boot as a binary blob and have an
> EFI stub copy it into RAM. Add support for this feature, targeting 32-bit
> initially.
>
> Also add a way to detect when U-Boot has been loaded via a stub. This goes
> in common.h since it needs to be widely available so that we avoid redoing
> initialisation that should be skipped.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Improvements to how the payload is built:
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3:
> - Fix calling convention to starting U-Boot in the 32-bit stub
> - Rename LDFLAGS_EFI to LDFLAGS_EFI_PAYLOAD and move into this patch
> - Use quiet_cmd_xxx to link the payload
>
> Changes in v2:
> - Add a comment as to why we must call exit_boot_services() twice
> - Drop \n\t at the end of a one-line asm statement
> - Merge in Bin's implementation of adding a U-Boot payload with objcopy
> - Remove comment about reset_cpu() returning to EFI in the stub
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>
>  Makefile           |  24 +++++
>  arch/x86/config.mk |   7 ++
>  include/common.h   |   7 ++
>  include/efi.h      |   4 +
>  lib/efi/Kconfig    |  21 ++++
>  lib/efi/Makefile   |   9 ++
>  lib/efi/efi_stub.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 376 insertions(+)
>  create mode 100644 lib/efi/efi_stub.c
>
> diff --git a/Makefile b/Makefile
> index 620c18f..752ee0d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -755,6 +755,7 @@ ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
>  endif
>  ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
>  ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
> +ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi
>
>  ifneq ($(BUILD_ROM),)
>  ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
> @@ -790,6 +791,9 @@ cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
>  quiet_cmd_zobjcopy = OBJCOPY $@
>  cmd_zobjcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
>
> +quiet_cmd_efipayload = OBJCOPY $@
> +cmd_efipayload = $(OBJCOPY) -I binary -O $(EFIPAYLOAD_BFDTARGET) -B $(EFIPAYLOAD_BFDARCH) $< $@
> +
>  quiet_cmd_mkimage = MKIMAGE $@
>  cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
>         $(if $(KBUILD_VERBOSE:1=), >/dev/null)
> @@ -1087,6 +1091,26 @@ OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)
>  u-boot-app.efi: u-boot FORCE
>         $(call if_changed,zobjcopy)
>
> +u-boot-dtb.bin.o: u-boot-dtb.bin FORCE
> +       $(call if_changed,efipayload)
> +
> +u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE
> +       $(call if_changed_dep,cpp_lds)
> +
> +# Rule to link the EFI payload which contains a stub and a U-Boot binary
> +quiet_cmd_u-boot_payload ?= LD      $@
> +      cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
> +      -T u-boot-payload.lds \
> +      lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \
> +      $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
> +
> +u-boot-payload: u-boot-dtb.bin.o u-boot-payload.lds FORCE
> +       $(call if_changed,u-boot_payload)
> +
> +OBJCOPYFLAGS_u-boot-payload.efi := $(OBJCOPYFLAGS_EFI)
> +u-boot-payload.efi: u-boot-payload FORCE
> +       $(call if_changed,zobjcopy)
> +
>  u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE
>         $(call if_changed,cat)
>
> diff --git a/arch/x86/config.mk b/arch/x86/config.mk
> index e27f84a..334c10b 100644
> --- a/arch/x86/config.mk
> +++ b/arch/x86/config.mk
> @@ -24,6 +24,10 @@ PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions -m elf_i386
>  LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
>  LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
>
> +# This is used in the top-level Makefile which does not include
> +# PLATFORM_LDFLAGS
> +LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined
> +
>  OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
>         -j .rel -j .rela -j .reloc
>
> @@ -31,6 +35,9 @@ CFLAGS_NON_EFI := -mregparm=3
>  CFLAGS_EFI := -fpic -fshort-wchar
>
>  EFIARCH = ia32
> +EFIPAYLOAD_BFDTARGET = elf32-i386
> +
> +EFIPAYLOAD_BFDARCH = i386
>
>  LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
>  OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
> diff --git a/include/common.h b/include/common.h
> index 4566bd1..fcc9ae7 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -1021,6 +1021,13 @@ int cpu_release(int nr, int argc, char * const argv[]);
>         offsetof(struct structure, member) == offset, \
>         "`struct " #structure "` offset for `" #member "` is not " #offset)
>
> +/* Avoid using CONFIG_EFI_STUB directly as we may boot from other loaders */
> +#ifdef CONFIG_EFI_STUB
> +#define ll_boot_init() false
> +#else
> +#define ll_boot_init() true
> +#endif
> +
>  /* Pull in stuff for the build system */
>  #ifdef DO_DEPS_ONLY
>  # include <environment.h>
> diff --git a/include/efi.h b/include/efi.h
> index f009701..1470c08 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -268,11 +268,15 @@ struct efi_priv {
>  /* Base address of the EFI image */
>  extern char image_base[];
>
> +/* Start and end of U-Boot image (for payload) */
> +extern char _binary_u_boot_dtb_bin_start[], _binary_u_boot_dtb_bin_end[];
> +
>  /**
>   * efi_get_sys_table() - Get access to the main EFI system table
>   *
>   * @return pointer to EFI system table
>   */
> +
>  struct efi_system_table *efi_get_sys_table(void);
>
>  /**
> diff --git a/lib/efi/Kconfig b/lib/efi/Kconfig
> index b23ba5b..919e314 100644
> --- a/lib/efi/Kconfig
> +++ b/lib/efi/Kconfig
> @@ -20,6 +20,11 @@ config EFI_APP
>           command prompt and memory and I/O functions. Use 'reset' to return
>           to EFI.
>
> +config EFI_STUB
> +       bool "Support running as an EFI payload"
> +
> +endchoice
> +
>  config EFI_RAM_SIZE
>         hex "Amount of EFI RAM for U-Boot"
>         depends on EFI_APP
> @@ -30,4 +35,20 @@ config EFI_RAM_SIZE
>           other smaller amounts) and it can never be increased after that.
>           It is used as the RAM size in with U-Boot.
>
> +choice
> +       prompt "EFI 32/64-bit selection"
> +       depends on EFI_STUB
> +       help
> +         EFI does not support mixing 32-bit and 64-bit modes. This is a
> +         significant problem because it means that you must build a stub with
> +         the correct type for EFI to load it correctly. If you are using
> +         32-bit EFI, select 32-bit here, else select 64-bit. Failure to do
> +         this may produce no error message - it just won't start!
> +
> +config EFI_STUB_32BIT
> +       bool "Produce a stub for running with 32-bit EFI"
> +
> +config EFI_STUB_64BIT
> +       bool "Produce a stub for running with 64-bit EFI"
> +
>  endchoice
> diff --git a/lib/efi/Makefile b/lib/efi/Makefile
> index 5ee344c..4bc67f0 100644
> --- a/lib/efi/Makefile
> +++ b/lib/efi/Makefile
> @@ -5,3 +5,12 @@
>  #
>
>  obj-$(CONFIG_EFI_APP) += efi_app.o efi.o
> +
> +CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
> +       $(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
> +CFLAGS_efi_stub.o := -fpic -fshort-wchar
> +CFLAGS_REMOVE_efi.o := -mregparm=3 \
> +       $(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
> +CFLAGS_efi.o := -fpic -fshort-wchar
> +
> +extra-$(CONFIG_EFI_STUB) += efi_stub.o efi.o
> diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
> new file mode 100644
> index 0000000..1e46f6e
> --- /dev/null
> +++ b/lib/efi/efi_stub.c
> @@ -0,0 +1,304 @@
> +/*
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + *
> + * EFI information obtained here:
> + * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES
> + *
> + * Loads a payload (U-Boot) within the EFI environment. This is built as a
> + * 32-bit EFI application.
> + */
> +
> +#include <common.h>
> +#include <debug_uart.h>
> +#include <efi.h>
> +#include <efi_api.h>
> +#include <errno.h>
> +#include <ns16550.h>
> +#include <asm/cpu.h>
> +#include <asm/io.h>
> +#include <linux/err.h>
> +#include <linux/types.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#ifndef CONFIG_X86
> +/*
> + * Problem areas:
> + * - putc() uses the ns16550 address directly and assumed I/O access. Many
> + *     platforms will use memory access
> + * get_codeseg32() is only meaningful on x86
> + */
> +#error "This file needs to be ported for use on architectures"
> +#endif
> +
> +static struct efi_priv *global_priv;
> +static bool use_uart;
> +
> +struct __packed desctab_info {
> +       uint16_t limit;
> +       uint64_t addr;
> +       uint16_t pad;
> +};
> +
> +/*
> + * EFI uses Unicode and we don't. The easiest way to get a sensible output
> + * function is to use the U-Boot debug UART. We use EFI's console output
> + * function where available, and assume the built-in UART after that. We rely
> + * on EFI to set up the UART for us and just bring in the functions here.
> + * This last bit is a bit icky, but it's only for debugging anyway. We could
> + * build in ns16550.c with some effort, but this is a payload loader after
> + * all.
> + *
> + * Note: We avoid using printf() so we don't need to bring in lib/vsprintf.c.
> + * That would require some refactoring since we already build this for U-Boot.
> + * Building an EFI shared library version would have to be a separate stem.
> + * That might push us to using the SPL framework to build this stub. However
> + * that would involve a round of EFI-specific changes in SPL. Worth
> + * considering if we start needing more U-Boot functionality. Note that we
> + * could then move get_codeseg32() to arch/x86/cpu/cpu.c.
> + */
> +void debug_uart_init(void)
> +{
> +}
> +
> +void putc(const char ch)
> +{
> +       if (use_uart) {
> +               NS16550_t com_port = (NS16550_t)0x3f8;
> +
> +               while ((inb((ulong)&com_port->lsr) & UART_LSR_THRE) == 0)
> +                       ;
> +               outb(ch, (ulong)&com_port->thr);
> +       } else {
> +               efi_putc(global_priv, ch);
> +       }
> +       if (ch == '\n')
> +               putc('\r');
> +}
> +
> +void puts(const char *str)
> +{
> +       while (*str)
> +               putc(*str++);
> +}
> +
> +static void _debug_uart_putc(int ch)
> +{
> +       putc(ch);
> +}
> +
> +DEBUG_UART_FUNCS
> +
> +void *memcpy(void *dest, const void *src, size_t size)
> +{
> +       unsigned char *dptr = dest;
> +       const unsigned char *ptr = src;
> +       const unsigned char *end = src + size;
> +
> +       while (ptr < end)
> +               *dptr++ = *ptr++;
> +
> +       return dest;
> +}
> +
> +void *memset(void *inptr, int ch, size_t size)
> +{
> +       char *ptr = inptr;
> +       char *end = ptr + size;
> +
> +       while (ptr < end)
> +               *ptr++ = ch;
> +
> +       return ptr;
> +}
> +
> +static void jump_to_uboot(ulong cs32, ulong addr, ulong info)
> +{
> +#ifdef CONFIG_EFI_STUB_32BIT
> +       /*
> +        * U-Boot requires these parameters in registers, not on the stack.
> +        * See _x86boot_start() for this code.
> +        */
> +       typedef void (*func_t)(int bist, int unused, ulong info)
> +               __attribute__((regparm(3)));
> +
> +       ((func_t)addr)(0, 0, info);
> +#else
> +       /* TODO: Implement this */
> +#endif
> +}
> +
> +static void get_gdt(struct desctab_info *info)
> +{
> +       asm volatile ("sgdt %0" : : "m"(*info) : "memory");
> +}
> +
> +static inline unsigned long read_cr3(void)
> +{
> +       unsigned long val;
> +
> +       asm volatile("mov %%cr3,%0" : "=r" (val) : : "memory");
> +       return val;
> +}
> +
> +/**
> + * get_codeseg32() - Find the code segment to use for 32-bit code
> + *
> + * U-Boot only works in 32-bit mode at present, so when booting from 64-bit
> + * EFI we must first change to 32-bit mode. To do this we need to find the
> + * correct code segment to use (an entry in the Global Descriptor Table).
> + *
> + * @return code segment GDT offset, or 0 for 32-bit EFI, -ENOENT if not found
> + */
> +static int get_codeseg32(void)
> +{
> +       int cs32 = 0;
> +
> +       /* TODO(sjg): Implement this for 64-bit mode */
> +       return cs32;
> +}
> +
> +static int setup_info_table(struct efi_priv *priv, int size)
> +{
> +       struct efi_info_hdr *info;
> +       efi_status_t ret;
> +
> +       /* Get some memory for our info table */
> +       priv->info_size = size;
> +       info = efi_malloc(priv, priv->info_size, &ret);
> +       if (ret) {
> +               printhex2(ret);
> +               puts(" No memory for info table: ");
> +               return ret;
> +       }
> +
> +       memset(info, '\0', sizeof(*info));
> +       info->version = EFI_TABLE_VERSION;
> +       info->hdr_size = sizeof(*info);
> +       priv->info = info;
> +       priv->next_hdr = (char *)info + info->hdr_size;
> +
> +       return 0;
> +}
> +
> +static void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type,
> +                          void *ptr1, int size1, void *ptr2, int size2)
> +{
> +       struct efi_entry_hdr *hdr = priv->next_hdr;
> +
> +       hdr->type = type;
> +       hdr->size = size1 + size2;
> +       hdr->addr = 0;
> +       hdr->link = ALIGN(sizeof(*hdr) + hdr->size, 16);
> +       priv->next_hdr += hdr->link;
> +       memcpy(hdr + 1, ptr1, size1);
> +       memcpy((void *)(hdr + 1) + size1, ptr2, size2);
> +       priv->info->total_size = (ulong)priv->next_hdr - (ulong)priv->info;
> +}
> +
> +/**
> + * efi_main() - Start an EFI image
> + *
> + * This function is called by our EFI start-up code. It handles running
> + * U-Boot. If it returns, EFI will continue.
> + */
> +efi_status_t efi_main(efi_handle_t image, struct efi_system_table *sys_table)
> +{
> +       struct efi_priv local_priv, *priv = &local_priv;
> +       struct efi_boot_services *boot = sys_table->boottime;
> +       struct efi_mem_desc *desc;
> +       struct efi_entry_memmap map;
> +       ulong key, desc_size, size;
> +       efi_status_t ret;
> +       u32 version;
> +       int cs32;
> +
> +       ret = efi_init(priv, "Payload", image, sys_table);
> +       if (ret) {
> +               printhex2(ret); puts(" efi_init() failed\n");
> +               return ret;
> +       }
> +       global_priv = priv;
> +
> +       cs32 = get_codeseg32();
> +       if (cs32 < 0)
> +               return EFI_UNSUPPORTED;
> +
> +       /* Get the memory map so we can switch off EFI */
> +       size = 0;
> +       ret = boot->get_memory_map(&size, NULL, &key, &desc_size, &version);
> +       if (ret != EFI_BUFFER_TOO_SMALL) {
> +               printhex2(BITS_PER_LONG);
> +               printhex2(ret);
> +               puts(" No memory map\n");
> +               return ret;
> +       }
> +       size += 1024;   /* Since doing a malloc() may change the memory map! */
> +       desc = efi_malloc(priv, size, &ret);
> +       if (!desc) {
> +               printhex2(ret);
> +               puts(" No memory for memory descriptor: ");
> +               return ret;
> +       }
> +       ret = setup_info_table(priv, size + 128);
> +       if (ret)
> +               return ret;
> +
> +       ret = boot->get_memory_map(&size, desc, &key, &desc_size, &version);
> +       if (ret) {
> +               printhex2(ret);
> +               puts(" Can't get memory map\n");
> +               return ret;
> +       }
> +
> +       ret = boot->exit_boot_services(image, key);
> +       if (ret) {
> +               /*
> +                * Unfortunately it happens that we cannot exit boot services
> +                * the first time. But the second time it work. I don't know
> +                * why but this seems to be a repeatable problem. To get
> +                * around it, just try again.
> +                */
> +               printhex2(ret);
> +               puts(" Can't exit boot services\n");
> +               size = sizeof(desc);
> +               ret = boot->get_memory_map(&size, desc, &key, &desc_size,
> +                                          &version);
> +               if (ret) {
> +                       printhex2(ret);
> +                       puts(" Can't get memory map\n");
> +                       return ret;
> +               }
> +               ret = boot->exit_boot_services(image, key);
> +               if (ret) {
> +                       printhex2(ret);
> +                       puts(" Can't exit boot services 2\n");
> +                       return ret;
> +               }
> +       }
> +
> +       map.version = version;
> +       map.desc_size = desc_size;
> +       add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), desc, size);
> +       add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0);
> +
> +       /* The EFI UART won't work now, switch to a debug one */
> +       use_uart = true;
> +
> +       memcpy((void *)CONFIG_SYS_TEXT_BASE, _binary_u_boot_dtb_bin_start,
> +              (ulong)_binary_u_boot_dtb_bin_end -
> +              (ulong)_binary_u_boot_dtb_bin_start);
> +
> +#ifdef DEBUG
> +       puts("EFI table at ");
> +       printhex8((ulong)priv->info);
> +       puts(" size ");
> +       printhex8(priv->info->total_size);
> +#endif
> +       putc('\n');
> +       jump_to_uboot(cs32, CONFIG_SYS_TEXT_BASE, (ulong)priv->info);
> +
> +       return EFI_LOAD_ERROR;
> +}
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Tested on QEMU 32-bit and 64-bit
Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 18/28] efi: Add 64-bit payload support
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 18/28] efi: Add 64-bit payload support Simon Glass
@ 2015-08-05  8:02   ` Bin Meng
  2015-08-05 18:03     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  8:02 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> Most EFI implementations use 64-bit. Add a way to build U-Boot as a 64-bit
> EFI payload. The payload unpacks a (32-bit) U-Boot and starts it. This can
> be enabled for x86 boards at present.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Improvements to how the payload is built:
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3:
> - Add spaces around EFIARCH=
> - Use CONFIG_SYS_MONITOR_LEN as a more accurate value for U-Boot's size
>
> Changes in v2:
> - Add -no-red-zone for 64-bit only
> - Check the GDT selector's base and limit against the target address
> - Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application yet
> - Merge in Bin's implementation of adding a U-Boot payload with objcopy
> - Move the 64-bit crt and reloc code into this patch
> - Move the 64-bit efi.h additions into this patch
> - Rename GDT_4GB to GDT_4KB
>
>  Makefile                           |  2 +-
>  arch/x86/config.mk                 | 10 ++++++
>  arch/x86/include/asm/types.h       |  5 ++-
>  arch/x86/lib/efi/crt0-efi-x86_64.S | 51 ++++++++++++++++++++++++++
>  include/efi.h                      |  7 ++++
>  lib/efi/efi_stub.c                 | 74 +++++++++++++++++++++++++++++++++++---
>  6 files changed, 143 insertions(+), 6 deletions(-)
>  create mode 100644 arch/x86/lib/efi/crt0-efi-x86_64.S
>
> diff --git a/Makefile b/Makefile
> index 752ee0d..bb0ba9f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1100,7 +1100,7 @@ u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE
>  # Rule to link the EFI payload which contains a stub and a U-Boot binary
>  quiet_cmd_u-boot_payload ?= LD      $@
>        cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
> -      -T u-boot-payload.lds \
> +      -T u-boot-payload.lds arch/x86/cpu/call32.o \
>        lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \
>        $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
>
> diff --git a/arch/x86/config.mk b/arch/x86/config.mk
> index 334c10b..d7addd8 100644
> --- a/arch/x86/config.mk
> +++ b/arch/x86/config.mk
> @@ -34,14 +34,24 @@ OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
>  CFLAGS_NON_EFI := -mregparm=3
>  CFLAGS_EFI := -fpic -fshort-wchar
>
> +ifeq ($(CONFIG_EFI_STUB_64BIT),)
> +CFLAGS_EFI += $(call cc-option, -mno-red-zone)
>  EFIARCH = ia32
>  EFIPAYLOAD_BFDTARGET = elf32-i386
> +else
> +EFIARCH = x86_64
> +EFIPAYLOAD_BFDTARGET = elf64-x86-64
> +endif
>
>  EFIPAYLOAD_BFDARCH = i386
>
>  LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
> +EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o
>  OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
>
> +CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
> +CPPFLAGS_crt0-efi-$(EFIARCH).o += $(CFLAGS_EFI)
> +
>  ifeq ($(CONFIG_EFI_APP),y)
>
>  PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
> diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
> index e272c90..766617f 100644
> --- a/arch/x86/include/asm/types.h
> +++ b/arch/x86/include/asm/types.h
> @@ -44,8 +44,11 @@ typedef __INT64_TYPE__ s64;
>  typedef __UINT64_TYPE__ u64;
>  #endif
>
> +#ifdef CONFIG_EFI_STUB_64BIT
> +#define BITS_PER_LONG 64
> +#else
>  #define BITS_PER_LONG 32
> -
> +#endif
>  /* Dma addresses are 32-bits wide.  */
>
>  typedef u32 dma_addr_t;
> diff --git a/arch/x86/lib/efi/crt0-efi-x86_64.S b/arch/x86/lib/efi/crt0-efi-x86_64.S
> new file mode 100644
> index 0000000..c5cbf41
> --- /dev/null
> +++ b/arch/x86/lib/efi/crt0-efi-x86_64.S
> @@ -0,0 +1,51 @@
> +/*
> + * crt0-efi-x86_64.S - x86_64 EFI startup code.
> + * Copyright (C) 1999 Hewlett-Packard Co.
> + * Contributed by David Mosberger <davidm@hpl.hp.com>.
> + * Copyright (C) 2005 Intel Co.
> + * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
> + *
> + * All rights reserved.
> + * SPDX-License-Identifier:    BSD-3-Clause
> + */
> +       .text
> +       .align 4
> +
> +       .globl _start
> +_start:
> +       subq $8, %rsp
> +       pushq %rcx
> +       pushq %rdx
> +
> +0:
> +       lea image_base(%rip), %rdi
> +       lea _DYNAMIC(%rip), %rsi
> +
> +       popq %rcx
> +       popq %rdx
> +       pushq %rcx
> +       pushq %rdx
> +       call _relocate
> +
> +       popq %rdi
> +       popq %rsi
> +
> +       call efi_main
> +       addq $8, %rsp
> +
> +.exit:
> +       ret
> +
> +       /*
> +        * hand-craft a dummy .reloc section so EFI knows it's a relocatable
> +        * executable:
> +        */
> +       .data
> +dummy: .long   0
> +
> +#define IMAGE_REL_ABSOLUTE     0
> +       .section .reloc, "a"
> +label1:
> +       .long   dummy-label1                            /* Page RVA */
> +       .long   10                                      /* Block Size (2*4+2) */
> +       .word   (IMAGE_REL_ABSOLUTE << 12) +  0         /* reloc for dummy */
> diff --git a/include/efi.h b/include/efi.h
> index 1470c08..fcafda0 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -18,6 +18,13 @@
>  #include <linux/string.h>
>  #include <linux/types.h>
>
> +#ifdef CONFIG_EFI_STUB_64BIT
> +/* EFI uses the Microsoft ABI which is not the default for GCC */
> +#define EFIAPI __attribute__((ms_abi))
> +#else
> +#define EFIAPI
> +#endif
> +
>  struct efi_device_path;
>
>  #define EFI_SUCCESS            0
> diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c
> index 1e46f6e..d4d3e49 100644
> --- a/lib/efi/efi_stub.c
> +++ b/lib/efi/efi_stub.c
> @@ -6,8 +6,8 @@
>   * EFI information obtained here:
>   * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES
>   *
> - * Loads a payload (U-Boot) within the EFI environment. This is built as a
> - * 32-bit EFI application.
> + * Loads a payload (U-Boot) within the EFI environment. This is built as an
> + * EFI application. It can be built either in 32-bit or 64-bit mode.
>   */
>
>  #include <common.h>
> @@ -126,14 +126,16 @@ static void jump_to_uboot(ulong cs32, ulong addr, ulong info)
>
>         ((func_t)addr)(0, 0, info);
>  #else
> -       /* TODO: Implement this */
> +       cpu_call32(cs32, CONFIG_SYS_TEXT_BASE, info);
>  #endif
>  }
>
> +#ifdef CONFIG_EFI_STUB_64BIT
>  static void get_gdt(struct desctab_info *info)
>  {
>         asm volatile ("sgdt %0" : : "m"(*info) : "memory");
>  }
> +#endif
>
>  static inline unsigned long read_cr3(void)
>  {
> @@ -156,7 +158,71 @@ static int get_codeseg32(void)
>  {
>         int cs32 = 0;
>
> -       /* TODO(sjg): Implement this for 64-bit mode */
> +#ifdef CONFIG_EFI_STUB_64BIT
> +       struct desctab_info gdt;
> +       uint64_t *ptr;
> +       int i;
> +
> +       get_gdt(&gdt);
> +       for (ptr = (uint64_t *)(unsigned long)gdt.addr, i = 0; i < gdt.limit;
> +            i += 8, ptr++) {
> +               uint64_t desc = *ptr;
> +               uint64_t base, limit;
> +
> +               /*
> +                * Check that the target U-Boot jump address is within the
> +                * selector and that the selector is of the right type.
> +                */
> +               base = ((desc >> GDT_BASE_LOW_SHIFT) & GDT_BASE_LOW_MASK) |
> +                       ((desc >> GDT_BASE_HIGH_SHIFT) & GDT_BASE_HIGH_MASK)
> +                               << 16;
> +               limit = ((desc >> GDT_LIMIT_LOW_SHIFT) & GDT_LIMIT_LOW_MASK) |
> +                       ((desc >> GDT_LIMIT_HIGH_SHIFT) & GDT_LIMIT_HIGH_MASK)
> +                               << 16;
> +               base <<= 12;    /* 4KB granularity */
> +               limit <<= 12;
> +               if ((desc & GDT_PRESENT) && (desc && GDT_NOTSYS) &&
> +                   !(desc & GDT_LONG) && (desc & GDT_4KB) &&
> +                   (desc & GDT_32BIT) && (desc & GDT_CODE) &&
> +                   CONFIG_SYS_TEXT_BASE > base &&
> +                   CONFIG_SYS_TEXT_BASE + CONFIG_SYS_MONITOR_LEN < limit
> +               ) {
> +                       cs32 = i;
> +                       break;
> +               }
> +       }
> +
> +#ifdef DEBUG
> +       puts("\ngdt: ");
> +       printhex8(gdt.limit);
> +       puts(", addr: ");
> +       printhex8(gdt.addr >> 32);
> +       printhex8(gdt.addr);
> +       for (i = 0; i < gdt.limit; i += 8) {
> +               uint32_t *ptr = (uint32_t *)((unsigned long)gdt.addr + i);
> +
> +               puts("\n");
> +               printhex2(i);
> +               puts(": ");
> +               printhex8(ptr[1]);
> +               puts("  ");
> +               printhex8(ptr[0]);
> +       }
> +       puts("\n ");
> +       puts("32-bit code segment: ");
> +       printhex2(cs32);
> +       puts("\n ");
> +
> +       puts("page_table: ");
> +       printhex8(read_cr3());
> +       puts("\n ");
> +#endif
> +       if (!cs32) {
> +               puts("Can't find 32-bit code segment\n");
> +               return -ENOENT;
> +       }
> +#endif
> +
>         return cs32;
>  }
>
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Tested on QEMU 32-bit and 64-bit
Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled
  2015-08-05  3:38   ` Simon Glass
@ 2015-08-05  8:07     ` Bin Meng
  2015-08-05 18:03       ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  8:07 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Aug 5, 2015 at 11:38 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Bin,
>
> On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
>> This was missed in the patch 'Add a way to skip relocation'. Add it in now.
>>
>> I hope to squash this patch into the earlier one before sending to mainline.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

>> ---
>>
>> Changes in v3:
>> - Add new patch to allow device tree relocation to be disabled
>>
>> Changes in v2: None
>>
>>  common/board_f.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/common/board_f.c b/common/board_f.c
>> index c596083..c7cc67c 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -654,6 +654,8 @@ static int setup_dram_config(void)
>>
>>  static int reloc_fdt(void)
>>  {
>> +       if (gd->flags & GD_FLG_SKIP_RELOC)
>> +               return 0;
>>         if (gd->new_fdt) {
>>                 memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
>>                 gd->fdt_blob = gd->new_fdt;
>> --
>> 2.5.0.rc2.392.g76e840b
>>
>
> I should have just squashed this in before sending the series. Anyway,
> I can do it either in the next version, or when applying.
>

Yep, I think this needs to be squashed in v3 [01/28] patch:
http://patchwork.ozlabs.org/patch/503752/

Regards,
Bin

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 25/28] x86: qemu: Support operation as an EFI payload
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 25/28] x86: qemu: " Simon Glass
@ 2015-08-05  8:19   ` Bin Meng
  2015-08-05 18:03     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05  8:19 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:34 AM, Simon Glass <sjg@chromium.org> wrote:
> Disable a few things which interfere with the EFI init. This allows QEMU to
> to boot into EFI, load a U-Boot payload then boot to the U-Boot prompt.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Fix indenting in board/emulation/qemu-x86/Kconfig
>
>  arch/x86/cpu/qemu/Makefile       | 5 ++++-
>  arch/x86/cpu/qemu/qemu.c         | 2 ++
>  board/emulation/qemu-x86/Kconfig | 5 +++--
>  3 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile
> index be79723..9a66b16 100644
> --- a/arch/x86/cpu/qemu/Makefile
> +++ b/arch/x86/cpu/qemu/Makefile
> @@ -4,5 +4,8 @@
>  # SPDX-License-Identifier:     GPL-2.0+
>  #
>
> -obj-y += car.o dram.o qemu.o
> +ifndef CONFIG_EFI_STUB
> +obj-y += car.o dram.o
> +endif
> +obj-y += qemu.o
>  obj-$(CONFIG_PCI) += pci.o
> diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
> index 930d2b6..64634a9 100644
> --- a/arch/x86/cpu/qemu/qemu.c
> +++ b/arch/x86/cpu/qemu/qemu.c
> @@ -25,11 +25,13 @@ int arch_cpu_init(void)
>         return 0;
>  }
>
> +#ifndef CONFIG_EFI_STUB
>  int print_cpuinfo(void)
>  {
>         post_code(POST_CPU_INFO);
>         return default_print_cpuinfo();
>  }
> +#endif
>
>  void reset_cpu(ulong addr)
>  {
> diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
> index e777ef4..c9181fc 100644
> --- a/board/emulation/qemu-x86/Kconfig
> +++ b/board/emulation/qemu-x86/Kconfig
> @@ -13,11 +13,12 @@ config SYS_CONFIG_NAME
>         default "qemu-x86"
>
>  config SYS_TEXT_BASE
> -       default 0xfff00000
> +       default 0xfff00000 if !EFI_STUB
> +       default 0x01110000 if EFI_STUB
>
>  config BOARD_SPECIFIC_OPTIONS # dummy
>         def_bool y
> -       select X86_RESET_VECTOR
> +       select X86_RESET_VECTOR if !EFI_STUB
>         select QEMU
>         select BOARD_ROMSIZE_KB_1024
>
> --

Tested on QEMU 32-bit and 64-bit
Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 15/28] x86: Support building the EFI stub
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 15/28] x86: Support building the " Simon Glass
@ 2015-08-05 12:20   ` Bin Meng
  2015-08-05 18:03     ` Simon Glass
  0 siblings, 1 reply; 69+ messages in thread
From: Bin Meng @ 2015-08-05 12:20 UTC (permalink / raw)
  To: u-boot

On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
> Add support for building a 32/64-bit EFI stub for x86. This involves
> building the startup and relocation code for either i386 or x86_64.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3:
> - Move 64-bit comment to just above the 64-bit flag adjustments
>
> Changes in v2:
> - Add a comment as to why the AFLAGS_REMOVE_.. lines are needed
> - Move the crt and reloc files into arch/x86/lib/efi/
>
>  arch/x86/lib/Makefile     |  2 +-
>  arch/x86/lib/efi/Makefile | 24 ++++++++++++++++++++++++
>  2 files changed, 25 insertions(+), 1 deletion(-)
>  create mode 100644 arch/x86/lib/efi/Makefile
>
> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
> index 43489fd..09c236b 100644
> --- a/arch/x86/lib/Makefile
> +++ b/arch/x86/lib/Makefile
> @@ -34,7 +34,7 @@ obj-$(CONFIG_SYS_X86_TSC_TIMER)       += tsc_timer.o
>  obj-$(CONFIG_CMD_ZBOOT)        += zimage.o
>  obj-$(CONFIG_HAVE_FSP) += fsp/
>
> -extra-$(CONFIG_USE_PRIVATE_LIBGCC) := lib.a
> +extra-$(CONFIG_USE_PRIVATE_LIBGCC) += lib.a
>
>  NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
>  OBJCOPYFLAGS := --prefix-symbols=__normal_
> diff --git a/arch/x86/lib/efi/Makefile b/arch/x86/lib/efi/Makefile
> new file mode 100644
> index 0000000..bb7b95b
> --- /dev/null
> +++ b/arch/x86/lib/efi/Makefile
> @@ -0,0 +1,24 @@
> +#
> +# (C) Copyright 2002-2006
> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +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
> --

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 01/28] Add a way to skip relocation
  2015-08-05  7:41   ` Bin Meng
@ 2015-08-05 18:02     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:41, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> When running U-Boot as an EFI application we cannot relocate since we do not
>> have relocation information. U-Boot has already been relocated to a suitable
>> address.
>>
>> Add a global_data flag to control skipping relocation.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3: None
>> Changes in v2: None
>>
>>  common/board_f.c                  | 7 +++++++
>>  include/asm-generic/global_data.h | 1 +
>>  2 files changed, 8 insertions(+)
>>
>> diff --git a/common/board_f.c b/common/board_f.c
>> index 6d922b8..c596083 100644
>> --- a/common/board_f.c
>> +++ b/common/board_f.c
>> @@ -664,6 +664,11 @@ static int reloc_fdt(void)
>>
>>  static int setup_reloc(void)
>>  {
>> +       if (gd->flags & GD_FLG_SKIP_RELOC) {
>> +               debug("Skipping relocation due to flag\n");
>> +               return 0;
>> +       }
>> +
>>  #ifdef CONFIG_SYS_TEXT_BASE
>>         gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
>>  #ifdef CONFIG_M68K
>> @@ -689,6 +694,8 @@ static int setup_reloc(void)
>>
>>  static int jump_to_copy(void)
>>  {
>> +       if (gd->flags & GD_FLG_SKIP_RELOC)
>> +               return 0;
>>         /*
>>          * x86 is special, but in a nice way. It uses a trampoline which
>>          * enables the dcache if possible.
>> diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
>> index 9f5db0f..2155265 100644
>> --- a/include/asm-generic/global_data.h
>> +++ b/include/asm-generic/global_data.h
>> @@ -117,5 +117,6 @@ typedef struct global_data {
>>  #define GD_FLG_SERIAL_READY    0x00100 /* Pre-reloc serial console ready  */
>>  #define GD_FLG_FULL_MALLOC_INIT        0x00200 /* Full malloc() is ready          */
>>  #define GD_FLG_SPL_INIT                0x00400 /* spl_init() has been called      */
>> +#define GD_FLG_SKIP_RELOC      0x00800 /* Don't relocate */
>>
>>  #endif /* __ASM_GENERIC_GBL_DATA_H */
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Squashed in the later patch:

http://patchwork.ozlabs.org/patch/503779/

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 02/28] efi: Add a serial driver
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 02/28] efi: Add a serial driver Simon Glass
@ 2015-08-05 18:02   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> Add a serial driver which makes use of EFI's console in/out service.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> Tested on Intel Crown Bay and QEMU
> Tested-by: Bin Meng <bmeng.cn@gmail.com>
>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Add a comment about special handling for backspace
> - Add a comment as to why debug_uart_init() is empty
> - Drop unused DECLARE_GLOBAL_DATA_PTR
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
> - Rename EFI debug UART to EFI_CONSOLE
> - Replace serial_s5p with serial_efi
>
>  drivers/serial/Kconfig      |   9 +++
>  drivers/serial/Makefile     |   1 +
>  drivers/serial/serial_efi.c | 157 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 167 insertions(+)
>  create mode 100644 drivers/serial/serial_efi.c

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 03/28] efi: Drop CONFIG_SYS_TEXT_BASE for EFI
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 03/28] efi: Drop CONFIG_SYS_TEXT_BASE for EFI Simon Glass
@ 2015-08-05 18:02   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> From: Ben Stoltz <stoltz@google.com>
>
> When U-Boot runs as an EFI application is does not have a definition of
> CONFIG_SYS_TEXT_BASE. U-Boot is a relocatable application and the relocation
> is done by EFI. U-Boot can be loaded at any address.
>
> Ensure that this CONFIG option is not set in this case.
>
> Signed-off-by: Ben Stoltz <stoltz@google.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>
>  Kconfig | 1 +
>  1 file changed, 1 insertion(+)

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 04/28] x86: Set up toolchain flags for running as EFI application
  2015-08-05  7:41   ` Bin Meng
@ 2015-08-05 18:02     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:41, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> From: Ben Stoltz <stoltz@google.com>
>>
>> Adjust the toolchain flags to build U-Boot as a relocatable shared library,
>> as required by EFI.
>>
>> Signed-off-by: Ben Stoltz <stoltz@google.com>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3:
>> - Add spaces around EFIARCH=
>> - Drop LDFLAGS_EFI from this patch
>> - Move '-m elf_i386' into the common PLATFORM_LDFLAGS
>>
>> Changes in v2:
>> - Add a comment as to where LDFLAGS_EFI is used
>> - Drop duplicate OBJCOPYFLAGS_EFI
>> - Drop no-red-zone as it is not needed for i386
>> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>> - Use toolchain instead of tool chain
>>
>>  arch/x86/config.mk | 30 +++++++++++++++++++++++++++---
>>  1 file changed, 27 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/config.mk b/arch/x86/config.mk
>> index 999143e..e27f84a 100644
>> --- a/arch/x86/config.mk
>> +++ b/arch/x86/config.mk
>> @@ -8,19 +8,43 @@
>>  CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
>>
>>  PLATFORM_CPPFLAGS += -fno-strict-aliasing
>> -PLATFORM_CPPFLAGS += -mregparm=3
>>  PLATFORM_CPPFLAGS += -fomit-frame-pointer
>>  PF_CPPFLAGS_X86   := $(call cc-option, -fno-toplevel-reorder, \
>>                        $(call cc-option, -fno-unit-at-a-time)) \
>>                      $(call cc-option, -mpreferred-stack-boundary=2)
>> +
>>  PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86)
>>  PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
>>  PLATFORM_CPPFLAGS += -march=i386 -m32
>>
>>  PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
>>
>> -PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions -m elf_i386
>> +PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions -m elf_i386
>>
>> -LDFLAGS_FINAL += --gc-sections -pie
>>  LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
>>  LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
>> +
>> +OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
>> +       -j .rel -j .rela -j .reloc
>> +
>> +CFLAGS_NON_EFI := -mregparm=3
>> +CFLAGS_EFI := -fpic -fshort-wchar
>> +
>> +EFIARCH = ia32
>> +
>> +LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
>> +OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
>> +
>> +ifeq ($(CONFIG_EFI_APP),y)
>> +
>> +PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
>> +LDFLAGS_FINAL += -znocombreloc -shared
>> +LDSCRIPT := $(LDSCRIPT_EFI)
>> +
>> +else
>> +
>> +PLATFORM_CPPFLAGS += $(CFLAGS_NON_EFI)
>> +PLATFORM_LDFLAGS += --emit-relocs
>> +LDFLAGS_FINAL += --gc-sections -pie
>> +
>> +endif
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> Tested-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 05/28] efi: Support building a u-boot-app.efi executable
  2015-08-05  7:42   ` Bin Meng
@ 2015-08-05 18:02     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:42, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> Add support for building U-Boot as an EFI application with a .efi suffix.
>> This can be loaded by EFI provided that EFI has the same bit width (32-
>> or 64-bit) as U-Boot. This unfortunate limitation is imposed by EFI.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3:
>> - Move the rename to u-boot-app.efi into this patch
>> - Update the patch subject
>>
>> Changes in v2:
>> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>>
>>  Makefile | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/Makefile b/Makefile
>> index 1b03357..620c18f 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -754,6 +754,7 @@ ifneq ($(CONFIG_SPL_TARGET),)
>>  ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
>>  endif
>>  ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
>> +ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
>>
>>  ifneq ($(BUILD_ROM),)
>>  ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
>> @@ -1082,6 +1083,10 @@ u-boot-dtb-tegra.bin: u-boot-nodtb-tegra.bin dts/dt.dtb FORCE
>>  endif
>>  endif
>>
>> +OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)
>> +u-boot-app.efi: u-boot FORCE
>> +       $(call if_changed,zobjcopy)
>> +
>>  u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE
>>         $(call if_changed,cat)
>>
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 06/28] x86: Support skipping relocation for EFI
  2015-08-05  7:42   ` Bin Meng
@ 2015-08-05 18:02     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:42, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> When running as an EFI application we must skip relocation. Add support for
>> this in the x86 relocation code.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3: None
>> Changes in v2:
>> - Return early in copy_uboot_to_ram() and clear_bbs() when relocation disabled
>>
>>  arch/x86/lib/relocate.c | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c
>> index 1a62142..9e748d2 100644
>> --- a/arch/x86/lib/relocate.c
>> +++ b/arch/x86/lib/relocate.c
>> @@ -28,6 +28,8 @@ int copy_uboot_to_ram(void)
>>  {
>>         size_t len = (size_t)&__data_end - (size_t)&__text_start;
>>
>> +       if (gd->flags & GD_FLG_SKIP_RELOC)
>> +               return 0;
>>         memcpy((void *)gd->relocaddr, (void *)&__text_start, len);
>>
>>         return 0;
>> @@ -38,6 +40,8 @@ int clear_bss(void)
>>         ulong dst_addr = (ulong)&__bss_start + gd->reloc_off;
>>         size_t len = (size_t)&__bss_end - (size_t)&__bss_start;
>>
>> +       if (gd->flags & GD_FLG_SKIP_RELOC)
>> +               return 0;
>>         memset((void *)dst_addr, 0x00, len);
>>
>>         return 0;
>> @@ -58,6 +62,8 @@ int do_elf_reloc_fixups(void)
>>         /* The size of the region of u-boot that runs out of RAM. */
>>         uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start;
>>
>> +       if (gd->flags & GD_FLG_SKIP_RELOC)
>> +               return 0;
>>         if (re_src == re_end)
>>                 panic("No relocation data");
>>
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 07/28] x86: Add asm/elf.h for x86-specific ELF definitions
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 07/28] x86: Add asm/elf.h for x86-specific ELF definitions Simon Glass
@ 2015-08-05 18:02   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> Bring in this file from Linux 4.1. It supports relocation features specific
> to x86.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Drop unneeded include of asm/ptrace.h
> - Fix comment style
>
>  arch/x86/include/asm/elf.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 arch/x86/include/asm/elf.h

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 08/28] x86: Add support for U-Boot as an EFI application
  2015-08-05  7:42   ` Bin Meng
@ 2015-08-05 18:02     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:42, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> From: Ben Stoltz <stoltz@google.com>
>>
>> Add the required x86 glue code. This includes the initial start-up,
>> relocation and jumping to efi_main(). We also need to avoid fiddling with
>> interrupts.
>>
>> Signed-off-by: Ben Stoltz <stoltz@google.com>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3:
>> - Move u-boot-app.efi Makefile change to the earlier patch
>> - Use "BSD-2-Clause" for the SPDX license
>>
>> Changes in v2:
>> - Add ALIGN() before .dynamic in the linker script
>> - Add a blank line before return in the _relocate() function
>> - Add a comment as to why .hash has to be first in the linker script
>> - Add a comment as to why interrupt_init() must be skipped for EFI
>> - Drop unused DECLARE_GLOBAL_DATA_INIT
>> - Drop unused board_eth_init()
>> - Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application yet
>> - Fix spacing around operators
>> - Move 64-bit crt0 to a later patch
>> - Move crt0 and reloc files into arch/x86/lib/efi/
>> - Remove KEEP in the EFI linker script since garbage collection is not enabled
>> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>> - Rename ImageBase to image_base
>> - Use SPDX for the EFI start and relocation code
>> - Use u-boot-app.efi instead of u-boot.efi
>>
>>  arch/x86/Kconfig                     |  3 ++
>>  arch/x86/Makefile                    |  2 +
>>  arch/x86/cpu/Makefile                |  1 +
>>  arch/x86/cpu/efi/Makefile            |  8 +++
>>  arch/x86/cpu/efi/efi.c               | 42 ++++++++++++++++
>>  arch/x86/cpu/efi/elf_ia32_efi.lds    | 94 ++++++++++++++++++++++++++++++++++++
>>  arch/x86/cpu/efi/sdram.c             | 29 +++++++++++
>>  arch/x86/cpu/interrupts.c            |  6 +++
>>  arch/x86/include/asm/arch-efi/gpio.h | 10 ++++
>>  arch/x86/lib/efi/crt0-efi-ia32.S     | 52 ++++++++++++++++++++
>>  arch/x86/lib/efi/reloc_ia32.c        | 72 +++++++++++++++++++++++++++
>>  11 files changed, 319 insertions(+)
>>  create mode 100644 arch/x86/cpu/efi/Makefile
>>  create mode 100644 arch/x86/cpu/efi/efi.c
>>  create mode 100644 arch/x86/cpu/efi/elf_ia32_efi.lds
>>  create mode 100644 arch/x86/cpu/efi/sdram.c
>>  create mode 100644 arch/x86/include/asm/arch-efi/gpio.h
>>  create mode 100644 arch/x86/lib/efi/crt0-efi-ia32.S
>>  create mode 100644 arch/x86/lib/efi/reloc_ia32.c
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index e8968a7..7e6e89c 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -11,6 +11,9 @@ choice
>>  config VENDOR_COREBOOT
>>         bool "coreboot"
>>
>> +config VENDOR_EFI
>> +       bool "efi"
>> +
>>  config VENDOR_EMULATION
>>         bool "emulation"
>>
>> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
>> index 36a6018..d104a49 100644
>> --- a/arch/x86/Makefile
>> +++ b/arch/x86/Makefile
>> @@ -2,7 +2,9 @@
>>  # SPDX-License-Identifier:     GPL-2.0+
>>  #
>>
>> +ifeq ($(CONFIG_EFI_APP),)
>>  head-y := arch/x86/cpu/start.o
>> +endif
>>  ifeq ($(CONFIG_SPL_BUILD),y)
>>  head-y += arch/x86/cpu/start16.o
>>  head-y += arch/x86/cpu/resetvec.o
>> diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
>> index 8a8e63e..5e058c0 100644
>> --- a/arch/x86/cpu/Makefile
>> +++ b/arch/x86/cpu/Makefile
>> @@ -14,6 +14,7 @@ obj-y += interrupts.o cpu.o cpu_x86.o call64.o
>>
>>  obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
>>  obj-$(CONFIG_SYS_COREBOOT) += coreboot/
>> +obj-$(CONFIG_EFI_APP) += efi/
>>  obj-$(CONFIG_QEMU) += qemu/
>>  obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
>>  obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
>> diff --git a/arch/x86/cpu/efi/Makefile b/arch/x86/cpu/efi/Makefile
>> new file mode 100644
>> index 0000000..e091637
>> --- /dev/null
>> +++ b/arch/x86/cpu/efi/Makefile
>> @@ -0,0 +1,8 @@
>> +#
>> +# Copyright (c) 2015 Google, Inc
>> +#
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +obj-y += efi.o
>> +obj-y += sdram.o
>> diff --git a/arch/x86/cpu/efi/efi.c b/arch/x86/cpu/efi/efi.c
>> new file mode 100644
>> index 0000000..75ba0d4
>> --- /dev/null
>> +++ b/arch/x86/cpu/efi/efi.c
>> @@ -0,0 +1,42 @@
>> +/*
>> + * Copyright (c) 2015 Google, Inc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <fdtdec.h>
>> +#include <netdev.h>
>> +
>> +int arch_cpu_init(void)
>> +{
>> +#ifdef CONFIG_SYS_X86_TSC_TIMER
>> +       timer_set_base(rdtsc());
>> +#endif
>> +
>> +       return 0;
>> +}
>> +
>> +int board_early_init_f(void)
>> +{
>> +       return 0;
>> +}
>> +
>> +int print_cpuinfo(void)
>> +{
>> +       return default_print_cpuinfo();
>> +}
>> +
>> +void board_final_cleanup(void)
>> +{
>> +}
>> +
>> +int misc_init_r(void)
>> +{
>> +       return 0;
>> +}
>> +
>> +int arch_misc_init(void)
>> +{
>> +       return 0;
>> +}
>> diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds b/arch/x86/cpu/efi/elf_ia32_efi.lds
>> new file mode 100644
>> index 0000000..cd3b0a9
>> --- /dev/null
>> +++ b/arch/x86/cpu/efi/elf_ia32_efi.lds
>> @@ -0,0 +1,94 @@
>> +/*
>> + * U-Boot EFI linker script
>> + *
>> + * SPDX-License-Identifier:    BSD-2-Clause
>> + *
>> + * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
>> + */
>> +
>> +#include <config.h>
>> +
>> +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
>> +OUTPUT_ARCH(i386)
>> +ENTRY(_start)
>> +SECTIONS
>> +{
>> +       image_base = .;
>> +       .hash : { *(.hash) }    /* this MUST come first, EFI expects it */
>> +       . = ALIGN(4096);
>> +       .text :
>> +       {
>> +               *(.text)
>> +               *(.text.*)
>> +               *(.gnu.linkonce.t.*)
>> +       }
>> +       . = ALIGN(4096);
>> +       .sdata :
>> +       {
>> +               *(.got.plt)
>> +               *(.got)
>> +               *(.srodata)
>> +               *(.sdata)
>> +               *(.sbss)
>> +               *(.scommon)
>> +       }
>> +       . = ALIGN(4096);
>> +       .data :
>> +       {
>> +               *(.rodata*)
>> +               *(.data)
>> +               *(.data1)
>> +               *(.data.*)
>> +               *(.sdata)
>> +               *(.got.plt)
>> +               *(.got)
>> +               /*
>> +                * the EFI loader doesn't seem to like a .bss section, so we
>> +                * stick it all into .data:
>> +                */
>> +               *(.sbss)
>> +               *(.scommon)
>> +               *(.dynbss)
>> +               *(.bss)
>> +               *(COMMON)
>> +
>> +               /* U-Boot lists and device tree */
>> +               . = ALIGN(8);
>> +               *(SORT(.u_boot_list*));
>> +               . = ALIGN(8);
>> +               *(.dtb*);
>> +       }
>> +
>> +       . = ALIGN(4096);
>> +       .dynamic  : { *(.dynamic) }
>> +       . = ALIGN(4096);
>> +       .rel :
>> +       {
>> +               *(.rel.data)
>> +               *(.rel.data.*)
>> +               *(.rel.got)
>> +               *(.rel.stab)
>> +               *(.data.rel.ro.local)
>> +               *(.data.rel.local)
>> +               *(.data.rel.ro)
>> +               *(.data.rel*)
>> +               *(.rel.u_boot_list*)
>> +       }
>> +       . = ALIGN(4096);
>> +               .reloc :        /* This is the PECOFF .reloc section! */
>> +       {
>> +       *(.reloc)
>> +       }
>> +       . = ALIGN(4096);
>> +       .dynsym   : { *(.dynsym) }
>> +       . = ALIGN(4096);
>> +       .dynstr   : { *(.dynstr) }
>> +       . = ALIGN(4096);
>> +       /DISCARD/ :
>> +       {
>> +               *(.rel.reloc)
>> +               *(.eh_frame)
>> +               *(.note.GNU-stack)
>> +       }
>> +       .comment 0 : { *(.comment) }
>> +}
>> diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c
>> new file mode 100644
>> index 0000000..5159944
>> --- /dev/null
>> +++ b/arch/x86/cpu/efi/sdram.c
>> @@ -0,0 +1,29 @@
>> +/*
>> + * Copyright (c) 2015 Google, Inc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <efi.h>
>> +#include <asm/u-boot-x86.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +ulong board_get_usable_ram_top(ulong total_size)
>> +{
>> +       return (ulong)efi_get_ram_base() + gd->ram_size;
>> +}
>> +
>> +int dram_init(void)
>> +{
>> +       /* gd->ram_size is set as part of EFI init */
>> +
>> +       return 0;
>> +}
>> +
>> +void dram_init_banksize(void)
>> +{
>> +       gd->bd->bi_dram[0].start = efi_get_ram_base();
>> +       gd->bd->bi_dram[0].size = CONFIG_EFI_RAM_SIZE;
>> +}
>> diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c
>> index 3a9c2d4..a112938 100644
>> --- a/arch/x86/cpu/interrupts.c
>> +++ b/arch/x86/cpu/interrupts.c
>> @@ -242,6 +242,11 @@ int disable_interrupts(void)
>>
>>  int interrupt_init(void)
>>  {
>> +       /*
>> +        * When running as an EFI application we are not in control of
>> +        * interrupts and should leave them alone.
>> +        */
>> +#ifndef CONFIG_EFI_APP
>>         /* Just in case... */
>>         disable_interrupts();
>>
>> @@ -255,6 +260,7 @@ int interrupt_init(void)
>>
>>         /* It is now safe to enable interrupts */
>>         enable_interrupts();
>> +#endif
>>
>>         return 0;
>>  }
>> diff --git a/arch/x86/include/asm/arch-efi/gpio.h b/arch/x86/include/asm/arch-efi/gpio.h
>> new file mode 100644
>> index 0000000..f044f07
>> --- /dev/null
>> +++ b/arch/x86/include/asm/arch-efi/gpio.h
>> @@ -0,0 +1,10 @@
>> +/*
>> + * Copyright (c) 2015 Google, Inc.
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef _X86_ARCH_GPIO_H_
>> +#define _X86_ARCH_GPIO_H_
>> +
>> +#endif /* _X86_ARCH_GPIO_H_ */
>> diff --git a/arch/x86/lib/efi/crt0-efi-ia32.S b/arch/x86/lib/efi/crt0-efi-ia32.S
>> new file mode 100644
>> index 0000000..30e5eb0
>> --- /dev/null
>> +++ b/arch/x86/lib/efi/crt0-efi-ia32.S
>> @@ -0,0 +1,52 @@
>> +/*
>> + * crt0-efi-ia32.S - x86 EFI startup code.
>> + *
>> + * Copyright (C) 1999 Hewlett-Packard Co.
>> + * Contributed by David Mosberger <davidm@hpl.hp.com>.
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +       .text
>> +       .align 4
>> +
>> +       .globl _start
>> +_start:
>> +       pushl %ebp
>> +       movl %esp,%ebp
>> +
>> +       pushl 12(%ebp)                  # copy "image" argument
>> +       pushl  8(%ebp)                  # copy "systab" argument
>> +
>> +       call 0f
>> +0:     popl %eax
>> +       movl %eax,%ebx
>> +
>> +       addl $image_base-0b,%eax        # %eax = ldbase
>> +       addl $_DYNAMIC-0b,%ebx          # %ebx = _DYNAMIC
>> +
>> +       pushl %ebx                      # pass _DYNAMIC as second argument
>> +       pushl %eax                      # pass ldbase as first argument
>> +       call _relocate
>> +       popl %ebx
>> +       popl %ebx
>> +       testl %eax,%eax
>> +       jne .exit
>> +       call efi_main           # call app with "image" and "systab" argument
>> +
>> +.exit: leave
>> +       ret
>> +
>> +       /*
>> +        * hand-craft a dummy .reloc section so EFI knows it's a relocatable
>> +        * executable:
>> +        */
>> +       .data
>> +dummy: .long   0
>> +
>> +#define IMAGE_REL_ABSOLUTE     0
>> +       .section .reloc
>> +       .long   dummy                                   /* Page RVA */
>> +       .long   10                                      /* Block Size (2*4+2) */
>> +       .word   (IMAGE_REL_ABSOLUTE << 12) +  0         /* reloc for dummy */
>> diff --git a/arch/x86/lib/efi/reloc_ia32.c b/arch/x86/lib/efi/reloc_ia32.c
>> new file mode 100644
>> index 0000000..4d68255
>> --- /dev/null
>> +++ b/arch/x86/lib/efi/reloc_ia32.c
>> @@ -0,0 +1,72 @@
>> +/*
>> + * reloc_ia32.c - position independent x86 ELF shared object relocator
>> + * Copyright (C) 1999 Hewlett-Packard Co.
>> + * Contributed by David Mosberger <davidm@hpl.hp.com>.
>> + *
>> + * All rights reserved.
>> + *
>> + * SPDX-License-Identifier:    BSD-3-Clause
>> + */
>> +
>> +#include <common.h>
>> +#include <efi.h>
>> +#include <elf.h>
>> +#include <asm/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;
>> +       unsigned long *addr;
>> +       int i;
>> +
>> +       for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
>> +               switch (dyn[i].d_tag) {
>> +               case DT_REL:
>> +                       rel = (Elf32_Rel *)((unsigned long)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;
>> +
>> +               case DT_RELA:
>> +                       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_386_NONE:
>> +                       break;
>> +
>> +               case R_386_RELATIVE:
>> +                       addr = (unsigned long *)(ldbase + rel->r_offset);
>> +                       *addr += ldbase;
>> +                       break;
>> +
>> +               default:
>> +                       break;
>> +               }
>> +               rel = (Elf32_Rel *)((char *)rel + relent);
>> +               relsz -= relent;
>> +       }
>> +
>> +       return EFI_SUCCESS;
>> +}
>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 09/28] x86: Add EFI board code
  2015-08-05  7:41   ` Bin Meng
@ 2015-08-05 18:02     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:41, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> From: Ben Stoltz <stoltz@google.com>
>>
>> Add support for the efi-x86 board, which supports running U-Boot as an
>> EFI 32-bit application.
>>
>> Signed-off-by: Ben Stoltz <stoltz@google.com>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
>> ---
>>
>> Changes in v3: None
>> Changes in v2:
>> - Drop unnecessary SYS_CAR_ADDR/SIZE Kconfig options
>> - Fix text alignment in Kconfig files
>>
>>  arch/x86/Kconfig              |  1 +
>>  board/efi/Kconfig             | 19 +++++++++++++++++++
>>  board/efi/efi-x86/Kconfig     | 15 +++++++++++++++
>>  board/efi/efi-x86/MAINTAINERS |  6 ++++++
>>  board/efi/efi-x86/Makefile    |  7 +++++++
>>  board/efi/efi-x86/efi.c       | 18 ++++++++++++++++++
>>  6 files changed, 66 insertions(+)
>>  create mode 100644 board/efi/Kconfig
>>  create mode 100644 board/efi/efi-x86/Kconfig
>>  create mode 100644 board/efi/efi-x86/MAINTAINERS
>>  create mode 100644 board/efi/efi-x86/Makefile
>>  create mode 100644 board/efi/efi-x86/efi.c
>>
[snip]
>
> Tested on Intel Crown Bay and QEMU
> Tested-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 10/28] x86: dts: Add a device tree file for EFI
  2015-08-05  7:41   ` Bin Meng
@ 2015-08-05 18:02     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:41, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> This contains just enough to bring up the serial UART.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
>> ---
>>
>> Changes in v3: None
>> Changes in v2:
>> - Remove extraneous '+' in comment
>> - Use "efi,app" instead of "efi,payload" for the compatible string
>>
>>  arch/x86/dts/Makefile |  1 +
>>  arch/x86/dts/efi.dts  | 22 ++++++++++++++++++++++
>>  2 files changed, 23 insertions(+)
>>  create mode 100644 arch/x86/dts/efi.dts
>>
>> diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
>> index 44e2829..71595c7 100644
>> --- a/arch/x86/dts/Makefile
>> +++ b/arch/x86/dts/Makefile
>> @@ -2,6 +2,7 @@ dtb-y += bayleybay.dtb \
>>         chromebook_link.dtb \
>>         chromebox_panther.dtb \
>>         crownbay.dtb \
>> +       efi.dtb \
>>         galileo.dtb \
>>         minnowmax.dtb \
>>         qemu-x86_i440fx.dtb \
>> diff --git a/arch/x86/dts/efi.dts b/arch/x86/dts/efi.dts
>> new file mode 100644
>> index 0000000..1f50428
>> --- /dev/null
>> +++ b/arch/x86/dts/efi.dts
>> @@ -0,0 +1,22 @@
>> +/*
>> + * Copyright (c) 2015 Google, Inc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +/dts-v1/;
>> +
>> +/include/ "skeleton.dtsi"
>> +
>> +/ {
>> +       model = "EFI";
>> +       compatible = "efi,app";
>> +
>> +       chosen {
>> +               stdout-path = &serial;
>> +       };
>> +
>> +       serial: serial {
>> +               compatible = "efi,uart";
>> +       };
>> +};
>> --
>
> Tested on Intel Crown Bay and QEMU
> Tested-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 11/28] x86: Allow relocation code to build without text base
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 11/28] x86: Allow relocation code to build without text base Simon Glass
@ 2015-08-05 18:02   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:02 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> This code currently requires CONFIG_SYS_TEXT_BASE but this should be
> unnecessary. As a first step, remove the build-time limitation and report an
> error instead.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Set text_base to 0 to avoid possible compiler warning
>
>  arch/x86/lib/relocate.c | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 13/28] x86: Add relocation and link script for a 64-bit EFI application
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 13/28] x86: Add relocation and link script for a 64-bit EFI application Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> Add a linker script and relocation code for building 64-bit EFI
> applications. This can be used for the EFI stub.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Improvements to how the payload is built:
> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3:
> - Use "BSD-2-Clause" for the SPDX license
>
> Changes in v2:
> - Add a comment as to why .hash has to be first in the linker script
> - Change 'link script' to 'linker script'
> - Drop . = 0x0;
> - Fix reference to elf_ia32_efi instead of elf_x86_64_efi
> - Merge in Bin's implementation of adding a U-Boot payload with objcopy
> - Remove KEEP in the EFI linker script since garbage collection is not enabled
> - Rename ImageBase to image_base
> - Update based on the elf.h changes
>
>  arch/x86/cpu/efi/elf_x86_64_efi.lds | 83 +++++++++++++++++++++++++++++++++++++
>  arch/x86/lib/efi/reloc_x86_64.c     | 66 +++++++++++++++++++++++++++++
>  2 files changed, 149 insertions(+)
>  create mode 100644 arch/x86/cpu/efi/elf_x86_64_efi.lds
>  create mode 100644 arch/x86/lib/efi/reloc_x86_64.c

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 14/28] efi: Add support for loading U-Boot through an EFI stub
  2015-08-05  7:59   ` Bin Meng
@ 2015-08-05 18:03     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 01:59, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> It is useful to be able to load U-Boot onto a board even if is it already
>> running EFI. This can allow access to the U-Boot command interface, flexible
>> booting options and easier development.
>>
>> The easiest way to do this is to build U-Boot as a binary blob and have an
>> EFI stub copy it into RAM. Add support for this feature, targeting 32-bit
>> initially.
>>
>> Also add a way to detect when U-Boot has been loaded via a stub. This goes
>> in common.h since it needs to be widely available so that we avoid redoing
>> initialisation that should be skipped.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Improvements to how the payload is built:
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>> ---
>>
>> Changes in v3:
>> - Fix calling convention to starting U-Boot in the 32-bit stub
>> - Rename LDFLAGS_EFI to LDFLAGS_EFI_PAYLOAD and move into this patch
>> - Use quiet_cmd_xxx to link the payload
>>
>> Changes in v2:
>> - Add a comment as to why we must call exit_boot_services() twice
>> - Drop \n\t at the end of a one-line asm statement
>> - Merge in Bin's implementation of adding a U-Boot payload with objcopy
>> - Remove comment about reset_cpu() returning to EFI in the stub
>> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>>
>>  Makefile           |  24 +++++
>>  arch/x86/config.mk |   7 ++
>>  include/common.h   |   7 ++
>>  include/efi.h      |   4 +
>>  lib/efi/Kconfig    |  21 ++++
>>  lib/efi/Makefile   |   9 ++
>>  lib/efi/efi_stub.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  7 files changed, 376 insertions(+)
>>  create mode 100644 lib/efi/efi_stub.c
>>
[snip]

>> --
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
>
> Tested on QEMU 32-bit and 64-bit
> Tested-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 15/28] x86: Support building the EFI stub
  2015-08-05 12:20   ` Bin Meng
@ 2015-08-05 18:03     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 06:20, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> Add support for building a 32/64-bit EFI stub for x86. This involves
>> building the startup and relocation code for either i386 or x86_64.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v3:
>> - Move 64-bit comment to just above the 64-bit flag adjustments
>>
>> Changes in v2:
>> - Add a comment as to why the AFLAGS_REMOVE_.. lines are needed
>> - Move the crt and reloc files into arch/x86/lib/efi/
>>
>>  arch/x86/lib/Makefile     |  2 +-
>>  arch/x86/lib/efi/Makefile | 24 ++++++++++++++++++++++++
>>  2 files changed, 25 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/x86/lib/efi/Makefile
>>
[snip]
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 16/28] x86: Add an enum for some commonly-used GDT bits
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 16/28] x86: Add an enum for some commonly-used GDT bits Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> Rather than add these as open-coded values, create an enum with the commonly
> used flags.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Add descriptor bits for the base and limit
> - Rename GDT_4GB to GDT_4KB
>
>  arch/x86/include/asm/cpu.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 17/28] x86: Add a way to call 32-bit code from 64-bit mode
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 17/28] x86: Add a way to call 32-bit code from 64-bit mode Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> The procedure to drop from 64-bit mode to 32-bit is a bit messy. Add a
> function to take care of it. It requires identity-mapped pages and that
> the calling code is running below 4GB.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Add a comment about the REX prefix
> - Drop the REX prefix in 32-bit mode
>
>  arch/x86/cpu/Makefile      |  6 +++++
>  arch/x86/cpu/call32.S      | 64 ++++++++++++++++++++++++++++++++++++++++++++++
>  arch/x86/include/asm/cpu.h |  9 +++++++
>  3 files changed, 79 insertions(+)
>  create mode 100644 arch/x86/cpu/call32.S

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 18/28] efi: Add 64-bit payload support
  2015-08-05  8:02   ` Bin Meng
@ 2015-08-05 18:03     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 02:02, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:33 AM, Simon Glass <sjg@chromium.org> wrote:
>> Most EFI implementations use 64-bit. Add a way to build U-Boot as a 64-bit
>> EFI payload. The payload unpacks a (32-bit) U-Boot and starts it. This can
>> be enabled for x86 boards at present.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Improvements to how the payload is built:
>> Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
>> ---
>>
>> Changes in v3:
>> - Add spaces around EFIARCH=
>> - Use CONFIG_SYS_MONITOR_LEN as a more accurate value for U-Boot's size
>>
>> Changes in v2:
>> - Add -no-red-zone for 64-bit only
>> - Check the GDT selector's base and limit against the target address
>> - Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application yet
>> - Merge in Bin's implementation of adding a U-Boot payload with objcopy
>> - Move the 64-bit crt and reloc code into this patch
>> - Move the 64-bit efi.h additions into this patch
>> - Rename GDT_4GB to GDT_4KB
>>
>>  Makefile                           |  2 +-
>>  arch/x86/config.mk                 | 10 ++++++
>>  arch/x86/include/asm/types.h       |  5 ++-
>>  arch/x86/lib/efi/crt0-efi-x86_64.S | 51 ++++++++++++++++++++++++++
>>  include/efi.h                      |  7 ++++
>>  lib/efi/efi_stub.c                 | 74 +++++++++++++++++++++++++++++++++++---
>>  6 files changed, 143 insertions(+), 6 deletions(-)
>>  create mode 100644 arch/x86/lib/efi/crt0-efi-x86_64.S
>>
[snip]
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
>
> Tested on QEMU 32-bit and 64-bit
> Tested-by: Bin Meng <bmeng.cn@gmail.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 19/28] x86: Add support for passing tables into U-Boot
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 19/28] x86: Add support for passing tables into U-Boot Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> The EFI stub provides information to U-Boot in a table. This includes the
> memory map which is needed to decide where to relocate U-Boot. Collect this
> information in the early init code and store it in global_data.
>
> Fix up the BIST code at the same time since we don't have it when booting
> from EFI and can assume it is 0.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Zero BIST when starting from EFI/coreboot
>
>  arch/x86/cpu/start.S               | 19 ++++++++++++++++++-
>  arch/x86/include/asm/global_data.h |  1 +
>  arch/x86/lib/asm-offsets.c         |  1 +
>  3 files changed, 20 insertions(+), 1 deletion(-)

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 20/28] efi: Add functions for decoding the EFI tables
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 20/28] efi: Add functions for decoding the EFI tables Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> The EFI stub can pass a table to U-Boot with information about the memory map
> Potentially other things will follow. Add a way to access this table.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  lib/efi/Makefile   |  1 +
>  lib/efi/efi_info.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 48 insertions(+)
>  create mode 100644 lib/efi/efi_info.c

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 21/28] efi: Add a command to display the memory map
  2015-08-04 18:33 ` [U-Boot] [PATCH v3 21/28] efi: Add a command to display the memory map Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:33, Simon Glass <sjg@chromium.org> wrote:
> The EFI memory map is passed from the stub to U-Boot in a table. Add a
> command to display it in a vaguely readable fashion.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> Tested on QEMU
> Tested-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Drop a left-over debug printf()
> - Fix alignment of region index field in the output
> - Fix efi_mem_desc_VERSION typo
> - Output the region index in decimal
>
>  common/Makefile  |   1 +
>  common/cmd_efi.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 258 insertions(+)
>  create mode 100644 common/cmd_efi.c

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 22/28] x86: Handle running as EFI payload
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 22/28] x86: Handle running as EFI payload Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
> When U-Boot runs as an EFI payload it needs to avoid setting up the CPU
> again. Also U-Boot currently does not handle interrupts for many devices, so
> run with interrupts disabled.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Add a note that bootm does not work when running as an EFI app
> - Move EFI CAR settings to arch/x86/lib/efi/Kconfig
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>
>  arch/x86/Kconfig          |  6 ++++++
>  arch/x86/cpu/cpu.c        | 21 +++++++++++++--------
>  arch/x86/cpu/interrupts.c | 10 ++++++++--
>  arch/x86/lib/bootm.c      |  5 +++++
>  arch/x86/lib/efi/Kconfig  | 11 +++++++++++
>  5 files changed, 43 insertions(+), 10 deletions(-)
>  create mode 100644 arch/x86/lib/efi/Kconfig

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 23/28] x86: Add helper code for running from EFI
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 23/28] x86: Add helper code for running from EFI Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
> When U-Boot is running from EFI some of the x86 init is replaced with
> EFI-specific init. For example, since DRAM has already been set up, we only
> need to find it, not init it. Add these functions so that boards can easily
> allow booting from EFI if required.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Drop unnecessary .section .text
>
>  arch/x86/lib/Makefile     |   1 +
>  arch/x86/lib/efi/Makefile |   3 +
>  arch/x86/lib/efi/car.S    |  10 +++
>  arch/x86/lib/efi/efi.c    | 151 ++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 165 insertions(+)
>  create mode 100644 arch/x86/lib/efi/car.S
>  create mode 100644 arch/x86/lib/efi/efi.c

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 24/28] x86: baytrail: Support operation as an EFI payload
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 24/28] x86: baytrail: Support operation as an EFI payload Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
> Disable a few things which interfere with the EFI init. This allows the
> Minnowboard MAX to boot into EFI, load a U-Boot payload then boot to the
> U-Boot prompt.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Fix indenting in board/intel/minnowmax/Kconfig
> - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP
>
>  arch/x86/cpu/baytrail/Kconfig      | 2 +-
>  arch/x86/cpu/baytrail/cpu.c        | 2 ++
>  arch/x86/cpu/baytrail/valleyview.c | 2 ++
>  board/intel/minnowmax/Kconfig      | 5 +++--
>  4 files changed, 8 insertions(+), 3 deletions(-)

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 25/28] x86: qemu: Support operation as an EFI payload
  2015-08-05  8:19   ` Bin Meng
@ 2015-08-05 18:03     ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 02:19, Bin Meng <bmeng.cn@gmail.com> wrote:
> On Wed, Aug 5, 2015 at 2:34 AM, Simon Glass <sjg@chromium.org> wrote:
>> Disable a few things which interfere with the EFI init. This allows QEMU to
>> to boot into EFI, load a U-Boot payload then boot to the U-Boot prompt.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
>> ---
>>
>> Changes in v3: None
>> Changes in v2:
>> - Fix indenting in board/emulation/qemu-x86/Kconfig
>>
>>  arch/x86/cpu/qemu/Makefile       | 5 ++++-
>>  arch/x86/cpu/qemu/qemu.c         | 2 ++
>>  board/emulation/qemu-x86/Kconfig | 5 +++--
>>  3 files changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile
>> index be79723..9a66b16 100644
>> --- a/arch/x86/cpu/qemu/Makefile
>> +++ b/arch/x86/cpu/qemu/Makefile
>> @@ -4,5 +4,8 @@
>>  # SPDX-License-Identifier:     GPL-2.0+
>>  #
>>
>> -obj-y += car.o dram.o qemu.o
>> +ifndef CONFIG_EFI_STUB
>> +obj-y += car.o dram.o
>> +endif
>> +obj-y += qemu.o
>>  obj-$(CONFIG_PCI) += pci.o
>> diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c
>> index 930d2b6..64634a9 100644
>> --- a/arch/x86/cpu/qemu/qemu.c
>> +++ b/arch/x86/cpu/qemu/qemu.c
>> @@ -25,11 +25,13 @@ int arch_cpu_init(void)
>>         return 0;
>>  }
>>
>> +#ifndef CONFIG_EFI_STUB
>>  int print_cpuinfo(void)
>>  {
>>         post_code(POST_CPU_INFO);
>>         return default_print_cpuinfo();
>>  }
>> +#endif
>>
>>  void reset_cpu(ulong addr)
>>  {
>> diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
>> index e777ef4..c9181fc 100644
>> --- a/board/emulation/qemu-x86/Kconfig
>> +++ b/board/emulation/qemu-x86/Kconfig
>> @@ -13,11 +13,12 @@ config SYS_CONFIG_NAME
>>         default "qemu-x86"
>>
>>  config SYS_TEXT_BASE
>> -       default 0xfff00000
>> +       default 0xfff00000 if !EFI_STUB
>> +       default 0x01110000 if EFI_STUB
>>
>>  config BOARD_SPECIFIC_OPTIONS # dummy
>>         def_bool y
>> -       select X86_RESET_VECTOR
>> +       select X86_RESET_VECTOR if !EFI_STUB
>>         select QEMU
>>         select BOARD_ROMSIZE_KB_1024
>>
>> --
>
> Tested on QEMU 32-bit and 64-bit
> Tested-by: Bin Meng <bmeng.cn@gmail.com>

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 26/28] x86: Gracefully disable the vesa driver when running from EFI
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 26/28] x86: Gracefully disable the vesa driver when running from EFI Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
> We cannot use this driver when running from EFI as we have no direct hardware
> access. In fact coreboot uses a different driver which uses tables provided
> by coreboot. So far it does not seem possible to use a normal video driver
> when booting from EFI.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Acked-by: Anatolij Gustschin <agust@denx.de>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Replace 'Coreboot' with 'coreboot'
>
>  drivers/video/vesa_fb.c | 8 ++++++++
>  1 file changed, 8 insertions(+)

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 27/28] efi: Add a README to explain how things work
  2015-08-04 18:34 ` [U-Boot] [PATCH v3 27/28] efi: Add a README to explain how things work Simon Glass
@ 2015-08-05 18:03   ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
> Add some documentation on the EFI implementation in U-Boot.
>
> Signed-off-by: Ben Stoltz <stoltz@google.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Drop patch "Add a link script entry for U-Boot as a payload"
> - Replace 'Coreboot' with 'coreboot'
> - Use CONFIG_EFI_APP instead of CONFIG_ARCH_EFI
> - Use u-boot-app.efi instead of u-boot.efi
>
>  doc/README.efi | 237 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 237 insertions(+)
>  create mode 100644 doc/README.efi

Applied to u-boot-x86.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled
  2015-08-05  8:07     ` Bin Meng
@ 2015-08-05 18:03       ` Simon Glass
  0 siblings, 0 replies; 69+ messages in thread
From: Simon Glass @ 2015-08-05 18:03 UTC (permalink / raw)
  To: u-boot

On 5 August 2015 at 02:07, Bin Meng <bmeng.cn@gmail.com> wrote:
> Hi Simon,
>
> On Wed, Aug 5, 2015 at 11:38 AM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Bin,
>>
>> On 4 August 2015 at 12:34, Simon Glass <sjg@chromium.org> wrote:
>>> This was missed in the patch 'Add a way to skip relocation'. Add it in now.
>>>
>>> I hope to squash this patch into the earlier one before sending to mainline.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
>
>>> ---
>>>
>>> Changes in v3:
>>> - Add new patch to allow device tree relocation to be disabled
>>>
>>> Changes in v2: None
>>>
>>>  common/board_f.c | 2 ++
>>>  1 file changed, 2 insertions(+)
>>>
>>> diff --git a/common/board_f.c b/common/board_f.c
>>> index c596083..c7cc67c 100644
>>> --- a/common/board_f.c
>>> +++ b/common/board_f.c
>>> @@ -654,6 +654,8 @@ static int setup_dram_config(void)
>>>
>>>  static int reloc_fdt(void)
>>>  {
>>> +       if (gd->flags & GD_FLG_SKIP_RELOC)
>>> +               return 0;
>>>         if (gd->new_fdt) {
>>>                 memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
>>>                 gd->fdt_blob = gd->new_fdt;
>>> --
>>> 2.5.0.rc2.392.g76e840b
>>>
>>
>> I should have just squashed this in before sending the series. Anyway,
>> I can do it either in the next version, or when applying.
>>
>
> Yep, I think this needs to be squashed in v3 [01/28] patch:
> http://patchwork.ozlabs.org/patch/503752/

I squashed this in and applied it.

^ permalink raw reply	[flat|nested] 69+ messages in thread

end of thread, other threads:[~2015-08-05 18:03 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-04 18:33 [U-Boot] [PATCH v3 00/28] Add support for running U-Boot as an EFI payload/application Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 01/28] Add a way to skip relocation Simon Glass
2015-08-05  7:41   ` Bin Meng
2015-08-05 18:02     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 02/28] efi: Add a serial driver Simon Glass
2015-08-05 18:02   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 03/28] efi: Drop CONFIG_SYS_TEXT_BASE for EFI Simon Glass
2015-08-05 18:02   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 04/28] x86: Set up toolchain flags for running as EFI application Simon Glass
2015-08-05  7:41   ` Bin Meng
2015-08-05 18:02     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 05/28] efi: Support building a u-boot-app.efi executable Simon Glass
2015-08-05  7:42   ` Bin Meng
2015-08-05 18:02     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 06/28] x86: Support skipping relocation for EFI Simon Glass
2015-08-05  7:42   ` Bin Meng
2015-08-05 18:02     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 07/28] x86: Add asm/elf.h for x86-specific ELF definitions Simon Glass
2015-08-05 18:02   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 08/28] x86: Add support for U-Boot as an EFI application Simon Glass
2015-08-05  7:42   ` Bin Meng
2015-08-05 18:02     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 09/28] x86: Add EFI board code Simon Glass
2015-08-05  7:41   ` Bin Meng
2015-08-05 18:02     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 10/28] x86: dts: Add a device tree file for EFI Simon Glass
2015-08-05  7:41   ` Bin Meng
2015-08-05 18:02     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 11/28] x86: Allow relocation code to build without text base Simon Glass
2015-08-05 18:02   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 12/28] x86: Add definitions for the x86-efi board and plumb it in Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 13/28] x86: Add relocation and link script for a 64-bit EFI application Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 14/28] efi: Add support for loading U-Boot through an EFI stub Simon Glass
2015-08-05  7:59   ` Bin Meng
2015-08-05 18:03     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 15/28] x86: Support building the " Simon Glass
2015-08-05 12:20   ` Bin Meng
2015-08-05 18:03     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 16/28] x86: Add an enum for some commonly-used GDT bits Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 17/28] x86: Add a way to call 32-bit code from 64-bit mode Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 18/28] efi: Add 64-bit payload support Simon Glass
2015-08-05  8:02   ` Bin Meng
2015-08-05 18:03     ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 19/28] x86: Add support for passing tables into U-Boot Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 20/28] efi: Add functions for decoding the EFI tables Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:33 ` [U-Boot] [PATCH v3 21/28] efi: Add a command to display the memory map Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:34 ` [U-Boot] [PATCH v3 22/28] x86: Handle running as EFI payload Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:34 ` [U-Boot] [PATCH v3 23/28] x86: Add helper code for running from EFI Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:34 ` [U-Boot] [PATCH v3 24/28] x86: baytrail: Support operation as an EFI payload Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:34 ` [U-Boot] [PATCH v3 25/28] x86: qemu: " Simon Glass
2015-08-05  8:19   ` Bin Meng
2015-08-05 18:03     ` Simon Glass
2015-08-04 18:34 ` [U-Boot] [PATCH v3 26/28] x86: Gracefully disable the vesa driver when running from EFI Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:34 ` [U-Boot] [PATCH v3 27/28] efi: Add a README to explain how things work Simon Glass
2015-08-05 18:03   ` Simon Glass
2015-08-04 18:34 ` [U-Boot] [PATCH v3 28/28] Allow device tree relocation to be disabled Simon Glass
2015-08-05  3:38   ` Simon Glass
2015-08-05  8:07     ` Bin Meng
2015-08-05 18:03       ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.