x86: Move common CPU code to its own place

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@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
master
Simon Glass 8 years ago committed by Bin Meng
parent 8c30b57130
commit 50dd3da004
  1. 1
      arch/x86/cpu/intel_common/Makefile
  2. 111
      arch/x86/cpu/intel_common/cpu.c
  3. 80
      arch/x86/cpu/ivybridge/cpu.c
  4. 2
      arch/x86/include/asm/arch-ivybridge/pch.h
  5. 35
      arch/x86/include/asm/cpu_common.h
  6. 9
      arch/x86/include/asm/intel_regs.h

@ -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

@ -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;
}

@ -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,16 +144,10 @@ 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_err(UCLASS_LPC, &lpc);
ret = cpu_common_init();
if (ret)
return ret;
/* 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);
@ -240,8 +170,10 @@ int print_cpuinfo(void)
return ret;
/* 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;

@ -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) | \

@ -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

@ -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

Loading…
Cancel
Save