]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
x86: identify_cpu_without_cpuid v2
authorYinghai Lu <yhlu.kernel@gmail.com>
Sun, 14 Sep 2008 09:33:15 +0000 (02:33 -0700)
committerIngo Molnar <mingo@elte.hu>
Sun, 14 Sep 2008 12:09:13 +0000 (14:09 +0200)
Krzysztof found some old cyrix cpu where an mtrr-alike cpu feature was
not detected properly.

this one is based on Krzysztof' patch, and we call ->c_identify() in
early_identify_cpu.

need to call c_identify() for cpus without cpuid even earlier ...

v2: Krzysztof point out need to give cyrix another chance about cpuid
    checking again, after ->c_identify() enables cpuid for it

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Cc: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/cpu/common.c

index 9a57106c199579dc6f338f50ef9dc0d6d2a97af2..f5f25b85be9520aa7b3ffb2769a97a3de851845a 100644 (file)
@@ -485,6 +485,33 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
                c->x86_power = cpuid_edx(0x80000007);
 
 }
+
+static void __cpuinit identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_X86_32
+       int i;
+
+       /*
+        * First of all, decide if this is a 486 or higher
+        * It's a 486 if we can modify the AC flag
+        */
+       if (flag_is_changeable_p(X86_EFLAGS_AC))
+               c->x86 = 4;
+       else
+               c->x86 = 3;
+
+       for (i = 0; i < X86_VENDOR_NUM; i++)
+               if (cpu_devs[i] && cpu_devs[i]->c_identify) {
+                       c->x86_vendor_id[0] = 0;
+                       cpu_devs[i]->c_identify(c);
+                       if (c->x86_vendor_id[0]) {
+                               get_cpu_vendor(c);
+                               break;
+                       }
+               }
+#endif
+}
+
 /*
  * Do minimum CPU detection early.
  * Fields really needed: vendor, cpuid_level, family, model, mask,
@@ -503,13 +530,16 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
 #endif
        c->x86_cache_alignment = c->x86_clflush_size;
 
-       if (!have_cpuid_p())
-               return;
-
        memset(&c->x86_capability, 0, sizeof c->x86_capability);
-
        c->extended_cpuid_level = 0;
 
+       if (!have_cpuid_p())
+               identify_cpu_without_cpuid(c);
+
+       /* cyrix could have cpuid enabled via c_identify()*/
+       if (!have_cpuid())
+               return;
+
        cpu_detect(c);
 
        get_cpu_vendor(c);
@@ -583,10 +613,14 @@ static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
 
 static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
 {
+       c->extended_cpuid_level = 0;
+
        if (!have_cpuid_p())
-               return;
+               identify_cpu_without_cpuid(c);
 
-       c->extended_cpuid_level = 0;
+       /* cyrix could have cpuid enabled via c_identify()*/
+       if (!have_cpuid())
+               return;
 
        cpu_detect(c);
 
@@ -639,17 +673,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
        c->x86_cache_alignment = c->x86_clflush_size;
        memset(&c->x86_capability, 0, sizeof c->x86_capability);
 
-       if (!have_cpuid_p()) {
-               /*
-                * First of all, decide if this is a 486 or higher
-                * It's a 486 if we can modify the AC flag
-                */
-               if (flag_is_changeable_p(X86_EFLAGS_AC))
-                       c->x86 = 4;
-               else
-                       c->x86 = 3;
-       }
-
        generic_identify(c);
 
        if (this_cpu->c_identify)