[U-Boot] [PATCH v2 13/51] x86: Move common CPU code to its own place

Simon Glass sjg at chromium.org
Sat Mar 12 06:06:58 CET 2016


Some of the Intel CPU code is common to several Intel CPUs. Move it into a
common location along with required declarations.

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

Changes in v2:
- Use capitals for header guard

 arch/x86/cpu/intel_common/Makefile        |   1 +
 arch/x86/cpu/intel_common/cpu.c           | 111 ++++++++++++++++++++++++++++++
 arch/x86/cpu/ivybridge/cpu.c              |  82 ++--------------------
 arch/x86/include/asm/arch-ivybridge/pch.h |   2 -
 arch/x86/include/asm/cpu_common.h         |  35 ++++++++++
 arch/x86/include/asm/intel_regs.h         |   9 +++
 6 files changed, 162 insertions(+), 78 deletions(-)
 create mode 100644 arch/x86/cpu/intel_common/cpu.c
 create mode 100644 arch/x86/include/asm/cpu_common.h

diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile
index 74b005a..06de964 100644
--- a/arch/x86/cpu/intel_common/Makefile
+++ b/arch/x86/cpu/intel_common/Makefile
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_HAVE_MRC) += car.o
+obj-y += cpu.o
 obj-y += lpc.o
 ifndef CONFIG_TARGET_EFI
 obj-y += microcode.o
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
new file mode 100644
index 0000000..1210943
--- /dev/null
+++ b/arch/x86/cpu/intel_common/cpu.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/cpu_common.h>
+#include <asm/intel_regs.h>
+#include <asm/lapic.h>
+#include <asm/lpc_common.h>
+#include <asm/msr.h>
+#include <asm/mtrr.h>
+#include <asm/post.h>
+#include <asm/microcode.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int report_bist_failure(void)
+{
+	if (gd->arch.bist != 0) {
+		post_code(POST_BIST_FAILURE);
+		printf("BIST failed: %08x\n", gd->arch.bist);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int cpu_common_init(void)
+{
+	struct udevice *dev, *lpc;
+	int ret;
+
+	/* Halt if there was a built in self test failure */
+	ret = report_bist_failure();
+	if (ret)
+		return ret;
+
+	enable_lapic();
+
+	ret = microcode_update_intel();
+	if (ret && ret != -EEXIST)
+		return ret;
+
+	/* Enable upper 128bytes of CMOS */
+	writel(1 << 2, RCB_REG(RC));
+
+	/* Early chipset init required before RAM init can work */
+	uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
+
+	ret = uclass_first_device(UCLASS_LPC, &lpc);
+	if (ret)
+		return ret;
+	if (!lpc)
+		return -ENODEV;
+
+	/* Cause the SATA device to do its early init */
+	uclass_first_device(UCLASS_DISK, &dev);
+
+	return 0;
+}
+
+int cpu_set_flex_ratio_to_tdp_nominal(void)
+{
+	msr_t flex_ratio, msr;
+	u8 nominal_ratio;
+
+	/* Check for Flex Ratio support */
+	flex_ratio = msr_read(MSR_FLEX_RATIO);
+	if (!(flex_ratio.lo & FLEX_RATIO_EN))
+		return -EINVAL;
+
+	/* Check for >0 configurable TDPs */
+	msr = msr_read(MSR_PLATFORM_INFO);
+	if (((msr.hi >> 1) & 3) == 0)
+		return -EINVAL;
+
+	/* Use nominal TDP ratio for flex ratio */
+	msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
+	nominal_ratio = msr.lo & 0xff;
+
+	/* See if flex ratio is already set to nominal TDP ratio */
+	if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
+		return 0;
+
+	/* Set flex ratio to nominal TDP ratio */
+	flex_ratio.lo &= ~0xff00;
+	flex_ratio.lo |= nominal_ratio << 8;
+	flex_ratio.lo |= FLEX_RATIO_LOCK;
+	msr_write(MSR_FLEX_RATIO, flex_ratio);
+
+	/* Set flex ratio in soft reset data register bits 11:6 */
+	clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
+			(nominal_ratio & 0x3f) << 6);
+
+	debug("CPU: Soft reset to set up flex ratio\n");
+
+	/* Set soft reset control to use register value */
+	setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
+
+	/* Issue warm reset, will be "CPU only" due to soft reset data */
+	outb(0x0, PORT_RESET);
+	outb(SYS_RST | RST_CPU, PORT_RESET);
+	cpu_hlt();
+
+	/* Not reached */
+	return -EINVAL;
+}
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index f847a2f..b8234ae 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -17,6 +17,7 @@
 #include <fdtdec.h>
 #include <pch.h>
 #include <asm/cpu.h>
+#include <asm/cpu_common.h>
 #include <asm/intel_regs.h>
 #include <asm/io.h>
 #include <asm/lapic.h>
@@ -34,51 +35,11 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static int set_flex_ratio_to_tdp_nominal(void)
 {
-	msr_t flex_ratio, msr;
-	u8 nominal_ratio;
-
 	/* Minimum CPU revision for configurable TDP support */
 	if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
 		return -EINVAL;
 
-	/* Check for Flex Ratio support */
-	flex_ratio = msr_read(MSR_FLEX_RATIO);
-	if (!(flex_ratio.lo & FLEX_RATIO_EN))
-		return -EINVAL;
-
-	/* Check for >0 configurable TDPs */
-	msr = msr_read(MSR_PLATFORM_INFO);
-	if (((msr.hi >> 1) & 3) == 0)
-		return -EINVAL;
-
-	/* Use nominal TDP ratio for flex ratio */
-	msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
-	nominal_ratio = msr.lo & 0xff;
-
-	/* See if flex ratio is already set to nominal TDP ratio */
-	if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
-		return 0;
-
-	/* Set flex ratio to nominal TDP ratio */
-	flex_ratio.lo &= ~0xff00;
-	flex_ratio.lo |= nominal_ratio << 8;
-	flex_ratio.lo |= FLEX_RATIO_LOCK;
-	msr_write(MSR_FLEX_RATIO, flex_ratio);
-
-	/* Set flex ratio in soft reset data register bits 11:6 */
-	clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
-			(nominal_ratio & 0x3f) << 6);
-
-	/* Set soft reset control to use register value */
-	setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
-
-	/* Issue warm reset, will be "CPU only" due to soft reset data */
-	outb(0x0, PORT_RESET);
-	outb(SYS_RST | RST_CPU, PORT_RESET);
-	cpu_hlt();
-
-	/* Not reached */
-	return -EINVAL;
+	return cpu_set_flex_ratio_to_tdp_nominal();
 }
 
 int arch_cpu_init(void)
@@ -163,17 +124,6 @@ static void enable_usb_bar(struct udevice *bus)
 	pci_bus_write_config(bus, usb3, PCI_COMMAND, cmd, PCI_SIZE_32);
 }
 
-static int report_bist_failure(void)
-{
-	if (gd->arch.bist != 0) {
-		post_code(POST_BIST_FAILURE);
-		printf("BIST failed: %08x\n", gd->arch.bist);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
 int print_cpuinfo(void)
 {
 	enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE;
@@ -184,20 +134,6 @@ int print_cpuinfo(void)
 	uint16_t pm1_sts;
 	int ret;
 
-	/* Halt if there was a built in self test failure */
-	ret = report_bist_failure();
-	if (ret)
-		return ret;
-
-	enable_lapic();
-
-	ret = microcode_update_intel();
-	if (ret)
-		return ret;
-
-	/* Enable upper 128bytes of CMOS */
-	writel(1 << 2, RCB_REG(RC));
-
 	/* TODO: cmos_post_init() */
 	if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) {
 		debug("soft reset detected\n");
@@ -208,17 +144,9 @@ int print_cpuinfo(void)
 		reset_cpu(0);
 	}
 
-	/* Early chipset init required before RAM init can work */
-	uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
-
-	ret = uclass_first_device(UCLASS_LPC, &lpc);
+	ret = cpu_common_init();
 	if (ret)
 		return ret;
-	if (!dev)
-		return -ENODEV;
-
-	/* Cause the SATA device to do its early init */
-	uclass_first_device(UCLASS_DISK, &dev);
 
 	/* Check PM1_STS[15] to see if we are waking from Sx */
 	pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
@@ -244,8 +172,10 @@ int print_cpuinfo(void)
 		return -ENODEV;
 
 	/* Prepare USB controller early in S3 resume */
-	if (boot_mode == PEI_BOOT_RESUME)
+	if (boot_mode == PEI_BOOT_RESUME) {
+		uclass_first_device(UCLASS_LPC, &lpc);
 		enable_usb_bar(pci_get_controller(lpc->parent));
+	}
 
 	gd->arch.pei_boot_mode = boot_mode;
 
diff --git a/arch/x86/include/asm/arch-ivybridge/pch.h b/arch/x86/include/asm/arch-ivybridge/pch.h
index f96dc2b..e72ff2a 100644
--- a/arch/x86/include/asm/arch-ivybridge/pch.h
+++ b/arch/x86/include/asm/arch-ivybridge/pch.h
@@ -332,8 +332,6 @@
 #define SPI_FREQ_SWSEQ	0x3893
 #define SPI_DESC_COMP0	0x38b0
 #define SPI_FREQ_WR_ERA	0x38b4
-#define SOFT_RESET_CTRL 0x38f4
-#define SOFT_RESET_DATA 0x38f8
 
 #define DIR_ROUTE(a, b, c, d) \
 		(((d) << DIR_IDR) | ((c) << DIR_ICR) | \
diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
new file mode 100644
index 0000000..562de3e
--- /dev/null
+++ b/arch/x86/include/asm/cpu_common.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef __ASM_CPU_COMMON_H
+#define __ASM_CPU_COMMON_H
+
+#define IA32_PERF_CTL			0x199
+
+/**
+ * cpu_common_init() - Set up common CPU init
+ *
+ * This reports BIST failure, enables the LAPIC, updates microcode, enables
+ * the upper 128-bytes of CROM RAM, probes the northbridge, PCH, LPC and SATA.
+ *
+ * @return 0 if OK, -ve on error
+ */
+int cpu_common_init(void);
+
+/**
+ * cpu_set_flex_ratio_to_tdp_nominal() - Set up the maximum non-turbo rate
+ *
+ * If a change is needed, this function will do a soft reset so it takes
+ * effect.
+ *
+ * Some details are available here:
+ * http://forum.hwbot.org/showthread.php?t=76092
+ *
+ * @return 0 if OK, -ve on error
+ */
+int cpu_set_flex_ratio_to_tdp_nominal(void);
+
+#endif
diff --git a/arch/x86/include/asm/intel_regs.h b/arch/x86/include/asm/intel_regs.h
index 961d2bd..d2a6d26 100644
--- a/arch/x86/include/asm/intel_regs.h
+++ b/arch/x86/include/asm/intel_regs.h
@@ -12,8 +12,17 @@
 #define MCH_BASE_SIZE		0x8000
 #define MCHBAR_REG(reg)		(MCH_BASE_ADDRESS + (reg))
 
+#define MCHBAR_PEI_VERSION	0x5034
+#define MCH_PKG_POWER_LIMIT_LO	0x59a0
+#define MCH_PKG_POWER_LIMIT_HI	0x59a4
+#define MCH_DDR_POWER_LIMIT_LO	0x58e0
+#define MCH_DDR_POWER_LIMIT_HI	0x58e4
+
 /* Access the Root Complex Register Block */
 #define RCB_BASE_ADDRESS	0xfed1c000
 #define RCB_REG(reg)		(RCB_BASE_ADDRESS + (reg))
 
+#define SOFT_RESET_CTRL		0x38f4
+#define SOFT_RESET_DATA		0x38f8
+
 #endif
-- 
2.7.0.rc3.207.g0ac5344



More information about the U-Boot mailing list