summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorBill Holler <Bill.Holler@Sun.COM>2009-09-02 15:36:26 -0700
committerBill Holler <Bill.Holler@Sun.COM>2009-09-02 15:36:26 -0700
commit56b56c0dc63eac41299ada6dcb890406f9063b1c (patch)
tree6255ebe02c44bc3516d3d03c54e55f86e397fc76 /usr/src
parent4fd5d0674a83e10428a10ee35d37170e08cda101 (diff)
downloadillumos-joyent-56b56c0dc63eac41299ada6dcb890406f9063b1c.tar.gz
6872740 deeper c-state residency greatly hampered by legacy code on some platforms
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/os/cpupm/cpu_acpi.c1
-rw-r--r--usr/src/uts/i86pc/os/cpupm/cpu_idle.c85
-rw-r--r--usr/src/uts/i86pc/sys/cpu_acpi.h2
3 files changed, 21 insertions, 67 deletions
diff --git a/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c b/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c
index 4a9a9e9dd7..381973d7cc 100644
--- a/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c
+++ b/usr/src/uts/i86pc/os/cpupm/cpu_acpi.c
@@ -734,7 +734,6 @@ cpu_acpi_cache_cst(cpu_acpi_handle_t handle)
CPU_ACPI_CSTATES_COUNT(handle) = (uint32_t)cnt;
alloc_size = CPU_ACPI_CSTATES_SIZE(cnt);
CPU_ACPI_CSTATES(handle) = kmem_zalloc(alloc_size, KM_SLEEP);
- CPU_ACPI_BM_INFO(handle) = 0;
cstate = (cpu_acpi_cstate_t *)CPU_ACPI_CSTATES(handle);
p = cstate;
diff --git a/usr/src/uts/i86pc/os/cpupm/cpu_idle.c b/usr/src/uts/i86pc/os/cpupm/cpu_idle.c
index 81a0904b01..524f0c8c6f 100644
--- a/usr/src/uts/i86pc/os/cpupm/cpu_idle.c
+++ b/usr/src/uts/i86pc/os/cpupm/cpu_idle.c
@@ -543,22 +543,6 @@ acpi_cpu_cstate(cpu_acpi_cstate_t *cstate)
}
/*
- * indicate when bus masters are active
- */
-static uint32_t
-cpu_acpi_bm_sts(void)
-{
- uint32_t bm_sts = 0;
-
- cpu_acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_sts);
-
- if (bm_sts)
- cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
-
- return (bm_sts);
-}
-
-/*
* Idle the present CPU, deep c-state is supported
*/
void
@@ -593,32 +577,8 @@ cpu_acpi_idle(void)
cs_indx = cpupm_next_cstate(cs_data, cstates, cpu_max_cstates, start);
- /*
- * OSPM uses the BM_STS bit to determine the power state to enter
- * when considering a transition to or from the C2/C3 power state.
- * if C3 is determined, bus master activity demotes the power state
- * to C2.
- */
- if ((cstates[cs_indx].cs_type >= CPU_ACPI_C3) && cpu_acpi_bm_sts())
- --cs_indx;
cs_type = cstates[cs_indx].cs_type;
- /*
- * BM_RLD determines if the Cx power state was exited as a result of
- * bus master requests. Set this bit when using a C3 power state, and
- * clear it when using a C1 or C2 power state.
- */
- if ((CPU_ACPI_BM_INFO(handle) & BM_RLD) && (cs_type < CPU_ACPI_C3)) {
- cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- CPU_ACPI_BM_INFO(handle) &= ~BM_RLD;
- }
-
- if ((!(CPU_ACPI_BM_INFO(handle) & BM_RLD)) &&
- (cs_type >= CPU_ACPI_C3)) {
- cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
- CPU_ACPI_BM_INFO(handle) |= BM_RLD;
- }
-
switch (cs_type) {
default:
/* FALLTHROUGH */
@@ -632,24 +592,16 @@ cpu_acpi_idle(void)
case CPU_ACPI_C3:
/*
- * recommended in ACPI spec, providing hardware mechanisms
- * to prevent master from writing to memory (UP-only)
- */
- if ((ncpus_online == 1) &&
- (CPU_ACPI_BM_INFO(handle) & BM_CTL)) {
- cpu_acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
- CPU_ACPI_BM_INFO(handle) |= BM_ARB_DIS;
- /*
- * Today all Intel's processor support C3 share cache.
+ * All supported Intel processors maintain cache coherency
+ * during C3. Currently when entering C3 processors flush
+ * core caches to higher level shared cache. The shared cache
+ * maintains state and supports probes during C3.
+ * Consequently there is no need to handle cache coherency
+ * and Bus Master activity here with the cache flush, BM_RLD
+ * bit, BM_STS bit, nor PM2_CNT.ARB_DIS mechanisms described
+ * in section 8.1.4 of the ACPI Specification 4.0.
*/
- } else if (x86_vendor != X86_VENDOR_Intel) {
- __acpi_wbinvd();
- }
acpi_cpu_cstate(&cstates[cs_indx]);
- if (CPU_ACPI_BM_INFO(handle) & BM_ARB_DIS) {
- cpu_acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
- CPU_ACPI_BM_INFO(handle) &= ~BM_ARB_DIS;
- }
break;
}
@@ -699,7 +651,6 @@ cpu_idle_init(cpu_t *cp)
cpu_acpi_cstate_t *cstate;
char name[KSTAT_STRLEN];
int cpu_max_cstates, i;
- ACPI_TABLE_FADT *gbl_FADT;
int ret;
/*
@@ -715,13 +666,6 @@ cpu_idle_init(cpu_t *cp)
return (-1);
}
- /*
- * Check the bus master arbitration control ability.
- */
- acpica_get_global_FADT(&gbl_FADT);
- if (gbl_FADT->Pm2ControlBlock && gbl_FADT->Pm2ControlLength)
- CPU_ACPI_BM_INFO(handle) |= BM_CTL;
-
cstate = (cpu_acpi_cstate_t *)CPU_ACPI_CSTATES(handle);
cpu_max_cstates = cpu_acpi_get_max_cstates(handle);
@@ -754,6 +698,8 @@ cpu_idle_init(cpu_t *cp)
cpupm_alloc_ms_cstate(cp);
if (cpu_deep_cstates_supported()) {
+ uint32_t value;
+
mutex_enter(&cpu_idle_callb_mutex);
if (cpu_deep_idle_callb_id == (callb_id_t)0)
cpu_deep_idle_callb_id = callb_add(&cpu_deep_idle_callb,
@@ -762,6 +708,17 @@ cpu_idle_init(cpu_t *cp)
cpu_idle_cpr_callb_id = callb_add(&cpu_idle_cpr_callb,
(void *)NULL, CB_CL_CPR_PM, "cpu_idle_cpr");
mutex_exit(&cpu_idle_callb_mutex);
+
+
+ /*
+ * All supported CPUs (Nehalem and later) will remain in C3
+ * during Bus Master activity.
+ * All CPUs set ACPI_BITREG_BUS_MASTER_RLD to 0 here if it
+ * is not already 0 before enabling Deeper C-states.
+ */
+ cpu_acpi_get_register(ACPI_BITREG_BUS_MASTER_RLD, &value);
+ if (value & 1)
+ cpu_acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
}
return (0);
diff --git a/usr/src/uts/i86pc/sys/cpu_acpi.h b/usr/src/uts/i86pc/sys/cpu_acpi.h
index 6a5de8edf6..c558b9d9a8 100644
--- a/usr/src/uts/i86pc/sys/cpu_acpi.h
+++ b/usr/src/uts/i86pc/sys/cpu_acpi.h
@@ -71,7 +71,6 @@ extern "C" {
* C-state realted macros
*/
#define CPU_ACPI_CSD(sp) sp->cs_csd
-#define CPU_ACPI_BM_INFO(sp) sp->bm_info
#define CPU_ACPI_CSTATES(sp) sp->cs_cstates.ss_states
#define CPU_ACPI_CSTATES_COUNT(sp) sp->cs_cstates.ss_count
@@ -205,7 +204,6 @@ typedef struct cpu_acpi_state {
cpu_acpi_tpc_t cs_tpc;
cpu_acpi_cstates_t cs_cstates;
cpu_acpi_csd_t cs_csd;
- uint_t bm_info;
} cpu_acpi_state_t;
typedef cpu_acpi_state_t *cpu_acpi_handle_t;