Matt Delco has uploaded this change for review. ( https://review.coreboot.org/27611
Change subject: soc/intel: set turbo mode on all processors ......................................................................
soc/intel: set turbo mode on all processors
The diagnostic test suite at biosbits.org complains that coreboot only sets up turbo mode on the first (i.e., 0th) processor. This change has the same speed set on all processors.
The function that returns the turbo speed ratio is always returning the value for 1 core, which I'm not sure is another oversight or was done intentionally because turbo mode is only being set on the first processor.
This change enables turbo mode on all processors (the test suite is now happy), though we're also now setting a slightly lower turbo mode ration (at least for the skylakes I'm using, where there's a higher value for 1-core but 2-4 cores all have the same [but slightly lower] value).
I'm not sure what's the lesser evil, though practically speaking it may not matter much either way since the OS that's booted is likely to just set its own parameters (or make these moot, e.g., by writing 1 to MSR 0x770 to enable Speed Shift).
Change-Id: Ib9b9989fdcb211f2a6a03cf60a7037cdbd028a7f Signed-off-by: Matt Delco delco@chromium.org --- M src/soc/intel/common/block/cpu/cpulib.c M src/soc/intel/common/block/include/intelblocks/cpulib.h M src/soc/intel/skylake/cpu.c 3 files changed, 54 insertions(+), 17 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/11/27611/1
diff --git a/src/soc/intel/common/block/cpu/cpulib.c b/src/soc/intel/common/block/cpu/cpulib.c index 112a049..b7ef990 100644 --- a/src/soc/intel/common/block/cpu/cpulib.c +++ b/src/soc/intel/common/block/cpu/cpulib.c @@ -75,24 +75,11 @@ return (platform_info.hi >> 1) & 3; }
-/* - * TURBO_RATIO_LIMIT MSR (0x1AD) Bits 31:0 indicates the - * factory configured values for of 1-core, 2-core, 3-core - * and 4-core turbo ratio limits for all processors. - * - * 7:0 - MAX_TURBO_1_CORE - * 15:8 - MAX_TURBO_2_CORES - * 23:16 - MAX_TURBO_3_CORES - * 31:24 - MAX_TURBO_4_CORES - * - * Set PERF_CTL MSR (0x199) P_Req (14:8 bits) with that value. - */ void cpu_set_p_state_to_turbo_ratio(void) { - msr_t msr, perf_ctl; + msr_t perf_ctl;
- msr = rdmsr(MSR_TURBO_RATIO_LIMIT); - perf_ctl.lo = (msr.lo & 0xff) << 8; + perf_ctl.lo = cpu_get_max_turbo_ratio() << 8; perf_ctl.hi = 0;
wrmsr(MSR_IA32_PERF_CTL, perf_ctl); @@ -290,11 +277,51 @@ return (msr.lo & 0x7fff) * 1000 / power_unit; }
+uint32_t cpu_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; +} + +/* + * TURBO_RATIO_LIMIT MSR (0x1AD) Bits 31:0 indicates the + * factory configured values for of 1-core, 2-core, 3-core + * and 4-core turbo ratio limits for all processors. + * + * 7:0 - MAX_TURBO_1_CORE + * 15:8 - MAX_TURBO_2_CORES + * 23:16 - MAX_TURBO_3_CORES + * 31:24 - MAX_TURBO_4_CORES + * + */ uint32_t cpu_get_max_turbo_ratio(void) { + uint32_t cores_per_package = cpu_get_cores_per_package(); msr_t msr; + + /* + * Some chip architectures have more than 4 cores and + * thus can have more than 32-bits set in the MSR. + * For now the cores are capped at 4 to avoid adding + * architecture-specific validation/checks. Using the + * 4th element is still better than the prior + * functionality that only used the 1-core setting. + */ + if (cores_per_package > 4) + cores_per_package = 4; + msr = rdmsr(MSR_TURBO_RATIO_LIMIT); - return msr.lo & 0xff; + return (msr.lo >> (8 * (cores_per_package - 1))) & 0xff; }
void mca_configure(void *unused) diff --git a/src/soc/intel/common/block/include/intelblocks/cpulib.h b/src/soc/intel/common/block/include/intelblocks/cpulib.h index 88f04b4..b17515c 100644 --- a/src/soc/intel/common/block/include/intelblocks/cpulib.h +++ b/src/soc/intel/common/block/include/intelblocks/cpulib.h @@ -151,6 +151,11 @@ uint32_t cpu_get_power_max(void);
/* + * cpu_get_cores_per_package returns number of cores per package + */ +uint32_t cpu_get_cores_per_package(void); + +/* * cpu_get_max_turbo_ratio returns the maximum turbo ratio limit for the * processor */ diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 5535ec6..1c9f064 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -462,10 +462,15 @@ smm_relocate(); }
+static void per_cpu_set_max_ratio(void *unused) +{ + cpu_set_max_ratio(); +} + static void post_mp_init(void) { /* Set Max Ratio */ - cpu_set_max_ratio(); + mp_run_on_all_cpus(per_cpu_set_max_ratio, NULL, 2 * USECS_PER_MSEC);
/* * Now that all APs have been relocated as well as the BSP let SMIs