diff options
| -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 | ||||
| -rw-r--r-- | include/asm-x86/apic.h | 29 | ||||
| -rw-r--r-- | include/asm-x86/cpufeature.h | 1 | ||||
| -rw-r--r-- | include/asm-x86/mach-bigsmp/mach_apic.h | 4 | ||||
| -rw-r--r-- | include/asm-x86/mach-default/mach_apic.h | 4 | ||||
| -rw-r--r-- | include/asm-x86/mach-es7000/mach_apic.h | 4 | ||||
| -rw-r--r-- | include/asm-x86/mach-summit/mach_apic.h | 4 |
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 | ||
| 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, |
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 | ||
| 40 | extern int apic_verbosity; | 42 | extern unsigned int apic_verbosity; |
| 41 | extern int local_apic_timer_c2_ok; | 43 | extern int local_apic_timer_c2_ok; |
| 42 | 44 | ||
| 43 | extern int ioapic_force; | 45 | extern int ioapic_force; |
| @@ -57,12 +59,11 @@ extern int is_vsmp_box(void); | |||
| 57 | 59 | ||
| 58 | static inline void native_apic_mem_write(u32 reg, u32 v) | 60 | static 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 | ||
| 63 | static 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 | ||
| 68 | static inline u32 native_apic_mem_read(u32 reg) | 69 | static inline u32 native_apic_mem_read(u32 reg) |
| @@ -101,7 +102,6 @@ extern void x2apic_icr_write(u32 low, u32 id); | |||
| 101 | struct apic_ops { | 102 | struct 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 | ||
| 121 | extern int get_physical_broadcast(void); | 120 | extern 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 |
| 134 | static inline void ack_x2APIC_irq(void) | 123 | static 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 | ||
| 71 | static inline void setup_apic_routing(void) | 71 | static 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 | ||
| 57 | static inline int apic_id_registered(void) | 57 | static 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 | ||
| 72 | static inline int multi_timer_check(int apic, int irq) | 72 | static inline int multi_timer_check(int apic, int irq) |
