diff options
Diffstat (limited to 'arch/x86/kernel/apic.c')
-rw-r--r-- | arch/x86/kernel/apic.c | 386 |
1 files changed, 210 insertions, 176 deletions
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 04a7f960bbc0..cf2ca19e62da 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Local APIC handling, local APIC timers | 2 | * Local APIC handling, local APIC timers |
3 | * | 3 | * |
4 | * (c) 1999, 2000 Ingo Molnar <mingo@redhat.com> | 4 | * (c) 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com> |
5 | * | 5 | * |
6 | * Fixes | 6 | * Fixes |
7 | * Maciej W. Rozycki : Bits for genuine 82489DX APICs; | 7 | * Maciej W. Rozycki : Bits for genuine 82489DX APICs; |
@@ -14,49 +14,71 @@ | |||
14 | * Mikael Pettersson : PM converted to driver model. | 14 | * Mikael Pettersson : PM converted to driver model. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/init.h> | ||
18 | |||
19 | #include <linux/mm.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/bootmem.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/mc146818rtc.h> | ||
24 | #include <linux/kernel_stat.h> | 17 | #include <linux/kernel_stat.h> |
25 | #include <linux/sysdev.h> | 18 | #include <linux/mc146818rtc.h> |
26 | #include <linux/ioport.h> | ||
27 | #include <linux/cpu.h> | ||
28 | #include <linux/clockchips.h> | ||
29 | #include <linux/acpi_pmtmr.h> | 19 | #include <linux/acpi_pmtmr.h> |
20 | #include <linux/clockchips.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/bootmem.h> | ||
23 | #include <linux/ftrace.h> | ||
24 | #include <linux/ioport.h> | ||
30 | #include <linux/module.h> | 25 | #include <linux/module.h> |
31 | #include <linux/dmi.h> | 26 | #include <linux/sysdev.h> |
27 | #include <linux/delay.h> | ||
28 | #include <linux/timex.h> | ||
32 | #include <linux/dmar.h> | 29 | #include <linux/dmar.h> |
30 | #include <linux/init.h> | ||
31 | #include <linux/cpu.h> | ||
32 | #include <linux/dmi.h> | ||
33 | #include <linux/nmi.h> | ||
34 | #include <linux/smp.h> | ||
35 | #include <linux/mm.h> | ||
33 | 36 | ||
34 | #include <asm/atomic.h> | ||
35 | #include <asm/smp.h> | ||
36 | #include <asm/mtrr.h> | ||
37 | #include <asm/mpspec.h> | ||
38 | #include <asm/desc.h> | ||
39 | #include <asm/arch_hooks.h> | 37 | #include <asm/arch_hooks.h> |
40 | #include <asm/hpet.h> | ||
41 | #include <asm/pgalloc.h> | 38 | #include <asm/pgalloc.h> |
39 | #include <asm/genapic.h> | ||
40 | #include <asm/atomic.h> | ||
41 | #include <asm/mpspec.h> | ||
42 | #include <asm/i8253.h> | 42 | #include <asm/i8253.h> |
43 | #include <asm/nmi.h> | 43 | #include <asm/i8259.h> |
44 | #include <asm/idle.h> | ||
45 | #include <asm/proto.h> | 44 | #include <asm/proto.h> |
46 | #include <asm/timex.h> | ||
47 | #include <asm/apic.h> | 45 | #include <asm/apic.h> |
48 | #include <asm/i8259.h> | 46 | #include <asm/desc.h> |
47 | #include <asm/hpet.h> | ||
48 | #include <asm/idle.h> | ||
49 | #include <asm/mtrr.h> | ||
50 | #include <asm/smp.h> | ||
51 | |||
52 | unsigned int num_processors; | ||
53 | |||
54 | unsigned disabled_cpus __cpuinitdata; | ||
55 | |||
56 | /* Processor that is doing the boot up */ | ||
57 | unsigned int boot_cpu_physical_apicid = -1U; | ||
49 | 58 | ||
50 | #include <mach_apic.h> | 59 | /* |
51 | #include <mach_apicdef.h> | 60 | * The highest APIC ID seen during enumeration. |
52 | #include <mach_ipi.h> | 61 | * |
62 | * This determines the messaging protocol we can use: if all APIC IDs | ||
63 | * are in the 0 ... 7 range, then we can use logical addressing which | ||
64 | * has some performance advantages (better broadcasting). | ||
65 | * | ||
66 | * If there's an APIC ID above 8, we use physical addressing. | ||
67 | */ | ||
68 | unsigned int max_physical_apicid; | ||
53 | 69 | ||
54 | /* | 70 | /* |
55 | * Sanity check | 71 | * Bitmask of physically existing CPUs: |
56 | */ | 72 | */ |
57 | #if ((SPURIOUS_APIC_VECTOR & 0x0F) != 0x0F) | 73 | physid_mask_t phys_cpu_present_map; |
58 | # error SPURIOUS_APIC_VECTOR definition error | 74 | |
59 | #endif | 75 | /* |
76 | * Map cpu index to physical APIC ID | ||
77 | */ | ||
78 | DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID); | ||
79 | DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID); | ||
80 | EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid); | ||
81 | EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); | ||
60 | 82 | ||
61 | #ifdef CONFIG_X86_32 | 83 | #ifdef CONFIG_X86_32 |
62 | /* | 84 | /* |
@@ -97,8 +119,8 @@ __setup("apicpmtimer", setup_apicpmtimer); | |||
97 | #ifdef HAVE_X2APIC | 119 | #ifdef HAVE_X2APIC |
98 | int x2apic; | 120 | int x2apic; |
99 | /* x2apic enabled before OS handover */ | 121 | /* x2apic enabled before OS handover */ |
100 | int x2apic_preenabled; | 122 | static int x2apic_preenabled; |
101 | int disable_x2apic; | 123 | static int disable_x2apic; |
102 | static __init int setup_nox2apic(char *str) | 124 | static __init int setup_nox2apic(char *str) |
103 | { | 125 | { |
104 | disable_x2apic = 1; | 126 | disable_x2apic = 1; |
@@ -118,8 +140,6 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); | |||
118 | 140 | ||
119 | int first_system_vector = 0xfe; | 141 | int first_system_vector = 0xfe; |
120 | 142 | ||
121 | char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE}; | ||
122 | |||
123 | /* | 143 | /* |
124 | * Debug level, exported for io_apic.c | 144 | * Debug level, exported for io_apic.c |
125 | */ | 145 | */ |
@@ -141,7 +161,7 @@ static int lapic_next_event(unsigned long delta, | |||
141 | struct clock_event_device *evt); | 161 | struct clock_event_device *evt); |
142 | static void lapic_timer_setup(enum clock_event_mode mode, | 162 | static void lapic_timer_setup(enum clock_event_mode mode, |
143 | struct clock_event_device *evt); | 163 | struct clock_event_device *evt); |
144 | static void lapic_timer_broadcast(cpumask_t mask); | 164 | static void lapic_timer_broadcast(const struct cpumask *mask); |
145 | static void apic_pm_activate(void); | 165 | static void apic_pm_activate(void); |
146 | 166 | ||
147 | /* | 167 | /* |
@@ -227,7 +247,7 @@ void xapic_icr_write(u32 low, u32 id) | |||
227 | apic_write(APIC_ICR, low); | 247 | apic_write(APIC_ICR, low); |
228 | } | 248 | } |
229 | 249 | ||
230 | u64 xapic_icr_read(void) | 250 | static u64 xapic_icr_read(void) |
231 | { | 251 | { |
232 | u32 icr1, icr2; | 252 | u32 icr1, icr2; |
233 | 253 | ||
@@ -267,7 +287,7 @@ void x2apic_icr_write(u32 low, u32 id) | |||
267 | wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); | 287 | wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); |
268 | } | 288 | } |
269 | 289 | ||
270 | u64 x2apic_icr_read(void) | 290 | static u64 x2apic_icr_read(void) |
271 | { | 291 | { |
272 | unsigned long val; | 292 | unsigned long val; |
273 | 293 | ||
@@ -441,6 +461,7 @@ static void lapic_timer_setup(enum clock_event_mode mode, | |||
441 | v = apic_read(APIC_LVTT); | 461 | v = apic_read(APIC_LVTT); |
442 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); | 462 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); |
443 | apic_write(APIC_LVTT, v); | 463 | apic_write(APIC_LVTT, v); |
464 | apic_write(APIC_TMICT, 0xffffffff); | ||
444 | break; | 465 | break; |
445 | case CLOCK_EVT_MODE_RESUME: | 466 | case CLOCK_EVT_MODE_RESUME: |
446 | /* Nothing to do here */ | 467 | /* Nothing to do here */ |
@@ -453,10 +474,10 @@ static void lapic_timer_setup(enum clock_event_mode mode, | |||
453 | /* | 474 | /* |
454 | * Local APIC timer broadcast function | 475 | * Local APIC timer broadcast function |
455 | */ | 476 | */ |
456 | static void lapic_timer_broadcast(cpumask_t mask) | 477 | static void lapic_timer_broadcast(const struct cpumask *mask) |
457 | { | 478 | { |
458 | #ifdef CONFIG_SMP | 479 | #ifdef CONFIG_SMP |
459 | send_IPI_mask(mask, LOCAL_TIMER_VECTOR); | 480 | apic->send_IPI_mask(mask, LOCAL_TIMER_VECTOR); |
460 | #endif | 481 | #endif |
461 | } | 482 | } |
462 | 483 | ||
@@ -469,7 +490,7 @@ static void __cpuinit setup_APIC_timer(void) | |||
469 | struct clock_event_device *levt = &__get_cpu_var(lapic_events); | 490 | struct clock_event_device *levt = &__get_cpu_var(lapic_events); |
470 | 491 | ||
471 | memcpy(levt, &lapic_clockevent, sizeof(*levt)); | 492 | memcpy(levt, &lapic_clockevent, sizeof(*levt)); |
472 | levt->cpumask = cpumask_of_cpu(smp_processor_id()); | 493 | levt->cpumask = cpumask_of(smp_processor_id()); |
473 | 494 | ||
474 | clockevents_register_device(levt); | 495 | clockevents_register_device(levt); |
475 | } | 496 | } |
@@ -534,7 +555,8 @@ static void __init lapic_cal_handler(struct clock_event_device *dev) | |||
534 | } | 555 | } |
535 | } | 556 | } |
536 | 557 | ||
537 | static int __init calibrate_by_pmtimer(long deltapm, long *delta) | 558 | static int __init |
559 | calibrate_by_pmtimer(long deltapm, long *delta, long *deltatsc) | ||
538 | { | 560 | { |
539 | const long pm_100ms = PMTMR_TICKS_PER_SEC / 10; | 561 | const long pm_100ms = PMTMR_TICKS_PER_SEC / 10; |
540 | const long pm_thresh = pm_100ms / 100; | 562 | const long pm_thresh = pm_100ms / 100; |
@@ -545,7 +567,7 @@ static int __init calibrate_by_pmtimer(long deltapm, long *delta) | |||
545 | return -1; | 567 | return -1; |
546 | #endif | 568 | #endif |
547 | 569 | ||
548 | apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm); | 570 | apic_printk(APIC_VERBOSE, "... PM-Timer delta = %ld\n", deltapm); |
549 | 571 | ||
550 | /* Check, if the PM timer is available */ | 572 | /* Check, if the PM timer is available */ |
551 | if (!deltapm) | 573 | if (!deltapm) |
@@ -555,19 +577,30 @@ static int __init calibrate_by_pmtimer(long deltapm, long *delta) | |||
555 | 577 | ||
556 | if (deltapm > (pm_100ms - pm_thresh) && | 578 | if (deltapm > (pm_100ms - pm_thresh) && |
557 | deltapm < (pm_100ms + pm_thresh)) { | 579 | deltapm < (pm_100ms + pm_thresh)) { |
558 | apic_printk(APIC_VERBOSE, "... PM timer result ok\n"); | 580 | apic_printk(APIC_VERBOSE, "... PM-Timer result ok\n"); |
559 | } else { | 581 | return 0; |
560 | res = (((u64)deltapm) * mult) >> 22; | 582 | } |
561 | do_div(res, 1000000); | 583 | |
562 | printk(KERN_WARNING "APIC calibration not consistent " | 584 | res = (((u64)deltapm) * mult) >> 22; |
563 | "with PM Timer: %ldms instead of 100ms\n", | 585 | do_div(res, 1000000); |
564 | (long)res); | 586 | pr_warning("APIC calibration not consistent " |
565 | /* Correct the lapic counter value */ | 587 | "with PM-Timer: %ldms instead of 100ms\n",(long)res); |
566 | res = (((u64)(*delta)) * pm_100ms); | 588 | |
589 | /* Correct the lapic counter value */ | ||
590 | res = (((u64)(*delta)) * pm_100ms); | ||
591 | do_div(res, deltapm); | ||
592 | pr_info("APIC delta adjusted to PM-Timer: " | ||
593 | "%lu (%ld)\n", (unsigned long)res, *delta); | ||
594 | *delta = (long)res; | ||
595 | |||
596 | /* Correct the tsc counter value */ | ||
597 | if (cpu_has_tsc) { | ||
598 | res = (((u64)(*deltatsc)) * pm_100ms); | ||
567 | do_div(res, deltapm); | 599 | do_div(res, deltapm); |
568 | printk(KERN_INFO "APIC delta adjusted to PM-Timer: " | 600 | apic_printk(APIC_VERBOSE, "TSC delta adjusted to " |
569 | "%lu (%ld)\n", (unsigned long)res, *delta); | 601 | "PM-Timer: %lu (%ld) \n", |
570 | *delta = (long)res; | 602 | (unsigned long)res, *deltatsc); |
603 | *deltatsc = (long)res; | ||
571 | } | 604 | } |
572 | 605 | ||
573 | return 0; | 606 | return 0; |
@@ -578,7 +611,7 @@ static int __init calibrate_APIC_clock(void) | |||
578 | struct clock_event_device *levt = &__get_cpu_var(lapic_events); | 611 | struct clock_event_device *levt = &__get_cpu_var(lapic_events); |
579 | void (*real_handler)(struct clock_event_device *dev); | 612 | void (*real_handler)(struct clock_event_device *dev); |
580 | unsigned long deltaj; | 613 | unsigned long deltaj; |
581 | long delta; | 614 | long delta, deltatsc; |
582 | int pm_referenced = 0; | 615 | int pm_referenced = 0; |
583 | 616 | ||
584 | local_irq_disable(); | 617 | local_irq_disable(); |
@@ -608,9 +641,11 @@ static int __init calibrate_APIC_clock(void) | |||
608 | delta = lapic_cal_t1 - lapic_cal_t2; | 641 | delta = lapic_cal_t1 - lapic_cal_t2; |
609 | apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta); | 642 | apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta); |
610 | 643 | ||
644 | deltatsc = (long)(lapic_cal_tsc2 - lapic_cal_tsc1); | ||
645 | |||
611 | /* we trust the PM based calibration if possible */ | 646 | /* we trust the PM based calibration if possible */ |
612 | pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1, | 647 | pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1, |
613 | &delta); | 648 | &delta, &deltatsc); |
614 | 649 | ||
615 | /* Calculate the scaled math multiplication factor */ | 650 | /* Calculate the scaled math multiplication factor */ |
616 | lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, | 651 | lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS, |
@@ -628,11 +663,10 @@ static int __init calibrate_APIC_clock(void) | |||
628 | calibration_result); | 663 | calibration_result); |
629 | 664 | ||
630 | if (cpu_has_tsc) { | 665 | if (cpu_has_tsc) { |
631 | delta = (long)(lapic_cal_tsc2 - lapic_cal_tsc1); | ||
632 | apic_printk(APIC_VERBOSE, "..... CPU clock speed is " | 666 | apic_printk(APIC_VERBOSE, "..... CPU clock speed is " |
633 | "%ld.%04ld MHz.\n", | 667 | "%ld.%04ld MHz.\n", |
634 | (delta / LAPIC_CAL_LOOPS) / (1000000 / HZ), | 668 | (deltatsc / LAPIC_CAL_LOOPS) / (1000000 / HZ), |
635 | (delta / LAPIC_CAL_LOOPS) % (1000000 / HZ)); | 669 | (deltatsc / LAPIC_CAL_LOOPS) % (1000000 / HZ)); |
636 | } | 670 | } |
637 | 671 | ||
638 | apic_printk(APIC_VERBOSE, "..... host bus clock speed is " | 672 | apic_printk(APIC_VERBOSE, "..... host bus clock speed is " |
@@ -645,8 +679,7 @@ static int __init calibrate_APIC_clock(void) | |||
645 | */ | 679 | */ |
646 | if (calibration_result < (1000000 / HZ)) { | 680 | if (calibration_result < (1000000 / HZ)) { |
647 | local_irq_enable(); | 681 | local_irq_enable(); |
648 | printk(KERN_WARNING | 682 | pr_warning("APIC frequency too slow, disabling apic timer\n"); |
649 | "APIC frequency too slow, disabling apic timer\n"); | ||
650 | return -1; | 683 | return -1; |
651 | } | 684 | } |
652 | 685 | ||
@@ -672,13 +705,9 @@ static int __init calibrate_APIC_clock(void) | |||
672 | while (lapic_cal_loops <= LAPIC_CAL_LOOPS) | 705 | while (lapic_cal_loops <= LAPIC_CAL_LOOPS) |
673 | cpu_relax(); | 706 | cpu_relax(); |
674 | 707 | ||
675 | local_irq_disable(); | ||
676 | |||
677 | /* Stop the lapic timer */ | 708 | /* Stop the lapic timer */ |
678 | lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); | 709 | lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); |
679 | 710 | ||
680 | local_irq_enable(); | ||
681 | |||
682 | /* Jiffies delta */ | 711 | /* Jiffies delta */ |
683 | deltaj = lapic_cal_j2 - lapic_cal_j1; | 712 | deltaj = lapic_cal_j2 - lapic_cal_j1; |
684 | apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); | 713 | apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); |
@@ -692,8 +721,7 @@ static int __init calibrate_APIC_clock(void) | |||
692 | local_irq_enable(); | 721 | local_irq_enable(); |
693 | 722 | ||
694 | if (levt->features & CLOCK_EVT_FEAT_DUMMY) { | 723 | if (levt->features & CLOCK_EVT_FEAT_DUMMY) { |
695 | printk(KERN_WARNING | 724 | pr_warning("APIC timer disabled due to verification failure\n"); |
696 | "APIC timer disabled due to verification failure.\n"); | ||
697 | return -1; | 725 | return -1; |
698 | } | 726 | } |
699 | 727 | ||
@@ -714,7 +742,7 @@ void __init setup_boot_APIC_clock(void) | |||
714 | * broadcast mechanism is used. On UP systems simply ignore it. | 742 | * broadcast mechanism is used. On UP systems simply ignore it. |
715 | */ | 743 | */ |
716 | if (disable_apic_timer) { | 744 | if (disable_apic_timer) { |
717 | printk(KERN_INFO "Disabling APIC timer\n"); | 745 | pr_info("Disabling APIC timer\n"); |
718 | /* No broadcast on UP ! */ | 746 | /* No broadcast on UP ! */ |
719 | if (num_possible_cpus() > 1) { | 747 | if (num_possible_cpus() > 1) { |
720 | lapic_clockevent.mult = 1; | 748 | lapic_clockevent.mult = 1; |
@@ -741,7 +769,7 @@ void __init setup_boot_APIC_clock(void) | |||
741 | if (nmi_watchdog != NMI_IO_APIC) | 769 | if (nmi_watchdog != NMI_IO_APIC) |
742 | lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; | 770 | lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; |
743 | else | 771 | else |
744 | printk(KERN_WARNING "APIC timer registered as dummy," | 772 | pr_warning("APIC timer registered as dummy," |
745 | " due to nmi_watchdog=%d!\n", nmi_watchdog); | 773 | " due to nmi_watchdog=%d!\n", nmi_watchdog); |
746 | 774 | ||
747 | /* Setup the lapic or request the broadcast */ | 775 | /* Setup the lapic or request the broadcast */ |
@@ -773,8 +801,7 @@ static void local_apic_timer_interrupt(void) | |||
773 | * spurious. | 801 | * spurious. |
774 | */ | 802 | */ |
775 | if (!evt->event_handler) { | 803 | if (!evt->event_handler) { |
776 | printk(KERN_WARNING | 804 | pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu); |
777 | "Spurious LAPIC timer interrupt on cpu %d\n", cpu); | ||
778 | /* Switch it off */ | 805 | /* Switch it off */ |
779 | lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt); | 806 | lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt); |
780 | return; | 807 | return; |
@@ -783,11 +810,7 @@ static void local_apic_timer_interrupt(void) | |||
783 | /* | 810 | /* |
784 | * the NMI deadlock-detector uses this. | 811 | * the NMI deadlock-detector uses this. |
785 | */ | 812 | */ |
786 | #ifdef CONFIG_X86_64 | 813 | inc_irq_stat(apic_timer_irqs); |
787 | add_pda(apic_timer_irqs, 1); | ||
788 | #else | ||
789 | per_cpu(irq_stat, cpu).apic_timer_irqs++; | ||
790 | #endif | ||
791 | 814 | ||
792 | evt->event_handler(evt); | 815 | evt->event_handler(evt); |
793 | } | 816 | } |
@@ -800,7 +823,7 @@ static void local_apic_timer_interrupt(void) | |||
800 | * [ if a single-CPU system runs an SMP kernel then we call the local | 823 | * [ if a single-CPU system runs an SMP kernel then we call the local |
801 | * interrupt as well. Thus we cannot inline the local irq ... ] | 824 | * interrupt as well. Thus we cannot inline the local irq ... ] |
802 | */ | 825 | */ |
803 | void smp_apic_timer_interrupt(struct pt_regs *regs) | 826 | void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) |
804 | { | 827 | { |
805 | struct pt_regs *old_regs = set_irq_regs(regs); | 828 | struct pt_regs *old_regs = set_irq_regs(regs); |
806 | 829 | ||
@@ -814,9 +837,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) | |||
814 | * Besides, if we don't timer interrupts ignore the global | 837 | * Besides, if we don't timer interrupts ignore the global |
815 | * interrupt lock, which is the WrongThing (tm) to do. | 838 | * interrupt lock, which is the WrongThing (tm) to do. |
816 | */ | 839 | */ |
817 | #ifdef CONFIG_X86_64 | ||
818 | exit_idle(); | 840 | exit_idle(); |
819 | #endif | ||
820 | irq_enter(); | 841 | irq_enter(); |
821 | local_apic_timer_interrupt(); | 842 | local_apic_timer_interrupt(); |
822 | irq_exit(); | 843 | irq_exit(); |
@@ -907,6 +928,10 @@ void disable_local_APIC(void) | |||
907 | { | 928 | { |
908 | unsigned int value; | 929 | unsigned int value; |
909 | 930 | ||
931 | /* APIC hasn't been mapped yet */ | ||
932 | if (!apic_phys) | ||
933 | return; | ||
934 | |||
910 | clear_local_APIC(); | 935 | clear_local_APIC(); |
911 | 936 | ||
912 | /* | 937 | /* |
@@ -999,11 +1024,11 @@ int __init verify_local_APIC(void) | |||
999 | */ | 1024 | */ |
1000 | reg0 = apic_read(APIC_ID); | 1025 | reg0 = apic_read(APIC_ID); |
1001 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); | 1026 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); |
1002 | apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); | 1027 | apic_write(APIC_ID, reg0 ^ apic->apic_id_mask); |
1003 | reg1 = apic_read(APIC_ID); | 1028 | reg1 = apic_read(APIC_ID); |
1004 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); | 1029 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); |
1005 | apic_write(APIC_ID, reg0); | 1030 | apic_write(APIC_ID, reg0); |
1006 | if (reg1 != (reg0 ^ APIC_ID_MASK)) | 1031 | if (reg1 != (reg0 ^ apic->apic_id_mask)) |
1007 | return 0; | 1032 | return 0; |
1008 | 1033 | ||
1009 | /* | 1034 | /* |
@@ -1093,18 +1118,18 @@ static void __cpuinit lapic_setup_esr(void) | |||
1093 | unsigned int oldvalue, value, maxlvt; | 1118 | unsigned int oldvalue, value, maxlvt; |
1094 | 1119 | ||
1095 | if (!lapic_is_integrated()) { | 1120 | if (!lapic_is_integrated()) { |
1096 | printk(KERN_INFO "No ESR for 82489DX.\n"); | 1121 | pr_info("No ESR for 82489DX.\n"); |
1097 | return; | 1122 | return; |
1098 | } | 1123 | } |
1099 | 1124 | ||
1100 | if (esr_disable) { | 1125 | if (apic->disable_esr) { |
1101 | /* | 1126 | /* |
1102 | * Something untraceable is creating bad interrupts on | 1127 | * Something untraceable is creating bad interrupts on |
1103 | * secondary quads ... for the moment, just leave the | 1128 | * secondary quads ... for the moment, just leave the |
1104 | * ESR disabled - we can't do anything useful with the | 1129 | * ESR disabled - we can't do anything useful with the |
1105 | * errors anyway - mbligh | 1130 | * errors anyway - mbligh |
1106 | */ | 1131 | */ |
1107 | printk(KERN_INFO "Leaving ESR disabled.\n"); | 1132 | pr_info("Leaving ESR disabled.\n"); |
1108 | return; | 1133 | return; |
1109 | } | 1134 | } |
1110 | 1135 | ||
@@ -1138,9 +1163,14 @@ void __cpuinit setup_local_APIC(void) | |||
1138 | unsigned int value; | 1163 | unsigned int value; |
1139 | int i, j; | 1164 | int i, j; |
1140 | 1165 | ||
1166 | if (disable_apic) { | ||
1167 | arch_disable_smp_support(); | ||
1168 | return; | ||
1169 | } | ||
1170 | |||
1141 | #ifdef CONFIG_X86_32 | 1171 | #ifdef CONFIG_X86_32 |
1142 | /* Pound the ESR really hard over the head with a big hammer - mbligh */ | 1172 | /* Pound the ESR really hard over the head with a big hammer - mbligh */ |
1143 | if (lapic_is_integrated() && esr_disable) { | 1173 | if (lapic_is_integrated() && apic->disable_esr) { |
1144 | apic_write(APIC_ESR, 0); | 1174 | apic_write(APIC_ESR, 0); |
1145 | apic_write(APIC_ESR, 0); | 1175 | apic_write(APIC_ESR, 0); |
1146 | apic_write(APIC_ESR, 0); | 1176 | apic_write(APIC_ESR, 0); |
@@ -1154,7 +1184,7 @@ void __cpuinit setup_local_APIC(void) | |||
1154 | * Double-check whether this APIC is really registered. | 1184 | * Double-check whether this APIC is really registered. |
1155 | * This is meaningless in clustered apic mode, so we skip it. | 1185 | * This is meaningless in clustered apic mode, so we skip it. |
1156 | */ | 1186 | */ |
1157 | if (!apic_id_registered()) | 1187 | if (!apic->apic_id_registered()) |
1158 | BUG(); | 1188 | BUG(); |
1159 | 1189 | ||
1160 | /* | 1190 | /* |
@@ -1162,7 +1192,7 @@ void __cpuinit setup_local_APIC(void) | |||
1162 | * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel | 1192 | * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel |
1163 | * document number 292116). So here it goes... | 1193 | * document number 292116). So here it goes... |
1164 | */ | 1194 | */ |
1165 | init_apic_ldr(); | 1195 | apic->init_apic_ldr(); |
1166 | 1196 | ||
1167 | /* | 1197 | /* |
1168 | * Set Task Priority to 'accept all'. We never change this | 1198 | * Set Task Priority to 'accept all'. We never change this |
@@ -1298,7 +1328,7 @@ void check_x2apic(void) | |||
1298 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | 1328 | rdmsr(MSR_IA32_APICBASE, msr, msr2); |
1299 | 1329 | ||
1300 | if (msr & X2APIC_ENABLE) { | 1330 | if (msr & X2APIC_ENABLE) { |
1301 | printk("x2apic enabled by BIOS, switching to x2apic ops\n"); | 1331 | pr_info("x2apic enabled by BIOS, switching to x2apic ops\n"); |
1302 | x2apic_preenabled = x2apic = 1; | 1332 | x2apic_preenabled = x2apic = 1; |
1303 | apic_ops = &x2apic_ops; | 1333 | apic_ops = &x2apic_ops; |
1304 | } | 1334 | } |
@@ -1310,12 +1340,12 @@ void enable_x2apic(void) | |||
1310 | 1340 | ||
1311 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | 1341 | rdmsr(MSR_IA32_APICBASE, msr, msr2); |
1312 | if (!(msr & X2APIC_ENABLE)) { | 1342 | if (!(msr & X2APIC_ENABLE)) { |
1313 | printk("Enabling x2apic\n"); | 1343 | pr_info("Enabling x2apic\n"); |
1314 | wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); | 1344 | wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); |
1315 | } | 1345 | } |
1316 | } | 1346 | } |
1317 | 1347 | ||
1318 | void enable_IR_x2apic(void) | 1348 | void __init enable_IR_x2apic(void) |
1319 | { | 1349 | { |
1320 | #ifdef CONFIG_INTR_REMAP | 1350 | #ifdef CONFIG_INTR_REMAP |
1321 | int ret; | 1351 | int ret; |
@@ -1325,9 +1355,8 @@ void enable_IR_x2apic(void) | |||
1325 | return; | 1355 | return; |
1326 | 1356 | ||
1327 | if (!x2apic_preenabled && disable_x2apic) { | 1357 | if (!x2apic_preenabled && disable_x2apic) { |
1328 | printk(KERN_INFO | 1358 | pr_info("Skipped enabling x2apic and Interrupt-remapping " |
1329 | "Skipped enabling x2apic and Interrupt-remapping " | 1359 | "because of nox2apic\n"); |
1330 | "because of nox2apic\n"); | ||
1331 | return; | 1360 | return; |
1332 | } | 1361 | } |
1333 | 1362 | ||
@@ -1335,22 +1364,19 @@ void enable_IR_x2apic(void) | |||
1335 | panic("Bios already enabled x2apic, can't enforce nox2apic"); | 1364 | panic("Bios already enabled x2apic, can't enforce nox2apic"); |
1336 | 1365 | ||
1337 | if (!x2apic_preenabled && skip_ioapic_setup) { | 1366 | if (!x2apic_preenabled && skip_ioapic_setup) { |
1338 | printk(KERN_INFO | 1367 | pr_info("Skipped enabling x2apic and Interrupt-remapping " |
1339 | "Skipped enabling x2apic and Interrupt-remapping " | 1368 | "because of skipping io-apic setup\n"); |
1340 | "because of skipping io-apic setup\n"); | ||
1341 | return; | 1369 | return; |
1342 | } | 1370 | } |
1343 | 1371 | ||
1344 | ret = dmar_table_init(); | 1372 | ret = dmar_table_init(); |
1345 | if (ret) { | 1373 | if (ret) { |
1346 | printk(KERN_INFO | 1374 | pr_info("dmar_table_init() failed with %d:\n", ret); |
1347 | "dmar_table_init() failed with %d:\n", ret); | ||
1348 | 1375 | ||
1349 | if (x2apic_preenabled) | 1376 | if (x2apic_preenabled) |
1350 | panic("x2apic enabled by bios. But IR enabling failed"); | 1377 | panic("x2apic enabled by bios. But IR enabling failed"); |
1351 | else | 1378 | else |
1352 | printk(KERN_INFO | 1379 | pr_info("Not enabling x2apic,Intr-remapping\n"); |
1353 | "Not enabling x2apic,Intr-remapping\n"); | ||
1354 | return; | 1380 | return; |
1355 | } | 1381 | } |
1356 | 1382 | ||
@@ -1359,7 +1385,7 @@ void enable_IR_x2apic(void) | |||
1359 | 1385 | ||
1360 | ret = save_mask_IO_APIC_setup(); | 1386 | ret = save_mask_IO_APIC_setup(); |
1361 | if (ret) { | 1387 | if (ret) { |
1362 | printk(KERN_INFO "Saving IO-APIC state failed: %d\n", ret); | 1388 | pr_info("Saving IO-APIC state failed: %d\n", ret); |
1363 | goto end; | 1389 | goto end; |
1364 | } | 1390 | } |
1365 | 1391 | ||
@@ -1394,14 +1420,11 @@ end: | |||
1394 | 1420 | ||
1395 | if (!ret) { | 1421 | if (!ret) { |
1396 | if (!x2apic_preenabled) | 1422 | if (!x2apic_preenabled) |
1397 | printk(KERN_INFO | 1423 | pr_info("Enabled x2apic and interrupt-remapping\n"); |
1398 | "Enabled x2apic and interrupt-remapping\n"); | ||
1399 | else | 1424 | else |
1400 | printk(KERN_INFO | 1425 | pr_info("Enabled Interrupt-remapping\n"); |
1401 | "Enabled Interrupt-remapping\n"); | ||
1402 | } else | 1426 | } else |
1403 | printk(KERN_ERR | 1427 | pr_err("Failed to enable Interrupt-remapping and x2apic\n"); |
1404 | "Failed to enable Interrupt-remapping and x2apic\n"); | ||
1405 | #else | 1428 | #else |
1406 | if (!cpu_has_x2apic) | 1429 | if (!cpu_has_x2apic) |
1407 | return; | 1430 | return; |
@@ -1410,8 +1433,8 @@ end: | |||
1410 | panic("x2apic enabled prior OS handover," | 1433 | panic("x2apic enabled prior OS handover," |
1411 | " enable CONFIG_INTR_REMAP"); | 1434 | " enable CONFIG_INTR_REMAP"); |
1412 | 1435 | ||
1413 | printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping " | 1436 | pr_info("Enable CONFIG_INTR_REMAP for enabling intr-remapping " |
1414 | " and x2apic\n"); | 1437 | " and x2apic\n"); |
1415 | #endif | 1438 | #endif |
1416 | 1439 | ||
1417 | return; | 1440 | return; |
@@ -1428,7 +1451,7 @@ end: | |||
1428 | static int __init detect_init_APIC(void) | 1451 | static int __init detect_init_APIC(void) |
1429 | { | 1452 | { |
1430 | if (!cpu_has_apic) { | 1453 | if (!cpu_has_apic) { |
1431 | printk(KERN_INFO "No local APIC present\n"); | 1454 | pr_info("No local APIC present\n"); |
1432 | return -1; | 1455 | return -1; |
1433 | } | 1456 | } |
1434 | 1457 | ||
@@ -1451,7 +1474,7 @@ static int __init detect_init_APIC(void) | |||
1451 | switch (boot_cpu_data.x86_vendor) { | 1474 | switch (boot_cpu_data.x86_vendor) { |
1452 | case X86_VENDOR_AMD: | 1475 | case X86_VENDOR_AMD: |
1453 | if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || | 1476 | if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || |
1454 | (boot_cpu_data.x86 == 15)) | 1477 | (boot_cpu_data.x86 >= 15)) |
1455 | break; | 1478 | break; |
1456 | goto no_apic; | 1479 | goto no_apic; |
1457 | case X86_VENDOR_INTEL: | 1480 | case X86_VENDOR_INTEL: |
@@ -1469,8 +1492,8 @@ static int __init detect_init_APIC(void) | |||
1469 | * "lapic" specified. | 1492 | * "lapic" specified. |
1470 | */ | 1493 | */ |
1471 | if (!force_enable_local_apic) { | 1494 | if (!force_enable_local_apic) { |
1472 | printk(KERN_INFO "Local APIC disabled by BIOS -- " | 1495 | pr_info("Local APIC disabled by BIOS -- " |
1473 | "you can enable it with \"lapic\"\n"); | 1496 | "you can enable it with \"lapic\"\n"); |
1474 | return -1; | 1497 | return -1; |
1475 | } | 1498 | } |
1476 | /* | 1499 | /* |
@@ -1480,8 +1503,7 @@ static int __init detect_init_APIC(void) | |||
1480 | */ | 1503 | */ |
1481 | rdmsr(MSR_IA32_APICBASE, l, h); | 1504 | rdmsr(MSR_IA32_APICBASE, l, h); |
1482 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { | 1505 | if (!(l & MSR_IA32_APICBASE_ENABLE)) { |
1483 | printk(KERN_INFO | 1506 | pr_info("Local APIC disabled by BIOS -- reenabling.\n"); |
1484 | "Local APIC disabled by BIOS -- reenabling.\n"); | ||
1485 | l &= ~MSR_IA32_APICBASE_BASE; | 1507 | l &= ~MSR_IA32_APICBASE_BASE; |
1486 | l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; | 1508 | l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE; |
1487 | wrmsr(MSR_IA32_APICBASE, l, h); | 1509 | wrmsr(MSR_IA32_APICBASE, l, h); |
@@ -1494,7 +1516,7 @@ static int __init detect_init_APIC(void) | |||
1494 | */ | 1516 | */ |
1495 | features = cpuid_edx(1); | 1517 | features = cpuid_edx(1); |
1496 | if (!(features & (1 << X86_FEATURE_APIC))) { | 1518 | if (!(features & (1 << X86_FEATURE_APIC))) { |
1497 | printk(KERN_WARNING "Could not enable APIC!\n"); | 1519 | pr_warning("Could not enable APIC!\n"); |
1498 | return -1; | 1520 | return -1; |
1499 | } | 1521 | } |
1500 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); | 1522 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); |
@@ -1505,14 +1527,14 @@ static int __init detect_init_APIC(void) | |||
1505 | if (l & MSR_IA32_APICBASE_ENABLE) | 1527 | if (l & MSR_IA32_APICBASE_ENABLE) |
1506 | mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; | 1528 | mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; |
1507 | 1529 | ||
1508 | printk(KERN_INFO "Found and enabled local APIC!\n"); | 1530 | pr_info("Found and enabled local APIC!\n"); |
1509 | 1531 | ||
1510 | apic_pm_activate(); | 1532 | apic_pm_activate(); |
1511 | 1533 | ||
1512 | return 0; | 1534 | return 0; |
1513 | 1535 | ||
1514 | no_apic: | 1536 | no_apic: |
1515 | printk(KERN_INFO "No local APIC present or hardware disabled\n"); | 1537 | pr_info("No local APIC present or hardware disabled\n"); |
1516 | return -1; | 1538 | return -1; |
1517 | } | 1539 | } |
1518 | #endif | 1540 | #endif |
@@ -1586,14 +1608,14 @@ int apic_version[MAX_APICS]; | |||
1586 | 1608 | ||
1587 | int __init APIC_init_uniprocessor(void) | 1609 | int __init APIC_init_uniprocessor(void) |
1588 | { | 1610 | { |
1589 | #ifdef CONFIG_X86_64 | ||
1590 | if (disable_apic) { | 1611 | if (disable_apic) { |
1591 | printk(KERN_INFO "Apic disabled\n"); | 1612 | pr_info("Apic disabled\n"); |
1592 | return -1; | 1613 | return -1; |
1593 | } | 1614 | } |
1615 | #ifdef CONFIG_X86_64 | ||
1594 | if (!cpu_has_apic) { | 1616 | if (!cpu_has_apic) { |
1595 | disable_apic = 1; | 1617 | disable_apic = 1; |
1596 | printk(KERN_INFO "Apic disabled by BIOS\n"); | 1618 | pr_info("Apic disabled by BIOS\n"); |
1597 | return -1; | 1619 | return -1; |
1598 | } | 1620 | } |
1599 | #else | 1621 | #else |
@@ -1605,8 +1627,8 @@ int __init APIC_init_uniprocessor(void) | |||
1605 | */ | 1627 | */ |
1606 | if (!cpu_has_apic && | 1628 | if (!cpu_has_apic && |
1607 | APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | 1629 | APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { |
1608 | printk(KERN_ERR "BIOS bug, local APIC 0x%x not detected!...\n", | 1630 | pr_err("BIOS bug, local APIC 0x%x not detected!...\n", |
1609 | boot_cpu_physical_apicid); | 1631 | boot_cpu_physical_apicid); |
1610 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); | 1632 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); |
1611 | return -1; | 1633 | return -1; |
1612 | } | 1634 | } |
@@ -1616,7 +1638,7 @@ int __init APIC_init_uniprocessor(void) | |||
1616 | enable_IR_x2apic(); | 1638 | enable_IR_x2apic(); |
1617 | #endif | 1639 | #endif |
1618 | #ifdef CONFIG_X86_64 | 1640 | #ifdef CONFIG_X86_64 |
1619 | setup_apic_routing(); | 1641 | default_setup_apic_routing(); |
1620 | #endif | 1642 | #endif |
1621 | 1643 | ||
1622 | verify_local_APIC(); | 1644 | verify_local_APIC(); |
@@ -1682,9 +1704,7 @@ void smp_spurious_interrupt(struct pt_regs *regs) | |||
1682 | { | 1704 | { |
1683 | u32 v; | 1705 | u32 v; |
1684 | 1706 | ||
1685 | #ifdef CONFIG_X86_64 | ||
1686 | exit_idle(); | 1707 | exit_idle(); |
1687 | #endif | ||
1688 | irq_enter(); | 1708 | irq_enter(); |
1689 | /* | 1709 | /* |
1690 | * Check if this really is a spurious interrupt and ACK it | 1710 | * Check if this really is a spurious interrupt and ACK it |
@@ -1695,14 +1715,11 @@ void smp_spurious_interrupt(struct pt_regs *regs) | |||
1695 | if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) | 1715 | if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f))) |
1696 | ack_APIC_irq(); | 1716 | ack_APIC_irq(); |
1697 | 1717 | ||
1698 | #ifdef CONFIG_X86_64 | 1718 | inc_irq_stat(irq_spurious_count); |
1699 | add_pda(irq_spurious_count, 1); | 1719 | |
1700 | #else | ||
1701 | /* see sw-dev-man vol 3, chapter 7.4.13.5 */ | 1720 | /* see sw-dev-man vol 3, chapter 7.4.13.5 */ |
1702 | printk(KERN_INFO "spurious APIC interrupt on CPU#%d, " | 1721 | pr_info("spurious APIC interrupt on CPU#%d, " |
1703 | "should never happen.\n", smp_processor_id()); | 1722 | "should never happen.\n", smp_processor_id()); |
1704 | __get_cpu_var(irq_stat).irq_spurious_count++; | ||
1705 | #endif | ||
1706 | irq_exit(); | 1723 | irq_exit(); |
1707 | } | 1724 | } |
1708 | 1725 | ||
@@ -1713,9 +1730,7 @@ void smp_error_interrupt(struct pt_regs *regs) | |||
1713 | { | 1730 | { |
1714 | u32 v, v1; | 1731 | u32 v, v1; |
1715 | 1732 | ||
1716 | #ifdef CONFIG_X86_64 | ||
1717 | exit_idle(); | 1733 | exit_idle(); |
1718 | #endif | ||
1719 | irq_enter(); | 1734 | irq_enter(); |
1720 | /* First tickle the hardware, only then report what went on. -- REW */ | 1735 | /* First tickle the hardware, only then report what went on. -- REW */ |
1721 | v = apic_read(APIC_ESR); | 1736 | v = apic_read(APIC_ESR); |
@@ -1724,17 +1739,18 @@ void smp_error_interrupt(struct pt_regs *regs) | |||
1724 | ack_APIC_irq(); | 1739 | ack_APIC_irq(); |
1725 | atomic_inc(&irq_err_count); | 1740 | atomic_inc(&irq_err_count); |
1726 | 1741 | ||
1727 | /* Here is what the APIC error bits mean: | 1742 | /* |
1728 | 0: Send CS error | 1743 | * Here is what the APIC error bits mean: |
1729 | 1: Receive CS error | 1744 | * 0: Send CS error |
1730 | 2: Send accept error | 1745 | * 1: Receive CS error |
1731 | 3: Receive accept error | 1746 | * 2: Send accept error |
1732 | 4: Reserved | 1747 | * 3: Receive accept error |
1733 | 5: Send illegal vector | 1748 | * 4: Reserved |
1734 | 6: Received illegal vector | 1749 | * 5: Send illegal vector |
1735 | 7: Illegal register address | 1750 | * 6: Received illegal vector |
1736 | */ | 1751 | * 7: Illegal register address |
1737 | printk(KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n", | 1752 | */ |
1753 | pr_debug("APIC error on CPU%d: %02x(%02x)\n", | ||
1738 | smp_processor_id(), v , v1); | 1754 | smp_processor_id(), v , v1); |
1739 | irq_exit(); | 1755 | irq_exit(); |
1740 | } | 1756 | } |
@@ -1760,7 +1776,8 @@ void __init connect_bsp_APIC(void) | |||
1760 | outb(0x01, 0x23); | 1776 | outb(0x01, 0x23); |
1761 | } | 1777 | } |
1762 | #endif | 1778 | #endif |
1763 | enable_apic_mode(); | 1779 | if (apic->enable_apic_mode) |
1780 | apic->enable_apic_mode(); | ||
1764 | } | 1781 | } |
1765 | 1782 | ||
1766 | /** | 1783 | /** |
@@ -1832,28 +1849,37 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
1832 | void __cpuinit generic_processor_info(int apicid, int version) | 1849 | void __cpuinit generic_processor_info(int apicid, int version) |
1833 | { | 1850 | { |
1834 | int cpu; | 1851 | int cpu; |
1835 | cpumask_t tmp_map; | ||
1836 | 1852 | ||
1837 | /* | 1853 | /* |
1838 | * Validate version | 1854 | * Validate version |
1839 | */ | 1855 | */ |
1840 | if (version == 0x0) { | 1856 | if (version == 0x0) { |
1841 | printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! " | 1857 | pr_warning("BIOS bug, APIC version is 0 for CPU#%d! " |
1842 | "fixing up to 0x10. (tell your hw vendor)\n", | 1858 | "fixing up to 0x10. (tell your hw vendor)\n", |
1843 | version); | 1859 | version); |
1844 | version = 0x10; | 1860 | version = 0x10; |
1845 | } | 1861 | } |
1846 | apic_version[apicid] = version; | 1862 | apic_version[apicid] = version; |
1847 | 1863 | ||
1848 | if (num_processors >= NR_CPUS) { | 1864 | if (num_processors >= nr_cpu_ids) { |
1849 | printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." | 1865 | int max = nr_cpu_ids; |
1850 | " Processor ignored.\n", NR_CPUS); | 1866 | int thiscpu = max + disabled_cpus; |
1867 | |||
1868 | pr_warning( | ||
1869 | "ACPI: NR_CPUS/possible_cpus limit of %i reached." | ||
1870 | " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); | ||
1871 | |||
1872 | disabled_cpus++; | ||
1851 | return; | 1873 | return; |
1852 | } | 1874 | } |
1853 | 1875 | ||
1854 | num_processors++; | 1876 | num_processors++; |
1855 | cpus_complement(tmp_map, cpu_present_map); | 1877 | cpu = cpumask_next_zero(-1, cpu_present_mask); |
1856 | cpu = first_cpu(tmp_map); | 1878 | |
1879 | if (version != apic_version[boot_cpu_physical_apicid]) | ||
1880 | WARN_ONCE(1, | ||
1881 | "ACPI: apic version mismatch, bootcpu: %x cpu %d: %x\n", | ||
1882 | apic_version[boot_cpu_physical_apicid], cpu, version); | ||
1857 | 1883 | ||
1858 | physid_set(apicid, phys_cpu_present_map); | 1884 | physid_set(apicid, phys_cpu_present_map); |
1859 | if (apicid == boot_cpu_physical_apicid) { | 1885 | if (apicid == boot_cpu_physical_apicid) { |
@@ -1889,29 +1915,39 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1889 | } | 1915 | } |
1890 | #endif | 1916 | #endif |
1891 | 1917 | ||
1892 | #if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64) | 1918 | #if defined(CONFIG_SMP) || defined(CONFIG_X86_64) |
1893 | /* are we being called early in kernel startup? */ | 1919 | early_per_cpu(x86_cpu_to_apicid, cpu) = apicid; |
1894 | if (early_per_cpu_ptr(x86_cpu_to_apicid)) { | 1920 | early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid; |
1895 | u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid); | ||
1896 | u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); | ||
1897 | |||
1898 | cpu_to_apicid[cpu] = apicid; | ||
1899 | bios_cpu_apicid[cpu] = apicid; | ||
1900 | } else { | ||
1901 | per_cpu(x86_cpu_to_apicid, cpu) = apicid; | ||
1902 | per_cpu(x86_bios_cpu_apicid, cpu) = apicid; | ||
1903 | } | ||
1904 | #endif | 1921 | #endif |
1905 | 1922 | ||
1906 | cpu_set(cpu, cpu_possible_map); | 1923 | set_cpu_possible(cpu, true); |
1907 | cpu_set(cpu, cpu_present_map); | 1924 | set_cpu_present(cpu, true); |
1908 | } | 1925 | } |
1909 | 1926 | ||
1910 | #ifdef CONFIG_X86_64 | ||
1911 | int hard_smp_processor_id(void) | 1927 | int hard_smp_processor_id(void) |
1912 | { | 1928 | { |
1913 | return read_apic_id(); | 1929 | return read_apic_id(); |
1914 | } | 1930 | } |
1931 | |||
1932 | void default_init_apic_ldr(void) | ||
1933 | { | ||
1934 | unsigned long val; | ||
1935 | |||
1936 | apic_write(APIC_DFR, APIC_DFR_VALUE); | ||
1937 | val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; | ||
1938 | val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); | ||
1939 | apic_write(APIC_LDR, val); | ||
1940 | } | ||
1941 | |||
1942 | #ifdef CONFIG_X86_32 | ||
1943 | int default_apicid_to_node(int logical_apicid) | ||
1944 | { | ||
1945 | #ifdef CONFIG_SMP | ||
1946 | return apicid_2_node[hard_smp_processor_id()]; | ||
1947 | #else | ||
1948 | return 0; | ||
1949 | #endif | ||
1950 | } | ||
1915 | #endif | 1951 | #endif |
1916 | 1952 | ||
1917 | /* | 1953 | /* |
@@ -2106,18 +2142,16 @@ __cpuinit int apic_is_clustered_box(void) | |||
2106 | bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); | 2142 | bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid); |
2107 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); | 2143 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); |
2108 | 2144 | ||
2109 | for (i = 0; i < NR_CPUS; i++) { | 2145 | for (i = 0; i < nr_cpu_ids; i++) { |
2110 | /* are we being called early in kernel startup? */ | 2146 | /* are we being called early in kernel startup? */ |
2111 | if (bios_cpu_apicid) { | 2147 | if (bios_cpu_apicid) { |
2112 | id = bios_cpu_apicid[i]; | 2148 | id = bios_cpu_apicid[i]; |
2113 | } | 2149 | } else if (i < nr_cpu_ids) { |
2114 | else if (i < nr_cpu_ids) { | ||
2115 | if (cpu_present(i)) | 2150 | if (cpu_present(i)) |
2116 | id = per_cpu(x86_bios_cpu_apicid, i); | 2151 | id = per_cpu(x86_bios_cpu_apicid, i); |
2117 | else | 2152 | else |
2118 | continue; | 2153 | continue; |
2119 | } | 2154 | } else |
2120 | else | ||
2121 | break; | 2155 | break; |
2122 | 2156 | ||
2123 | if (id != BAD_APICID) | 2157 | if (id != BAD_APICID) |
@@ -2209,7 +2243,7 @@ static int __init apic_set_verbosity(char *arg) | |||
2209 | else if (strcmp("verbose", arg) == 0) | 2243 | else if (strcmp("verbose", arg) == 0) |
2210 | apic_verbosity = APIC_VERBOSE; | 2244 | apic_verbosity = APIC_VERBOSE; |
2211 | else { | 2245 | else { |
2212 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" | 2246 | pr_warning("APIC Verbosity level %s not recognised" |
2213 | " use apic=verbose or apic=debug\n", arg); | 2247 | " use apic=verbose or apic=debug\n", arg); |
2214 | return -EINVAL; | 2248 | return -EINVAL; |
2215 | } | 2249 | } |