diff options
Diffstat (limited to 'src/cpu/intel/common')
-rw-r--r-- | src/cpu/intel/common/common.h | 19 | ||||
-rw-r--r-- | src/cpu/intel/common/common_init.c | 45 |
2 files changed, 63 insertions, 1 deletions
diff --git a/src/cpu/intel/common/common.h b/src/cpu/intel/common/common.h index ef0a5d9044..a29fd2e6b6 100644 --- a/src/cpu/intel/common/common.h +++ b/src/cpu/intel/common/common.h @@ -47,4 +47,23 @@ void configure_dca_cap(void); */ void set_energy_perf_bias(u8 policy); +/* + * Check energy performance preference and HWP capabilities from Thermal and + * Power Management Leaf CPUID. + */ +bool check_energy_perf_cap(void); + +/* + * Set the IA32_HWP_REQUEST Energy-Performance Preference bits on the logical + * thread. 0 is a hint to the HWP to prefer performance, and 255 is a hint to + * prefer energy efficiency. + */ +void set_energy_perf_pref(u8 pref); + +/* + * Instructs the CPU to use EPP hints. This means that any energy policies set + * up in `set_energy_perf_bias` will be ignored afterwards. + */ +void enable_energy_perf_pref(void); + #endif diff --git a/src/cpu/intel/common/common_init.c b/src/cpu/intel/common/common_init.c index 24e3eeb60b..4d6df845f7 100644 --- a/src/cpu/intel/common/common_init.c +++ b/src/cpu/intel/common/common_init.c @@ -5,9 +5,12 @@ #include <console/console.h> #include <cpu/intel/msr.h> #include <cpu/x86/msr.h> +#include <cpu/intel/turbo.h> #include "common.h" -#define CPUID_6_ECX_EPB (1 << 3) +#define CPUID_6_ECX_EPB (1 << 3) +#define CPUID_6_ENGERY_PERF_PREF (1 << 10) +#define CPUID_6_HWP (1 << 7) void set_vmx_and_lock(void) { @@ -182,3 +185,43 @@ void set_energy_perf_bias(u8 policy) msr_unset_and_set(IA32_ENERGY_PERF_BIAS, ENERGY_POLICY_MASK, epb); printk(BIOS_DEBUG, "cpu: energy policy set to %u\n", epb); } + +/* + * Check energy performance preference and HWP capabilities from Thermal and + * Power Management Leaf CPUID + */ +bool check_energy_perf_cap(void) +{ + const u32 cap = cpuid_eax(CPUID_LEAF_PM); + if (!(cap & CPUID_6_ENGERY_PERF_PREF)) + return false; + if (!(cap & CPUID_6_HWP)) + return false; + return true; +} + +/* + * Instructs the CPU to use EPP hints. This means that any energy policies set + * up in `set_energy_perf_bias` will be ignored afterwards. + */ +void enable_energy_perf_pref(void) +{ + msr_t msr = rdmsr(IA32_PM_ENABLE); + if (!(msr.lo & HWP_ENABLE)) { + /* Package-scoped MSR */ + printk(BIOS_DEBUG, "HWP_ENABLE: energy-perf preference in favor of energy-perf bias\n"); + msr_set(IA32_PM_ENABLE, HWP_ENABLE); + } +} + +/* + * Set the IA32_HWP_REQUEST Energy-Performance Preference bits on the logical + * thread. 0 is a hint to the HWP to prefer performance, and 255 is a hint to + * prefer energy efficiency. + * This function needs to be called when HWP_ENABLE is set. +*/ +void set_energy_perf_pref(u8 pref) +{ + msr_unset_and_set(IA32_HWP_REQUEST, IA32_HWP_REQUEST_EPP_MASK, + pref << IA32_HWP_REQUEST_EPP_SHIFT); +} |