diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2008-06-09 18:04:27 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-10 15:52:21 +0200 |
commit | 09fd4b4ef5bc7e5222c13acec1bee8cd252fb63f (patch) | |
tree | f23eec885a8506c2f84987ac443db618fb58aa27 | |
parent | 732d7be17b98ebfd59e5864c3490f19856fa832c (diff) |
x86: use cpuid to check MWAIT support for C1
cpuid(0x05) provides extended information about MWAIT in EDX when bit
0 of ECX is set. Bit 4-7 of EDX determine whether MWAIT is supported
for C1. C1E enabled CPUs have these bits set to 0.
Based on an earlier patch from Andi Kleen.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/process.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index b3078f4ce25..fe415ba606e 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -122,19 +122,31 @@ static void poll_idle(void) * * idle=mwait overrides this decision and forces the usage of mwait. */ + +#define MWAIT_INFO 0x05 +#define MWAIT_ECX_EXTENDED_INFO 0x01 +#define MWAIT_EDX_C1 0xf0 + static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) { + u32 eax, ebx, ecx, edx; + if (force_mwait) return 1; - if (c->x86_vendor == X86_VENDOR_AMD) { - switch(c->x86) { - case 0x10: - case 0x11: - return 0; - } - } - return 1; + if (c->cpuid_level < MWAIT_INFO) + return 0; + + cpuid(MWAIT_INFO, &eax, &ebx, &ecx, &edx); + /* Check, whether EDX has extended info about MWAIT */ + if (!(ecx & MWAIT_ECX_EXTENDED_INFO)) + return 1; + + /* + * edx enumeratios MONITOR/MWAIT extensions. Check, whether + * C1 supports MWAIT + */ + return (edx & MWAIT_EDX_C1); } void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) |