diff options
Diffstat (limited to 'arch/x86/kernel/apic_64.c')
-rw-r--r-- | arch/x86/kernel/apic_64.c | 626 |
1 files changed, 540 insertions, 86 deletions
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 57744f4a75b4..94ddb69ae15e 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/clockchips.h> | 27 | #include <linux/clockchips.h> |
28 | #include <linux/acpi_pmtmr.h> | 28 | #include <linux/acpi_pmtmr.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/dmar.h> | ||
30 | 31 | ||
31 | #include <asm/atomic.h> | 32 | #include <asm/atomic.h> |
32 | #include <asm/smp.h> | 33 | #include <asm/smp.h> |
@@ -39,13 +40,20 @@ | |||
39 | #include <asm/proto.h> | 40 | #include <asm/proto.h> |
40 | #include <asm/timex.h> | 41 | #include <asm/timex.h> |
41 | #include <asm/apic.h> | 42 | #include <asm/apic.h> |
43 | #include <asm/i8259.h> | ||
42 | 44 | ||
43 | #include <mach_ipi.h> | 45 | #include <mach_ipi.h> |
44 | #include <mach_apic.h> | 46 | #include <mach_apic.h> |
45 | 47 | ||
48 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ | ||
46 | static int disable_apic_timer __cpuinitdata; | 49 | static int disable_apic_timer __cpuinitdata; |
47 | static int apic_calibrate_pmtmr __initdata; | 50 | static int apic_calibrate_pmtmr __initdata; |
48 | int disable_apic; | 51 | int disable_apic; |
52 | int disable_x2apic; | ||
53 | int x2apic; | ||
54 | |||
55 | /* x2apic enabled before OS handover */ | ||
56 | int x2apic_preenabled; | ||
49 | 57 | ||
50 | /* Local APIC timer works in C2 */ | 58 | /* Local APIC timer works in C2 */ |
51 | int local_apic_timer_c2_ok; | 59 | int local_apic_timer_c2_ok; |
@@ -73,6 +81,9 @@ static void lapic_timer_setup(enum clock_event_mode mode, | |||
73 | static void lapic_timer_broadcast(cpumask_t mask); | 81 | static void lapic_timer_broadcast(cpumask_t mask); |
74 | static void apic_pm_activate(void); | 82 | static void apic_pm_activate(void); |
75 | 83 | ||
84 | /* | ||
85 | * The local apic timer can be used for any function which is CPU local. | ||
86 | */ | ||
76 | static struct clock_event_device lapic_clockevent = { | 87 | static struct clock_event_device lapic_clockevent = { |
77 | .name = "lapic", | 88 | .name = "lapic", |
78 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | 89 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
@@ -99,11 +110,15 @@ static inline int lapic_get_version(void) | |||
99 | } | 110 | } |
100 | 111 | ||
101 | /* | 112 | /* |
102 | * Check, if the APIC is integrated or a seperate chip | 113 | * Check, if the APIC is integrated or a separate chip |
103 | */ | 114 | */ |
104 | static inline int lapic_is_integrated(void) | 115 | static inline int lapic_is_integrated(void) |
105 | { | 116 | { |
117 | #ifdef CONFIG_X86_64 | ||
106 | return 1; | 118 | return 1; |
119 | #else | ||
120 | return APIC_INTEGRATED(lapic_get_version()); | ||
121 | #endif | ||
107 | } | 122 | } |
108 | 123 | ||
109 | /* | 124 | /* |
@@ -118,13 +133,18 @@ static int modern_apic(void) | |||
118 | return lapic_get_version() >= 0x14; | 133 | return lapic_get_version() >= 0x14; |
119 | } | 134 | } |
120 | 135 | ||
121 | void apic_wait_icr_idle(void) | 136 | /* |
137 | * Paravirt kernels also might be using these below ops. So we still | ||
138 | * use generic apic_read()/apic_write(), which might be pointing to different | ||
139 | * ops in PARAVIRT case. | ||
140 | */ | ||
141 | void xapic_wait_icr_idle(void) | ||
122 | { | 142 | { |
123 | while (apic_read(APIC_ICR) & APIC_ICR_BUSY) | 143 | while (apic_read(APIC_ICR) & APIC_ICR_BUSY) |
124 | cpu_relax(); | 144 | cpu_relax(); |
125 | } | 145 | } |
126 | 146 | ||
127 | u32 safe_apic_wait_icr_idle(void) | 147 | u32 safe_xapic_wait_icr_idle(void) |
128 | { | 148 | { |
129 | u32 send_status; | 149 | u32 send_status; |
130 | int timeout; | 150 | int timeout; |
@@ -140,6 +160,68 @@ u32 safe_apic_wait_icr_idle(void) | |||
140 | return send_status; | 160 | return send_status; |
141 | } | 161 | } |
142 | 162 | ||
163 | void xapic_icr_write(u32 low, u32 id) | ||
164 | { | ||
165 | apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id)); | ||
166 | apic_write(APIC_ICR, low); | ||
167 | } | ||
168 | |||
169 | u64 xapic_icr_read(void) | ||
170 | { | ||
171 | u32 icr1, icr2; | ||
172 | |||
173 | icr2 = apic_read(APIC_ICR2); | ||
174 | icr1 = apic_read(APIC_ICR); | ||
175 | |||
176 | return icr1 | ((u64)icr2 << 32); | ||
177 | } | ||
178 | |||
179 | static struct apic_ops xapic_ops = { | ||
180 | .read = native_apic_mem_read, | ||
181 | .write = native_apic_mem_write, | ||
182 | .icr_read = xapic_icr_read, | ||
183 | .icr_write = xapic_icr_write, | ||
184 | .wait_icr_idle = xapic_wait_icr_idle, | ||
185 | .safe_wait_icr_idle = safe_xapic_wait_icr_idle, | ||
186 | }; | ||
187 | |||
188 | struct apic_ops __read_mostly *apic_ops = &xapic_ops; | ||
189 | EXPORT_SYMBOL_GPL(apic_ops); | ||
190 | |||
191 | static void x2apic_wait_icr_idle(void) | ||
192 | { | ||
193 | /* no need to wait for icr idle in x2apic */ | ||
194 | return; | ||
195 | } | ||
196 | |||
197 | static u32 safe_x2apic_wait_icr_idle(void) | ||
198 | { | ||
199 | /* no need to wait for icr idle in x2apic */ | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | void x2apic_icr_write(u32 low, u32 id) | ||
204 | { | ||
205 | wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low); | ||
206 | } | ||
207 | |||
208 | u64 x2apic_icr_read(void) | ||
209 | { | ||
210 | unsigned long val; | ||
211 | |||
212 | rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val); | ||
213 | return val; | ||
214 | } | ||
215 | |||
216 | static struct apic_ops x2apic_ops = { | ||
217 | .read = native_apic_msr_read, | ||
218 | .write = native_apic_msr_write, | ||
219 | .icr_read = x2apic_icr_read, | ||
220 | .icr_write = x2apic_icr_write, | ||
221 | .wait_icr_idle = x2apic_wait_icr_idle, | ||
222 | .safe_wait_icr_idle = safe_x2apic_wait_icr_idle, | ||
223 | }; | ||
224 | |||
143 | /** | 225 | /** |
144 | * enable_NMI_through_LVT0 - enable NMI through local vector table 0 | 226 | * enable_NMI_through_LVT0 - enable NMI through local vector table 0 |
145 | */ | 227 | */ |
@@ -149,6 +231,11 @@ void __cpuinit enable_NMI_through_LVT0(void) | |||
149 | 231 | ||
150 | /* unmask and set to NMI */ | 232 | /* unmask and set to NMI */ |
151 | v = APIC_DM_NMI; | 233 | v = APIC_DM_NMI; |
234 | |||
235 | /* Level triggered for 82489DX (32bit mode) */ | ||
236 | if (!lapic_is_integrated()) | ||
237 | v |= APIC_LVT_LEVEL_TRIGGER; | ||
238 | |||
152 | apic_write(APIC_LVT0, v); | 239 | apic_write(APIC_LVT0, v); |
153 | } | 240 | } |
154 | 241 | ||
@@ -157,14 +244,28 @@ void __cpuinit enable_NMI_through_LVT0(void) | |||
157 | */ | 244 | */ |
158 | int lapic_get_maxlvt(void) | 245 | int lapic_get_maxlvt(void) |
159 | { | 246 | { |
160 | unsigned int v, maxlvt; | 247 | unsigned int v; |
161 | 248 | ||
162 | v = apic_read(APIC_LVR); | 249 | v = apic_read(APIC_LVR); |
163 | maxlvt = GET_APIC_MAXLVT(v); | 250 | /* |
164 | return maxlvt; | 251 | * - we always have APIC integrated on 64bit mode |
252 | * - 82489DXs do not report # of LVT entries | ||
253 | */ | ||
254 | return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2; | ||
165 | } | 255 | } |
166 | 256 | ||
167 | /* | 257 | /* |
258 | * Local APIC timer | ||
259 | */ | ||
260 | |||
261 | /* Clock divisor */ | ||
262 | #ifdef CONFG_X86_64 | ||
263 | #define APIC_DIVISOR 1 | ||
264 | #else | ||
265 | #define APIC_DIVISOR 16 | ||
266 | #endif | ||
267 | |||
268 | /* | ||
168 | * This function sets up the local APIC timer, with a timeout of | 269 | * This function sets up the local APIC timer, with a timeout of |
169 | * 'clocks' APIC bus clock. During calibration we actually call | 270 | * 'clocks' APIC bus clock. During calibration we actually call |
170 | * this function twice on the boot CPU, once with a bogus timeout | 271 | * this function twice on the boot CPU, once with a bogus timeout |
@@ -174,7 +275,6 @@ int lapic_get_maxlvt(void) | |||
174 | * We do reads before writes even if unnecessary, to get around the | 275 | * We do reads before writes even if unnecessary, to get around the |
175 | * P5 APIC double write bug. | 276 | * P5 APIC double write bug. |
176 | */ | 277 | */ |
177 | |||
178 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | 278 | static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) |
179 | { | 279 | { |
180 | unsigned int lvtt_value, tmp_value; | 280 | unsigned int lvtt_value, tmp_value; |
@@ -182,6 +282,9 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | |||
182 | lvtt_value = LOCAL_TIMER_VECTOR; | 282 | lvtt_value = LOCAL_TIMER_VECTOR; |
183 | if (!oneshot) | 283 | if (!oneshot) |
184 | lvtt_value |= APIC_LVT_TIMER_PERIODIC; | 284 | lvtt_value |= APIC_LVT_TIMER_PERIODIC; |
285 | if (!lapic_is_integrated()) | ||
286 | lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV); | ||
287 | |||
185 | if (!irqen) | 288 | if (!irqen) |
186 | lvtt_value |= APIC_LVT_MASKED; | 289 | lvtt_value |= APIC_LVT_MASKED; |
187 | 290 | ||
@@ -191,12 +294,12 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) | |||
191 | * Divide PICLK by 16 | 294 | * Divide PICLK by 16 |
192 | */ | 295 | */ |
193 | tmp_value = apic_read(APIC_TDCR); | 296 | tmp_value = apic_read(APIC_TDCR); |
194 | apic_write(APIC_TDCR, (tmp_value | 297 | apic_write(APIC_TDCR, |
195 | & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | 298 | (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) | |
196 | | APIC_TDR_DIV_16); | 299 | APIC_TDR_DIV_16); |
197 | 300 | ||
198 | if (!oneshot) | 301 | if (!oneshot) |
199 | apic_write(APIC_TMICT, clocks); | 302 | apic_write(APIC_TMICT, clocks / APIC_DIVISOR); |
200 | } | 303 | } |
201 | 304 | ||
202 | /* | 305 | /* |
@@ -370,7 +473,7 @@ static int __init calibrate_APIC_clock(void) | |||
370 | lapic_clockevent.min_delta_ns = | 473 | lapic_clockevent.min_delta_ns = |
371 | clockevent_delta2ns(0xF, &lapic_clockevent); | 474 | clockevent_delta2ns(0xF, &lapic_clockevent); |
372 | 475 | ||
373 | calibration_result = result / HZ; | 476 | calibration_result = (result * APIC_DIVISOR) / HZ; |
374 | 477 | ||
375 | /* | 478 | /* |
376 | * Do a sanity check on the APIC calibration result | 479 | * Do a sanity check on the APIC calibration result |
@@ -392,10 +495,10 @@ static int __init calibrate_APIC_clock(void) | |||
392 | void __init setup_boot_APIC_clock(void) | 495 | void __init setup_boot_APIC_clock(void) |
393 | { | 496 | { |
394 | /* | 497 | /* |
395 | * The local apic timer can be disabled via the kernel commandline. | 498 | * The local apic timer can be disabled via the kernel |
396 | * Register the lapic timer as a dummy clock event source on SMP | 499 | * commandline or from the CPU detection code. Register the lapic |
397 | * systems, so the broadcast mechanism is used. On UP systems simply | 500 | * timer as a dummy clock event source on SMP systems, so the |
398 | * ignore it. | 501 | * broadcast mechanism is used. On UP systems simply ignore it. |
399 | */ | 502 | */ |
400 | if (disable_apic_timer) { | 503 | if (disable_apic_timer) { |
401 | printk(KERN_INFO "Disabling APIC timer\n"); | 504 | printk(KERN_INFO "Disabling APIC timer\n"); |
@@ -407,7 +510,9 @@ void __init setup_boot_APIC_clock(void) | |||
407 | return; | 510 | return; |
408 | } | 511 | } |
409 | 512 | ||
410 | printk(KERN_INFO "Using local APIC timer interrupts.\n"); | 513 | apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" |
514 | "calibrating APIC timer ...\n"); | ||
515 | |||
411 | if (calibrate_APIC_clock()) { | 516 | if (calibrate_APIC_clock()) { |
412 | /* No broadcast on UP ! */ | 517 | /* No broadcast on UP ! */ |
413 | if (num_possible_cpus() > 1) | 518 | if (num_possible_cpus() > 1) |
@@ -426,6 +531,7 @@ void __init setup_boot_APIC_clock(void) | |||
426 | printk(KERN_WARNING "APIC timer registered as dummy," | 531 | printk(KERN_WARNING "APIC timer registered as dummy," |
427 | " due to nmi_watchdog=%d!\n", nmi_watchdog); | 532 | " due to nmi_watchdog=%d!\n", nmi_watchdog); |
428 | 533 | ||
534 | /* Setup the lapic or request the broadcast */ | ||
429 | setup_APIC_timer(); | 535 | setup_APIC_timer(); |
430 | } | 536 | } |
431 | 537 | ||
@@ -464,7 +570,11 @@ static void local_apic_timer_interrupt(void) | |||
464 | /* | 570 | /* |
465 | * the NMI deadlock-detector uses this. | 571 | * the NMI deadlock-detector uses this. |
466 | */ | 572 | */ |
573 | #ifdef CONFIG_X86_64 | ||
467 | add_pda(apic_timer_irqs, 1); | 574 | add_pda(apic_timer_irqs, 1); |
575 | #else | ||
576 | per_cpu(irq_stat, cpu).apic_timer_irqs++; | ||
577 | #endif | ||
468 | 578 | ||
469 | evt->event_handler(evt); | 579 | evt->event_handler(evt); |
470 | } | 580 | } |
@@ -495,6 +605,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) | |||
495 | irq_enter(); | 605 | irq_enter(); |
496 | local_apic_timer_interrupt(); | 606 | local_apic_timer_interrupt(); |
497 | irq_exit(); | 607 | irq_exit(); |
608 | |||
498 | set_irq_regs(old_regs); | 609 | set_irq_regs(old_regs); |
499 | } | 610 | } |
500 | 611 | ||
@@ -548,6 +659,13 @@ void clear_local_APIC(void) | |||
548 | apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); | 659 | apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); |
549 | } | 660 | } |
550 | 661 | ||
662 | /* lets not touch this if we didn't frob it */ | ||
663 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL) | ||
664 | if (maxlvt >= 5) { | ||
665 | v = apic_read(APIC_LVTTHMR); | ||
666 | apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); | ||
667 | } | ||
668 | #endif | ||
551 | /* | 669 | /* |
552 | * Clean APIC state for other OSs: | 670 | * Clean APIC state for other OSs: |
553 | */ | 671 | */ |
@@ -558,8 +676,14 @@ void clear_local_APIC(void) | |||
558 | apic_write(APIC_LVTERR, APIC_LVT_MASKED); | 676 | apic_write(APIC_LVTERR, APIC_LVT_MASKED); |
559 | if (maxlvt >= 4) | 677 | if (maxlvt >= 4) |
560 | apic_write(APIC_LVTPC, APIC_LVT_MASKED); | 678 | apic_write(APIC_LVTPC, APIC_LVT_MASKED); |
561 | apic_write(APIC_ESR, 0); | 679 | |
562 | apic_read(APIC_ESR); | 680 | /* Integrated APIC (!82489DX) ? */ |
681 | if (lapic_is_integrated()) { | ||
682 | if (maxlvt > 3) | ||
683 | /* Clear ESR due to Pentium errata 3AP and 11AP */ | ||
684 | apic_write(APIC_ESR, 0); | ||
685 | apic_read(APIC_ESR); | ||
686 | } | ||
563 | } | 687 | } |
564 | 688 | ||
565 | /** | 689 | /** |
@@ -578,8 +702,28 @@ void disable_local_APIC(void) | |||
578 | value = apic_read(APIC_SPIV); | 702 | value = apic_read(APIC_SPIV); |
579 | value &= ~APIC_SPIV_APIC_ENABLED; | 703 | value &= ~APIC_SPIV_APIC_ENABLED; |
580 | apic_write(APIC_SPIV, value); | 704 | apic_write(APIC_SPIV, value); |
705 | |||
706 | #ifdef CONFIG_X86_32 | ||
707 | /* | ||
708 | * When LAPIC was disabled by the BIOS and enabled by the kernel, | ||
709 | * restore the disabled state. | ||
710 | */ | ||
711 | if (enabled_via_apicbase) { | ||
712 | unsigned int l, h; | ||
713 | |||
714 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
715 | l &= ~MSR_IA32_APICBASE_ENABLE; | ||
716 | wrmsr(MSR_IA32_APICBASE, l, h); | ||
717 | } | ||
718 | #endif | ||
581 | } | 719 | } |
582 | 720 | ||
721 | /* | ||
722 | * If Linux enabled the LAPIC against the BIOS default disable it down before | ||
723 | * re-entering the BIOS on shutdown. Otherwise the BIOS may get confused and | ||
724 | * not power-off. Additionally clear all LVT entries before disable_local_APIC | ||
725 | * for the case where Linux didn't enable the LAPIC. | ||
726 | */ | ||
583 | void lapic_shutdown(void) | 727 | void lapic_shutdown(void) |
584 | { | 728 | { |
585 | unsigned long flags; | 729 | unsigned long flags; |
@@ -589,7 +733,13 @@ void lapic_shutdown(void) | |||
589 | 733 | ||
590 | local_irq_save(flags); | 734 | local_irq_save(flags); |
591 | 735 | ||
592 | disable_local_APIC(); | 736 | #ifdef CONFIG_X86_32 |
737 | if (!enabled_via_apicbase) | ||
738 | clear_local_APIC(); | ||
739 | else | ||
740 | #endif | ||
741 | disable_local_APIC(); | ||
742 | |||
593 | 743 | ||
594 | local_irq_restore(flags); | 744 | local_irq_restore(flags); |
595 | } | 745 | } |
@@ -633,10 +783,10 @@ int __init verify_local_APIC(void) | |||
633 | /* | 783 | /* |
634 | * The ID register is read/write in a real APIC. | 784 | * The ID register is read/write in a real APIC. |
635 | */ | 785 | */ |
636 | reg0 = read_apic_id(); | 786 | reg0 = apic_read(APIC_ID); |
637 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); | 787 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); |
638 | apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); | 788 | apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); |
639 | reg1 = read_apic_id(); | 789 | reg1 = apic_read(APIC_ID); |
640 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); | 790 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); |
641 | apic_write(APIC_ID, reg0); | 791 | apic_write(APIC_ID, reg0); |
642 | if (reg1 != (reg0 ^ APIC_ID_MASK)) | 792 | if (reg1 != (reg0 ^ APIC_ID_MASK)) |
@@ -660,8 +810,11 @@ int __init verify_local_APIC(void) | |||
660 | */ | 810 | */ |
661 | void __init sync_Arb_IDs(void) | 811 | void __init sync_Arb_IDs(void) |
662 | { | 812 | { |
663 | /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ | 813 | /* |
664 | if (modern_apic()) | 814 | * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not |
815 | * needed on AMD. | ||
816 | */ | ||
817 | if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD) | ||
665 | return; | 818 | return; |
666 | 819 | ||
667 | /* | 820 | /* |
@@ -670,8 +823,8 @@ void __init sync_Arb_IDs(void) | |||
670 | apic_wait_icr_idle(); | 823 | apic_wait_icr_idle(); |
671 | 824 | ||
672 | apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); | 825 | apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); |
673 | apic_write(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | 826 | apic_write(APIC_ICR, APIC_DEST_ALLINC | |
674 | | APIC_DM_INIT); | 827 | APIC_INT_LEVELTRIG | APIC_DM_INIT); |
675 | } | 828 | } |
676 | 829 | ||
677 | /* | 830 | /* |
@@ -688,8 +841,6 @@ void __init init_bsp_APIC(void) | |||
688 | if (smp_found_config || !cpu_has_apic) | 841 | if (smp_found_config || !cpu_has_apic) |
689 | return; | 842 | return; |
690 | 843 | ||
691 | value = apic_read(APIC_LVR); | ||
692 | |||
693 | /* | 844 | /* |
694 | * Do not trust the local APIC being empty at bootup. | 845 | * Do not trust the local APIC being empty at bootup. |
695 | */ | 846 | */ |
@@ -701,7 +852,15 @@ void __init init_bsp_APIC(void) | |||
701 | value = apic_read(APIC_SPIV); | 852 | value = apic_read(APIC_SPIV); |
702 | value &= ~APIC_VECTOR_MASK; | 853 | value &= ~APIC_VECTOR_MASK; |
703 | value |= APIC_SPIV_APIC_ENABLED; | 854 | value |= APIC_SPIV_APIC_ENABLED; |
704 | value |= APIC_SPIV_FOCUS_DISABLED; | 855 | |
856 | #ifdef CONFIG_X86_32 | ||
857 | /* This bit is reserved on P4/Xeon and should be cleared */ | ||
858 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
859 | (boot_cpu_data.x86 == 15)) | ||
860 | value &= ~APIC_SPIV_FOCUS_DISABLED; | ||
861 | else | ||
862 | #endif | ||
863 | value |= APIC_SPIV_FOCUS_DISABLED; | ||
705 | value |= SPURIOUS_APIC_VECTOR; | 864 | value |= SPURIOUS_APIC_VECTOR; |
706 | apic_write(APIC_SPIV, value); | 865 | apic_write(APIC_SPIV, value); |
707 | 866 | ||
@@ -710,9 +869,50 @@ void __init init_bsp_APIC(void) | |||
710 | */ | 869 | */ |
711 | apic_write(APIC_LVT0, APIC_DM_EXTINT); | 870 | apic_write(APIC_LVT0, APIC_DM_EXTINT); |
712 | value = APIC_DM_NMI; | 871 | value = APIC_DM_NMI; |
872 | if (!lapic_is_integrated()) /* 82489DX */ | ||
873 | value |= APIC_LVT_LEVEL_TRIGGER; | ||
713 | apic_write(APIC_LVT1, value); | 874 | apic_write(APIC_LVT1, value); |
714 | } | 875 | } |
715 | 876 | ||
877 | static void __cpuinit lapic_setup_esr(void) | ||
878 | { | ||
879 | unsigned long oldvalue, value, maxlvt; | ||
880 | if (lapic_is_integrated() && !esr_disable) { | ||
881 | if (esr_disable) { | ||
882 | /* | ||
883 | * Something untraceable is creating bad interrupts on | ||
884 | * secondary quads ... for the moment, just leave the | ||
885 | * ESR disabled - we can't do anything useful with the | ||
886 | * errors anyway - mbligh | ||
887 | */ | ||
888 | printk(KERN_INFO "Leaving ESR disabled.\n"); | ||
889 | return; | ||
890 | } | ||
891 | /* !82489DX */ | ||
892 | maxlvt = lapic_get_maxlvt(); | ||
893 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ | ||
894 | apic_write(APIC_ESR, 0); | ||
895 | oldvalue = apic_read(APIC_ESR); | ||
896 | |||
897 | /* enables sending errors */ | ||
898 | value = ERROR_APIC_VECTOR; | ||
899 | apic_write(APIC_LVTERR, value); | ||
900 | /* | ||
901 | * spec says clear errors after enabling vector. | ||
902 | */ | ||
903 | if (maxlvt > 3) | ||
904 | apic_write(APIC_ESR, 0); | ||
905 | value = apic_read(APIC_ESR); | ||
906 | if (value != oldvalue) | ||
907 | apic_printk(APIC_VERBOSE, "ESR value before enabling " | ||
908 | "vector: 0x%08lx after: 0x%08lx\n", | ||
909 | oldvalue, value); | ||
910 | } else { | ||
911 | printk(KERN_INFO "No ESR for 82489DX.\n"); | ||
912 | } | ||
913 | } | ||
914 | |||
915 | |||
716 | /** | 916 | /** |
717 | * setup_local_APIC - setup the local APIC | 917 | * setup_local_APIC - setup the local APIC |
718 | */ | 918 | */ |
@@ -818,25 +1018,143 @@ void __cpuinit setup_local_APIC(void) | |||
818 | preempt_enable(); | 1018 | preempt_enable(); |
819 | } | 1019 | } |
820 | 1020 | ||
821 | static void __cpuinit lapic_setup_esr(void) | ||
822 | { | ||
823 | unsigned maxlvt = lapic_get_maxlvt(); | ||
824 | |||
825 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR); | ||
826 | /* | ||
827 | * spec says clear errors after enabling vector. | ||
828 | */ | ||
829 | if (maxlvt > 3) | ||
830 | apic_write(APIC_ESR, 0); | ||
831 | } | ||
832 | |||
833 | void __cpuinit end_local_APIC_setup(void) | 1021 | void __cpuinit end_local_APIC_setup(void) |
834 | { | 1022 | { |
835 | lapic_setup_esr(); | 1023 | lapic_setup_esr(); |
1024 | |||
1025 | #ifdef CONFIG_X86_32 | ||
1026 | { | ||
1027 | unsigned int value; | ||
1028 | /* Disable the local apic timer */ | ||
1029 | value = apic_read(APIC_LVTT); | ||
1030 | value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); | ||
1031 | apic_write(APIC_LVTT, value); | ||
1032 | } | ||
1033 | #endif | ||
1034 | |||
836 | setup_apic_nmi_watchdog(NULL); | 1035 | setup_apic_nmi_watchdog(NULL); |
837 | apic_pm_activate(); | 1036 | apic_pm_activate(); |
838 | } | 1037 | } |
839 | 1038 | ||
1039 | void check_x2apic(void) | ||
1040 | { | ||
1041 | int msr, msr2; | ||
1042 | |||
1043 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | ||
1044 | |||
1045 | if (msr & X2APIC_ENABLE) { | ||
1046 | printk("x2apic enabled by BIOS, switching to x2apic ops\n"); | ||
1047 | x2apic_preenabled = x2apic = 1; | ||
1048 | apic_ops = &x2apic_ops; | ||
1049 | } | ||
1050 | } | ||
1051 | |||
1052 | void enable_x2apic(void) | ||
1053 | { | ||
1054 | int msr, msr2; | ||
1055 | |||
1056 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | ||
1057 | if (!(msr & X2APIC_ENABLE)) { | ||
1058 | printk("Enabling x2apic\n"); | ||
1059 | wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); | ||
1060 | } | ||
1061 | } | ||
1062 | |||
1063 | void enable_IR_x2apic(void) | ||
1064 | { | ||
1065 | #ifdef CONFIG_INTR_REMAP | ||
1066 | int ret; | ||
1067 | unsigned long flags; | ||
1068 | |||
1069 | if (!cpu_has_x2apic) | ||
1070 | return; | ||
1071 | |||
1072 | if (!x2apic_preenabled && disable_x2apic) { | ||
1073 | printk(KERN_INFO | ||
1074 | "Skipped enabling x2apic and Interrupt-remapping " | ||
1075 | "because of nox2apic\n"); | ||
1076 | return; | ||
1077 | } | ||
1078 | |||
1079 | if (x2apic_preenabled && disable_x2apic) | ||
1080 | panic("Bios already enabled x2apic, can't enforce nox2apic"); | ||
1081 | |||
1082 | if (!x2apic_preenabled && skip_ioapic_setup) { | ||
1083 | printk(KERN_INFO | ||
1084 | "Skipped enabling x2apic and Interrupt-remapping " | ||
1085 | "because of skipping io-apic setup\n"); | ||
1086 | return; | ||
1087 | } | ||
1088 | |||
1089 | ret = dmar_table_init(); | ||
1090 | if (ret) { | ||
1091 | printk(KERN_INFO | ||
1092 | "dmar_table_init() failed with %d:\n", ret); | ||
1093 | |||
1094 | if (x2apic_preenabled) | ||
1095 | panic("x2apic enabled by bios. But IR enabling failed"); | ||
1096 | else | ||
1097 | printk(KERN_INFO | ||
1098 | "Not enabling x2apic,Intr-remapping\n"); | ||
1099 | return; | ||
1100 | } | ||
1101 | |||
1102 | local_irq_save(flags); | ||
1103 | mask_8259A(); | ||
1104 | save_mask_IO_APIC_setup(); | ||
1105 | |||
1106 | ret = enable_intr_remapping(1); | ||
1107 | |||
1108 | if (ret && x2apic_preenabled) { | ||
1109 | local_irq_restore(flags); | ||
1110 | panic("x2apic enabled by bios. But IR enabling failed"); | ||
1111 | } | ||
1112 | |||
1113 | if (ret) | ||
1114 | goto end; | ||
1115 | |||
1116 | if (!x2apic) { | ||
1117 | x2apic = 1; | ||
1118 | apic_ops = &x2apic_ops; | ||
1119 | enable_x2apic(); | ||
1120 | } | ||
1121 | end: | ||
1122 | if (ret) | ||
1123 | /* | ||
1124 | * IR enabling failed | ||
1125 | */ | ||
1126 | restore_IO_APIC_setup(); | ||
1127 | else | ||
1128 | reinit_intr_remapped_IO_APIC(x2apic_preenabled); | ||
1129 | |||
1130 | unmask_8259A(); | ||
1131 | local_irq_restore(flags); | ||
1132 | |||
1133 | if (!ret) { | ||
1134 | if (!x2apic_preenabled) | ||
1135 | printk(KERN_INFO | ||
1136 | "Enabled x2apic and interrupt-remapping\n"); | ||
1137 | else | ||
1138 | printk(KERN_INFO | ||
1139 | "Enabled Interrupt-remapping\n"); | ||
1140 | } else | ||
1141 | printk(KERN_ERR | ||
1142 | "Failed to enable Interrupt-remapping and x2apic\n"); | ||
1143 | #else | ||
1144 | if (!cpu_has_x2apic) | ||
1145 | return; | ||
1146 | |||
1147 | if (x2apic_preenabled) | ||
1148 | panic("x2apic enabled prior OS handover," | ||
1149 | " enable CONFIG_INTR_REMAP"); | ||
1150 | |||
1151 | printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping " | ||
1152 | " and x2apic\n"); | ||
1153 | #endif | ||
1154 | |||
1155 | return; | ||
1156 | } | ||
1157 | |||
840 | /* | 1158 | /* |
841 | * Detect and enable local APICs on non-SMP boards. | 1159 | * Detect and enable local APICs on non-SMP boards. |
842 | * Original code written by Keir Fraser. | 1160 | * Original code written by Keir Fraser. |
@@ -876,7 +1194,7 @@ void __init early_init_lapic_mapping(void) | |||
876 | * Fetch the APIC ID of the BSP in case we have a | 1194 | * Fetch the APIC ID of the BSP in case we have a |
877 | * default configuration (or the MP table is broken). | 1195 | * default configuration (or the MP table is broken). |
878 | */ | 1196 | */ |
879 | boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); | 1197 | boot_cpu_physical_apicid = read_apic_id(); |
880 | } | 1198 | } |
881 | 1199 | ||
882 | /** | 1200 | /** |
@@ -884,6 +1202,11 @@ void __init early_init_lapic_mapping(void) | |||
884 | */ | 1202 | */ |
885 | void __init init_apic_mappings(void) | 1203 | void __init init_apic_mappings(void) |
886 | { | 1204 | { |
1205 | if (x2apic) { | ||
1206 | boot_cpu_physical_apicid = read_apic_id(); | ||
1207 | return; | ||
1208 | } | ||
1209 | |||
887 | /* | 1210 | /* |
888 | * If no local APIC can be found then set up a fake all | 1211 | * If no local APIC can be found then set up a fake all |
889 | * zeroes page to simulate the local APIC and another | 1212 | * zeroes page to simulate the local APIC and another |
@@ -903,13 +1226,15 @@ void __init init_apic_mappings(void) | |||
903 | * Fetch the APIC ID of the BSP in case we have a | 1226 | * Fetch the APIC ID of the BSP in case we have a |
904 | * default configuration (or the MP table is broken). | 1227 | * default configuration (or the MP table is broken). |
905 | */ | 1228 | */ |
906 | boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); | 1229 | boot_cpu_physical_apicid = read_apic_id(); |
907 | } | 1230 | } |
908 | 1231 | ||
909 | /* | 1232 | /* |
910 | * This initializes the IO-APIC and APIC hardware if this is | 1233 | * This initializes the IO-APIC and APIC hardware if this is |
911 | * a UP kernel. | 1234 | * a UP kernel. |
912 | */ | 1235 | */ |
1236 | int apic_version[MAX_APICS]; | ||
1237 | |||
913 | int __init APIC_init_uniprocessor(void) | 1238 | int __init APIC_init_uniprocessor(void) |
914 | { | 1239 | { |
915 | if (disable_apic) { | 1240 | if (disable_apic) { |
@@ -922,6 +1247,9 @@ int __init APIC_init_uniprocessor(void) | |||
922 | return -1; | 1247 | return -1; |
923 | } | 1248 | } |
924 | 1249 | ||
1250 | enable_IR_x2apic(); | ||
1251 | setup_apic_routing(); | ||
1252 | |||
925 | verify_local_APIC(); | 1253 | verify_local_APIC(); |
926 | 1254 | ||
927 | connect_bsp_APIC(); | 1255 | connect_bsp_APIC(); |
@@ -1008,17 +1336,57 @@ asmlinkage void smp_error_interrupt(void) | |||
1008 | } | 1336 | } |
1009 | 1337 | ||
1010 | /** | 1338 | /** |
1011 | * * connect_bsp_APIC - attach the APIC to the interrupt system | 1339 | * connect_bsp_APIC - attach the APIC to the interrupt system |
1012 | * */ | 1340 | */ |
1013 | void __init connect_bsp_APIC(void) | 1341 | void __init connect_bsp_APIC(void) |
1014 | { | 1342 | { |
1343 | #ifdef CONFIG_X86_32 | ||
1344 | if (pic_mode) { | ||
1345 | /* | ||
1346 | * Do not trust the local APIC being empty at bootup. | ||
1347 | */ | ||
1348 | clear_local_APIC(); | ||
1349 | /* | ||
1350 | * PIC mode, enable APIC mode in the IMCR, i.e. connect BSP's | ||
1351 | * local APIC to INT and NMI lines. | ||
1352 | */ | ||
1353 | apic_printk(APIC_VERBOSE, "leaving PIC mode, " | ||
1354 | "enabling APIC mode.\n"); | ||
1355 | outb(0x70, 0x22); | ||
1356 | outb(0x01, 0x23); | ||
1357 | } | ||
1358 | #endif | ||
1015 | enable_apic_mode(); | 1359 | enable_apic_mode(); |
1016 | } | 1360 | } |
1017 | 1361 | ||
1362 | /** | ||
1363 | * disconnect_bsp_APIC - detach the APIC from the interrupt system | ||
1364 | * @virt_wire_setup: indicates, whether virtual wire mode is selected | ||
1365 | * | ||
1366 | * Virtual wire mode is necessary to deliver legacy interrupts even when the | ||
1367 | * APIC is disabled. | ||
1368 | */ | ||
1018 | void disconnect_bsp_APIC(int virt_wire_setup) | 1369 | void disconnect_bsp_APIC(int virt_wire_setup) |
1019 | { | 1370 | { |
1371 | unsigned int value; | ||
1372 | |||
1373 | #ifdef CONFIG_X86_32 | ||
1374 | if (pic_mode) { | ||
1375 | /* | ||
1376 | * Put the board back into PIC mode (has an effect only on | ||
1377 | * certain older boards). Note that APIC interrupts, including | ||
1378 | * IPIs, won't work beyond this point! The only exception are | ||
1379 | * INIT IPIs. | ||
1380 | */ | ||
1381 | apic_printk(APIC_VERBOSE, "disabling APIC mode, " | ||
1382 | "entering PIC mode.\n"); | ||
1383 | outb(0x70, 0x22); | ||
1384 | outb(0x00, 0x23); | ||
1385 | return; | ||
1386 | } | ||
1387 | #endif | ||
1388 | |||
1020 | /* Go back to Virtual Wire compatibility mode */ | 1389 | /* Go back to Virtual Wire compatibility mode */ |
1021 | unsigned long value; | ||
1022 | 1390 | ||
1023 | /* For the spurious interrupt use vector F, and enable it */ | 1391 | /* For the spurious interrupt use vector F, and enable it */ |
1024 | value = apic_read(APIC_SPIV); | 1392 | value = apic_read(APIC_SPIV); |
@@ -1044,7 +1412,10 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
1044 | apic_write(APIC_LVT0, APIC_LVT_MASKED); | 1412 | apic_write(APIC_LVT0, APIC_LVT_MASKED); |
1045 | } | 1413 | } |
1046 | 1414 | ||
1047 | /* For LVT1 make it edge triggered, active high, nmi and enabled */ | 1415 | /* |
1416 | * For LVT1 make it edge triggered, active high, | ||
1417 | * nmi and enabled | ||
1418 | */ | ||
1048 | value = apic_read(APIC_LVT1); | 1419 | value = apic_read(APIC_LVT1); |
1049 | value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | | 1420 | value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | |
1050 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | 1421 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | |
@@ -1059,9 +1430,20 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1059 | int cpu; | 1430 | int cpu; |
1060 | cpumask_t tmp_map; | 1431 | cpumask_t tmp_map; |
1061 | 1432 | ||
1433 | /* | ||
1434 | * Validate version | ||
1435 | */ | ||
1436 | if (version == 0x0) { | ||
1437 | printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! " | ||
1438 | "fixing up to 0x10. (tell your hw vendor)\n", | ||
1439 | version); | ||
1440 | version = 0x10; | ||
1441 | } | ||
1442 | apic_version[apicid] = version; | ||
1443 | |||
1062 | if (num_processors >= NR_CPUS) { | 1444 | if (num_processors >= NR_CPUS) { |
1063 | printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." | 1445 | printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." |
1064 | " Processor ignored.\n", NR_CPUS); | 1446 | " Processor ignored.\n", NR_CPUS); |
1065 | return; | 1447 | return; |
1066 | } | 1448 | } |
1067 | 1449 | ||
@@ -1081,6 +1463,29 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1081 | if (apicid > max_physical_apicid) | 1463 | if (apicid > max_physical_apicid) |
1082 | max_physical_apicid = apicid; | 1464 | max_physical_apicid = apicid; |
1083 | 1465 | ||
1466 | #ifdef CONFIG_X86_32 | ||
1467 | /* | ||
1468 | * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y | ||
1469 | * but we need to work other dependencies like SMP_SUSPEND etc | ||
1470 | * before this can be done without some confusion. | ||
1471 | * if (CPU_HOTPLUG_ENABLED || num_processors > 8) | ||
1472 | * - Ashok Raj <ashok.raj@intel.com> | ||
1473 | */ | ||
1474 | if (max_physical_apicid >= 8) { | ||
1475 | switch (boot_cpu_data.x86_vendor) { | ||
1476 | case X86_VENDOR_INTEL: | ||
1477 | if (!APIC_XAPIC(version)) { | ||
1478 | def_to_bigsmp = 0; | ||
1479 | break; | ||
1480 | } | ||
1481 | /* If P4 and above fall through */ | ||
1482 | case X86_VENDOR_AMD: | ||
1483 | def_to_bigsmp = 1; | ||
1484 | } | ||
1485 | } | ||
1486 | #endif | ||
1487 | |||
1488 | #if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64) | ||
1084 | /* are we being called early in kernel startup? */ | 1489 | /* are we being called early in kernel startup? */ |
1085 | if (early_per_cpu_ptr(x86_cpu_to_apicid)) { | 1490 | if (early_per_cpu_ptr(x86_cpu_to_apicid)) { |
1086 | u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid); | 1491 | u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid); |
@@ -1092,20 +1497,28 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1092 | per_cpu(x86_cpu_to_apicid, cpu) = apicid; | 1497 | per_cpu(x86_cpu_to_apicid, cpu) = apicid; |
1093 | per_cpu(x86_bios_cpu_apicid, cpu) = apicid; | 1498 | per_cpu(x86_bios_cpu_apicid, cpu) = apicid; |
1094 | } | 1499 | } |
1500 | #endif | ||
1095 | 1501 | ||
1096 | cpu_set(cpu, cpu_possible_map); | 1502 | cpu_set(cpu, cpu_possible_map); |
1097 | cpu_set(cpu, cpu_present_map); | 1503 | cpu_set(cpu, cpu_present_map); |
1098 | } | 1504 | } |
1099 | 1505 | ||
1506 | int hard_smp_processor_id(void) | ||
1507 | { | ||
1508 | return read_apic_id(); | ||
1509 | } | ||
1510 | |||
1100 | /* | 1511 | /* |
1101 | * Power management | 1512 | * Power management |
1102 | */ | 1513 | */ |
1103 | #ifdef CONFIG_PM | 1514 | #ifdef CONFIG_PM |
1104 | 1515 | ||
1105 | static struct { | 1516 | static struct { |
1106 | /* 'active' is true if the local APIC was enabled by us and | 1517 | /* |
1107 | not the BIOS; this signifies that we are also responsible | 1518 | * 'active' is true if the local APIC was enabled by us and |
1108 | for disabling it before entering apm/acpi suspend */ | 1519 | * not the BIOS; this signifies that we are also responsible |
1520 | * for disabling it before entering apm/acpi suspend | ||
1521 | */ | ||
1109 | int active; | 1522 | int active; |
1110 | /* r/w apic fields */ | 1523 | /* r/w apic fields */ |
1111 | unsigned int apic_id; | 1524 | unsigned int apic_id; |
@@ -1133,7 +1546,7 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) | |||
1133 | 1546 | ||
1134 | maxlvt = lapic_get_maxlvt(); | 1547 | maxlvt = lapic_get_maxlvt(); |
1135 | 1548 | ||
1136 | apic_pm_state.apic_id = read_apic_id(); | 1549 | apic_pm_state.apic_id = apic_read(APIC_ID); |
1137 | apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); | 1550 | apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); |
1138 | apic_pm_state.apic_ldr = apic_read(APIC_LDR); | 1551 | apic_pm_state.apic_ldr = apic_read(APIC_LDR); |
1139 | apic_pm_state.apic_dfr = apic_read(APIC_DFR); | 1552 | apic_pm_state.apic_dfr = apic_read(APIC_DFR); |
@@ -1146,10 +1559,11 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) | |||
1146 | apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); | 1559 | apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); |
1147 | apic_pm_state.apic_tmict = apic_read(APIC_TMICT); | 1560 | apic_pm_state.apic_tmict = apic_read(APIC_TMICT); |
1148 | apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); | 1561 | apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); |
1149 | #ifdef CONFIG_X86_MCE_INTEL | 1562 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) |
1150 | if (maxlvt >= 5) | 1563 | if (maxlvt >= 5) |
1151 | apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); | 1564 | apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); |
1152 | #endif | 1565 | #endif |
1566 | |||
1153 | local_irq_save(flags); | 1567 | local_irq_save(flags); |
1154 | disable_local_APIC(); | 1568 | disable_local_APIC(); |
1155 | local_irq_restore(flags); | 1569 | local_irq_restore(flags); |
@@ -1168,10 +1582,25 @@ static int lapic_resume(struct sys_device *dev) | |||
1168 | maxlvt = lapic_get_maxlvt(); | 1582 | maxlvt = lapic_get_maxlvt(); |
1169 | 1583 | ||
1170 | local_irq_save(flags); | 1584 | local_irq_save(flags); |
1171 | rdmsr(MSR_IA32_APICBASE, l, h); | 1585 | |
1172 | l &= ~MSR_IA32_APICBASE_BASE; | 1586 | #ifdef CONFIG_X86_64 |
1173 | l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; | 1587 | if (x2apic) |
1174 | wrmsr(MSR_IA32_APICBASE, l, h); | 1588 | enable_x2apic(); |
1589 | else | ||
1590 | #endif | ||
1591 | { | ||
1592 | /* | ||
1593 | * Make sure the APICBASE points to the right address | ||
1594 | * | ||
1595 | * FIXME! This will be wrong if we ever support suspend on | ||
1596 | * SMP! We'll need to do this as part of the CPU restore! | ||
1597 | */ | ||
1598 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
1599 | l &= ~MSR_IA32_APICBASE_BASE; | ||
1600 | l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; | ||
1601 | wrmsr(MSR_IA32_APICBASE, l, h); | ||
1602 | } | ||
1603 | |||
1175 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); | 1604 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); |
1176 | apic_write(APIC_ID, apic_pm_state.apic_id); | 1605 | apic_write(APIC_ID, apic_pm_state.apic_id); |
1177 | apic_write(APIC_DFR, apic_pm_state.apic_dfr); | 1606 | apic_write(APIC_DFR, apic_pm_state.apic_dfr); |
@@ -1180,7 +1609,7 @@ static int lapic_resume(struct sys_device *dev) | |||
1180 | apic_write(APIC_SPIV, apic_pm_state.apic_spiv); | 1609 | apic_write(APIC_SPIV, apic_pm_state.apic_spiv); |
1181 | apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); | 1610 | apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); |
1182 | apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); | 1611 | apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); |
1183 | #ifdef CONFIG_X86_MCE_INTEL | 1612 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) |
1184 | if (maxlvt >= 5) | 1613 | if (maxlvt >= 5) |
1185 | apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); | 1614 | apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); |
1186 | #endif | 1615 | #endif |
@@ -1194,10 +1623,17 @@ static int lapic_resume(struct sys_device *dev) | |||
1194 | apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); | 1623 | apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); |
1195 | apic_write(APIC_ESR, 0); | 1624 | apic_write(APIC_ESR, 0); |
1196 | apic_read(APIC_ESR); | 1625 | apic_read(APIC_ESR); |
1626 | |||
1197 | local_irq_restore(flags); | 1627 | local_irq_restore(flags); |
1628 | |||
1198 | return 0; | 1629 | return 0; |
1199 | } | 1630 | } |
1200 | 1631 | ||
1632 | /* | ||
1633 | * This device has no shutdown method - fully functioning local APICs | ||
1634 | * are needed on every CPU up until machine_halt/restart/poweroff. | ||
1635 | */ | ||
1636 | |||
1201 | static struct sysdev_class lapic_sysclass = { | 1637 | static struct sysdev_class lapic_sysclass = { |
1202 | .name = "lapic", | 1638 | .name = "lapic", |
1203 | .resume = lapic_resume, | 1639 | .resume = lapic_resume, |
@@ -1311,31 +1747,19 @@ __cpuinit int apic_is_clustered_box(void) | |||
1311 | return (clusters > 2); | 1747 | return (clusters > 2); |
1312 | } | 1748 | } |
1313 | 1749 | ||
1314 | /* | 1750 | static __init int setup_nox2apic(char *str) |
1315 | * APIC command line parameters | ||
1316 | */ | ||
1317 | static int __init apic_set_verbosity(char *str) | ||
1318 | { | 1751 | { |
1319 | if (str == NULL) { | 1752 | disable_x2apic = 1; |
1320 | skip_ioapic_setup = 0; | 1753 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_X2APIC); |
1321 | ioapic_force = 1; | ||
1322 | return 0; | ||
1323 | } | ||
1324 | if (strcmp("debug", str) == 0) | ||
1325 | apic_verbosity = APIC_DEBUG; | ||
1326 | else if (strcmp("verbose", str) == 0) | ||
1327 | apic_verbosity = APIC_VERBOSE; | ||
1328 | else { | ||
1329 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" | ||
1330 | " use apic=verbose or apic=debug\n", str); | ||
1331 | return -EINVAL; | ||
1332 | } | ||
1333 | |||
1334 | return 0; | 1754 | return 0; |
1335 | } | 1755 | } |
1336 | early_param("apic", apic_set_verbosity); | 1756 | early_param("nox2apic", setup_nox2apic); |
1757 | |||
1337 | 1758 | ||
1338 | static __init int setup_disableapic(char *str) | 1759 | /* |
1760 | * APIC command line parameters | ||
1761 | */ | ||
1762 | static int __init setup_disableapic(char *arg) | ||
1339 | { | 1763 | { |
1340 | disable_apic = 1; | 1764 | disable_apic = 1; |
1341 | setup_clear_cpu_cap(X86_FEATURE_APIC); | 1765 | setup_clear_cpu_cap(X86_FEATURE_APIC); |
@@ -1344,9 +1768,9 @@ static __init int setup_disableapic(char *str) | |||
1344 | early_param("disableapic", setup_disableapic); | 1768 | early_param("disableapic", setup_disableapic); |
1345 | 1769 | ||
1346 | /* same as disableapic, for compatibility */ | 1770 | /* same as disableapic, for compatibility */ |
1347 | static __init int setup_nolapic(char *str) | 1771 | static int __init setup_nolapic(char *arg) |
1348 | { | 1772 | { |
1349 | return setup_disableapic(str); | 1773 | return setup_disableapic(arg); |
1350 | } | 1774 | } |
1351 | early_param("nolapic", setup_nolapic); | 1775 | early_param("nolapic", setup_nolapic); |
1352 | 1776 | ||
@@ -1357,14 +1781,19 @@ static int __init parse_lapic_timer_c2_ok(char *arg) | |||
1357 | } | 1781 | } |
1358 | early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); | 1782 | early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); |
1359 | 1783 | ||
1360 | static __init int setup_noapictimer(char *str) | 1784 | static int __init parse_disable_apic_timer(char *arg) |
1361 | { | 1785 | { |
1362 | if (str[0] != ' ' && str[0] != 0) | ||
1363 | return 0; | ||
1364 | disable_apic_timer = 1; | 1786 | disable_apic_timer = 1; |
1365 | return 1; | 1787 | return 0; |
1366 | } | 1788 | } |
1367 | __setup("noapictimer", setup_noapictimer); | 1789 | early_param("noapictimer", parse_disable_apic_timer); |
1790 | |||
1791 | static int __init parse_nolapic_timer(char *arg) | ||
1792 | { | ||
1793 | disable_apic_timer = 1; | ||
1794 | return 0; | ||
1795 | } | ||
1796 | early_param("nolapic_timer", parse_nolapic_timer); | ||
1368 | 1797 | ||
1369 | static __init int setup_apicpmtimer(char *s) | 1798 | static __init int setup_apicpmtimer(char *s) |
1370 | { | 1799 | { |
@@ -1374,6 +1803,31 @@ static __init int setup_apicpmtimer(char *s) | |||
1374 | } | 1803 | } |
1375 | __setup("apicpmtimer", setup_apicpmtimer); | 1804 | __setup("apicpmtimer", setup_apicpmtimer); |
1376 | 1805 | ||
1806 | static int __init apic_set_verbosity(char *arg) | ||
1807 | { | ||
1808 | if (!arg) { | ||
1809 | #ifdef CONFIG_X86_64 | ||
1810 | skip_ioapic_setup = 0; | ||
1811 | ioapic_force = 1; | ||
1812 | return 0; | ||
1813 | #endif | ||
1814 | return -EINVAL; | ||
1815 | } | ||
1816 | |||
1817 | if (strcmp("debug", arg) == 0) | ||
1818 | apic_verbosity = APIC_DEBUG; | ||
1819 | else if (strcmp("verbose", arg) == 0) | ||
1820 | apic_verbosity = APIC_VERBOSE; | ||
1821 | else { | ||
1822 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" | ||
1823 | " use apic=verbose or apic=debug\n", arg); | ||
1824 | return -EINVAL; | ||
1825 | } | ||
1826 | |||
1827 | return 0; | ||
1828 | } | ||
1829 | early_param("apic", apic_set_verbosity); | ||
1830 | |||
1377 | static int __init lapic_insert_resource(void) | 1831 | static int __init lapic_insert_resource(void) |
1378 | { | 1832 | { |
1379 | if (!apic_phys) | 1833 | if (!apic_phys) |