changeset 10147:48b482c3a952

6861405 Solaris needs to callback to BIOS to take over system P-State management
author Mark Haywood <Mark.Haywood@Sun.COM>
date Tue, 21 Jul 2009 09:50:16 -0400
parents 226bcade3f94
children 11819ef37733
files usr/src/uts/i86pc/os/cpupm/cpupm_mach.c usr/src/uts/intel/ia32/ml/modstubs.s usr/src/uts/intel/io/acpica/osl.c usr/src/uts/intel/sys/acpica.h
diffstat 4 files changed, 30 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/i86pc/os/cpupm/cpupm_mach.c	Tue Jul 21 01:32:11 2009 -0700
+++ b/usr/src/uts/i86pc/os/cpupm/cpupm_mach.c	Tue Jul 21 09:50:16 2009 -0400
@@ -33,6 +33,8 @@
 #include <sys/spl.h>
 #include <sys/machsystm.h>
 #include <sys/hpet.h>
+#include <sys/acpi/acpi.h>
+#include <sys/acpica.h>
 #include <sys/cpupm.h>
 #include <sys/cpu_idle.h>
 #include <sys/cpu_acpi.h>
@@ -144,6 +146,7 @@
 	cpupm_vendor_t *vendors;
 	cpupm_mach_state_t *mach_state;
 	struct machcpu *mcpu = &(cp->cpu_m);
+	static boolean_t first = B_TRUE;
 	int *speeds;
 	uint_t nspeeds;
 	int ret;
@@ -160,6 +163,7 @@
 		    "unable to get ACPI handle", cp->cpu_id);
 		cmn_err(CE_NOTE, "!CPU power management will not function.");
 		CPUPM_DISABLE();
+		first = B_FALSE;
 		return;
 	}
 
@@ -179,6 +183,7 @@
 	if (vendors == NULL) {
 		cpupm_free(cp);
 		CPUPM_DISABLE();
+		first = B_FALSE;
 		return;
 	}
 
@@ -249,13 +254,21 @@
 	if (mach_state->ms_caps == CPUPM_NO_STATES) {
 		cpupm_free(cp);
 		CPUPM_DISABLE();
+		first = B_FALSE;
 		return;
 	}
 
 	if ((mach_state->ms_caps & CPUPM_T_STATES) ||
 	    (mach_state->ms_caps & CPUPM_P_STATES) ||
-	    (mach_state->ms_caps & CPUPM_C_STATES))
+	    (mach_state->ms_caps & CPUPM_C_STATES)) {
 		cpupm_add_notify_handler(cp, cpupm_event_notify_handler, cp);
+		if (first) {
+			acpica_write_cpupm_capabilities(
+			    mach_state->ms_caps & CPUPM_P_STATES,
+			    mach_state->ms_caps & CPUPM_C_STATES);
+		}
+	}
+	first = B_FALSE;
 #endif
 }
 
--- a/usr/src/uts/intel/ia32/ml/modstubs.s	Tue Jul 21 01:32:11 2009 -0700
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s	Tue Jul 21 09:50:16 2009 -0400
@@ -1339,6 +1339,8 @@
 	NO_UNLOAD_STUB(acpica, AcpiOsFree, nomod_minus_one) ;
 	NO_UNLOAD_STUB(acpica, acpica_get_handle_cpu, nomod_minus_one) ;
 	NO_UNLOAD_STUB(acpica, acpica_get_global_FADT, nomod_minus_one) ;
+	NO_UNLOAD_STUB(acpica, acpica_write_cpupm_capabilities,
+	    nomod_minus_one)		       ;
 	NO_UNLOAD_STUB(acpica, __acpi_wbinvd, nomod_minus_one) ;
 	END_MODULE(acpica);
 #endif
--- a/usr/src/uts/intel/io/acpica/osl.c	Tue Jul 21 01:32:11 2009 -0700
+++ b/usr/src/uts/intel/io/acpica/osl.c	Tue Jul 21 09:50:16 2009 -0400
@@ -46,6 +46,7 @@
 #include <sys/note.h>
 
 #include <sys/acpi/acpi.h>
+#include <sys/acpi/accommon.h>
 #include <sys/acpica.h>
 
 #define	MAX_DAT_FILE_SIZE	(64*1024)
@@ -2219,3 +2220,15 @@
 {
 	*gbl_FADT = &AcpiGbl_FADT;
 }
+
+void
+acpica_write_cpupm_capabilities(boolean_t pstates, boolean_t cstates)
+{
+	if (pstates && AcpiGbl_FADT.PstateControl != 0)
+		(void) AcpiHwRegisterWrite(ACPI_REGISTER_SMI_COMMAND_BLOCK,
+		    AcpiGbl_FADT.PstateControl);
+
+	if (cstates && AcpiGbl_FADT.CstControl != 0)
+		(void) AcpiHwRegisterWrite(ACPI_REGISTER_SMI_COMMAND_BLOCK,
+		    AcpiGbl_FADT.CstControl);
+}
--- a/usr/src/uts/intel/sys/acpica.h	Tue Jul 21 01:32:11 2009 -0700
+++ b/usr/src/uts/intel/sys/acpica.h	Tue Jul 21 09:50:16 2009 -0400
@@ -171,6 +171,7 @@
 extern void acpica_ddi_save_resources(dev_info_t *);
 extern void acpica_ddi_restore_resources(dev_info_t *);
 extern void acpica_get_global_FADT(ACPI_TABLE_FADT **);
+extern void acpica_write_cpupm_capabilities(boolean_t, boolean_t);
 
 extern ACPI_STATUS acpica_tag_devinfo(dev_info_t *, ACPI_HANDLE);
 extern ACPI_STATUS acpica_untag_devinfo(dev_info_t *, ACPI_HANDLE);