aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/x86/cpu/mwait-idle.c106
-rw-r--r--xen/include/asm-x86/mwait.h1
2 files changed, 50 insertions, 57 deletions
diff --git a/xen/arch/x86/cpu/mwait-idle.c b/xen/arch/x86/cpu/mwait-idle.c
index e0c97079be..ccfa750908 100644
--- a/xen/arch/x86/cpu/mwait-idle.c
+++ b/xen/arch/x86/cpu/mwait-idle.c
@@ -116,146 +116,146 @@ static const struct cpuidle_state {
*/
#define flg2MWAIT(flags) (((flags) >> 24) & 0xFF)
#define MWAIT2flg(eax) ((eax & 0xFF) << 24)
+#define MWAIT_HINT2CSTATE(hint) (((hint) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK)
+#define MWAIT_HINT2SUBSTATE(hint) ((hint) & MWAIT_CSTATE_MASK)
/*
* States are indexed by the cstate number,
* which is also the index into the MWAIT hint array.
* Thus C0 is a dummy.
*/
-static const struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
- { /* MWAIT C0 */ },
- { /* MWAIT C1 */
+static const struct cpuidle_state nehalem_cstates[] = {
+ {
.name = "C1-NHM",
.flags = MWAIT2flg(0x00),
.exit_latency = 3,
.target_residency = 6,
},
- { /* MWAIT C2 */
+ {
.name = "C3-NHM",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 20,
.target_residency = 80,
},
- { /* MWAIT C3 */
+ {
.name = "C6-NHM",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 200,
.target_residency = 800,
- }
+ },
+ {}
};
-static const struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
- { /* MWAIT C0 */ },
- { /* MWAIT C1 */
+static const struct cpuidle_state snb_cstates[] = {
+ {
.name = "C1-SNB",
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
},
- { /* MWAIT C2 */
+ {
.name = "C3-SNB",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 80,
.target_residency = 211,
},
- { /* MWAIT C3 */
+ {
.name = "C6-SNB",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 104,
.target_residency = 345,
},
- { /* MWAIT C4 */
+ {
.name = "C7-SNB",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 109,
.target_residency = 345,
- }
+ },
+ {}
};
-static const struct cpuidle_state ivb_cstates[MWAIT_MAX_NUM_CSTATES] = {
- { /* MWAIT C0 */ },
- { /* MWAIT C1 */
+static const struct cpuidle_state ivb_cstates[] = {
+ {
.name = "C1-IVB",
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 1,
},
- { /* MWAIT C2 */
+ {
.name = "C3-IVB",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 59,
.target_residency = 156,
},
- { /* MWAIT C3 */
+ {
.name = "C6-IVB",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 80,
.target_residency = 300,
},
- { /* MWAIT C4 */
+ {
.name = "C7-IVB",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 87,
.target_residency = 300,
- }
+ },
+ {}
};
-static const struct cpuidle_state hsw_cstates[MWAIT_MAX_NUM_CSTATES] = {
- { /* MWAIT C0 */ },
- { /* MWAIT C1 */
+static const struct cpuidle_state hsw_cstates[] = {
+ {
.name = "C1-HSW",
.flags = MWAIT2flg(0x00),
.exit_latency = 2,
.target_residency = 2,
},
- { /* MWAIT C2 */
+ {
.name = "C3-HSW",
.flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 33,
.target_residency = 100,
},
- { /* MWAIT C3 */
+ {
.name = "C6-HSW",
.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 133,
.target_residency = 400,
},
- { /* MWAIT C4 */
+ {
.name = "C7s-HSW",
.flags = MWAIT2flg(0x32) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 166,
.target_residency = 500,
},
+ {}
};
-static const struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
- { /* MWAIT C0 */ },
- { /* MWAIT C1 */
+static const struct cpuidle_state atom_cstates[] = {
+ {
.name = "C1-ATM",
.flags = MWAIT2flg(0x00),
.exit_latency = 1,
.target_residency = 4,
},
- { /* MWAIT C2 */
+ {
.name = "C2-ATM",
.flags = MWAIT2flg(0x10),
.exit_latency = 20,
.target_residency = 80,
},
- { /* MWAIT C3 */ },
- { /* MWAIT C4 */
+ {
.name = "C4-ATM",
.flags = MWAIT2flg(0x30) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 100,
.target_residency = 400,
},
- { /* MWAIT C5 */ },
- { /* MWAIT C6 */
+ {
.name = "C6-ATM",
.flags = MWAIT2flg(0x52) | CPUIDLE_FLAG_TLB_FLUSHED,
.exit_latency = 140,
.target_residency = 560,
- }
+ },
+ {}
};
static void mwait_idle(void)
@@ -476,29 +476,25 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb,
dev->count = 1;
- for (cstate = 1; cstate < MWAIT_MAX_NUM_CSTATES; ++cstate) {
- unsigned int num_substates;
+ for (cstate = 0; cpuidle_state_table[cstate].target_residency; ++cstate) {
+ unsigned int num_substates, hint, state, substate;
struct acpi_processor_cx *cx;
- if (cstate > max_cstate) {
+ hint = flg2MWAIT(cpuidle_state_table[cstate].flags);
+ state = MWAIT_HINT2CSTATE(hint) + 1;
+ substate = MWAIT_HINT2SUBSTATE(hint);
+
+ if (state > max_cstate) {
printk(PREFIX "max C-state %u reached\n", max_cstate);
break;
}
/* Does the state exist in CPUID.MWAIT? */
- num_substates = (mwait_substates >> (cstate * 4))
- & MWAIT_SUBSTATE_MASK;
- if (!num_substates)
- continue;
- /* Is the state not enabled? */
- if (!cpuidle_state_table[cstate].target_residency) {
- /* does the driver not know about the state? */
- if (!pm_idle_save && !*cpuidle_state_table[cstate].name)
- pr_debug(PREFIX "unaware of family %#x model %#x MWAIT %u\n",
- boot_cpu_data.x86,
- boot_cpu_data.x86_model, cstate);
+ num_substates = (mwait_substates >> (state * 4))
+ & MWAIT_SUBSTATE_MASK;
+ /* if sub-state in table is not enumerated by CPUID */
+ if (substate >= num_substates)
continue;
- }
if (dev->count >= ACPI_PROCESSOR_MAX_POWER) {
printk(PREFIX "max C-state count of %u reached\n",
@@ -506,15 +502,13 @@ static int mwait_idle_cpu_init(struct notifier_block *nfb,
break;
}
- if (cstate > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) {
- if (pm_idle_save)
- continue;
+ if (state > 2 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC) &&
+ !pm_idle_save)
setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE);
- }
cx = dev->states + dev->count;
- cx->type = cstate;
- cx->address = flg2MWAIT(cpuidle_state_table[cstate].flags);
+ cx->type = state;
+ cx->address = hint;
cx->entry_method = ACPI_CSTATE_EM_FFH;
cx->latency = cpuidle_state_table[cstate].exit_latency;
cx->target_residency =
diff --git a/xen/include/asm-x86/mwait.h b/xen/include/asm-x86/mwait.h
index 3ad3d9ca1d..ba9c0ea096 100644
--- a/xen/include/asm-x86/mwait.h
+++ b/xen/include/asm-x86/mwait.h
@@ -4,7 +4,6 @@
#define MWAIT_SUBSTATE_MASK 0xf
#define MWAIT_CSTATE_MASK 0xf
#define MWAIT_SUBSTATE_SIZE 4
-#define MWAIT_MAX_NUM_CSTATES 8
#define CPUID_MWAIT_LEAF 5
#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1