Nicolas Provost has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/75995?usp=email )
Change subject: cpu/intel/turbo: rework of Intel Turbo Boost code ......................................................................
cpu/intel/turbo: rework of Intel Turbo Boost code
The CPUID(6) flag associated with the Turbo Boost mode is not a capability one, but is set to one once Turbo Boost has been enabled by clearing the bit 38 of msr IA32_MISC_ENABLE (see issue #439).
This patch also adds the CPU_INTEL_TURBO_DISABLE configuration option to disallow activation of the feature.
See the NOTE in cpu/intel/turbo/turbo.c for more details. This was tested on a Lenovo L420.
Change-Id: I1e9b51e52812600b36eba65eee5d6b5521ce2af2 Signed-off-by: Nicolas Provost dev@npsoft.fr --- M src/cpu/intel/turbo/Kconfig M src/cpu/intel/turbo/turbo.c 2 files changed, 37 insertions(+), 81 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/95/75995/1
diff --git a/src/cpu/intel/turbo/Kconfig b/src/cpu/intel/turbo/Kconfig index 5432c28..f631235 100644 --- a/src/cpu/intel/turbo/Kconfig +++ b/src/cpu/intel/turbo/Kconfig @@ -1,6 +1,14 @@ +config CPU_INTEL_TURBO_DISABLE + bool "Disallow activation of Intel Turbo Boost" + def_bool n + depends on CPU_INTEL_COMMON + help + If set, this option will disallow Turbo Boost to be enabled on + Intel cpus (if turbo mode is available).
config CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED def_bool n + depends on ! CPU_INTEL_TURBO_DISABLE help This option indicates that the turbo mode setting is not package scoped. i.e. enable_turbo() needs to be called on not just the bsp diff --git a/src/cpu/intel/turbo/turbo.c b/src/cpu/intel/turbo/turbo.c index 0b3b782..2698c70 100644 --- a/src/cpu/intel/turbo/turbo.c +++ b/src/cpu/intel/turbo/turbo.c @@ -5,82 +5,33 @@ #include <cpu/intel/turbo.h> #include <cpu/x86/msr.h>
-#if CONFIG(CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED) -static inline int get_global_turbo_state(void) -{ - return TURBO_UNKNOWN; -} - -static inline void set_global_turbo_state(int state) -{ -} -#else -static int g_turbo_state = TURBO_UNKNOWN; - -static inline int get_global_turbo_state(void) -{ - return g_turbo_state; -} - -static inline void set_global_turbo_state(int state) -{ - g_turbo_state = state; -} -#endif - -static const char *const turbo_state_desc[] = { - [TURBO_UNKNOWN] = "unknown", - [TURBO_UNAVAILABLE] = "unavailable", - [TURBO_DISABLED] = "available but hidden", - [TURBO_ENABLED] = "available and visible" -}; - -/* - * Try to update the global Turbo state. +/* NOTE: + * + * The CPUID(6) PM_CAP_TURBO_MODE bit is not a capability flag, but + * indicates that Turbo Mode has been enabled previously (Intel IA32 + * architecture Developer[s manual volume 3 14.3.2.2). + * + * There is no way to know if the cpu has support for Turbo Boost + * but has previously been disabled. Commonly, if turbo is supported, + * the associated bit in IA32_MISC_ENABLE msr (38) is 1 on startup, and + * then cleared to enable turbo. + * + * Furthermore, some cpus require to enable Turbo Mode on each core + * (config option CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED) whereas others + * need this only for the boot one (BSP). */ -static int update_turbo_state(void) -{ - struct cpuid_result cpuid_regs; - int turbo_en, turbo_cap; - msr_t msr; - int turbo_state = get_global_turbo_state(); - - cpuid_regs = cpuid(CPUID_LEAF_PM); - turbo_cap = !!(cpuid_regs.eax & PM_CAP_TURBO_MODE); - - msr = rdmsr(IA32_MISC_ENABLE); - turbo_en = !(msr.hi & H_MISC_DISABLE_TURBO); - - if (!turbo_cap && turbo_en) { - /* Unavailable */ - turbo_state = TURBO_UNAVAILABLE; - } else if (!turbo_cap && !turbo_en) { - /* Available but disabled */ - turbo_state = TURBO_DISABLED; - } else if (turbo_cap && turbo_en) { - /* Available */ - turbo_state = TURBO_ENABLED; - } - - set_global_turbo_state(turbo_state); - printk(BIOS_INFO, "Turbo is %s\n", turbo_state_desc[turbo_state]); - - return turbo_state; -}
/* - * Determine the current state of Turbo and cache it for later. Turbo is package - * level config so it does not need to be enabled on every core. + * Returns TURBO_ENABLED if Turbo Boost has been enabled, or + * TURBO_DISABLED. */ int get_turbo_state(void) { - int turbo_state = get_global_turbo_state(); + struct cpuid_result cpuid_regs;
- /* Return cached state if available */ - if (turbo_state == TURBO_UNKNOWN) - turbo_state = update_turbo_state(); - - return turbo_state; + cpuid_regs = cpuid(CPUID_LEAF_PM); + return (cpuid_regs.eax & PM_CAP_TURBO_MODE) ? + TURBO_ENABLED : TURBO_DISABLED; }
/* @@ -88,17 +39,17 @@ */ void enable_turbo(void) { + if (CONFIG(CPU_INTEL_TURBO_DISABLE)) + return; + msr_t msr;
- /* Only possible if turbo is available but hidden */ - if (get_turbo_state() == TURBO_DISABLED) { + msr = rdmsr(IA32_MISC_ENABLE); + if (msr.hi & H_MISC_DISABLE_TURBO) { /* Clear Turbo Disable bit in Misc Enables */ - msr = rdmsr(IA32_MISC_ENABLE); - msr.hi &= ~H_MISC_DISABLE_TURBO; + msr.hi &= ~ H_MISC_DISABLE_TURBO; wrmsr(IA32_MISC_ENABLE, msr); - - /* Update cached turbo state */ - update_turbo_state(); + printk(BIOS_INFO, "Turbo Boost is enabled\n"); } }
@@ -109,14 +60,11 @@ { msr_t msr;
- /* Only possible if turbo is available and visible */ - if (get_turbo_state() == TURBO_ENABLED) { + if (get_turbo_state () == TURBO_ENABLED) { /* Set Turbo Disable bit in Misc Enables */ msr = rdmsr(IA32_MISC_ENABLE); msr.hi |= H_MISC_DISABLE_TURBO; wrmsr(IA32_MISC_ENABLE, msr); - - /* Update cached turbo state */ - update_turbo_state(); + printk(BIOS_INFO, "Turbo Boost is disabled\n"); } }