changeset 10992:54a1c1cbd683

6887944 support for IA32_ENERGY_PERF_BIAS MSR
author aubrey.li@intel.com
date Fri, 06 Nov 2009 19:10:07 -0800
parents d59f9e6fc1f7
children 3801a6f1e78e
files usr/src/uts/i86pc/os/cpuid.c usr/src/uts/i86pc/os/cpupm/cpupm_intel.c usr/src/uts/intel/sys/x86_archext.h
diffstat 3 files changed, 89 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/i86pc/os/cpuid.c	Sat Nov 07 02:08:39 2009 +0100
+++ b/usr/src/uts/i86pc/os/cpuid.c	Fri Nov 06 19:10:07 2009 -0800
@@ -4145,6 +4145,33 @@
 	}
 }
 
+/*
+ * Check support for Intel ENERGY_PERF_BIAS feature
+ */
+int
+cpuid_iepb_supported(struct cpu *cp)
+{
+	struct cpuid_info *cpi = cp->cpu_m.mcpu_cpi;
+	struct cpuid_regs regs;
+
+	ASSERT(cpuid_checkpass(cp, 1));
+
+	if (!(x86_feature & X86_CPUID) || !(x86_feature & X86_MSR)) {
+		return (0);
+	}
+
+	/*
+	 * Intel ENERGY_PERF_BIAS MSR is indicated by
+	 * capability bit CPUID.6.ECX.3
+	 */
+	if ((cpi->cpi_vendor != X86_VENDOR_Intel) || (cpi->cpi_maxeax < 6))
+		return (0);
+
+	regs.cp_eax = 0x6;
+	(void) cpuid_insn(NULL, &regs);
+	return (regs.cp_ecx & CPUID_EPB_SUPPORT);
+}
+
 #if defined(__amd64) && !defined(__xpv)
 /*
  * Patch in versions of bcopy for high performance Intel Nhm processors
--- a/usr/src/uts/i86pc/os/cpupm/cpupm_intel.c	Sat Nov 07 02:08:39 2009 +0100
+++ b/usr/src/uts/i86pc/os/cpupm/cpupm_intel.c	Fri Nov 06 19:10:07 2009 -0800
@@ -24,6 +24,11 @@
  */
 
 /*
+ * Copyright (c) 2009, Intel Corporation.
+ * All rights reserved.
+ */
+
+/*
  * Intel specific CPU power management support.
  */
 
@@ -32,6 +37,7 @@
 #include <sys/speedstep.h>
 #include <sys/cpupm_throttle.h>
 #include <sys/cpu_idle.h>
+#include <sys/archsystm.h>
 
 /*
  * The Intel Processor Driver Capabilities (_PDC).
@@ -51,6 +57,31 @@
 
 static uint32_t cpupm_intel_pdccap = 0;
 
+/*
+ * MSR for Intel ENERGY_PERF_BIAS feature.
+ * The default processor power operation policy is max performance.
+ * Power control unit drives to max performance at any energy cost.
+ * This MSR is designed to be a power master control knob,
+ * it provides 4-bit OS input to the HW for the logical CPU, based on
+ * user power-policy preference(scale of 0 to 15). 0 is highest
+ * performance, 15 is minimal energy consumption.
+ * 7 is a good balance between performance and energy consumption.
+ */
+#define	IA32_ENERGY_PERF_BIAS_MSR	0x1B0
+#define	EPB_MSR_MASK			0xF
+#define	EPB_MAX_PERF			0
+#define	EPB_BALANCE			7
+#define	EPB_MAX_POWER_SAVE		15
+
+/*
+ * The value is used to initialize the user power policy preference
+ * in IA32_ENERGY_PERF_BIAS_MSR. Variable is used here to allow tuning
+ * from the /etc/system file.
+ */
+uint64_t cpupm_iepb_policy = EPB_MAX_PERF;
+
+static void cpupm_iepb_set_policy(uint64_t power_policy);
+
 boolean_t
 cpupm_intel_init(cpu_t *cp)
 {
@@ -105,5 +136,30 @@
 	(void) cpu_acpi_write_pdc(mach_state->ms_acpi_handle,
 	    CPUPM_INTEL_PDC_REVISION, 1, &cpupm_intel_pdccap);
 
+	/*
+	 * If Intel ENERGY PERFORMANCE BIAS feature is supported,
+	 * provides input to the HW, based on user power-policy.
+	 */
+	if (cpuid_iepb_supported(cp)) {
+		cpupm_iepb_set_policy(cpupm_iepb_policy);
+	}
+
 	return (B_TRUE);
 }
+
+/*
+ * ENERGY_PERF_BIAS setting,
+ * A hint to HW, based on user power-policy
+ */
+static void
+cpupm_iepb_set_policy(uint64_t iepb_policy)
+{
+	ulong_t		iflag;
+	uint64_t	epb_value;
+
+	epb_value = iepb_policy & EPB_MSR_MASK;
+
+	iflag = intr_clear();
+	wrmsr(IA32_ENERGY_PERF_BIAS_MSR, epb_value);
+	intr_restore(iflag);
+}
--- a/usr/src/uts/intel/sys/x86_archext.h	Sat Nov 07 02:08:39 2009 +0100
+++ b/usr/src/uts/intel/sys/x86_archext.h	Fri Nov 06 19:10:07 2009 -0800
@@ -383,6 +383,11 @@
 #define	CPUID_CSTATE_ARAT	(0x4)
 
 /*
+ * Intel ENERGY_PERF_BIAS MSR indicated by feature bit CPUID.6.ECX[3].
+ */
+#define	CPUID_EPB_SUPPORT	(1 << 3)
+
+/*
  * x86_type is a legacy concept; this is supplanted
  * for most purposes by x86_feature; modern CPUs
  * should be X86_TYPE_OTHER
@@ -657,6 +662,7 @@
 extern void cpuid_mwait_free(struct cpu *);
 extern int cpuid_deep_cstates_supported(void);
 extern int cpuid_arat_supported(void);
+extern int cpuid_iepb_supported(struct cpu *);
 extern int vmware_platform(void);
 #endif