diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/Kconfig.cpu | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic_32.c | 170 | ||||
-rw-r--r-- | arch/x86/kernel/apic_64.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 23 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 10 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/p4.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic_32.c | 53 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic_64.c | 41 | ||||
-rw-r--r-- | arch/x86/kernel/ipi.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/nmi.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/vmi_32.c | 1 | ||||
-rw-r--r-- | arch/x86/lguest/boot.c | 1 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 1 |
14 files changed, 179 insertions, 189 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 | ||
365 | config X86_GOOD_APIC | ||
366 | def_bool y | ||
367 | depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 || X86_64 | ||
368 | |||
369 | config X86_INTEL_USERCOPY | 365 | config 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 | */ |
78 | int apic_verbosity; | 78 | unsigned int apic_verbosity; |
79 | 79 | ||
80 | int pic_mode; | 80 | int 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 | */ |
253 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | 250 | static 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) | |||
283 | static int lapic_next_event(unsigned long delta, | 280 | static 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 | /* | 406 | static int __init calibrate_APIC_clock(void) |
410 | * Setup the boot APIC | ||
411 | * | ||
412 | * Calibrate and verify the result. | ||
413 | */ | ||
414 | void __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 | */ | ||
562 | void __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 | ||
951 | static void __cpuinit lapic_setup_esr(void) | 955 | static 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 | ||
1120 | void __cpuinit end_local_APIC_setup(void) | 1124 | void __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 | */ |
64 | int apic_verbosity; | 64 | unsigned int apic_verbosity; |
65 | 65 | ||
66 | /* Have we found an MP table */ | 66 | /* Have we found an MP table */ |
67 | int smp_found_config; | 67 | int 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 | ||
389 | static void __init calibrate_APIC_clock(void) | 389 | static 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 | ||
142 | static void __init check_config(void) | 136 | static 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 | ||
2035 | static void unmask_lapic_irq(unsigned int irq) | 2035 | static 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 | ||
2043 | static struct irq_chip lapic_chip __read_mostly = { | 2043 | static 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"); |
2284 | out: | 2289 | out: |
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"); | ||
2122 | out: | 2127 | out: |
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 | ||
76 | void send_IPI_self(int vector) | 76 | void 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 | ||
264 | static void __acpi_nmi_enable(void *__unused) | 264 | static 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 | ||
278 | static void __acpi_nmi_disable(void *__unused) | 278 | static 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) | |||
816 | static struct apic_ops lguest_basic_apic_ops = { | 816 | static 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) | |||
583 | static struct apic_ops xen_basic_apic_ops = { | 583 | static 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, |