Add support for Intel Nehalem CPU
Change-Id: I7ecc394b1e5bc0b8b85a8afac22efc0befe2d36a Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com> Signed-off-by: Stefan Reinauer <reinauer@google.com> Reviewed-on: http://review.coreboot.org/3395 Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
parent
3a09179f46
commit
22dcdd914c
|
@ -10,6 +10,7 @@ source src/cpu/intel/model_6fx/Kconfig
|
|||
source src/cpu/intel/model_1067x/Kconfig
|
||||
source src/cpu/intel/model_106cx/Kconfig
|
||||
source src/cpu/intel/model_206ax/Kconfig
|
||||
source src/cpu/intel/model_2065x/Kconfig
|
||||
source src/cpu/intel/model_f0x/Kconfig
|
||||
source src/cpu/intel/model_f1x/Kconfig
|
||||
source src/cpu/intel/model_f2x/Kconfig
|
||||
|
|
|
@ -15,6 +15,7 @@ subdirs-$(CONFIG_CPU_INTEL_SOCKET_MPGA603) += socket_mPGA603
|
|||
subdirs-$(CONFIG_CPU_INTEL_SOCKET_MPGA604) += socket_mPGA604
|
||||
subdirs-$(CONFIG_CPU_INTEL_SOCKET_PGA370) += socket_PGA370
|
||||
subdirs-$(CONFIG_CPU_INTEL_SOCKET_RPGA989) += socket_rPGA989
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_NEHALEM) += model_2065x
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += model_206ax
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += model_206ax
|
||||
subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
config CPU_INTEL_MODEL_2065X
|
||||
bool
|
||||
|
||||
if CPU_INTEL_MODEL_2065X
|
||||
|
||||
config CPU_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
select SMP
|
||||
select SSE
|
||||
select SSE2
|
||||
select UDELAY_LAPIC
|
||||
select SMM_TSEG
|
||||
select HAVE_INIT_TIMER
|
||||
select CPU_MICROCODE_IN_CBFS
|
||||
#select AP_IN_SIPI_WAIT
|
||||
select TSC_SYNC_MFENCE
|
||||
|
||||
config BOOTBLOCK_CPU_INIT
|
||||
string
|
||||
default "cpu/intel/model_2065x/bootblock.c"
|
||||
|
||||
config SERIAL_CPU_INIT
|
||||
bool
|
||||
default n
|
||||
|
||||
config SMM_TSEG_SIZE
|
||||
hex
|
||||
default 0x800000
|
||||
|
||||
config ENABLE_VMX
|
||||
bool "Enable VMX for virtualization"
|
||||
default n
|
||||
|
||||
config MICROCODE_INCLUDE_PATH
|
||||
string
|
||||
default "3rdparty/mainboard/lenovo/x201"
|
||||
|
||||
config XIP_ROM_SIZE
|
||||
hex
|
||||
default 0x20000
|
||||
|
||||
endif
|
|
@ -0,0 +1,16 @@
|
|||
ramstage-y += model_2065x_init.c
|
||||
subdirs-y += ../../x86/name
|
||||
subdirs-y += ../../x86/cache
|
||||
subdirs-y += ../../x86/mtrr
|
||||
subdirs-y += ../../x86/lapic
|
||||
subdirs-y += ../../intel/turbo
|
||||
subdirs-y += ../../intel/microcode
|
||||
subdirs-y += ../../x86/smm
|
||||
|
||||
ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c
|
||||
|
||||
smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c
|
||||
|
||||
cpu_microcode-$(CONFIG_CPU_MICROCODE_CBFS_GENERATE) += microcode_blob.c
|
||||
|
||||
cpu_incs += $(src)/cpu/intel/model_2065x/cache_as_ram.inc
|
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2009 coresystems GmbH
|
||||
* Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of
|
||||
* the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <console/console.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <arch/acpigen.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/intel/speedstep.h>
|
||||
#include <cpu/intel/turbo.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include "model_2065x.h"
|
||||
#include "chip.h"
|
||||
|
||||
static int get_cores_per_package(void)
|
||||
{
|
||||
struct cpuinfo_x86 c;
|
||||
struct cpuid_result result;
|
||||
int cores = 1;
|
||||
|
||||
get_fms(&c, cpuid_eax(1));
|
||||
if (c.x86 != 6)
|
||||
return 1;
|
||||
|
||||
result = cpuid_ext(0xb, 1);
|
||||
cores = result.ebx & 0xff;
|
||||
|
||||
return cores;
|
||||
}
|
||||
|
||||
static int generate_cstate_entries(acpi_cstate_t *cstates,
|
||||
int c1, int c2, int c3)
|
||||
{
|
||||
int length, cstate_count = 0;
|
||||
|
||||
/* Count number of active C-states */
|
||||
if (c1 > 0)
|
||||
++cstate_count;
|
||||
if (c2 > 0)
|
||||
++cstate_count;
|
||||
if (c3 > 0)
|
||||
++cstate_count;
|
||||
if (!cstate_count)
|
||||
return 0;
|
||||
|
||||
length = acpigen_write_package(cstate_count + 1);
|
||||
length += acpigen_write_byte(cstate_count);
|
||||
|
||||
/* Add an entry if the level is enabled */
|
||||
if (c1 > 0) {
|
||||
cstates[c1].ctype = 1;
|
||||
length += acpigen_write_CST_package_entry(&cstates[c1]);
|
||||
}
|
||||
if (c2 > 0) {
|
||||
cstates[c2].ctype = 2;
|
||||
length += acpigen_write_CST_package_entry(&cstates[c2]);
|
||||
}
|
||||
if (c3 > 0) {
|
||||
cstates[c3].ctype = 3;
|
||||
length += acpigen_write_CST_package_entry(&cstates[c3]);
|
||||
}
|
||||
|
||||
acpigen_patch_len(length - 1);
|
||||
return length;
|
||||
}
|
||||
|
||||
static int generate_C_state_entries(void)
|
||||
{
|
||||
struct cpu_info *info;
|
||||
struct cpu_driver *cpu;
|
||||
int len, lenif;
|
||||
device_t lapic;
|
||||
struct cpu_intel_model_2065x_config *conf = NULL;
|
||||
|
||||
/* Find the SpeedStep CPU in the device tree using magic APIC ID */
|
||||
lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
|
||||
if (!lapic)
|
||||
return 0;
|
||||
conf = lapic->chip_info;
|
||||
if (!conf)
|
||||
return 0;
|
||||
|
||||
/* Find CPU map of supported C-states */
|
||||
info = cpu_info();
|
||||
if (!info)
|
||||
return 0;
|
||||
cpu = find_cpu_driver(info->cpu);
|
||||
if (!cpu || !cpu->cstates)
|
||||
return 0;
|
||||
|
||||
len = acpigen_emit_byte(0x14); /* MethodOp */
|
||||
len += acpigen_write_len_f(); /* PkgLength */
|
||||
len += acpigen_emit_namestring("_CST");
|
||||
len += acpigen_emit_byte(0x00); /* No Arguments */
|
||||
|
||||
/* If running on AC power */
|
||||
len += acpigen_emit_byte(0xa0); /* IfOp */
|
||||
lenif = acpigen_write_len_f(); /* PkgLength */
|
||||
lenif += acpigen_emit_namestring("PWRS");
|
||||
lenif += acpigen_emit_byte(0xa4); /* ReturnOp */
|
||||
lenif += generate_cstate_entries(cpu->cstates, conf->c1_acpower,
|
||||
conf->c2_acpower, conf->c3_acpower);
|
||||
acpigen_patch_len(lenif - 1);
|
||||
len += lenif;
|
||||
|
||||
/* Else on battery power */
|
||||
len += acpigen_emit_byte(0xa4); /* ReturnOp */
|
||||
len += generate_cstate_entries(cpu->cstates, conf->c1_battery,
|
||||
conf->c2_battery, conf->c3_battery);
|
||||
acpigen_patch_len(len - 1);
|
||||
return len;
|
||||
}
|
||||
|
||||
static acpi_tstate_t tss_table_fine[] = {
|
||||
{ 100, 1000, 0, 0x00, 0 },
|
||||
{ 94, 940, 0, 0x1f, 0 },
|
||||
{ 88, 880, 0, 0x1e, 0 },
|
||||
{ 82, 820, 0, 0x1d, 0 },
|
||||
{ 75, 760, 0, 0x1c, 0 },
|
||||
{ 69, 700, 0, 0x1b, 0 },
|
||||
{ 63, 640, 0, 0x1a, 0 },
|
||||
{ 57, 580, 0, 0x19, 0 },
|
||||
{ 50, 520, 0, 0x18, 0 },
|
||||
{ 44, 460, 0, 0x17, 0 },
|
||||
{ 38, 400, 0, 0x16, 0 },
|
||||
{ 32, 340, 0, 0x15, 0 },
|
||||
{ 25, 280, 0, 0x14, 0 },
|
||||
{ 19, 220, 0, 0x13, 0 },
|
||||
{ 13, 160, 0, 0x12, 0 },
|
||||
};
|
||||
|
||||
static acpi_tstate_t tss_table_coarse[] = {
|
||||
{ 100, 1000, 0, 0x00, 0 },
|
||||
{ 88, 875, 0, 0x1f, 0 },
|
||||
{ 75, 750, 0, 0x1e, 0 },
|
||||
{ 63, 625, 0, 0x1d, 0 },
|
||||
{ 50, 500, 0, 0x1c, 0 },
|
||||
{ 38, 375, 0, 0x1b, 0 },
|
||||
{ 25, 250, 0, 0x1a, 0 },
|
||||
{ 13, 125, 0, 0x19, 0 },
|
||||
};
|
||||
|
||||
static int generate_T_state_entries(int core, int cores_per_package)
|
||||
{
|
||||
int len;
|
||||
|
||||
/* Indicate SW_ALL coordination for T-states */
|
||||
len = acpigen_write_TSD_package(core, cores_per_package, SW_ALL);
|
||||
|
||||
/* Indicate FFixedHW so OS will use MSR */
|
||||
len += acpigen_write_empty_PTC();
|
||||
|
||||
/* Set a T-state limit that can be modified in NVS */
|
||||
len += acpigen_write_TPC("\\TLVL");
|
||||
|
||||
/*
|
||||
* CPUID.(EAX=6):EAX[5] indicates support
|
||||
* for extended throttle levels.
|
||||
*/
|
||||
if (cpuid_eax(6) & (1 << 5))
|
||||
len += acpigen_write_TSS_package(
|
||||
ARRAY_SIZE(tss_table_fine), tss_table_fine);
|
||||
else
|
||||
len += acpigen_write_TSS_package(
|
||||
ARRAY_SIZE(tss_table_coarse), tss_table_coarse);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int calculate_power(int tdp, int p1_ratio, int ratio)
|
||||
{
|
||||
u32 m;
|
||||
u32 power;
|
||||
|
||||
/*
|
||||
* M = ((1.1 - ((p1_ratio - ratio) * 0.00625)) / 1.1) ^ 2
|
||||
*
|
||||
* Power = (ratio / p1_ratio) * m * tdp
|
||||
*/
|
||||
|
||||
m = (110000 - ((p1_ratio - ratio) * 625)) / 11;
|
||||
m = (m * m) / 1000;
|
||||
|
||||
power = ((ratio * 100000 / p1_ratio) / 100);
|
||||
power *= (m / 100) * (tdp / 1000);
|
||||
power /= 1000;
|
||||
|
||||
return (int)power;
|
||||
}
|
||||
|
||||
static int generate_P_state_entries(int core, int cores_per_package)
|
||||
{
|
||||
int len, len_pss;
|
||||
int ratio_min, ratio_max, ratio_turbo, ratio_step;
|
||||
int coord_type, power_max, num_entries;
|
||||
int ratio, power, clock, clock_max;
|
||||
msr_t msr;
|
||||
|
||||
/* Determine P-state coordination type from MISC_PWR_MGMT[0] */
|
||||
msr = rdmsr(MSR_MISC_PWR_MGMT);
|
||||
if (msr.lo & MISC_PWR_MGMT_EIST_HW_DIS)
|
||||
coord_type = SW_ANY;
|
||||
else
|
||||
coord_type = HW_ALL;
|
||||
|
||||
/* Get bus ratio limits and calculate clock speeds */
|
||||
msr = rdmsr(MSR_PLATFORM_INFO);
|
||||
ratio_min = (msr.hi >> (40-32)) & 0xff; /* Max Efficiency Ratio */
|
||||
|
||||
/* Determine if this CPU has configurable TDP */
|
||||
if (cpu_config_tdp_levels()) {
|
||||
/* Set max ratio to nominal TDP ratio */
|
||||
msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
|
||||
ratio_max = msr.lo & 0xff;
|
||||
} else {
|
||||
/* Max Non-Turbo Ratio */
|
||||
ratio_max = (msr.lo >> 8) & 0xff;
|
||||
}
|
||||
clock_max = ratio_max * SANDYBRIDGE_BCLK + ratio_max / 3;
|
||||
|
||||
/* Calculate CPU TDP in mW */
|
||||
power_max = 25000;
|
||||
|
||||
/* Write _PCT indicating use of FFixedHW */
|
||||
len = acpigen_write_empty_PCT();
|
||||
|
||||
/* Write _PPC with no limit on supported P-state */
|
||||
len += acpigen_write_PPC_NVS();
|
||||
|
||||
/* Write PSD indicating configured coordination type */
|
||||
len += acpigen_write_PSD_package(core, cores_per_package, coord_type);
|
||||
|
||||
/* Add P-state entries in _PSS table */
|
||||
len += acpigen_write_name("_PSS");
|
||||
|
||||
/* Determine ratio points */
|
||||
ratio_step = PSS_RATIO_STEP;
|
||||
num_entries = (ratio_max - ratio_min) / ratio_step;
|
||||
while (num_entries > PSS_MAX_ENTRIES-1) {
|
||||
ratio_step <<= 1;
|
||||
num_entries >>= 1;
|
||||
}
|
||||
|
||||
/* P[T] is Turbo state if enabled */
|
||||
if (get_turbo_state() == TURBO_ENABLED) {
|
||||
/* _PSS package count including Turbo */
|
||||
len_pss = acpigen_write_package(num_entries + 2);
|
||||
|
||||
msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
|
||||
ratio_turbo = msr.lo & 0xff;
|
||||
|
||||
/* Add entry for Turbo ratio */
|
||||
len_pss += acpigen_write_PSS_package(
|
||||
clock_max + 1, /*MHz*/
|
||||
power_max, /*mW*/
|
||||
PSS_LATENCY_TRANSITION, /*lat1*/
|
||||
PSS_LATENCY_BUSMASTER, /*lat2*/
|
||||
ratio_turbo, /*control*/
|
||||
ratio_turbo); /*status*/
|
||||
} else {
|
||||
/* _PSS package count without Turbo */
|
||||
len_pss = acpigen_write_package(num_entries + 1);
|
||||
}
|
||||
|
||||
/* First regular entry is max non-turbo ratio */
|
||||
len_pss += acpigen_write_PSS_package(
|
||||
clock_max, /*MHz*/
|
||||
power_max, /*mW*/
|
||||
PSS_LATENCY_TRANSITION, /*lat1*/
|
||||
PSS_LATENCY_BUSMASTER, /*lat2*/
|
||||
ratio_max, /*control*/
|
||||
ratio_max); /*status*/
|
||||
|
||||
/* Generate the remaining entries */
|
||||
for (ratio = ratio_min + ((num_entries - 1) * ratio_step);
|
||||
ratio >= ratio_min; ratio -= ratio_step) {
|
||||
|
||||
/* Calculate power at this ratio */
|
||||
power = calculate_power(power_max, ratio_max, ratio);
|
||||
clock = ratio * SANDYBRIDGE_BCLK + ratio / 3;
|
||||
|
||||
len_pss += acpigen_write_PSS_package(
|
||||
clock, /*MHz*/
|
||||
power, /*mW*/
|
||||
PSS_LATENCY_TRANSITION, /*lat1*/
|
||||
PSS_LATENCY_BUSMASTER, /*lat2*/
|
||||
ratio, /*control*/
|
||||
ratio); /*status*/
|
||||
}
|
||||
|
||||
/* Fix package length */
|
||||
len_pss--;
|
||||
acpigen_patch_len(len_pss);
|
||||
|
||||
return len + len_pss;
|
||||
}
|
||||
|
||||
void generate_cpu_entries(void)
|
||||
{
|
||||
int len_pr;
|
||||
int coreID, cpuID, pcontrol_blk = PMB0_BASE, plen = 6;
|
||||
int totalcores = dev_count_cpu();
|
||||
int cores_per_package = get_cores_per_package();
|
||||
int numcpus = totalcores/cores_per_package;
|
||||
|
||||
printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
|
||||
numcpus, cores_per_package);
|
||||
|
||||
for (cpuID=1; cpuID <=numcpus; cpuID++) {
|
||||
for (coreID=1; coreID<=cores_per_package; coreID++) {
|
||||
if (coreID>1) {
|
||||
pcontrol_blk = 0;
|
||||
plen = 0;
|
||||
}
|
||||
|
||||
/* Generate processor \_PR.CPUx */
|
||||
len_pr = acpigen_write_processor(
|
||||
(cpuID-1)*cores_per_package+coreID-1,
|
||||
pcontrol_blk, plen);
|
||||
|
||||
/* Generate P-state tables */
|
||||
len_pr += generate_P_state_entries(
|
||||
cpuID-1, cores_per_package);
|
||||
|
||||
/* Generate C-state tables */
|
||||
len_pr += generate_C_state_entries();
|
||||
|
||||
/* Generate T-state tables */
|
||||
len_pr += generate_T_state_entries(
|
||||
cpuID-1, cores_per_package);
|
||||
|
||||
len_pr--;
|
||||
acpigen_patch_len(len_pr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct chip_operations cpu_intel_model_2065x_ops = {
|
||||
CHIP_NAME("Intel Nehalem CPU")
|
||||
};
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <arch/io.h>
|
||||
|
||||
#include <cpu/intel/microcode/microcode.c>
|
||||
|
||||
#if CONFIG_SOUTHBRIDGE_INTEL_IBEXPEAK
|
||||
#include <southbridge/intel/ibexpeak/pch.h>
|
||||
#include "model_2065x.h"
|
||||
#else
|
||||
#error "CPU must be paired with Intel BD82X6X or C216 southbridge"
|
||||
#endif
|
||||
|
||||
static void set_var_mtrr(
|
||||
unsigned reg, unsigned base, unsigned size, unsigned type)
|
||||
|
||||
{
|
||||
/* Bit Bit 32-35 of MTRRphysMask should be set to 1 */
|
||||
/* FIXME: It only support 4G less range */
|
||||
msr_t basem, maskm;
|
||||
basem.lo = base | type;
|
||||
basem.hi = 0;
|
||||
wrmsr(MTRRphysBase_MSR(reg), basem);
|
||||
maskm.lo = ~(size - 1) | MTRRphysMaskValid;
|
||||
maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
|
||||
wrmsr(MTRRphysMask_MSR(reg), maskm);
|
||||
}
|
||||
|
||||
static void enable_rom_caching(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
disable_cache();
|
||||
set_var_mtrr(1, 0xffc00000, 4*1024*1024, MTRR_TYPE_WRPROT);
|
||||
enable_cache();
|
||||
|
||||
/* Enable Variable MTRRs */
|
||||
msr.hi = 0x00000000;
|
||||
msr.lo = 0x00000800;
|
||||
wrmsr(MTRRdefType_MSR, msr);
|
||||
}
|
||||
|
||||
static void set_flex_ratio_to_tdp_nominal(void)
|
||||
{
|
||||
msr_t flex_ratio, msr;
|
||||
u32 soft_reset;
|
||||
u8 nominal_ratio;
|
||||
|
||||
/* Minimum CPU revision for configurable TDP support */
|
||||
if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
|
||||
return;
|
||||
|
||||
/* Check for Flex Ratio support */
|
||||
flex_ratio = rdmsr(MSR_FLEX_RATIO);
|
||||
if (!(flex_ratio.lo & FLEX_RATIO_EN))
|
||||
return;
|
||||
|
||||
/* Check for >0 configurable TDPs */
|
||||
msr = rdmsr(MSR_PLATFORM_INFO);
|
||||
if (((msr.hi >> 1) & 3) == 0)
|
||||
return;
|
||||
|
||||
/* Use nominal TDP ratio for flex ratio */
|
||||
msr = rdmsr(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;
|
||||
|
||||
/* Set flex ratio to nominal TDP ratio */
|
||||
flex_ratio.lo &= ~0xff00;
|
||||
flex_ratio.lo |= nominal_ratio << 8;
|
||||
flex_ratio.lo |= FLEX_RATIO_LOCK;
|
||||
wrmsr(MSR_FLEX_RATIO, flex_ratio);
|
||||
|
||||
/* Set flex ratio in soft reset data register bits 11:6.
|
||||
* RCBA region is enabled in southbridge bootblock */
|
||||
soft_reset = RCBA32(SOFT_RESET_DATA);
|
||||
soft_reset &= ~(0x3f << 6);
|
||||
soft_reset |= (nominal_ratio & 0x3f) << 6;
|
||||
RCBA32(SOFT_RESET_DATA) = soft_reset;
|
||||
|
||||
/* Set soft reset control to use register value */
|
||||
RCBA32_OR(SOFT_RESET_CTRL, 1);
|
||||
|
||||
/* Issue warm reset, will be "CPU only" due to soft reset data */
|
||||
outb(0x0, 0xcf9);
|
||||
outb(0x6, 0xcf9);
|
||||
asm("hlt");
|
||||
}
|
||||
|
||||
static void bootblock_cpu_init(void)
|
||||
{
|
||||
/* Set flex ratio and reset if needed */
|
||||
set_flex_ratio_to_tdp_nominal();
|
||||
enable_rom_caching();
|
||||
intel_update_microcode_from_cbfs();
|
||||
}
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
|
||||
* Copyright (C) 2007-2008 coresystems GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <cpu/x86/stack.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/x86/post_code.h>
|
||||
#include <cbmem.h>
|
||||
|
||||
#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
|
||||
#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
|
||||
|
||||
/* Cache 4GB - MRC_SIZE_KB for MRC */
|
||||
#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
|
||||
#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
|
||||
#define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
|
||||
|
||||
#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
|
||||
|
||||
#define NoEvictMod_MSR 0x2e0
|
||||
|
||||
/* Save the BIST result. */
|
||||
movl %eax, %ebp
|
||||
|
||||
cache_as_ram:
|
||||
post_code(0x20)
|
||||
|
||||
/* Send INIT IPI to all excluding ourself. */
|
||||
movl $0x000C4500, %eax
|
||||
movl $0xFEE00300, %esi
|
||||
movl %eax, (%esi)
|
||||
|
||||
/* All CPUs need to be in Wait for SIPI state */
|
||||
wait_for_sipi:
|
||||
movl (%esi), %eax
|
||||
bt $12, %eax
|
||||
jc wait_for_sipi
|
||||
|
||||
post_code(0x21)
|
||||
/* Zero out all fixed range and variable range MTRRs. */
|
||||
movl $mtrr_table, %esi
|
||||
movl $((mtrr_table_end - mtrr_table) / 2), %edi
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
clear_mtrrs:
|
||||
movw (%esi), %bx
|
||||
movzx %bx, %ecx
|
||||
wrmsr
|
||||
add $2, %esi
|
||||
dec %edi
|
||||
jnz clear_mtrrs
|
||||
|
||||
post_code(0x22)
|
||||
/* Configure the default memory type to uncacheable. */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(~0x00000cff), %eax
|
||||
wrmsr
|
||||
|
||||
post_code(0x23)
|
||||
/* Set Cache-as-RAM base address. */
|
||||
movl $(MTRRphysBase_MSR(0)), %ecx
|
||||
movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
post_code(0x24)
|
||||
/* Set Cache-as-RAM mask. */
|
||||
movl $(MTRRphysMask_MSR(0)), %ecx
|
||||
movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
wrmsr
|
||||
|
||||
post_code(0x25)
|
||||
|
||||
/* Enable MTRR. */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
rdmsr
|
||||
orl $MTRRdefTypeEn, %eax
|
||||
wrmsr
|
||||
|
||||
/* Enable cache (CR0.CD = 0, CR0.NW = 0). */
|
||||
movl %cr0, %eax
|
||||
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
|
||||
invd
|
||||
movl %eax, %cr0
|
||||
|
||||
/* enable the 'no eviction' mode */
|
||||
movl $NoEvictMod_MSR, %ecx
|
||||
rdmsr
|
||||
orl $1, %eax
|
||||
andl $~2, %eax
|
||||
wrmsr
|
||||
|
||||
/* Clear the cache memory region. This will also fill up the cache */
|
||||
movl $CACHE_AS_RAM_BASE, %esi
|
||||
movl %esi, %edi
|
||||
movl $(CACHE_AS_RAM_SIZE / 4), %ecx
|
||||
// movl $0x23322332, %eax
|
||||
xorl %eax, %eax
|
||||
rep stosl
|
||||
|
||||
/* enable the 'no eviction run' state */
|
||||
movl $NoEvictMod_MSR, %ecx
|
||||
rdmsr
|
||||
orl $3, %eax
|
||||
wrmsr
|
||||
|
||||
post_code(0x26)
|
||||
/* Enable Cache-as-RAM mode by disabling cache. */
|
||||
movl %cr0, %eax
|
||||
orl $CR0_CacheDisable, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Enable cache for our code in Flash because we do XIP here */
|
||||
movl $MTRRphysBase_MSR(1), %ecx
|
||||
xorl %edx, %edx
|
||||
/*
|
||||
* IMPORTANT: The following calculation _must_ be done at runtime. See
|
||||
* http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
|
||||
*/
|
||||
movl $copy_and_run, %eax
|
||||
andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
|
||||
orl $MTRR_TYPE_WRPROT, %eax
|
||||
wrmsr
|
||||
|
||||
movl $MTRRphysMask_MSR(1), %ecx
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
|
||||
wrmsr
|
||||
|
||||
post_code(0x27)
|
||||
#if CONFIG_CACHE_MRC_BIN
|
||||
/* Enable caching for ram init code to run faster */
|
||||
movl $MTRRphysBase_MSR(2), %ecx
|
||||
movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
movl $MTRRphysMask_MSR(2), %ecx
|
||||
movl $(CACHE_MRC_MASK | MTRRphysMaskValid), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
post_code(0x28)
|
||||
/* Enable cache. */
|
||||
movl %cr0, %eax
|
||||
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Set up the stack pointer below MRC variable space. */
|
||||
movl $(CACHE_AS_RAM_SIZE + CACHE_AS_RAM_BASE - \
|
||||
CONFIG_DCACHE_RAM_MRC_VAR_SIZE - 4 - 4096), %eax
|
||||
movl %eax, %esp
|
||||
|
||||
/* Restore the BIST result. */
|
||||
movl %ebp, %eax
|
||||
movl %esp, %ebp
|
||||
pushl %eax
|
||||
|
||||
before_romstage:
|
||||
post_code(0x29)
|
||||
/* Call romstage.c main function. */
|
||||
call main
|
||||
|
||||
post_code(0x2f)
|
||||
|
||||
/* Copy global variable space (for USBDEBUG) to memory */
|
||||
#if CONFIG_USBDEBUG
|
||||
cld
|
||||
movl $(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - 24), %esi
|
||||
movl $(CONFIG_RAMTOP - 24), %edi
|
||||
movl $24, %ecx
|
||||
rep movsb
|
||||
#endif
|
||||
|
||||
post_code(0x30)
|
||||
|
||||
/* Disable cache. */
|
||||
movl %cr0, %eax
|
||||
orl $CR0_CacheDisable, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
post_code(0x31)
|
||||
|
||||
/* Disable MTRR. */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(~MTRRdefTypeEn), %eax
|
||||
wrmsr
|
||||
|
||||
post_code(0x31)
|
||||
|
||||
/* Disable the no eviction run state */
|
||||
movl $NoEvictMod_MSR, %ecx
|
||||
rdmsr
|
||||
andl $~2, %eax
|
||||
wrmsr
|
||||
|
||||
invd
|
||||
|
||||
/* Disable the no eviction mode */
|
||||
rdmsr
|
||||
andl $~1, %eax
|
||||
wrmsr
|
||||
|
||||
#if CONFIG_CACHE_MRC_BIN
|
||||
/* Clear MTRR that was used to cache MRC */
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
movl $MTRRphysBase_MSR(2), %ecx
|
||||
wrmsr
|
||||
movl $MTRRphysMask_MSR(2), %ecx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
post_code(0x33)
|
||||
|
||||
/* Enable cache. */
|
||||
movl %cr0, %eax
|
||||
andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
post_code(0x36)
|
||||
|
||||
/* Disable cache. */
|
||||
movl %cr0, %eax
|
||||
orl $CR0_CacheDisable, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
post_code(0x38)
|
||||
|
||||
/* Enable Write Back and Speculative Reads for the first MB
|
||||
* and coreboot_ram.
|
||||
*/
|
||||
movl $MTRRphysBase_MSR(0), %ecx
|
||||
movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
movl $MTRRphysMask_MSR(0), %ecx
|
||||
movl $(~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx // 36bit address space
|
||||
wrmsr
|
||||
|
||||
#if CONFIG_CACHE_ROM_SIZE
|
||||
/* Enable Caching and speculative Reads for the
|
||||
* complete ROM now that we actually have RAM.
|
||||
*/
|
||||
movl $MTRRphysBase_MSR(1), %ecx
|
||||
movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
movl $MTRRphysMask_MSR(1), %ecx
|
||||
movl $(~(CONFIG_CACHE_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
|
||||
movl $CPU_PHYSMASK_HI, %edx
|
||||
wrmsr
|
||||
#endif
|
||||
|
||||
post_code(0x39)
|
||||
|
||||
/* And enable cache again after setting MTRRs. */
|
||||
movl %cr0, %eax
|
||||
andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
post_code(0x3a)
|
||||
|
||||
/* Enable MTRR. */
|
||||
movl $MTRRdefType_MSR, %ecx
|
||||
rdmsr
|
||||
orl $MTRRdefTypeEn, %eax
|
||||
wrmsr
|
||||
|
||||
post_code(0x3b)
|
||||
|
||||
/* Invalidate the cache again. */
|
||||
invd
|
||||
|
||||
post_code(0x3c)
|
||||
|
||||
#if CONFIG_HAVE_ACPI_RESUME
|
||||
movl CBMEM_BOOT_MODE, %eax
|
||||
cmpl $0x2, %eax // Resume?
|
||||
jne __acpi_resume_backup_done
|
||||
|
||||
/* copy 1MB - 64K to high tables ram_base to prevent memory corruption
|
||||
* through stage 2. We could keep stuff like stack and heap in high
|
||||
* tables memory completely, but that's a wonderful clean up task for
|
||||
* another day.
|
||||
*/
|
||||
cld
|
||||
movl $CONFIG_RAMBASE, %esi
|
||||
movl CBMEM_RESUME_BACKUP, %edi
|
||||
movl $HIGH_MEMORY_SAVE / 4, %ecx
|
||||
rep movsl
|
||||
|
||||
__acpi_resume_backup_done:
|
||||
#endif
|
||||
|
||||
post_code(0x3d)
|
||||
|
||||
__main:
|
||||
post_code(POST_PREPARE_RAMSTAGE)
|
||||
cld /* Clear direction flag. */
|
||||
|
||||
movl $ROMSTAGE_STACK, %esp
|
||||
movl %esp, %ebp
|
||||
call copy_and_run
|
||||
|
||||
.Lhlt:
|
||||
post_code(POST_DEAD_CODE)
|
||||
hlt
|
||||
jmp .Lhlt
|
||||
|
||||
mtrr_table:
|
||||
.word 0x02FF
|
||||
|
||||
/* Fixed MTRRs */
|
||||
.word 0x250, 0x258, 0x259
|
||||
.word 0x268, 0x269, 0x26A
|
||||
.word 0x26B, 0x26C, 0x26D
|
||||
.word 0x26E, 0x26F
|
||||
|
||||
/* Variable MTRRs */
|
||||
.word 0x200, 0x201, 0x202, 0x203
|
||||
.word 0x204, 0x205, 0x206, 0x207
|
||||
.word 0x208, 0x209, 0x20A, 0x20B
|
||||
.word 0x20C, 0x20D, 0x20E, 0x20F
|
||||
mtrr_table_end:
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Magic value used to locate this chip in the device tree */
|
||||
#define SPEEDSTEP_APIC_MAGIC 0xACAC
|
||||
|
||||
struct cpu_intel_model_2065x_config {
|
||||
u8 disable_acpi; /* Do not generate CPU ACPI tables */
|
||||
|
||||
u8 pstate_coord_type; /* Processor Coordination Type */
|
||||
|
||||
int c1_battery; /* ACPI C1 on Battery Power */
|
||||
int c2_battery; /* ACPI C2 on Battery Power */
|
||||
int c3_battery; /* ACPI C3 on Battery Power */
|
||||
|
||||
int c1_acpower; /* ACPI C1 on AC Power */
|
||||
int c2_acpower; /* ACPI C2 on AC Power */
|
||||
int c3_acpower; /* ACPI C3 on AC Power */
|
||||
|
||||
int tcc_offset; /* TCC Activation Offset */
|
||||
};
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 The Chromium OS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of
|
||||
* the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/intel/speedstep.h>
|
||||
#include "model_2065x.h"
|
||||
|
||||
static void msr_set_bit(unsigned reg, unsigned bit)
|
||||
{
|
||||
msr_t msr = rdmsr(reg);
|
||||
|
||||
if (bit < 32) {
|
||||
if (msr.lo & (1 << bit))
|
||||
return;
|
||||
msr.lo |= 1 << bit;
|
||||
} else {
|
||||
if (msr.hi & (1 << (bit - 32)))
|
||||
return;
|
||||
msr.hi |= 1 << (bit - 32);
|
||||
}
|
||||
|
||||
wrmsr(reg, msr);
|
||||
}
|
||||
|
||||
void intel_model_2065x_finalize_smm(void)
|
||||
{
|
||||
msr_set_bit(MSR_PMG_CST_CONFIG_CONTROL, 15);
|
||||
|
||||
/* Lock AES-NI only if supported */
|
||||
if (cpuid_ecx(1) & (1 << 25))
|
||||
msr_set_bit(MSR_FEATURE_CONFIG, 0);
|
||||
|
||||
#ifdef LOCK_POWER_CONTROL_REGISTERS
|
||||
/*
|
||||
* Lock the power control registers.
|
||||
*
|
||||
* These registers can be left unlocked if modifying power
|
||||
* limits from the OS is desirable. Modifying power limits
|
||||
* from the OS can be especially useful for experimentation
|
||||
* during early phases of system bringup while the thermal
|
||||
* power envelope is being proven.
|
||||
*/
|
||||
|
||||
msr_set_bit(MSR_PP0_CURRENT_CONFIG, 31);
|
||||
msr_set_bit(MSR_PP1_CURRENT_CONFIG, 31);
|
||||
msr_set_bit(MSR_PKG_POWER_LIMIT, 63);
|
||||
msr_set_bit(MSR_PP0_POWER_LIMIT, 31);
|
||||
msr_set_bit(MSR_PP1_POWER_LIMIT, 31);
|
||||
#endif
|
||||
|
||||
msr_set_bit(MSR_MISC_PWR_MGMT, 22);
|
||||
msr_set_bit(MSR_LT_LOCK_MEMORY, 0);
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/* m9220655_00000003.inc */
|
||||
0x00000001, 0x00000003, 0x09012011, 0x00020655,
|
||||
0xc50abfd4, 0x00000001, 0x00000092, 0x000007d0,
|
||||
0x00000800, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x000000a1, 0x00020001, 0x00000003,
|
||||
0x00000000, 0x00000000, 0x20110831, 0x000001a1,
|
||||
0x00000001, 0x00020655, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xc3323f9e, 0xa2912832, 0xa7a30a2e, 0x9e75a181,
|
||||
0x840159be, 0xd1c7dbb0, 0x921c5cf7, 0xb323111b,
|
||||
0x5d5f57b5, 0x9926d84a, 0xdaaf70e7, 0x91786b18,
|
||||
0x82da740d, 0xae90be68, 0x8b6a07cf, 0xc2c37ebc,
|
||||
0xde451f9c, 0x7a1444c0, 0xce6700b1, 0x5c29e58a,
|
||||
0x12eb603f, 0xaaf6cb53, 0xd807a1c9, 0xf51ed696,
|
||||
0x90d9e2c3, 0x641bff09, 0x732ab820, 0xfef7aa2f,
|
||||
0x8f518e1d, 0xf0d8c4d9, 0x73aefe19, 0xf6d7ae12,
|
||||
0xd50a095b, 0xdf21cbb8, 0x4b81ff9a, 0xe1a6d1f8,
|
||||
0xbe78b0de, 0xda86826f, 0xc4f9c057, 0x306f1761,
|
||||
0x7aae81f0, 0xdbab0ae2, 0x789ec0ff, 0xbaacd096,
|
||||
0x68fa4733, 0x2f3fd406, 0xd287247f, 0x79eefe4c,
|
||||
0x6f674a41, 0xd6948ad8, 0x90388682, 0x5a4bf35d,
|
||||
0xadab41ff, 0x89e9dc62, 0xb2eccfee, 0xd4d52153,
|
||||
0x34301d19, 0x8a2f38a6, 0x35b05e56, 0x482f029a,
|
||||
0x296cb5a3, 0xce64f437, 0xae1dfa06, 0xb9f29132,
|
||||
0x1960a103, 0x70bb6f46, 0x152a5d83, 0x171a19d9,
|
||||
0xac9aa4b7, 0x54b719f7, 0x5b781cb1, 0xaea548bb,
|
||||
0x00000011, 0x649668c5, 0xd3d4e73c, 0x0d7eee17,
|
||||
0xc8a4d8f1, 0xa531e67c, 0x0d4e93f9, 0x109a2c8e,
|
||||
0xb3a120eb, 0x1cb99ad0, 0xdf7fffa7, 0xcd22ae67,
|
||||
0xbe6f61df, 0x1fff8bc4, 0x7d413494, 0xbbc77986,
|
||||
0x4648fad1, 0x05a0b769, 0x14a2f426, 0x39081a28,
|
||||
0x343c7600, 0x3a9d78ed, 0xa8bcbbb1, 0x1128500a,
|
||||
0xb1f08088, 0x16f1cc2e, 0x187920e4, 0x7bd8c616,
|
||||
0x416a91ac, 0x2d156cd1, 0xd23473e7, 0xf326b7ff,
|
||||
0x991a226f, 0xf1a4f527, 0xe758dc3f, 0x20f89a4a,
|
||||
0x9f84858c, 0x9c5bde06, 0x839ea7e7, 0x42cfa525,
|
||||
0x869950f9, 0x48e6318f, 0x44314d3e, 0xc946335f,
|
||||
0x9439e0ba, 0x16bef497, 0x5dfeb355, 0x062e96dc,
|
||||
0x0c5b3442, 0x2317678c, 0x0688e8b9, 0x698df73a,
|
||||
0xd87f7a27, 0xc63a05b7, 0xb77b7ed1, 0xee993117,
|
||||
0xbffab1d3, 0x455c43b5, 0x5363cb6c, 0x9361cabc,
|
||||
0xd5bc2e2b, 0xb0079b02, 0x5b371608, 0x8228cc3c,
|
||||
0x97c217b0, 0xef92660a, 0x99e15bc3, 0x610d1881,
|
||||
0xa84efd04, 0x35f287c9, 0xc02cbf49, 0xdc291d6f,
|
||||
0x7d603a19, 0x420b25dc, 0x6d24d532, 0xf8c2d4b6,
|
||||
0x67104704, 0x7ae246b3, 0x24f07636, 0xf88808a0,
|
||||
0xcdcf7aed, 0xa78611a3, 0x9dafdde7, 0x5def0b11,
|
||||
0xb39ca9d7, 0xd0de1c2a, 0xe6e8cc61, 0x9824df50,
|
||||
0x501ef8c9, 0x5bb94ee7, 0x9d75a287, 0xc5b37ebc,
|
||||
0x8b7175f8, 0xe9bd1024, 0xc4e004c2, 0xb626e586,
|
||||
0xf71c129d, 0xe5562dd2, 0xd1d9c514, 0xaa69cd52,
|
||||
0x7ec85bfb, 0x1d6d69da, 0xbd735ff0, 0x496b0cc3,
|
||||
0xea10aa85, 0xd968b670, 0xe4674e6b, 0xd7725f8c,
|
||||
0xc845a270, 0x15d4b857, 0x0a130ca8, 0x707de71f,
|
||||
0x0cf7ba9f, 0xb46fbb4d, 0xc9631c72, 0xe0b4abcd,
|
||||
0x0b364ef1, 0xa390747a, 0x5945a462, 0xe0756457,
|
||||
0x5f79663c, 0x7418e5be, 0xc7ac38f4, 0x24aceecd,
|
||||
0xae762e2b, 0x04c63655, 0x2807f3ba, 0x8a9fdee2,
|
||||
0x4705e3b9, 0x0be41abf, 0x360a2475, 0x2188e84c,
|
||||
0x6724fa71, 0x0d80d39f, 0x06be8e55, 0xd49f817a,
|
||||
0x518f531d, 0x02775181, 0xbd1f8af9, 0x70c91b1f,
|
||||
0x67d619f2, 0x0e2f44b0, 0xde3a57b2, 0x0b96a208,
|
||||
0x86dbafdf, 0xd81a43ca, 0x894241a6, 0x453cd6c0,
|
||||
0x801398e5, 0x8dc7e734, 0x64f5f2f0, 0x023fe4ad,
|
||||
0x808b3fbe, 0x677dec2d, 0xc75aa416, 0x8d4a51c1,
|
||||
0xcb46efb4, 0x26af2486, 0xf28d384f, 0x1f74bbaa,
|
||||
0xb35dbfec, 0xa4acc70a, 0xd0c8ff4b, 0xf40e3136,
|
||||
0x24f08d6d, 0xf4a5792f, 0x3423ebc0, 0x47f54044,
|
||||
0x42939e1e, 0x3768fe97, 0x0890f228, 0xfe48104e,
|
||||
0xd095804b, 0xde7a40cb, 0xc8ed5843, 0x04cc48c5,
|
||||
0xa68d1936, 0x554d336f, 0x19cc9df7, 0xf2b5b0cc,
|
||||
0xf88858c2, 0x6bef0f07, 0xcff53326, 0xfbebbb76,
|
||||
0x63afbd06, 0x6d4b7c27, 0xdd5c8b52, 0x792f665e,
|
||||
0x44e8bc2d, 0x53522507, 0xf5971875, 0xef44f472,
|
||||
0x0ab3bc03, 0x068d792f, 0x86745dc4, 0xc0e63ca0,
|
||||
0xfddb054d, 0x46c23e3c, 0xc8184e1a, 0xb7e77cc7,
|
||||
0x59e90ac1, 0xd836bf58, 0xb220f287, 0x3c3a2e8f,
|
||||
0xa28a7e28, 0x99a249ec, 0xd2a6641c, 0x24adeb4a,
|
||||
0x2bbf323a, 0x618dee6e, 0x093e831a, 0x3f4d3194,
|
||||
0xa166732a, 0x0a80f2f3, 0x8f2f80de, 0xc4d2b7ea,
|
||||
0x17f9e541, 0x1059766d, 0xc2f7e49d, 0x666bb0a3,
|
||||
0xfe8eb21f, 0xa68c8c87, 0x30efe1af, 0x15763eab,
|
||||
0x1d18c1f0, 0xcf1907ee, 0xd478498e, 0xb8041744,
|
||||
0x1bd93f4b, 0x6bca9af1, 0xa54694db, 0xaccd6971,
|
||||
0x92af5474, 0x194c5290, 0xc573b14f, 0xe4d74f3c,
|
||||
0xaa128d24, 0xe50848a2, 0xa5001983, 0x9fc5c01f,
|
||||
0x495687cb, 0x7795998b, 0xcba451a5, 0x67c54058,
|
||||
0x3585e4cc, 0x07eaf375, 0xa1bef51d, 0x730960a4,
|
||||
0xc217f8f0, 0xe5779a63, 0x237b7f2f, 0x6d868035,
|
||||
0x70987ef1, 0x1ab1e989, 0xf1727403, 0x94cd3133,
|
||||
0xbe827fc7, 0x19e198d1, 0xf8f8a4dd, 0x0bdfc02e,
|
||||
0x788737f9, 0xf554a473, 0x22488c80, 0x4397d132,
|
||||
0x5602e73a, 0x4cbdf8b7, 0x14929ba4, 0xc49645d8,
|
||||
0x3a724eb1, 0x44134eef, 0x534f26fc, 0x2c9a2bcf,
|
||||
0xc329abc2, 0x79a52a91, 0xc4d8ecb2, 0x4f29e89b,
|
||||
0x08e3bc45, 0x02c7516b, 0xe4f79884, 0x21dc828a,
|
||||
0xb22adc25, 0xad6b4194, 0xc2e88ec8, 0xab76a868,
|
||||
0x3049d043, 0x9781e3b5, 0xa56602b8, 0xb844a1cf,
|
||||
0xd0c2f155, 0xfff59242, 0x7c0b1be7, 0x20c337ee,
|
||||
0x6eeedede, 0x3d544527, 0x4fa08565, 0x78035c9f,
|
||||
0x5ab9652f, 0x1679da28, 0x1d59380f, 0xfd693582,
|
||||
0x6647c152, 0xa494f5b7, 0x1e5a44e5, 0x49515666,
|
||||
0x80ad6e9f, 0x2857b798, 0x21c78a9c, 0xde2536d4,
|
||||
0x8cd0c906, 0x0e101e47, 0xb56139d8, 0x5f29407b,
|
||||
0xd86efa56, 0x60c1f662, 0x387dbee9, 0xd57f4fae,
|
||||
0xe27b9e73, 0x5e4d81b9, 0x2761f882, 0x923b00c9,
|
||||
0xf1d1ee2e, 0xbec5a579, 0xa90ebc17, 0x686554a2,
|
||||
0xa83f71fd, 0x8eb862bc, 0xdfd0bb6f, 0x1ac1a2bb,
|
||||
0x74d53b49, 0xda9430c4, 0x09797597, 0x35d8f250,
|
||||
0x8d33fb7b, 0x21ec9ecd, 0x6bd9041c, 0xf858aae6,
|
||||
0x3bb472b5, 0xf43a3d7e, 0x8ced914f, 0x5f5d9ce5,
|
||||
0xc0e27757, 0x6afee8ff, 0x45bd08fc, 0x74402451,
|
||||
0x5d1e3aff, 0xfe1e6e53, 0xcaf73401, 0x035d5585,
|
||||
0xb77a8af9, 0xc869836f, 0x72e43074, 0xf784f07b,
|
||||
0x17cf17fd, 0x5785c5c9, 0xa761ee5e, 0xaede1773,
|
||||
0xc58bab5a, 0x8fb77743, 0xc20c974e, 0x9f72ce11,
|
||||
0xdfdf11f8, 0x0153fda9, 0x87d08d4d, 0x8a8d163c,
|
||||
0x2f346fc4, 0x4aabbd39, 0x9866fbe8, 0x4fbc185a,
|
||||
0xc30ea07b, 0xc6e2c2e2, 0x6d9bcc5b, 0x292524ac,
|
||||
0xaad044e9, 0xd6fcd72b, 0x755b2c1b, 0xbc5f83ee,
|
||||
0xbb041dfd, 0x87eefef9, 0x68cdbb47, 0xf423fd81,
|
||||
0x1c106165, 0x35b223a3, 0x4212e6b7, 0x0868b1b0,
|
||||
0x5288c578, 0x108d97ff, 0x1962e7b9, 0x73d366ec,
|
||||
0x8c851ca9, 0x1705746d, 0xc1a261ae, 0xd685b108,
|
||||
0x42a77adc, 0x2c454ffe, 0x33b19c19, 0xefae69ca,
|
||||
0xa6ae093b, 0x6fdfb131, 0xb6fbe5d9, 0xe872ca64,
|
||||
0xecd6df71, 0xe133acfc, 0x3d16c48b, 0x240a15a8,
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
unsigned microcode[] = {
|
||||
#include "microcode_blob.h"
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "microcode-m9220655_00000003.h"
|
||||
|
||||
/* Dummy terminator */
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of
|
||||
* the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _CPU_INTEL_MODEL_2065X_H
|
||||
#define _CPU_INTEL_MODEL_2065X_H
|
||||
|
||||
/* SandyBridge/IvyBridge bus clock is fixed at 100MHz */
|
||||
#define SANDYBRIDGE_BCLK 133
|
||||
|
||||
#define IA32_FEATURE_CONTROL 0x3a
|
||||
#define CPUID_VMX (1 << 5)
|
||||
#define CPUID_SMX (1 << 6)
|
||||
#define MSR_FEATURE_CONFIG 0x13c
|
||||
#define MSR_FLEX_RATIO 0x194
|
||||
#define FLEX_RATIO_LOCK (1 << 20)
|
||||
#define FLEX_RATIO_EN (1 << 16)
|
||||
#define IA32_PLATFORM_DCA_CAP 0x1f8
|
||||
#define IA32_MISC_ENABLE 0x1a0
|
||||
#define MSR_TEMPERATURE_TARGET 0x1a2
|
||||
#define IA32_PERF_CTL 0x199
|
||||
#define IA32_THERM_INTERRUPT 0x19b
|
||||
#define IA32_ENERGY_PERFORMANCE_BIAS 0x1b0
|
||||
#define ENERGY_POLICY_PERFORMANCE 0
|
||||
#define ENERGY_POLICY_NORMAL 6
|
||||
#define ENERGY_POLICY_POWERSAVE 15
|
||||
#define IA32_PACKAGE_THERM_INTERRUPT 0x1b2
|
||||
#define MSR_LT_LOCK_MEMORY 0x2e7
|
||||
#define IA32_MC0_STATUS 0x401
|
||||
|
||||
#define MSR_PIC_MSG_CONTROL 0x2e
|
||||
#define MSR_PLATFORM_INFO 0xce
|
||||
#define PLATFORM_INFO_SET_TDP (1 << 29)
|
||||
|
||||
#define MSR_MISC_PWR_MGMT 0x1aa
|
||||
#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0)
|
||||
#define MSR_TURBO_RATIO_LIMIT 0x1ad
|
||||
#define MSR_POWER_CTL 0x1fc
|
||||
|
||||
#define MSR_PKGC3_IRTL 0x60a
|
||||
#define MSR_PKGC6_IRTL 0x60b
|
||||
#define MSR_PKGC7_IRTL 0x60c
|
||||
#define IRTL_VALID (1 << 15)
|
||||
#define IRTL_1_NS (0 << 10)
|
||||
#define IRTL_32_NS (1 << 10)
|
||||
#define IRTL_1024_NS (2 << 10)
|
||||
#define IRTL_32768_NS (3 << 10)
|
||||
#define IRTL_1048576_NS (4 << 10)
|
||||
#define IRTL_33554432_NS (5 << 10)
|
||||
#define IRTL_RESPONSE_MASK (0x3ff)
|
||||
|
||||
/* long duration in low dword, short duration in high dword */
|
||||
#define MSR_PKG_POWER_LIMIT 0x610
|
||||
#define PKG_POWER_LIMIT_MASK 0x7fff
|
||||
#define PKG_POWER_LIMIT_EN (1 << 15)
|
||||
#define PKG_POWER_LIMIT_CLAMP (1 << 16)
|
||||
#define PKG_POWER_LIMIT_TIME_SHIFT 17
|
||||
#define PKG_POWER_LIMIT_TIME_MASK 0x7f
|
||||
|
||||
#define MSR_PP0_CURRENT_CONFIG 0x601
|
||||
#define PP0_CURRENT_LIMIT (112 << 3) /* 112 A */
|
||||
#define MSR_PP1_CURRENT_CONFIG 0x602
|
||||
#define PP1_CURRENT_LIMIT_SNB (35 << 3) /* 35 A */
|
||||
#define PP1_CURRENT_LIMIT_IVB (50 << 3) /* 50 A */
|
||||
#define MSR_PKG_POWER_SKU_UNIT 0x606
|
||||
#define MSR_PKG_POWER_SKU 0x614
|
||||
#define MSR_PP0_POWER_LIMIT 0x638
|
||||
#define MSR_PP1_POWER_LIMIT 0x640
|
||||
|
||||
#define IVB_CONFIG_TDP_MIN_CPUID 0x306a2
|
||||
#define MSR_CONFIG_TDP_NOMINAL 0x648
|
||||
#define MSR_CONFIG_TDP_LEVEL1 0x649
|
||||
#define MSR_CONFIG_TDP_LEVEL2 0x64a
|
||||
#define MSR_CONFIG_TDP_CONTROL 0x64b
|
||||
#define MSR_TURBO_ACTIVATION_RATIO 0x64c
|
||||
|
||||
/* P-state configuration */
|
||||
#define PSS_MAX_ENTRIES 16
|
||||
#define PSS_RATIO_STEP 1
|
||||
#define PSS_LATENCY_TRANSITION 10
|
||||
#define PSS_LATENCY_BUSMASTER 10
|
||||
|
||||
#ifdef __SMM__
|
||||
/* Lock MSRs */
|
||||
void intel_model_2065x_finalize_smm(void);
|
||||
#else
|
||||
/* Configure power limits for turbo mode */
|
||||
void set_power_limits(u8 power_limit_1_time);
|
||||
int cpu_config_tdp_levels(void);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2007-2009 coresystems GmbH
|
||||
* Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; version 2 of
|
||||
* the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <string.h>
|
||||
#include <arch/acpi.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/x86/lapic.h>
|
||||
#include <cpu/intel/microcode.h>
|
||||
#include <cpu/intel/speedstep.h>
|
||||
#include <cpu/intel/turbo.h>
|
||||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/x86/name.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <usbdebug.h>
|
||||
#include "model_2065x.h"
|
||||
#include "chip.h"
|
||||
|
||||
/*
|
||||
* List of suported C-states in this processor
|
||||
*
|
||||
* Latencies are typical worst-case package exit time in uS
|
||||
* taken from the SandyBridge BIOS specification.
|
||||
*/
|
||||
static acpi_cstate_t cstate_map[] = {
|
||||
{ /* 0: C0 */
|
||||
},{ /* 1: C1 */
|
||||
.latency = 1,
|
||||
.power = 1000,
|
||||
.resource = {
|
||||
.addrl = 0x00, /* MWAIT State 0 */
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED,
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
|
||||
.resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
|
||||
}
|
||||
},
|
||||
{ /* 2: C1E */
|
||||
.latency = 1,
|
||||
.power = 1000,
|
||||
.resource = {
|
||||
.addrl = 0x01, /* MWAIT State 0 Sub-state 1 */
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED,
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
|
||||
.resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
|
||||
}
|
||||
},
|
||||
{ /* 3: C3 */
|
||||
.latency = 63,
|
||||
.power = 500,
|
||||
.resource = {
|
||||
.addrl = 0x10, /* MWAIT State 1 */
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED,
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
|
||||
.resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
|
||||
}
|
||||
},
|
||||
{ /* 4: C6 */
|
||||
.latency = 87,
|
||||
.power = 350,
|
||||
.resource = {
|
||||
.addrl = 0x20, /* MWAIT State 2 */
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED,
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
|
||||
.resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
|
||||
}
|
||||
},
|
||||
{ /* 5: C7 */
|
||||
.latency = 90,
|
||||
.power = 200,
|
||||
.resource = {
|
||||
.addrl = 0x30, /* MWAIT State 3 */
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED,
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
|
||||
.resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
|
||||
}
|
||||
},
|
||||
{ /* 6: C7S */
|
||||
.latency = 90,
|
||||
.power = 200,
|
||||
.resource = {
|
||||
.addrl = 0x31, /* MWAIT State 3 Sub-state 1 */
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED,
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL,
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT,
|
||||
.resv = ACPI_FFIXEDHW_FLAG_HW_COORD,
|
||||
}
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void enable_vmx(void)
|
||||
{
|
||||
struct cpuid_result regs;
|
||||
msr_t msr;
|
||||
int enable = CONFIG_ENABLE_VMX;
|
||||
|
||||
regs = cpuid(1);
|
||||
/* Check that the VMX is supported before reading or writing the MSR. */
|
||||
if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX)))
|
||||
return;
|
||||
|
||||
msr = rdmsr(IA32_FEATURE_CONTROL);
|
||||
|
||||
if (msr.lo & (1 << 0)) {
|
||||
printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__);
|
||||
/* VMX locked. If we set it again we get an illegal
|
||||
* instruction
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* The IA32_FEATURE_CONTROL MSR may initialize with random values.
|
||||
* It must be cleared regardless of VMX config setting.
|
||||
*/
|
||||
msr.hi = msr.lo = 0;
|
||||
|
||||
printk(BIOS_DEBUG, "%s VMX\n", enable ? "Enabling" : "Disabling");
|
||||
|
||||
/* Even though the Intel manual says you must set the lock bit in addition
|
||||
* to the VMX bit in order for VMX to work, it is incorrect. Thus we leave
|
||||
* it unlocked for the OS to manage things itself. This is good for a few
|
||||
* reasons:
|
||||
* - No need to reflash the bios just to toggle the lock bit.
|
||||
* - The VMX bits really really should match each other across cores, so
|
||||
* hard locking it on one while another has the opposite setting can
|
||||
* easily lead to crashes as code using VMX migrates between them.
|
||||
* - Vendors that want to "upsell" from a bios that disables+locks to
|
||||
* one that doesn't is sleazy.
|
||||
* By leaving this to the OS (e.g. Linux), people can do exactly what they
|
||||
* want on the fly, and do it correctly (e.g. across multiple cores).
|
||||
*/
|
||||
if (enable) {
|
||||
msr.lo |= (1 << 2);
|
||||
if (regs.ecx & CPUID_SMX)
|
||||
msr.lo |= (1 << 1);
|
||||
}
|
||||
|
||||
wrmsr(IA32_FEATURE_CONTROL, msr);
|
||||
}
|
||||
|
||||
/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
|
||||
static const u8 power_limit_time_sec_to_msr[] = {
|
||||
[0] = 0x00,
|
||||
[1] = 0x0a,
|
||||
[2] = 0x0b,
|
||||
[3] = 0x4b,
|
||||
[4] = 0x0c,
|
||||
[5] = 0x2c,
|
||||
[6] = 0x4c,
|
||||
[7] = 0x6c,
|
||||
[8] = 0x0d,
|
||||
[10] = 0x2d,
|
||||
[12] = 0x4d,
|
||||
[14] = 0x6d,
|
||||
[16] = 0x0e,
|
||||
[20] = 0x2e,
|
||||
[24] = 0x4e,
|
||||
[28] = 0x6e,
|
||||
[32] = 0x0f,
|
||||
[40] = 0x2f,
|
||||
[48] = 0x4f,
|
||||
[56] = 0x6f,
|
||||
[64] = 0x10,
|
||||
[80] = 0x30,
|
||||
[96] = 0x50,
|
||||
[112] = 0x70,
|
||||
[128] = 0x11,
|
||||
};
|
||||
|
||||
/* Convert POWER_LIMIT_1_TIME MSR value to seconds */
|
||||
static const u8 power_limit_time_msr_to_sec[] = {
|
||||
[0x00] = 0,
|
||||
[0x0a] = 1,
|
||||
[0x0b] = 2,
|
||||
[0x4b] = 3,
|
||||
[0x0c] = 4,
|
||||
[0x2c] = 5,
|
||||
[0x4c] = 6,
|
||||
[0x6c] = 7,
|
||||
[0x0d] = 8,
|
||||
[0x2d] = 10,
|
||||
[0x4d] = 12,
|
||||
[0x6d] = 14,
|
||||
[0x0e] = 16,
|
||||
[0x2e] = 20,
|
||||
[0x4e] = 24,
|
||||
[0x6e] = 28,
|
||||
[0x0f] = 32,
|
||||
[0x2f] = 40,
|
||||
[0x4f] = 48,
|
||||
[0x6f] = 56,
|
||||
[0x10] = 64,
|
||||
[0x30] = 80,
|
||||
[0x50] = 96,
|
||||
[0x70] = 112,
|
||||
[0x11] = 128,
|
||||
};
|
||||
|
||||
int cpu_config_tdp_levels(void)
|
||||
{
|
||||
msr_t platform_info;
|
||||
|
||||
/* Minimum CPU revision */
|
||||
if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
|
||||
return 0;
|
||||
|
||||
/* Bits 34:33 indicate how many levels supported */
|
||||
platform_info = rdmsr(MSR_PLATFORM_INFO);
|
||||
return (platform_info.hi >> 1) & 3;
|
||||
}
|
||||
|
||||
|
||||
static void configure_thermal_target(void)
|
||||
{
|
||||
struct cpu_intel_model_2065x_config *conf;
|
||||
device_t lapic;
|
||||
msr_t msr;
|
||||
|
||||
/* Find pointer to CPU configuration */
|
||||
lapic = dev_find_lapic(SPEEDSTEP_APIC_MAGIC);
|
||||
if (!lapic || !lapic->chip_info)
|
||||
return;
|
||||
conf = lapic->chip_info;
|
||||
|
||||
/* Set TCC activaiton offset if supported */
|
||||
msr = rdmsr(MSR_PLATFORM_INFO);
|
||||
if ((msr.lo & (1 << 30)) && conf->tcc_offset) {
|
||||
msr = rdmsr(MSR_TEMPERATURE_TARGET);
|
||||
msr.lo &= ~(0xf << 24); /* Bits 27:24 */
|
||||
msr.lo |= (conf->tcc_offset & 0xf) << 24;
|
||||
wrmsr(MSR_TEMPERATURE_TARGET, msr);
|
||||
}
|
||||
}
|
||||
|
||||
static void configure_misc(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
msr = rdmsr(IA32_MISC_ENABLE);
|
||||
msr.lo |= (1 << 0); /* Fast String enable */
|
||||
msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
|
||||
msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
|
||||
wrmsr(IA32_MISC_ENABLE, msr);
|
||||
|
||||
/* Disable Thermal interrupts */
|
||||
msr.lo = 0;
|
||||
msr.hi = 0;
|
||||
wrmsr(IA32_THERM_INTERRUPT, msr);
|
||||
|
||||
#ifdef DISABLED
|
||||
/* Enable package critical interrupt only */
|
||||
msr.lo = 1 << 4;
|
||||
msr.hi = 0;
|
||||
wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void enable_lapic_tpr(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
msr = rdmsr(MSR_PIC_MSG_CONTROL);
|
||||
msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
|
||||
wrmsr(MSR_PIC_MSG_CONTROL, msr);
|
||||
}
|
||||
|
||||
|
||||
static void set_max_ratio(void)
|
||||
{
|
||||
msr_t msr, perf_ctl;
|
||||
|
||||
perf_ctl.hi = 0;
|
||||
|
||||
/* Check for configurable TDP option */
|
||||
if (cpu_config_tdp_levels()) {
|
||||
/* Set to nominal TDP ratio */
|
||||
msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
|
||||
perf_ctl.lo = (msr.lo & 0xff) << 8;
|
||||
} else {
|
||||
/* Platform Info bits 15:8 give max ratio */
|
||||
msr = rdmsr(MSR_PLATFORM_INFO);
|
||||
perf_ctl.lo = msr.lo & 0xff00;
|
||||
}
|
||||
wrmsr(IA32_PERF_CTL, perf_ctl);
|
||||
|
||||
printk(BIOS_DEBUG, "model_x06ax: frequency set to %d\n",
|
||||
((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
|
||||
}
|
||||
|
||||
static void set_energy_perf_bias(u8 policy)
|
||||
{
|
||||
#ifdef DISABLED
|
||||
msr_t msr;
|
||||
|
||||
/* Energy Policy is bits 3:0 */
|
||||
msr = rdmsr(IA32_ENERGY_PERFORMANCE_BIAS);
|
||||
msr.lo &= ~0xf;
|
||||
msr.lo |= policy & 0xf;
|
||||
wrmsr(IA32_ENERGY_PERFORMANCE_BIAS, msr);
|
||||
|
||||
printk(BIOS_DEBUG, "model_x06ax: energy policy set to %u\n",
|
||||
policy);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void configure_mca(void)
|
||||
{
|
||||
msr_t msr;
|
||||
int i;
|
||||
|
||||
msr.lo = msr.hi = 0;
|
||||
/* This should only be done on a cold boot */
|
||||
for (i = 0; i < 7; i++)
|
||||
wrmsr(IA32_MC0_STATUS + (i * 4), msr);
|
||||
}
|
||||
|
||||
#if CONFIG_USBDEBUG
|
||||
static unsigned ehci_debug_addr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize any extra cores/threads in this package.
|
||||
*/
|
||||
static void intel_cores_init(device_t cpu)
|
||||
{
|
||||
struct cpuid_result result;
|
||||
unsigned threads_per_package, threads_per_core, i;
|
||||
|
||||
/* Logical processors (threads) per core */
|
||||
result = cpuid_ext(0xb, 0);
|
||||
threads_per_core = result.ebx & 0xffff;
|
||||
|
||||
/* Logical processors (threads) per package */
|
||||
result = cpuid_ext(0xb, 1);
|
||||
threads_per_package = result.ebx & 0xffff;
|
||||
|
||||
/* Only initialize extra cores from BSP */
|
||||
if (cpu->path.apic.apic_id)
|
||||
return;
|
||||
|
||||
printk(BIOS_DEBUG, "CPU: %u has %u cores, %u threads per core\n",
|
||||
cpu->path.apic.apic_id, threads_per_package/threads_per_core,
|
||||
threads_per_core);
|
||||
|
||||
for (i = 1; i < threads_per_package; ++i) {
|
||||
struct device_path cpu_path;
|
||||
device_t new;
|
||||
|
||||
/* Build the cpu device path */
|
||||
cpu_path.type = DEVICE_PATH_APIC;
|
||||
cpu_path.apic.apic_id =
|
||||
cpu->path.apic.apic_id + (i & 1) + ((i & 2) << 1);
|
||||
|
||||
/* Update APIC ID if no hyperthreading */
|
||||
if (threads_per_core == 1)
|
||||
cpu_path.apic.apic_id <<= 1;
|
||||
|
||||
/* Allocate the new cpu device structure */
|
||||
new = alloc_dev(cpu->bus, &cpu_path);
|
||||
if (!new)
|
||||
continue;
|
||||
|
||||
printk(BIOS_DEBUG, "CPU: %u has core %u\n",
|
||||
cpu->path.apic.apic_id,
|
||||
new->path.apic.apic_id);
|
||||
|
||||
#if CONFIG_SMP && CONFIG_MAX_CPUS > 1
|
||||
/* Start the new cpu */
|
||||
if (!start_cpu(new)) {
|
||||
/* Record the error in cpu? */
|
||||
printk(BIOS_ERR, "CPU %u would not start!\n",
|
||||
new->path.apic.apic_id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void model_2065x_init(device_t cpu)
|
||||
{
|
||||
char processor_name[49];
|
||||
struct cpuid_result cpuid_regs;
|
||||
|
||||
/* Turn on caching if we haven't already */
|
||||
x86_enable_cache();
|
||||
|
||||
intel_update_microcode_from_cbfs();
|
||||
|
||||
/* Clear out pending MCEs */
|
||||
configure_mca();
|
||||
|
||||
/* Print processor name */
|
||||
fill_processor_name(processor_name);
|
||||
printk(BIOS_INFO, "CPU: %s.\n", processor_name);
|
||||
printk(BIOS_INFO, "CPU:lapic=%ld, boot_cpu=%d\n", lapicid (), boot_cpu ());
|
||||
#if CONFIG_USBDEBUG
|
||||
// Is this caution really needed?
|
||||
if(!ehci_debug_addr)
|
||||
ehci_debug_addr = get_ehci_debug();
|
||||
set_ehci_debug(0);
|
||||
#endif
|
||||
|
||||
/* Setup MTRRs based on physical address size */
|
||||
cpuid_regs = cpuid(0x80000008);
|
||||
x86_setup_fixed_mtrrs();
|
||||
x86_setup_var_mtrrs(cpuid_regs.eax & 0xff, 2);
|
||||
x86_mtrr_check();
|
||||
|
||||
/* Setup Page Attribute Tables (PAT) */
|
||||
// TODO set up PAT
|
||||
|
||||
#if CONFIG_USBDEBUG
|
||||
set_ehci_debug(ehci_debug_addr);
|
||||
#endif
|
||||
|
||||
/* Enable the local cpu apics */
|
||||
enable_lapic_tpr();
|
||||
setup_lapic();
|
||||
|
||||
/* Enable virtualization if enabled in CMOS */
|
||||
enable_vmx();
|
||||
|
||||
/* Configure Enhanced SpeedStep and Thermal Sensors */
|
||||
configure_misc();
|
||||
|
||||
/* Thermal throttle activation offset */
|
||||
configure_thermal_target();
|
||||
|
||||
/* Set energy policy */
|
||||
set_energy_perf_bias(ENERGY_POLICY_NORMAL);
|
||||
|
||||
/* Set Max Ratio */
|
||||
set_max_ratio();
|
||||
|
||||
/* Enable Turbo */
|
||||
enable_turbo();
|
||||
|
||||
/* Start up extra cores */
|
||||
intel_cores_init(cpu);
|
||||
}
|
||||
|
||||
static struct device_operations cpu_dev_ops = {
|
||||
.init = model_2065x_init,
|
||||
};
|
||||
|
||||
static struct cpu_device_id cpu_table[] = {
|
||||
{ X86_VENDOR_INTEL, 0x20655 }, /* Intel Nehalem */
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
static const struct cpu_driver driver __cpu_driver = {
|
||||
.ops = &cpu_dev_ops,
|
||||
.id_table = cpu_table,
|
||||
.cstates = cstate_map,
|
||||
};
|
||||
|
Loading…
Reference in New Issue