aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-18 17:00:05 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-18 17:00:05 -0400
commit453c1404c5273a30d715e5a83372a78cff70b6d9 (patch)
tree94a5a3abd85137c4def416a84a45989751260f20
parenta208f37a465e222218974ab20a31b42b7b4893b2 (diff)
parent35b680557f95564f70f21a8d3f5c72e101fab260 (diff)
Merge branch 'x86/apic' into x86/x2apic
Conflicts: arch/x86/kernel/paravirt.c arch/x86/kernel/smpboot.c arch/x86/kernel/vmi_32.c arch/x86/lguest/boot.c arch/x86/xen/enlighten.c include/asm-x86/apic.h include/asm-x86/paravirt.h Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/Kconfig.cpu4
-rw-r--r--arch/x86/kernel/apic_32.c170
-rw-r--r--arch/x86/kernel/apic_64.c24
-rw-r--r--arch/x86/kernel/cpu/bugs.c23
-rw-r--r--arch/x86/kernel/cpu/intel.c10
-rw-r--r--arch/x86/kernel/cpu/mcheck/p4.c4
-rw-r--r--arch/x86/kernel/io_apic_32.c53
-rw-r--r--arch/x86/kernel/io_apic_64.c41
-rw-r--r--arch/x86/kernel/ipi.c6
-rw-r--r--arch/x86/kernel/nmi.c4
-rw-r--r--arch/x86/kernel/smpboot.c26
-rw-r--r--arch/x86/kernel/vmi_32.c1
-rw-r--r--arch/x86/lguest/boot.c1
-rw-r--r--arch/x86/xen/enlighten.c1
-rw-r--r--include/asm-x86/apic.h29
-rw-r--r--include/asm-x86/cpufeature.h1
-rw-r--r--include/asm-x86/mach-bigsmp/mach_apic.h4
-rw-r--r--include/asm-x86/mach-default/mach_apic.h4
-rw-r--r--include/asm-x86/mach-es7000/mach_apic.h4
-rw-r--r--include/asm-x86/mach-summit/mach_apic.h4
20 files changed, 197 insertions, 217 deletions
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index abff1b84ed5b..54b8c02c71e6 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -362,10 +362,6 @@ config X86_ALIGNMENT_16
362 def_bool y 362 def_bool y
363 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 363 depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
364 364
365config X86_GOOD_APIC
366 def_bool y
367 depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64
368
369config X86_INTEL_USERCOPY 365config X86_INTEL_USERCOPY
370 def_bool y 366 def_bool y
371 depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 367 depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index 34101962fb0e..dcb897f22aa2 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -75,7 +75,7 @@ char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
75/* 75/*
76 * Debug level, exported for io_apic.c 76 * Debug level, exported for io_apic.c
77 */ 77 */
78int apic_verbosity; 78unsigned int apic_verbosity;
79 79
80int pic_mode; 80int pic_mode;
81 81
@@ -211,7 +211,7 @@ void __cpuinit enable_NMI_through_LVT0(void)
211 /* Level triggered for 82489DX */ 211 /* Level triggered for 82489DX */
212 if (!lapic_is_integrated()) 212 if (!lapic_is_integrated())
213 v |= APIC_LVT_LEVEL_TRIGGER; 213 v |= APIC_LVT_LEVEL_TRIGGER;
214 apic_write_around(APIC_LVT0, v); 214 apic_write(APIC_LVT0, v);
215} 215}
216 216
217/** 217/**
@@ -246,9 +246,6 @@ int lapic_get_maxlvt(void)
246 * this function twice on the boot CPU, once with a bogus timeout 246 * this function twice on the boot CPU, once with a bogus timeout
247 * value, second time for real. The other (noncalibrating) CPUs 247 * value, second time for real. The other (noncalibrating) CPUs
248 * call this function only once, with the real, calibrated value. 248 * call this function only once, with the real, calibrated value.
249 *
250 * We do reads before writes even if unnecessary, to get around the
251 * P5 APIC double write bug.
252 */ 249 */
253static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) 250static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
254{ 251{
@@ -263,18 +260,18 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
263 if (!irqen) 260 if (!irqen)
264 lvtt_value |= APIC_LVT_MASKED; 261 lvtt_value |= APIC_LVT_MASKED;
265 262
266 apic_write_around(APIC_LVTT, lvtt_value); 263 apic_write(APIC_LVTT, lvtt_value);
267 264
268 /* 265 /*
269 * Divide PICLK by 16 266 * Divide PICLK by 16
270 */ 267 */
271 tmp_value = apic_read(APIC_TDCR); 268 tmp_value = apic_read(APIC_TDCR);
272 apic_write_around(APIC_TDCR, (tmp_value 269 apic_write(APIC_TDCR,
273 & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) 270 (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
274 | APIC_TDR_DIV_16); 271 APIC_TDR_DIV_16);
275 272
276 if (!oneshot) 273 if (!oneshot)
277 apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR); 274 apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
278} 275}
279 276
280/* 277/*
@@ -283,7 +280,7 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
283static int lapic_next_event(unsigned long delta, 280static int lapic_next_event(unsigned long delta,
284 struct clock_event_device *evt) 281 struct clock_event_device *evt)
285{ 282{
286 apic_write_around(APIC_TMICT, delta); 283 apic_write(APIC_TMICT, delta);
287 return 0; 284 return 0;
288} 285}
289 286
@@ -312,7 +309,7 @@ static void lapic_timer_setup(enum clock_event_mode mode,
312 case CLOCK_EVT_MODE_SHUTDOWN: 309 case CLOCK_EVT_MODE_SHUTDOWN:
313 v = apic_read(APIC_LVTT); 310 v = apic_read(APIC_LVTT);
314 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); 311 v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
315 apic_write_around(APIC_LVTT, v); 312 apic_write(APIC_LVTT, v);
316 break; 313 break;
317 case CLOCK_EVT_MODE_RESUME: 314 case CLOCK_EVT_MODE_RESUME:
318 /* Nothing to do here */ 315 /* Nothing to do here */
@@ -406,12 +403,7 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
406 } 403 }
407} 404}
408 405
409/* 406static int __init calibrate_APIC_clock(void)
410 * Setup the boot APIC
411 *
412 * Calibrate and verify the result.
413 */
414void __init setup_boot_APIC_clock(void)
415{ 407{
416 struct clock_event_device *levt = &__get_cpu_var(lapic_events); 408 struct clock_event_device *levt = &__get_cpu_var(lapic_events);
417 const long pm_100ms = PMTMR_TICKS_PER_SEC/10; 409 const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
@@ -421,24 +413,6 @@ void __init setup_boot_APIC_clock(void)
421 long delta, deltapm; 413 long delta, deltapm;
422 int pm_referenced = 0; 414 int pm_referenced = 0;
423 415
424 /*
425 * The local apic timer can be disabled via the kernel
426 * commandline or from the CPU detection code. Register the lapic
427 * timer as a dummy clock event source on SMP systems, so the
428 * broadcast mechanism is used. On UP systems simply ignore it.
429 */
430 if (local_apic_timer_disabled) {
431 /* No broadcast on UP ! */
432 if (num_possible_cpus() > 1) {
433 lapic_clockevent.mult = 1;
434 setup_APIC_timer();
435 }
436 return;
437 }
438
439 apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
440 "calibrating APIC timer ...\n");
441
442 local_irq_disable(); 416 local_irq_disable();
443 417
444 /* Replace the global interrupt handler */ 418 /* Replace the global interrupt handler */
@@ -523,8 +497,6 @@ void __init setup_boot_APIC_clock(void)
523 calibration_result / (1000000 / HZ), 497 calibration_result / (1000000 / HZ),
524 calibration_result % (1000000 / HZ)); 498 calibration_result % (1000000 / HZ));
525 499
526 local_apic_timer_verify_ok = 1;
527
528 /* 500 /*
529 * Do a sanity check on the APIC calibration result 501 * Do a sanity check on the APIC calibration result
530 */ 502 */
@@ -532,12 +504,11 @@ void __init setup_boot_APIC_clock(void)
532 local_irq_enable(); 504 local_irq_enable();
533 printk(KERN_WARNING 505 printk(KERN_WARNING
534 "APIC frequency too slow, disabling apic timer\n"); 506 "APIC frequency too slow, disabling apic timer\n");
535 /* No broadcast on UP ! */ 507 return -1;
536 if (num_possible_cpus() > 1)
537 setup_APIC_timer();
538 return;
539 } 508 }
540 509
510 local_apic_timer_verify_ok = 1;
511
541 /* We trust the pm timer based calibration */ 512 /* We trust the pm timer based calibration */
542 if (!pm_referenced) { 513 if (!pm_referenced) {
543 apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); 514 apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -577,22 +548,55 @@ void __init setup_boot_APIC_clock(void)
577 if (!local_apic_timer_verify_ok) { 548 if (!local_apic_timer_verify_ok) {
578 printk(KERN_WARNING 549 printk(KERN_WARNING
579 "APIC timer disabled due to verification failure.\n"); 550 "APIC timer disabled due to verification failure.\n");
551 return -1;
552 }
553
554 return 0;
555}
556
557/*
558 * Setup the boot APIC
559 *
560 * Calibrate and verify the result.
561 */
562void __init setup_boot_APIC_clock(void)
563{
564 /*
565 * The local apic timer can be disabled via the kernel
566 * commandline or from the CPU detection code. Register the lapic
567 * timer as a dummy clock event source on SMP systems, so the
568 * broadcast mechanism is used. On UP systems simply ignore it.
569 */
570 if (local_apic_timer_disabled) {
580 /* No broadcast on UP ! */ 571 /* No broadcast on UP ! */
581 if (num_possible_cpus() == 1) 572 if (num_possible_cpus() > 1) {
582 return; 573 lapic_clockevent.mult = 1;
583 } else { 574 setup_APIC_timer();
584 /* 575 }
585 * If nmi_watchdog is set to IO_APIC, we need the 576 return;
586 * PIT/HPET going. Otherwise register lapic as a dummy
587 * device.
588 */
589 if (nmi_watchdog != NMI_IO_APIC)
590 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
591 else
592 printk(KERN_WARNING "APIC timer registered as dummy,"
593 " due to nmi_watchdog=%d!\n", nmi_watchdog);
594 } 577 }
595 578
579 apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
580 "calibrating APIC timer ...\n");
581
582 if (calibrate_APIC_clock()) {
583 /* No broadcast on UP ! */
584 if (num_possible_cpus() > 1)
585 setup_APIC_timer();
586 return;
587 }
588
589 /*
590 * If nmi_watchdog is set to IO_APIC, we need the
591 * PIT/HPET going. Otherwise register lapic as a dummy
592 * device.
593 */
594 if (nmi_watchdog != NMI_IO_APIC)
595 lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
596 else
597 printk(KERN_WARNING "APIC timer registered as dummy,"
598 " due to nmi_watchdog=%d!\n", nmi_watchdog);
599
596 /* Setup the lapic or request the broadcast */ 600 /* Setup the lapic or request the broadcast */
597 setup_APIC_timer(); 601 setup_APIC_timer();
598} 602}
@@ -727,44 +731,44 @@ void clear_local_APIC(void)
727 */ 731 */
728 if (maxlvt >= 3) { 732 if (maxlvt >= 3) {
729 v = ERROR_APIC_VECTOR; /* any non-zero vector will do */ 733 v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
730 apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED); 734 apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
731 } 735 }
732 /* 736 /*
733 * Careful: we have to set masks only first to deassert 737 * Careful: we have to set masks only first to deassert
734 * any level-triggered sources. 738 * any level-triggered sources.
735 */ 739 */
736 v = apic_read(APIC_LVTT); 740 v = apic_read(APIC_LVTT);
737 apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED); 741 apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
738 v = apic_read(APIC_LVT0); 742 v = apic_read(APIC_LVT0);
739 apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); 743 apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
740 v = apic_read(APIC_LVT1); 744 v = apic_read(APIC_LVT1);
741 apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED); 745 apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
742 if (maxlvt >= 4) { 746 if (maxlvt >= 4) {
743 v = apic_read(APIC_LVTPC); 747 v = apic_read(APIC_LVTPC);
744 apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED); 748 apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
745 } 749 }
746 750
747 /* lets not touch this if we didn't frob it */ 751 /* lets not touch this if we didn't frob it */
748#ifdef CONFIG_X86_MCE_P4THERMAL 752#ifdef CONFIG_X86_MCE_P4THERMAL
749 if (maxlvt >= 5) { 753 if (maxlvt >= 5) {
750 v = apic_read(APIC_LVTTHMR); 754 v = apic_read(APIC_LVTTHMR);
751 apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED); 755 apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
752 } 756 }
753#endif 757#endif
754 /* 758 /*
755 * Clean APIC state for other OSs: 759 * Clean APIC state for other OSs:
756 */ 760 */
757 apic_write_around(APIC_LVTT, APIC_LVT_MASKED); 761 apic_write(APIC_LVTT, APIC_LVT_MASKED);
758 apic_write_around(APIC_LVT0, APIC_LVT_MASKED); 762 apic_write(APIC_LVT0, APIC_LVT_MASKED);
759 apic_write_around(APIC_LVT1, APIC_LVT_MASKED); 763 apic_write(APIC_LVT1, APIC_LVT_MASKED);
760 if (maxlvt >= 3) 764 if (maxlvt >= 3)
761 apic_write_around(APIC_LVTERR, APIC_LVT_MASKED); 765 apic_write(APIC_LVTERR, APIC_LVT_MASKED);
762 if (maxlvt >= 4) 766 if (maxlvt >= 4)
763 apic_write_around(APIC_LVTPC, APIC_LVT_MASKED); 767 apic_write(APIC_LVTPC, APIC_LVT_MASKED);
764 768
765#ifdef CONFIG_X86_MCE_P4THERMAL 769#ifdef CONFIG_X86_MCE_P4THERMAL
766 if (maxlvt >= 5) 770 if (maxlvt >= 5)
767 apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED); 771 apic_write(APIC_LVTTHMR, APIC_LVT_MASKED);
768#endif 772#endif
769 /* Integrated APIC (!82489DX) ? */ 773 /* Integrated APIC (!82489DX) ? */
770 if (lapic_is_integrated()) { 774 if (lapic_is_integrated()) {
@@ -790,7 +794,7 @@ void disable_local_APIC(void)
790 */ 794 */
791 value = apic_read(APIC_SPIV); 795 value = apic_read(APIC_SPIV);
792 value &= ~APIC_SPIV_APIC_ENABLED; 796 value &= ~APIC_SPIV_APIC_ENABLED;
793 apic_write_around(APIC_SPIV, value); 797 apic_write(APIC_SPIV, value);
794 798
795 /* 799 /*
796 * When LAPIC was disabled by the BIOS and enabled by the kernel, 800 * When LAPIC was disabled by the BIOS and enabled by the kernel,
@@ -899,8 +903,8 @@ void __init sync_Arb_IDs(void)
899 apic_wait_icr_idle(); 903 apic_wait_icr_idle();
900 904
901 apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); 905 apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
902 apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG 906 apic_write(APIC_ICR,
903 | APIC_DM_INIT); 907 APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | APIC_DM_INIT);
904} 908}
905 909
906/* 910/*
@@ -936,16 +940,16 @@ void __init init_bsp_APIC(void)
936 else 940 else
937 value |= APIC_SPIV_FOCUS_DISABLED; 941 value |= APIC_SPIV_FOCUS_DISABLED;
938 value |= SPURIOUS_APIC_VECTOR; 942 value |= SPURIOUS_APIC_VECTOR;
939 apic_write_around(APIC_SPIV, value); 943 apic_write(APIC_SPIV, value);
940 944
941 /* 945 /*
942 * Set up the virtual wire mode. 946 * Set up the virtual wire mode.
943 */ 947 */
944 apic_write_around(APIC_LVT0, APIC_DM_EXTINT); 948 apic_write(APIC_LVT0, APIC_DM_EXTINT);
945 value = APIC_DM_NMI; 949 value = APIC_DM_NMI;
946 if (!lapic_is_integrated()) /* 82489DX */ 950 if (!lapic_is_integrated()) /* 82489DX */
947 value |= APIC_LVT_LEVEL_TRIGGER; 951 value |= APIC_LVT_LEVEL_TRIGGER;
948 apic_write_around(APIC_LVT1, value); 952 apic_write(APIC_LVT1, value);
949} 953}
950 954
951static void __cpuinit lapic_setup_esr(void) 955static void __cpuinit lapic_setup_esr(void)
@@ -960,7 +964,7 @@ static void __cpuinit lapic_setup_esr(void)
960 964
961 /* enables sending errors */ 965 /* enables sending errors */
962 value = ERROR_APIC_VECTOR; 966 value = ERROR_APIC_VECTOR;
963 apic_write_around(APIC_LVTERR, value); 967 apic_write(APIC_LVTERR, value);
964 /* 968 /*
965 * spec says clear errors after enabling vector. 969 * spec says clear errors after enabling vector.
966 */ 970 */
@@ -1023,7 +1027,7 @@ void __cpuinit setup_local_APIC(void)
1023 */ 1027 */
1024 value = apic_read(APIC_TASKPRI); 1028 value = apic_read(APIC_TASKPRI);
1025 value &= ~APIC_TPRI_MASK; 1029 value &= ~APIC_TPRI_MASK;
1026 apic_write_around(APIC_TASKPRI, value); 1030 apic_write(APIC_TASKPRI, value);
1027 1031
1028 /* 1032 /*
1029 * After a crash, we no longer service the interrupts and a pending 1033 * After a crash, we no longer service the interrupts and a pending
@@ -1081,7 +1085,7 @@ void __cpuinit setup_local_APIC(void)
1081 * Set spurious IRQ vector 1085 * Set spurious IRQ vector
1082 */ 1086 */
1083 value |= SPURIOUS_APIC_VECTOR; 1087 value |= SPURIOUS_APIC_VECTOR;
1084 apic_write_around(APIC_SPIV, value); 1088 apic_write(APIC_SPIV, value);
1085 1089
1086 /* 1090 /*
1087 * Set up LVT0, LVT1: 1091 * Set up LVT0, LVT1:
@@ -1103,7 +1107,7 @@ void __cpuinit setup_local_APIC(void)
1103 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", 1107 apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
1104 smp_processor_id()); 1108 smp_processor_id());
1105 } 1109 }
1106 apic_write_around(APIC_LVT0, value); 1110 apic_write(APIC_LVT0, value);
1107 1111
1108 /* 1112 /*
1109 * only the BP should see the LINT1 NMI signal, obviously. 1113 * only the BP should see the LINT1 NMI signal, obviously.
@@ -1114,7 +1118,7 @@ void __cpuinit setup_local_APIC(void)
1114 value = APIC_DM_NMI | APIC_LVT_MASKED; 1118 value = APIC_DM_NMI | APIC_LVT_MASKED;
1115 if (!integrated) /* 82489DX */ 1119 if (!integrated) /* 82489DX */
1116 value |= APIC_LVT_LEVEL_TRIGGER; 1120 value |= APIC_LVT_LEVEL_TRIGGER;
1117 apic_write_around(APIC_LVT1, value); 1121 apic_write(APIC_LVT1, value);
1118} 1122}
1119 1123
1120void __cpuinit end_local_APIC_setup(void) 1124void __cpuinit end_local_APIC_setup(void)
@@ -1125,7 +1129,7 @@ void __cpuinit end_local_APIC_setup(void)
1125 /* Disable the local apic timer */ 1129 /* Disable the local apic timer */
1126 value = apic_read(APIC_LVTT); 1130 value = apic_read(APIC_LVTT);
1127 value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); 1131 value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
1128 apic_write_around(APIC_LVTT, value); 1132 apic_write(APIC_LVTT, value);
1129 1133
1130 setup_apic_nmi_watchdog(NULL); 1134 setup_apic_nmi_watchdog(NULL);
1131 apic_pm_activate(); 1135 apic_pm_activate();
@@ -1453,7 +1457,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
1453 value &= ~APIC_VECTOR_MASK; 1457 value &= ~APIC_VECTOR_MASK;
1454 value |= APIC_SPIV_APIC_ENABLED; 1458 value |= APIC_SPIV_APIC_ENABLED;
1455 value |= 0xf; 1459 value |= 0xf;
1456 apic_write_around(APIC_SPIV, value); 1460 apic_write(APIC_SPIV, value);
1457 1461
1458 if (!virt_wire_setup) { 1462 if (!virt_wire_setup) {
1459 /* 1463 /*
@@ -1466,10 +1470,10 @@ void disconnect_bsp_APIC(int virt_wire_setup)
1466 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); 1470 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
1467 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; 1471 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
1468 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); 1472 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
1469 apic_write_around(APIC_LVT0, value); 1473 apic_write(APIC_LVT0, value);
1470 } else { 1474 } else {
1471 /* Disable LVT0 */ 1475 /* Disable LVT0 */
1472 apic_write_around(APIC_LVT0, APIC_LVT_MASKED); 1476 apic_write(APIC_LVT0, APIC_LVT_MASKED);
1473 } 1477 }
1474 1478
1475 /* 1479 /*
@@ -1483,7 +1487,7 @@ void disconnect_bsp_APIC(int virt_wire_setup)
1483 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); 1487 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
1484 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; 1488 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
1485 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); 1489 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
1486 apic_write_around(APIC_LVT1, value); 1490 apic_write(APIC_LVT1, value);
1487 } 1491 }
1488} 1492}
1489 1493
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
index c75f58a66d8e..46e612408aca 100644
--- a/arch/x86/kernel/apic_64.c
+++ b/arch/x86/kernel/apic_64.c
@@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
61/* 61/*
62 * Debug level, exported for io_apic.c 62 * Debug level, exported for io_apic.c
63 */ 63 */
64int apic_verbosity; 64unsigned int apic_verbosity;
65 65
66/* Have we found an MP table */ 66/* Have we found an MP table */
67int smp_found_config; 67int smp_found_config;
@@ -386,7 +386,7 @@ static void setup_APIC_timer(void)
386 386
387#define TICK_COUNT 100000000 387#define TICK_COUNT 100000000
388 388
389static void __init calibrate_APIC_clock(void) 389static int __init calibrate_APIC_clock(void)
390{ 390{
391 unsigned apic, apic_start; 391 unsigned apic, apic_start;
392 unsigned long tsc, tsc_start; 392 unsigned long tsc, tsc_start;
@@ -440,6 +440,17 @@ static void __init calibrate_APIC_clock(void)
440 clockevent_delta2ns(0xF, &lapic_clockevent); 440 clockevent_delta2ns(0xF, &lapic_clockevent);
441 441
442 calibration_result = result / HZ; 442 calibration_result = result / HZ;
443
444 /*
445 * Do a sanity check on the APIC calibration result
446 */
447 if (calibration_result < (1000000 / HZ)) {
448 printk(KERN_WARNING
449 "APIC frequency too slow, disabling apic timer\n");
450 return -1;
451 }
452
453 return 0;
443} 454}
444 455
445/* 456/*
@@ -466,14 +477,7 @@ void __init setup_boot_APIC_clock(void)
466 } 477 }
467 478
468 printk(KERN_INFO "Using local APIC timer interrupts.\n"); 479 printk(KERN_INFO "Using local APIC timer interrupts.\n");
469 calibrate_APIC_clock(); 480 if (calibrate_APIC_clock()) {
470
471 /*
472 * Do a sanity check on the APIC calibration result
473 */
474 if (calibration_result < (1000000 / HZ)) {
475 printk(KERN_WARNING
476 "APIC frequency too slow, disabling apic timer\n");
477 /* No broadcast on UP ! */ 481 /* No broadcast on UP ! */
478 if (num_possible_cpus() > 1) 482 if (num_possible_cpus() > 1)
479 setup_APIC_timer(); 483 setup_APIC_timer();
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 1b1c56bb338f..c9b58a806e85 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -131,13 +131,7 @@ static void __init check_popad(void)
131 * (for due to lack of "invlpg" and working WP on a i386) 131 * (for due to lack of "invlpg" and working WP on a i386)
132 * - In order to run on anything without a TSC, we need to be 132 * - In order to run on anything without a TSC, we need to be
133 * compiled for a i486. 133 * compiled for a i486.
134 * - In order to support the local APIC on a buggy Pentium machine, 134 */
135 * we need to be compiled with CONFIG_X86_GOOD_APIC disabled,
136 * which happens implicitly if compiled for a Pentium or lower
137 * (unless an advanced selection of CPU features is used) as an
138 * otherwise config implies a properly working local APIC without
139 * the need to do extra reads from the APIC.
140*/
141 135
142static void __init check_config(void) 136static void __init check_config(void)
143{ 137{
@@ -151,21 +145,6 @@ static void __init check_config(void)
151 if (boot_cpu_data.x86 == 3) 145 if (boot_cpu_data.x86 == 3)
152 panic("Kernel requires i486+ for 'invlpg' and other features"); 146 panic("Kernel requires i486+ for 'invlpg' and other features");
153#endif 147#endif
154
155/*
156 * If we were told we had a good local APIC, check for buggy Pentia,
157 * i.e. all B steppings and the C2 stepping of P54C when using their
158 * integrated APIC (see 11AP erratum in "Pentium Processor
159 * Specification Update").
160 */
161#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC)
162 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL
163 && cpu_has_apic
164 && boot_cpu_data.x86 == 5
165 && boot_cpu_data.x86_model == 2
166 && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11))
167 panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!");
168#endif
169} 148}
170 149
171 150
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 70609efdf1da..b75f2569b8f8 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -227,6 +227,16 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
227 if (cpu_has_bts) 227 if (cpu_has_bts)
228 ds_init_intel(c); 228 ds_init_intel(c);
229 229
230 /*
231 * See if we have a good local APIC by checking for buggy Pentia,
232 * i.e. all B steppings and the C2 stepping of P54C when using their
233 * integrated APIC (see 11AP erratum in "Pentium Processor
234 * Specification Update").
235 */
236 if (cpu_has_apic && (c->x86<<8 | c->x86_model<<4) == 0x520 &&
237 (c->x86_mask < 0x6 || c->x86_mask == 0xb))
238 set_cpu_cap(c, X86_FEATURE_11AP);
239
230#ifdef CONFIG_X86_NUMAQ 240#ifdef CONFIG_X86_NUMAQ
231 numaq_tsc_disable(); 241 numaq_tsc_disable();
232#endif 242#endif
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c
index eef001ad3bde..9b60fce09f75 100644
--- a/arch/x86/kernel/cpu/mcheck/p4.c
+++ b/arch/x86/kernel/cpu/mcheck/p4.c
@@ -102,7 +102,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
102 /* The temperature transition interrupt handler setup */ 102 /* The temperature transition interrupt handler setup */
103 h = THERMAL_APIC_VECTOR; /* our delivery vector */ 103 h = THERMAL_APIC_VECTOR; /* our delivery vector */
104 h |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */ 104 h |= (APIC_DM_FIXED | APIC_LVT_MASKED); /* we'll mask till we're ready */
105 apic_write_around(APIC_LVTTHMR, h); 105 apic_write(APIC_LVTTHMR, h);
106 106
107 rdmsr(MSR_IA32_THERM_INTERRUPT, l, h); 107 rdmsr(MSR_IA32_THERM_INTERRUPT, l, h);
108 wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h); 108 wrmsr(MSR_IA32_THERM_INTERRUPT, l | 0x03 , h);
@@ -114,7 +114,7 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
114 wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h); 114 wrmsr(MSR_IA32_MISC_ENABLE, l | (1<<3), h);
115 115
116 l = apic_read(APIC_LVTTHMR); 116 l = apic_read(APIC_LVTTHMR);
117 apic_write_around(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); 117 apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
118 printk(KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); 118 printk(KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu);
119 119
120 /* enable thermal throttle processing */ 120 /* enable thermal throttle processing */
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index a82065b0699e..98e4db5373f3 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -756,7 +756,7 @@ void send_IPI_self(int vector)
756 /* 756 /*
757 * Send the IPI. The write to APIC_ICR fires this off. 757 * Send the IPI. The write to APIC_ICR fires this off.
758 */ 758 */
759 apic_write_around(APIC_ICR, cfg); 759 apic_write(APIC_ICR, cfg);
760} 760}
761#endif /* !CONFIG_SMP */ 761#endif /* !CONFIG_SMP */
762 762
@@ -2029,7 +2029,7 @@ static void mask_lapic_irq(unsigned int irq)
2029 unsigned long v; 2029 unsigned long v;
2030 2030
2031 v = apic_read(APIC_LVT0); 2031 v = apic_read(APIC_LVT0);
2032 apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); 2032 apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
2033} 2033}
2034 2034
2035static void unmask_lapic_irq(unsigned int irq) 2035static void unmask_lapic_irq(unsigned int irq)
@@ -2037,7 +2037,7 @@ static void unmask_lapic_irq(unsigned int irq)
2037 unsigned long v; 2037 unsigned long v;
2038 2038
2039 v = apic_read(APIC_LVT0); 2039 v = apic_read(APIC_LVT0);
2040 apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); 2040 apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
2041} 2041}
2042 2042
2043static struct irq_chip lapic_chip __read_mostly = { 2043static struct irq_chip lapic_chip __read_mostly = {
@@ -2167,7 +2167,7 @@ static inline void __init check_timer(void)
2167 * The AEOI mode will finish them in the 8259A 2167 * The AEOI mode will finish them in the 8259A
2168 * automatically. 2168 * automatically.
2169 */ 2169 */
2170 apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); 2170 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
2171 init_8259A(1); 2171 init_8259A(1);
2172 timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); 2172 timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
2173 2173
@@ -2176,8 +2176,9 @@ static inline void __init check_timer(void)
2176 pin2 = ioapic_i8259.pin; 2176 pin2 = ioapic_i8259.pin;
2177 apic2 = ioapic_i8259.apic; 2177 apic2 = ioapic_i8259.apic;
2178 2178
2179 printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", 2179 apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
2180 vector, apic1, pin1, apic2, pin2); 2180 "apic1=%d pin1=%d apic2=%d pin2=%d\n",
2181 vector, apic1, pin1, apic2, pin2);
2181 2182
2182 /* 2183 /*
2183 * Some BIOS writers are clueless and report the ExtINTA 2184 * Some BIOS writers are clueless and report the ExtINTA
@@ -2215,12 +2216,13 @@ static inline void __init check_timer(void)
2215 } 2216 }
2216 clear_IO_APIC_pin(apic1, pin1); 2217 clear_IO_APIC_pin(apic1, pin1);
2217 if (!no_pin1) 2218 if (!no_pin1)
2218 printk(KERN_ERR "..MP-BIOS bug: " 2219 apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
2219 "8254 timer not connected to IO-APIC\n"); 2220 "8254 timer not connected to IO-APIC\n");
2220 2221
2221 printk(KERN_INFO "...trying to set up timer (IRQ0) " 2222 apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
2222 "through the 8259A ... "); 2223 "(IRQ0) through the 8259A ...\n");
2223 printk("\n..... (found pin %d) ...", pin2); 2224 apic_printk(APIC_QUIET, KERN_INFO
2225 "..... (found apic %d pin %d) ...\n", apic2, pin2);
2224 /* 2226 /*
2225 * legacy devices should be connected to IO APIC #0 2227 * legacy devices should be connected to IO APIC #0
2226 */ 2228 */
@@ -2229,7 +2231,7 @@ static inline void __init check_timer(void)
2229 unmask_IO_APIC_irq(0); 2231 unmask_IO_APIC_irq(0);
2230 enable_8259A_irq(0); 2232 enable_8259A_irq(0);
2231 if (timer_irq_works()) { 2233 if (timer_irq_works()) {
2232 printk("works.\n"); 2234 apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
2233 timer_through_8259 = 1; 2235 timer_through_8259 = 1;
2234 if (nmi_watchdog == NMI_IO_APIC) { 2236 if (nmi_watchdog == NMI_IO_APIC) {
2235 disable_8259A_irq(0); 2237 disable_8259A_irq(0);
@@ -2243,44 +2245,47 @@ static inline void __init check_timer(void)
2243 */ 2245 */
2244 disable_8259A_irq(0); 2246 disable_8259A_irq(0);
2245 clear_IO_APIC_pin(apic2, pin2); 2247 clear_IO_APIC_pin(apic2, pin2);
2246 printk(" failed.\n"); 2248 apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
2247 } 2249 }
2248 2250
2249 if (nmi_watchdog == NMI_IO_APIC) { 2251 if (nmi_watchdog == NMI_IO_APIC) {
2250 printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); 2252 apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
2253 "through the IO-APIC - disabling NMI Watchdog!\n");
2251 nmi_watchdog = NMI_NONE; 2254 nmi_watchdog = NMI_NONE;
2252 } 2255 }
2253 timer_ack = 0; 2256 timer_ack = 0;
2254 2257
2255 printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); 2258 apic_printk(APIC_QUIET, KERN_INFO
2259 "...trying to set up timer as Virtual Wire IRQ...\n");
2256 2260
2257 lapic_register_intr(0, vector); 2261 lapic_register_intr(0, vector);
2258 apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ 2262 apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
2259 enable_8259A_irq(0); 2263 enable_8259A_irq(0);
2260 2264
2261 if (timer_irq_works()) { 2265 if (timer_irq_works()) {
2262 printk(" works.\n"); 2266 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
2263 goto out; 2267 goto out;
2264 } 2268 }
2265 disable_8259A_irq(0); 2269 disable_8259A_irq(0);
2266 apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector); 2270 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
2267 printk(" failed.\n"); 2271 apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
2268 2272
2269 printk(KERN_INFO "...trying to set up timer as ExtINT IRQ..."); 2273 apic_printk(APIC_QUIET, KERN_INFO
2274 "...trying to set up timer as ExtINT IRQ...\n");
2270 2275
2271 init_8259A(0); 2276 init_8259A(0);
2272 make_8259A_irq(0); 2277 make_8259A_irq(0);
2273 apic_write_around(APIC_LVT0, APIC_DM_EXTINT); 2278 apic_write(APIC_LVT0, APIC_DM_EXTINT);
2274 2279
2275 unlock_ExtINT_logic(); 2280 unlock_ExtINT_logic();
2276 2281
2277 if (timer_irq_works()) { 2282 if (timer_irq_works()) {
2278 printk(" works.\n"); 2283 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
2279 goto out; 2284 goto out;
2280 } 2285 }
2281 printk(" failed :(.\n"); 2286 apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
2282 panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " 2287 panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a "
2283 "report. Then try booting with the 'noapic' option"); 2288 "report. Then try booting with the 'noapic' option.\n");
2284out: 2289out:
2285 local_irq_restore(flags); 2290 local_irq_restore(flags);
2286} 2291}
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 39f0be37e9a1..116aac365981 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -46,6 +46,7 @@
46#include <asm/proto.h> 46#include <asm/proto.h>
47#include <asm/acpi.h> 47#include <asm/acpi.h>
48#include <asm/dma.h> 48#include <asm/dma.h>
49#include <asm/i8259.h>
49#include <asm/nmi.h> 50#include <asm/nmi.h>
50#include <asm/msidef.h> 51#include <asm/msidef.h>
51#include <asm/hypertransport.h> 52#include <asm/hypertransport.h>
@@ -2010,8 +2011,9 @@ static inline void __init check_timer(void)
2010 pin2 = ioapic_i8259.pin; 2011 pin2 = ioapic_i8259.pin;
2011 apic2 = ioapic_i8259.apic; 2012 apic2 = ioapic_i8259.apic;
2012 2013
2013 apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", 2014 apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
2014 cfg->vector, apic1, pin1, apic2, pin2); 2015 "apic1=%d pin1=%d apic2=%d pin2=%d\n",
2016 cfg->vector, apic1, pin1, apic2, pin2);
2015 2017
2016 /* 2018 /*
2017 * Some BIOS writers are clueless and report the ExtINTA 2019 * Some BIOS writers are clueless and report the ExtINTA
@@ -2053,14 +2055,13 @@ static inline void __init check_timer(void)
2053 panic("timer doesn't work through Interrupt-remapped IO-APIC"); 2055 panic("timer doesn't work through Interrupt-remapped IO-APIC");
2054 clear_IO_APIC_pin(apic1, pin1); 2056 clear_IO_APIC_pin(apic1, pin1);
2055 if (!no_pin1) 2057 if (!no_pin1)
2056 apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: " 2058 apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
2057 "8254 timer not connected to IO-APIC\n"); 2059 "8254 timer not connected to IO-APIC\n");
2058 2060
2059 apic_printk(APIC_VERBOSE,KERN_INFO 2061 apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
2060 "...trying to set up timer (IRQ0) " 2062 "(IRQ0) through the 8259A ...\n");
2061 "through the 8259A ... "); 2063 apic_printk(APIC_QUIET, KERN_INFO
2062 apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...", 2064 "..... (found apic %d pin %d) ...\n", apic2, pin2);
2063 apic2, pin2);
2064 /* 2065 /*
2065 * legacy devices should be connected to IO APIC #0 2066 * legacy devices should be connected to IO APIC #0
2066 */ 2067 */
@@ -2069,7 +2070,7 @@ static inline void __init check_timer(void)
2069 unmask_IO_APIC_irq(0); 2070 unmask_IO_APIC_irq(0);
2070 enable_8259A_irq(0); 2071 enable_8259A_irq(0);
2071 if (timer_irq_works()) { 2072 if (timer_irq_works()) {
2072 apic_printk(APIC_VERBOSE," works.\n"); 2073 apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
2073 timer_through_8259 = 1; 2074 timer_through_8259 = 1;
2074 if (nmi_watchdog == NMI_IO_APIC) { 2075 if (nmi_watchdog == NMI_IO_APIC) {
2075 disable_8259A_irq(0); 2076 disable_8259A_irq(0);
@@ -2083,29 +2084,32 @@ static inline void __init check_timer(void)
2083 */ 2084 */
2084 disable_8259A_irq(0); 2085 disable_8259A_irq(0);
2085 clear_IO_APIC_pin(apic2, pin2); 2086 clear_IO_APIC_pin(apic2, pin2);
2086 apic_printk(APIC_VERBOSE," failed.\n"); 2087 apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
2087 } 2088 }
2088 2089
2089 if (nmi_watchdog == NMI_IO_APIC) { 2090 if (nmi_watchdog == NMI_IO_APIC) {
2090 printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); 2091 apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
2092 "through the IO-APIC - disabling NMI Watchdog!\n");
2091 nmi_watchdog = NMI_NONE; 2093 nmi_watchdog = NMI_NONE;
2092 } 2094 }
2093 2095
2094 apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); 2096 apic_printk(APIC_QUIET, KERN_INFO
2097 "...trying to set up timer as Virtual Wire IRQ...\n");
2095 2098
2096 lapic_register_intr(0); 2099 lapic_register_intr(0);
2097 apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ 2100 apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
2098 enable_8259A_irq(0); 2101 enable_8259A_irq(0);
2099 2102
2100 if (timer_irq_works()) { 2103 if (timer_irq_works()) {
2101 apic_printk(APIC_VERBOSE," works.\n"); 2104 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
2102 goto out; 2105 goto out;
2103 } 2106 }
2104 disable_8259A_irq(0); 2107 disable_8259A_irq(0);
2105 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); 2108 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
2106 apic_printk(APIC_VERBOSE," failed.\n"); 2109 apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
2107 2110
2108 apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as ExtINT IRQ..."); 2111 apic_printk(APIC_QUIET, KERN_INFO
2112 "...trying to set up timer as ExtINT IRQ...\n");
2109 2113
2110 init_8259A(0); 2114 init_8259A(0);
2111 make_8259A_irq(0); 2115 make_8259A_irq(0);
@@ -2114,11 +2118,12 @@ static inline void __init check_timer(void)
2114 unlock_ExtINT_logic(); 2118 unlock_ExtINT_logic();
2115 2119
2116 if (timer_irq_works()) { 2120 if (timer_irq_works()) {
2117 apic_printk(APIC_VERBOSE," works.\n"); 2121 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
2118 goto out; 2122 goto out;
2119 } 2123 }
2120 apic_printk(APIC_VERBOSE," failed :(.\n"); 2124 apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
2121 panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); 2125 panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a "
2126 "report. Then try booting with the 'noapic' option.\n");
2122out: 2127out:
2123 local_irq_restore(flags); 2128 local_irq_restore(flags);
2124} 2129}
diff --git a/arch/x86/kernel/ipi.c b/arch/x86/kernel/ipi.c
index 9d98cda39ad9..3f7537b669d3 100644
--- a/arch/x86/kernel/ipi.c
+++ b/arch/x86/kernel/ipi.c
@@ -70,7 +70,7 @@ void __send_IPI_shortcut(unsigned int shortcut, int vector)
70 /* 70 /*
71 * Send the IPI. The write to APIC_ICR fires this off. 71 * Send the IPI. The write to APIC_ICR fires this off.
72 */ 72 */
73 apic_write_around(APIC_ICR, cfg); 73 apic_write(APIC_ICR, cfg);
74} 74}
75 75
76void send_IPI_self(int vector) 76void send_IPI_self(int vector)
@@ -98,7 +98,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector)
98 * prepare target chip field 98 * prepare target chip field
99 */ 99 */
100 cfg = __prepare_ICR2(mask); 100 cfg = __prepare_ICR2(mask);
101 apic_write_around(APIC_ICR2, cfg); 101 apic_write(APIC_ICR2, cfg);
102 102
103 /* 103 /*
104 * program the ICR 104 * program the ICR
@@ -108,7 +108,7 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector)
108 /* 108 /*
109 * Send the IPI. The write to APIC_ICR fires this off. 109 * Send the IPI. The write to APIC_ICR fires this off.
110 */ 110 */
111 apic_write_around(APIC_ICR, cfg); 111 apic_write(APIC_ICR, cfg);
112} 112}
113 113
114/* 114/*
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index ec024b3baad0..384b49fed598 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -263,7 +263,7 @@ late_initcall(init_lapic_nmi_sysfs);
263 263
264static void __acpi_nmi_enable(void *__unused) 264static void __acpi_nmi_enable(void *__unused)
265{ 265{
266 apic_write_around(APIC_LVT0, APIC_DM_NMI); 266 apic_write(APIC_LVT0, APIC_DM_NMI);
267} 267}
268 268
269/* 269/*
@@ -277,7 +277,7 @@ void acpi_nmi_enable(void)
277 277
278static void __acpi_nmi_disable(void *__unused) 278static void __acpi_nmi_disable(void *__unused)
279{ 279{
280 apic_write_around(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); 280 apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED);
281} 281}
282 282
283/* 283/*
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 23c3b3d1f4cc..a4f2d8f06e48 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -590,14 +590,9 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
590 * Give the other CPU some time to accept the IPI. 590 * Give the other CPU some time to accept the IPI.
591 */ 591 */
592 udelay(200); 592 udelay(200);
593 /*
594 * Due to the Pentium erratum 3AP.
595 */
596 maxlvt = lapic_get_maxlvt(); 593 maxlvt = lapic_get_maxlvt();
597 if (maxlvt > 3) { 594 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
598 apic_read_around(APIC_SPIV);
599 apic_write(APIC_ESR, 0); 595 apic_write(APIC_ESR, 0);
600 }
601 accept_status = (apic_read(APIC_ESR) & 0xEF); 596 accept_status = (apic_read(APIC_ESR) & 0xEF);
602 Dprintk("NMI sent.\n"); 597 Dprintk("NMI sent.\n");
603 598
@@ -623,12 +618,14 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
623 return send_status; 618 return send_status;
624 } 619 }
625 620
621 maxlvt = lapic_get_maxlvt();
622
626 /* 623 /*
627 * Be paranoid about clearing APIC errors. 624 * Be paranoid about clearing APIC errors.
628 */ 625 */
629 if (APIC_INTEGRATED(apic_version[phys_apicid])) { 626 if (APIC_INTEGRATED(apic_version[phys_apicid])) {
630 apic_read_around(APIC_SPIV); 627 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
631 apic_write(APIC_ESR, 0); 628 apic_write(APIC_ESR, 0);
632 apic_read(APIC_ESR); 629 apic_read(APIC_ESR);
633 } 630 }
634 631
@@ -683,12 +680,10 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
683 */ 680 */
684 Dprintk("#startup loops: %d.\n", num_starts); 681 Dprintk("#startup loops: %d.\n", num_starts);
685 682
686 maxlvt = lapic_get_maxlvt();
687
688 for (j = 1; j <= num_starts; j++) { 683 for (j = 1; j <= num_starts; j++) {
689 Dprintk("Sending STARTUP #%d.\n", j); 684 Dprintk("Sending STARTUP #%d.\n", j);
690 apic_read_around(APIC_SPIV); 685 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
691 apic_write(APIC_ESR, 0); 686 apic_write(APIC_ESR, 0);
692 apic_read(APIC_ESR); 687 apic_read(APIC_ESR);
693 Dprintk("After apic_write.\n"); 688 Dprintk("After apic_write.\n");
694 689
@@ -716,13 +711,8 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
716 * Give the other CPU some time to accept the IPI. 711 * Give the other CPU some time to accept the IPI.
717 */ 712 */
718 udelay(200); 713 udelay(200);
719 /* 714 if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
720 * Due to the Pentium erratum 3AP.
721 */
722 if (maxlvt > 3) {
723 apic_read_around(APIC_SPIV);
724 apic_write(APIC_ESR, 0); 715 apic_write(APIC_ESR, 0);
725 }
726 accept_status = (apic_read(APIC_ESR) & 0xEF); 716 accept_status = (apic_read(APIC_ESR) & 0xEF);
727 if (send_status || accept_status) 717 if (send_status || accept_status)
728 break; 718 break;
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 237082833c14..45c27c4e2a6e 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -906,7 +906,6 @@ static inline int __init activate_vmi(void)
906#ifdef CONFIG_X86_LOCAL_APIC 906#ifdef CONFIG_X86_LOCAL_APIC
907 para_fill(apic_ops->read, APICRead); 907 para_fill(apic_ops->read, APICRead);
908 para_fill(apic_ops->write, APICWrite); 908 para_fill(apic_ops->write, APICWrite);
909 para_fill(apic_ops->write_atomic, APICWrite);
910#endif 909#endif
911 910
912 /* 911 /*
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 675ee7a6475e..35c4349cd668 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -816,7 +816,6 @@ static u32 lguest_apic_safe_wait_icr_idle(void)
816static struct apic_ops lguest_basic_apic_ops = { 816static struct apic_ops lguest_basic_apic_ops = {
817 .read = lguest_apic_read, 817 .read = lguest_apic_read,
818 .write = lguest_apic_write, 818 .write = lguest_apic_write,
819 .write_atomic = lguest_apic_write,
820 .icr_read = lguest_apic_icr_read, 819 .icr_read = lguest_apic_icr_read,
821 .icr_write = lguest_apic_icr_write, 820 .icr_write = lguest_apic_icr_write,
822 .wait_icr_idle = lguest_apic_wait_icr_idle, 821 .wait_icr_idle = lguest_apic_wait_icr_idle,
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 402f3e2c7bee..008b7b69581e 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -583,7 +583,6 @@ static u32 xen_safe_apic_wait_icr_idle(void)
583static struct apic_ops xen_basic_apic_ops = { 583static struct apic_ops xen_basic_apic_ops = {
584 .read = xen_apic_read, 584 .read = xen_apic_read,
585 .write = xen_apic_write, 585 .write = xen_apic_write,
586 .write_atomic = xen_apic_write,
587 .icr_read = xen_apic_icr_read, 586 .icr_read = xen_apic_icr_read,
588 .icr_write = xen_apic_icr_write, 587 .icr_write = xen_apic_icr_write,
589 .wait_icr_idle = xen_apic_wait_icr_idle, 588 .wait_icr_idle = xen_apic_wait_icr_idle,
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h
index fcd2f01277b6..300b65e57240 100644
--- a/include/asm-x86/apic.h
+++ b/include/asm-x86/apic.h
@@ -3,6 +3,8 @@
3 3
4#include <linux/pm.h> 4#include <linux/pm.h>
5#include <linux/delay.h> 5#include <linux/delay.h>
6
7#include <asm/alternative.h>
6#include <asm/fixmap.h> 8#include <asm/fixmap.h>
7#include <asm/apicdef.h> 9#include <asm/apicdef.h>
8#include <asm/processor.h> 10#include <asm/processor.h>
@@ -12,7 +14,7 @@
12 14
13#define ARCH_APICTIMER_STOPS_ON_C3 1 15#define ARCH_APICTIMER_STOPS_ON_C3 1
14 16
15#define Dprintk(x...) 17#define Dprintk printk
16 18
17/* 19/*
18 * Debugging macros 20 * Debugging macros
@@ -37,7 +39,7 @@ extern void generic_apic_probe(void);
37 39
38#ifdef CONFIG_X86_LOCAL_APIC 40#ifdef CONFIG_X86_LOCAL_APIC
39 41
40extern int apic_verbosity; 42extern unsigned int apic_verbosity;
41extern int local_apic_timer_c2_ok; 43extern int local_apic_timer_c2_ok;
42 44
43extern int ioapic_force; 45extern int ioapic_force;
@@ -57,12 +59,11 @@ extern int is_vsmp_box(void);
57 59
58static inline void native_apic_mem_write(u32 reg, u32 v) 60static inline void native_apic_mem_write(u32 reg, u32 v)
59{ 61{
60 *((volatile u32 *)(APIC_BASE + reg)) = v; 62 volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
61}
62 63
63static inline void native_apic_mem_write_atomic(u32 reg, u32 v) 64 alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP,
64{ 65 ASM_OUTPUT2("=r" (v), "=m" (*addr)),
65 (void)xchg((u32 *)(APIC_BASE + reg), v); 66 ASM_OUTPUT2("0" (v), "m" (*addr)));
66} 67}
67 68
68static inline u32 native_apic_mem_read(u32 reg) 69static inline u32 native_apic_mem_read(u32 reg)
@@ -101,7 +102,6 @@ extern void x2apic_icr_write(u32 low, u32 id);
101struct apic_ops { 102struct apic_ops {
102 u32 (*read)(u32 reg); 103 u32 (*read)(u32 reg);
103 void (*write)(u32 reg, u32 v); 104 void (*write)(u32 reg, u32 v);
104 void (*write_atomic)(u32 reg, u32 v);
105 u64 (*icr_read)(void); 105 u64 (*icr_read)(void);
106 void (*icr_write)(u32 low, u32 high); 106 void (*icr_write)(u32 low, u32 high);
107 void (*wait_icr_idle)(void); 107 void (*wait_icr_idle)(void);
@@ -112,7 +112,6 @@ extern struct apic_ops *apic_ops;
112 112
113#define apic_read (apic_ops->read) 113#define apic_read (apic_ops->read)
114#define apic_write (apic_ops->write) 114#define apic_write (apic_ops->write)
115#define apic_write_atomic (apic_ops->write_atomic)
116#define apic_icr_read (apic_ops->icr_read) 115#define apic_icr_read (apic_ops->icr_read)
117#define apic_icr_write (apic_ops->icr_write) 116#define apic_icr_write (apic_ops->icr_write)
118#define apic_wait_icr_idle (apic_ops->wait_icr_idle) 117#define apic_wait_icr_idle (apic_ops->wait_icr_idle)
@@ -120,16 +119,6 @@ extern struct apic_ops *apic_ops;
120 119
121extern int get_physical_broadcast(void); 120extern int get_physical_broadcast(void);
122 121
123#ifdef CONFIG_X86_GOOD_APIC
124# define FORCE_READ_AROUND_WRITE 0
125# define apic_read_around(x)
126# define apic_write_around(x, y) apic_write((x), (y))
127#else
128# define FORCE_READ_AROUND_WRITE 1
129# define apic_read_around(x) apic_read(x)
130# define apic_write_around(x, y) apic_write_atomic((x), (y))
131#endif
132
133#ifdef CONFIG_X86_64 122#ifdef CONFIG_X86_64
134static inline void ack_x2APIC_irq(void) 123static inline void ack_x2APIC_irq(void)
135{ 124{
@@ -150,7 +139,7 @@ static inline void ack_APIC_irq(void)
150 139
151 /* Docs say use 0 for future compatibility */ 140 /* Docs say use 0 for future compatibility */
152#ifdef CONFIG_X86_32 141#ifdef CONFIG_X86_32
153 apic_write_around(APIC_EOI, 0); 142 apic_write(APIC_EOI, 0);
154#else 143#else
155 native_apic_mem_write(APIC_EOI, 0); 144 native_apic_mem_write(APIC_EOI, 0);
156#endif 145#endif
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
index 5be9510ee012..89a7af37e37e 100644
--- a/include/asm-x86/cpufeature.h
+++ b/include/asm-x86/cpufeature.h
@@ -79,6 +79,7 @@
79#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */ 79#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */
80#define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */ 80#define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
81#define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */ 81#define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
82#define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */
82 83
83/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ 84/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
84#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ 85#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-x86/mach-bigsmp/mach_apic.h b/include/asm-x86/mach-bigsmp/mach_apic.h
index 017c8c19ad8f..c3b9dc6970c9 100644
--- a/include/asm-x86/mach-bigsmp/mach_apic.h
+++ b/include/asm-x86/mach-bigsmp/mach_apic.h
@@ -63,9 +63,9 @@ static inline void init_apic_ldr(void)
63 unsigned long val; 63 unsigned long val;
64 int cpu = smp_processor_id(); 64 int cpu = smp_processor_id();
65 65
66 apic_write_around(APIC_DFR, APIC_DFR_VALUE); 66 apic_write(APIC_DFR, APIC_DFR_VALUE);
67 val = calculate_ldr(cpu); 67 val = calculate_ldr(cpu);
68 apic_write_around(APIC_LDR, val); 68 apic_write(APIC_LDR, val);
69} 69}
70 70
71static inline void setup_apic_routing(void) 71static inline void setup_apic_routing(void)
diff --git a/include/asm-x86/mach-default/mach_apic.h b/include/asm-x86/mach-default/mach_apic.h
index 3d2b455581ec..e7ff8ac6abc5 100644
--- a/include/asm-x86/mach-default/mach_apic.h
+++ b/include/asm-x86/mach-default/mach_apic.h
@@ -48,10 +48,10 @@ static inline void init_apic_ldr(void)
48{ 48{
49 unsigned long val; 49 unsigned long val;
50 50
51 apic_write_around(APIC_DFR, APIC_DFR_VALUE); 51 apic_write(APIC_DFR, APIC_DFR_VALUE);
52 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; 52 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
53 val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); 53 val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
54 apic_write_around(APIC_LDR, val); 54 apic_write(APIC_LDR, val);
55} 55}
56 56
57static inline int apic_id_registered(void) 57static inline int apic_id_registered(void)
diff --git a/include/asm-x86/mach-es7000/mach_apic.h b/include/asm-x86/mach-es7000/mach_apic.h
index b3556ec3bca5..63b4d9c189bf 100644
--- a/include/asm-x86/mach-es7000/mach_apic.h
+++ b/include/asm-x86/mach-es7000/mach_apic.h
@@ -66,9 +66,9 @@ static inline void init_apic_ldr(void)
66 unsigned long val; 66 unsigned long val;
67 int cpu = smp_processor_id(); 67 int cpu = smp_processor_id();
68 68
69 apic_write_around(APIC_DFR, APIC_DFR_VALUE); 69 apic_write(APIC_DFR, APIC_DFR_VALUE);
70 val = calculate_ldr(cpu); 70 val = calculate_ldr(cpu);
71 apic_write_around(APIC_LDR, val); 71 apic_write(APIC_LDR, val);
72} 72}
73 73
74#ifndef CONFIG_X86_GENERICARCH 74#ifndef CONFIG_X86_GENERICARCH
diff --git a/include/asm-x86/mach-summit/mach_apic.h b/include/asm-x86/mach-summit/mach_apic.h
index 1f76c2e70232..75d2c95005d7 100644
--- a/include/asm-x86/mach-summit/mach_apic.h
+++ b/include/asm-x86/mach-summit/mach_apic.h
@@ -63,10 +63,10 @@ static inline void init_apic_ldr(void)
63 * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ 63 * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
64 BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); 64 BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
65 id = my_cluster | (1UL << count); 65 id = my_cluster | (1UL << count);
66 apic_write_around(APIC_DFR, APIC_DFR_VALUE); 66 apic_write(APIC_DFR, APIC_DFR_VALUE);
67 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; 67 val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
68 val |= SET_APIC_LOGICAL_ID(id); 68 val |= SET_APIC_LOGICAL_ID(id);
69 apic_write_around(APIC_LDR, val); 69 apic_write(APIC_LDR, val);
70} 70}
71 71
72static inline int multi_timer_check(int apic, int irq) 72static inline int multi_timer_check(int apic, int irq)