Merge git://git.denx.de/u-boot-x86
diff --git a/arch/x86/cpu/coreboot/Kconfig b/arch/x86/cpu/coreboot/Kconfig
index fa3b64f..392c258 100644
--- a/arch/x86/cpu/coreboot/Kconfig
+++ b/arch/x86/cpu/coreboot/Kconfig
@@ -10,6 +10,7 @@
 	imply MMC_PCI
 	imply MMC_SDHCI
 	imply MMC_SDHCI_SDMA
+	imply SCSI
 	imply SCSI_AHCI
 	imply SPI_FLASH
 	imply SYS_NS16550
diff --git a/arch/x86/cpu/intel_common/car.S b/arch/x86/cpu/intel_common/car.S
index fe8dfbc..52a77bb 100644
--- a/arch/x86/cpu/intel_common/car.S
+++ b/arch/x86/cpu/intel_common/car.S
@@ -239,4 +239,6 @@
 .globl ucode_base
 ucode_base:	/* Declared in microcode.h */
 	.long	0			/* microcode base */
+.globl ucode_size
+ucode_size:	/* Declared in microcode.h */
 	.long	0			/* microcode size */
diff --git a/arch/x86/cpu/intel_common/microcode.c b/arch/x86/cpu/intel_common/microcode.c
index 11b1ec8..c7a539d 100644
--- a/arch/x86/cpu/intel_common/microcode.c
+++ b/arch/x86/cpu/intel_common/microcode.c
@@ -43,8 +43,6 @@
 	update->data = fdt_getprop(blob, node, "data", &update->size);
 	if (!update->data)
 		return -ENOENT;
-	update->data += UCODE_HEADER_LEN;
-	update->size -= UCODE_HEADER_LEN;
 
 	update->header_version = fdtdec_get_int(blob, node,
 						"intel,header-version", 0);
@@ -124,6 +122,7 @@
 int microcode_update_intel(void)
 {
 	struct microcode_update cpu, update;
+	ulong address;
 	const void *blob = gd->fdt_blob;
 	int skipped;
 	int count;
@@ -167,7 +166,8 @@
 			skipped++;
 			continue;
 		}
-		wrmsr(MSR_IA32_UCODE_WRITE, (ulong)update.data, 0);
+		address = (ulong)update.data + UCODE_HEADER_LEN;
+		wrmsr(MSR_IA32_UCODE_WRITE, address, 0);
 		rev = microcode_read_rev();
 		debug("microcode: updated to revision 0x%x date=%04x-%02x-%02x\n",
 		      rev, update.date_code & 0xffff,
@@ -178,5 +178,9 @@
 			return -EFAULT;
 		}
 		count++;
+		if (!ucode_base) {
+			ucode_base = (ulong)update.data;
+			ucode_size = update.size;
+		}
 	} while (1);
 }
diff --git a/arch/x86/cpu/qemu/Kconfig b/arch/x86/cpu/qemu/Kconfig
index 31428dd..fdf558d 100644
--- a/arch/x86/cpu/qemu/Kconfig
+++ b/arch/x86/cpu/qemu/Kconfig
@@ -7,6 +7,7 @@
 	select ARCH_EARLY_INIT_R
 	imply AHCI_PCI
 	imply E1000
+	imply SCSI
 	imply SCSI_AHCI
 	imply SYS_NS16550
 	imply USB
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index f7b32a5..4ab7504 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -10,6 +10,7 @@
 
 /* This is a declaration for ucode_base in start.S */
 extern u32 ucode_base;
+extern u32 ucode_size;
 
 /**
  * microcode_update_intel() - Apply microcode updates
diff --git a/arch/x86/lib/e820.c b/arch/x86/lib/e820.c
index 9a9ec99..8b34f67 100644
--- a/arch/x86/lib/e820.c
+++ b/arch/x86/lib/e820.c
@@ -4,6 +4,7 @@
  */
 
 #include <common.h>
+#include <efi_loader.h>
 #include <asm/e820.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -34,3 +35,41 @@
 
 	return 4;
 }
+
+#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
+void efi_add_known_memory(void)
+{
+	struct e820_entry e820[E820MAX];
+	unsigned int i, num;
+	u64 start, pages;
+	int type;
+
+	num = install_e820_map(ARRAY_SIZE(e820), e820);
+
+	for (i = 0; i < num; ++i) {
+		start = e820[i].addr;
+		pages = ALIGN(e820[i].size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
+
+		switch (e820[i].type) {
+		case E820_RAM:
+			type = EFI_CONVENTIONAL_MEMORY;
+			break;
+		case E820_RESERVED:
+			type = EFI_RESERVED_MEMORY_TYPE;
+			break;
+		case E820_ACPI:
+			type = EFI_ACPI_RECLAIM_MEMORY;
+			break;
+		case E820_NVS:
+			type = EFI_ACPI_MEMORY_NVS;
+			break;
+		case E820_UNUSABLE:
+		default:
+			type = EFI_UNUSABLE_MEMORY;
+			break;
+		}
+
+		efi_add_memory_map(start, pages, type, false);
+	}
+}
+#endif /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */
diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp/fsp_car.S
index 549d863..48edc83 100644
--- a/arch/x86/lib/fsp/fsp_car.S
+++ b/arch/x86/lib/fsp/fsp_car.S
@@ -102,8 +102,10 @@
 _dt_ucode_base_size:
 	/* These next two fields are filled in by ifdtool */
 .globl ucode_base
-ucode_base:	/* Declared in micrcode.h */
+ucode_base:	/* Declared in microcode.h */
 	.long	0			/* microcode base */
+.globl ucode_size
+ucode_size:	/* Declared in microcode.h */
 	.long	0			/* microcode size */
 	.long	CONFIG_SYS_MONITOR_BASE	/* code region base */
 	.long	CONFIG_SYS_MONITOR_LEN	/* code region size */
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index f55a40d..cd755b6 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -61,6 +61,11 @@
 	if (ret != EFI_SUCCESS)
 		goto out;
 #endif
+#ifdef CONFIG_GENERATE_ACPI_TABLE
+	ret = efi_acpi_register();
+	if (ret != EFI_SUCCESS)
+		goto out;
+#endif
 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
 	ret = efi_smbios_register();
 	if (ret != EFI_SUCCESS)
diff --git a/doc/README.vxworks b/doc/README.vxworks
index 1aa8e44..3e08711 100644
--- a/doc/README.vxworks
+++ b/doc/README.vxworks
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0+
 #
 # Copyright (C) 2013, Miao Yan <miao.yan@windriver.com>
-# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
+# Copyright (C) 2015-2018, Bin Meng <bmeng.cn@gmail.com>
 
 VxWorks Support
 ===============
@@ -15,10 +15,13 @@
 on other architectures, 'bootvx' shall be used. For booting VxWorks 7 kernels
 on PowerPC and ARM, 'bootm' shall be used.
 
+With CONFIG_EFI_LOADER option, it's possible to chain load a VxWorks x86 kernel
+via the UEFI boot loader application for VxWorks loaded by 'bootefi' command.
+
 VxWorks 7 on PowerPC and ARM
 ---------------------------
-From VxWorks 7, VxWorks starts adopting device tree as its hardware decription
-mechansim (for PowerPC and ARM), thus requiring boot interface changes.
+From VxWorks 7, VxWorks starts adopting device tree as its hardware description
+mechanism (for PowerPC and ARM), thus requiring boot interface changes.
 This section will describe the new interface.
 
 For PowerPC, the calling convention of the new VxWorks entry point conforms to
@@ -53,6 +56,9 @@
 When using 'bootm', just define "bootargs" in the environment and U-Boot will
 handle bootline fix up for the kernel dtb automatically.
 
+When using 'bootefi' to chain load an x86 kernel, the UEFI boot loader
+application for VxWorks takes care of the kernel bootline preparation.
+
 Serial console
 --------------
 It's very common that VxWorks BSPs configure a different baud rate for the
@@ -63,9 +69,9 @@
 
 x86-specific information
 ------------------------
-Before loading an x86 kernel, one additional environment variable need to be
-provided. This is "vx_phys_mem_base", which represent the physical memory
-base address of VxWorks.
+Before direct loading an x86 kernel via 'bootvx', one additional environment
+variable need to be provided. This is "vx_phys_mem_base", which represent the
+physical memory base address of VxWorks.
 
 Check VxWorks kernel configuration to look for LOCAL_MEM_LOCAL_ADRS. For
 VxWorks 7, this is normally a virtual address and you need find out its
diff --git a/doc/README.x86 b/doc/README.x86
index 9f657df..9162ea1 100644
--- a/doc/README.x86
+++ b/doc/README.x86
@@ -1136,9 +1136,34 @@
 U-Boot supports booting as a 32-bit or 64-bit EFI payload, e.g. with UEFI.
 This is enabled with CONFIG_EFI_STUB to boot from both 32-bit and 64-bit
 UEFI BIOS. U-Boot can also run as an EFI application, with CONFIG_EFI_APP.
-The CONFIG_EFI_LOADER option, where U-Booot provides an EFI environment to
+The CONFIG_EFI_LOADER option, where U-Boot provides an EFI environment to
 the kernel (i.e. replaces UEFI completely but provides the same EFI run-time
-services) is not currently supported on x86.
+services) is supported too. For example, we can even use 'bootefi' command
+to load a 'u-boot-payload.efi', see below test logs on QEMU.
+
+  => load ide 0 3000000 u-boot-payload.efi
+  489787 bytes read in 138 ms (3.4 MiB/s)
+  => bootefi 3000000
+  Scanning disk ide.blk#0...
+  Found 2 disks
+  WARNING: booting without device tree
+  ## Starting EFI application at 03000000 ...
+  U-Boot EFI Payload
+
+
+  U-Boot 2018.07-rc2 (Jun 23 2018 - 17:12:58 +0800)
+
+  CPU: x86_64, vendor AMD, device 663h
+  DRAM:  2 GiB
+  MMC:
+  Video: 1024x768x32
+  Model: EFI x86 Payload
+  Net:   e1000: 52:54:00:12:34:56
+
+  Warning: e1000#0 using MAC address from ROM
+  eth0: e1000#0
+  No controllers found
+  Hit any key to stop autoboot:  0
 
 See README.u-boot_on_efi and README.uefi for details of EFI support in U-Boot.
 
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c
index cf86999..747f190 100644
--- a/drivers/timer/tsc_timer.c
+++ b/drivers/timer/tsc_timer.c
@@ -377,14 +377,23 @@
 {
 	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 
-	tsc_timer_ensure_setup();
-	uc_priv->clock_rate = gd->arch.clock_rate;
+	if (!uc_priv->clock_rate) {
+		tsc_timer_ensure_setup();
+		uc_priv->clock_rate = gd->arch.clock_rate;
+	} else {
+		gd->arch.tsc_base = rdtsc();
+	}
 
 	return 0;
 }
 
 unsigned long notrace timer_early_get_rate(void)
 {
+	/*
+	 * When TSC timer is used as the early timer, be warned that the timer
+	 * clock rate can only be calibrated via some hardware ways. Specifying
+	 * it in the device tree won't work for the early timer.
+	 */
 	tsc_timer_ensure_setup();
 
 	return gd->arch.clock_rate;
diff --git a/include/efi_api.h b/include/efi_api.h
index 094be6e..0c3dd3c 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -282,6 +282,10 @@
 	EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, \
 		 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
 
+#define EFI_ACPI_TABLE_GUID \
+	EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, \
+		 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
+
 #define SMBIOS_TABLE_GUID \
 	EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3,  \
 		 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
diff --git a/include/efi_loader.h b/include/efi_loader.h
index c66252a..d837e7b 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -215,6 +215,14 @@
 efi_status_t efi_watchdog_register(void);
 /* Called by bootefi to make SMBIOS tables available */
 /**
+ * efi_acpi_register() - write out ACPI tables
+ *
+ * Called by bootefi to make ACPI tables available
+ *
+ * @return 0 if OK, -ENOMEM if no memory is available for the tables
+ */
+efi_status_t efi_acpi_register(void);
+/**
  * efi_smbios_register() - write out SMBIOS tables
  *
  * Called by bootefi to make SMBIOS tables available
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index c6046e3..d6402c4 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -22,4 +22,5 @@
 obj-$(CONFIG_DM_VIDEO) += efi_gop.o
 obj-$(CONFIG_PARTITIONS) += efi_disk.o
 obj-$(CONFIG_NET) += efi_net.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += efi_acpi.o
 obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += efi_smbios.o
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c
new file mode 100644
index 0000000..a4e5e53
--- /dev/null
+++ b/lib/efi_loader/efi_acpi.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  EFI application ACPI tables support
+ *
+ *  Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <efi_loader.h>
+#include <asm/acpi_table.h>
+
+static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
+
+/*
+ * Install the ACPI table as a configuration table.
+ *
+ * @return	status code
+ */
+efi_status_t efi_acpi_register(void)
+{
+	/* Map within the low 32 bits, to allow for 32bit ACPI tables */
+	u64 acpi = U32_MAX;
+	efi_status_t ret;
+
+	/* Reserve 64kiB page for ACPI */
+	ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+				 EFI_RUNTIME_SERVICES_DATA, 16, &acpi);
+	if (ret != EFI_SUCCESS)
+		return ret;
+
+	/*
+	 * Generate ACPI tables - we know that efi_allocate_pages() returns
+	 * a 4k-aligned address, so it is safe to assume that
+	 * write_acpi_tables() will write the table at that address.
+	 */
+	assert(!(acpi & 0xf));
+	write_acpi_tables(acpi);
+
+	/* And expose them to our EFI payload */
+	return efi_install_configuration_table(&acpi_guid,
+					       (void *)(uintptr_t)acpi);
+}
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 50d3115..261d66d 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -43,7 +43,7 @@
  * In most cases we want to pass an FDT to the payload, so reserve one slot of
  * config table space for it. The pointer gets populated by do_bootefi_exec().
  */
-static struct efi_configuration_table __efi_runtime_data efi_conf_table[2];
+static struct efi_configuration_table __efi_runtime_data efi_conf_table[16];
 
 #ifdef CONFIG_ARM
 /*
diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c
index 046b46a..3b8de5b 100644
--- a/lib/efi_loader/helloworld.c
+++ b/lib/efi_loader/helloworld.c
@@ -14,6 +14,7 @@
 
 static const efi_guid_t loaded_image_guid = LOADED_IMAGE_GUID;
 static const efi_guid_t fdt_guid = EFI_FDT_GUID;
+static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
 static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
 
 static int hw_memcmp(const void *buf1, const void *buf2, size_t length)
@@ -79,6 +80,9 @@
 		if (!hw_memcmp(&systable->tables[i].guid, &fdt_guid,
 			       sizeof(efi_guid_t)))
 			con_out->output_string(con_out, L"Have device tree\n");
+		if (!hw_memcmp(&systable->tables[i].guid, &acpi_guid,
+			       sizeof(efi_guid_t)))
+			con_out->output_string(con_out, L"Have ACPI 2.0 table\n");
 		if (!hw_memcmp(&systable->tables[i].guid, &smbios_guid,
 			       sizeof(efi_guid_t)))
 			con_out->output_string(con_out, L"Have SMBIOS table\n");