aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-09-14 05:33:15 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-14 08:09:13 -0400
commitaef93c8bd506a78983d91cd576a97fee6e934ac1 (patch)
treeecefbd11687673a0c5234450a421beef29adb214 /arch/x86/kernel/cpu
parente38e05a85828dac23540cd007df5f20985388afc (diff)
x86: identify_cpu_without_cpuid v2
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>
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r--arch/x86/kernel/cpu/common.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 9a57106c1995..f5f25b85be95 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -485,6 +485,33 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
485 c->x86_power = cpuid_edx(0x80000007); 485 c->x86_power = cpuid_edx(0x80000007);
486 486
487} 487}
488
489static void __cpuinit identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
490{
491#ifdef CONFIG_X86_32
492 int i;
493
494 /*
495 * First of all, decide if this is a 486 or higher
496 * It's a 486 if we can modify the AC flag
497 */
498 if (flag_is_changeable_p(X86_EFLAGS_AC))
499 c->x86 = 4;
500 else
501 c->x86 = 3;
502
503 for (i = 0; i < X86_VENDOR_NUM; i++)
504 if (cpu_devs[i] && cpu_devs[i]->c_identify) {
505 c->x86_vendor_id[0] = 0;
506 cpu_devs[i]->c_identify(c);
507 if (c->x86_vendor_id[0]) {
508 get_cpu_vendor(c);
509 break;
510 }
511 }
512#endif
513}
514
488/* 515/*
489 * Do minimum CPU detection early. 516 * Do minimum CPU detection early.
490 * Fields really needed: vendor, cpuid_level, family, model, mask, 517 * Fields really needed: vendor, cpuid_level, family, model, mask,
@@ -503,13 +530,16 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
503#endif 530#endif
504 c->x86_cache_alignment = c->x86_clflush_size; 531 c->x86_cache_alignment = c->x86_clflush_size;
505 532
506 if (!have_cpuid_p())
507 return;
508
509 memset(&c->x86_capability, 0, sizeof c->x86_capability); 533 memset(&c->x86_capability, 0, sizeof c->x86_capability);
510
511 c->extended_cpuid_level = 0; 534 c->extended_cpuid_level = 0;
512 535
536 if (!have_cpuid_p())
537 identify_cpu_without_cpuid(c);
538
539 /* cyrix could have cpuid enabled via c_identify()*/
540 if (!have_cpuid())
541 return;
542
513 cpu_detect(c); 543 cpu_detect(c);
514 544
515 get_cpu_vendor(c); 545 get_cpu_vendor(c);
@@ -583,10 +613,14 @@ static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
583 613
584static void __cpuinit generic_identify(struct cpuinfo_x86 *c) 614static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
585{ 615{
616 c->extended_cpuid_level = 0;
617
586 if (!have_cpuid_p()) 618 if (!have_cpuid_p())
587 return; 619 identify_cpu_without_cpuid(c);
588 620
589 c->extended_cpuid_level = 0; 621 /* cyrix could have cpuid enabled via c_identify()*/
622 if (!have_cpuid())
623 return;
590 624
591 cpu_detect(c); 625 cpu_detect(c);
592 626
@@ -639,17 +673,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
639 c->x86_cache_alignment = c->x86_clflush_size; 673 c->x86_cache_alignment = c->x86_clflush_size;
640 memset(&c->x86_capability, 0, sizeof c->x86_capability); 674 memset(&c->x86_capability, 0, sizeof c->x86_capability);
641 675
642 if (!have_cpuid_p()) {
643 /*
644 * First of all, decide if this is a 486 or higher
645 * It's a 486 if we can modify the AC flag
646 */
647 if (flag_is_changeable_p(X86_EFLAGS_AC))
648 c->x86 = 4;
649 else
650 c->x86 = 3;
651 }
652
653 generic_identify(c); 676 generic_identify(c);
654 677
655 if (this_cpu->c_identify) 678 if (this_cpu->c_identify)