summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/intel/common/common.h19
-rw-r--r--src/cpu/intel/common/common_init.c45
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);
+}