浏览代码

Merge git://git.denx.de/u-boot-x86

Tom Rini 6 年之前
父节点
当前提交
ac378bb05f

+ 1 - 0
arch/x86/cpu/coreboot/Kconfig

@@ -10,6 +10,7 @@ config SYS_COREBOOT
 	imply MMC_PCI
 	imply MMC_SDHCI
 	imply MMC_SDHCI_SDMA
+	imply SCSI
 	imply SCSI_AHCI
 	imply SPI_FLASH
 	imply SYS_NS16550

+ 2 - 0
arch/x86/cpu/intel_common/car.S

@@ -239,4 +239,6 @@ _dt_ucode_base_size:
 .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 */

+ 7 - 3
arch/x86/cpu/intel_common/microcode.c

@@ -43,8 +43,6 @@ static int microcode_decode_node(const void *blob, int node,
 	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 @@ static void microcode_read_cpu(struct microcode_update *cpu)
 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 @@ int microcode_update_intel(void)
 			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 @@ int microcode_update_intel(void)
 			return -EFAULT;
 		}
 		count++;
+		if (!ucode_base) {
+			ucode_base = (ulong)update.data;
+			ucode_size = update.size;
+		}
 	} while (1);
 }

+ 1 - 0
arch/x86/cpu/qemu/Kconfig

@@ -7,6 +7,7 @@ config QEMU
 	select ARCH_EARLY_INIT_R
 	imply AHCI_PCI
 	imply E1000
+	imply SCSI
 	imply SCSI_AHCI
 	imply SYS_NS16550
 	imply USB

+ 1 - 0
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

+ 39 - 0
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 @@ __weak unsigned int install_e820_map(unsigned int max_entries,
 
 	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) */

+ 3 - 1
arch/x86/lib/fsp/fsp_car.S

@@ -102,8 +102,10 @@ temp_ram_init_params:
 _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 */

+ 5 - 0
cmd/bootefi.c

@@ -61,6 +61,11 @@ efi_status_t efi_init_obj_list(void)
 	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)

+ 12 - 6
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 @@ For booting old kernels (6.9.x) on PowerPC and ARM, and all kernel versions
 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 @@ gatewayip, hostname, othbootargs.
 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 @@ look like VxWorks hangs somewhere as nothing outputs on the serial console.
 
 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

+ 27 - 2
doc/README.x86

@@ -1136,9 +1136,34 @@ EFI Support
 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.
 

+ 11 - 2
drivers/timer/tsc_timer.c

@@ -377,14 +377,23 @@ static int tsc_timer_probe(struct udevice *dev)
 {
 	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;

+ 4 - 0
include/efi_api.h

@@ -282,6 +282,10 @@ struct efi_runtime_services {
 	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)

+ 8 - 0
include/efi_loader.h

@@ -214,6 +214,14 @@ efi_status_t efi_net_register(void);
 /* Called by bootefi to make the watchdog available */
 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
  *

+ 1 - 0
lib/efi_loader/Makefile

@@ -22,4 +22,5 @@ obj-$(CONFIG_LCD) += efi_gop.o
 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

+ 42 - 0
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);
+}

+ 1 - 1
lib/efi_loader/efi_boottime.c

@@ -43,7 +43,7 @@ static bool efi_is_direct_boot = true;
  * 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
 /*

+ 4 - 0
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 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
 		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");