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");