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 446c062e831c..53898b65a6ae 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 | /* |
@@ -366,7 +469,7 @@ static int __init calibrate_APIC_clock(void) | |||
366 | lapic_clockevent.min_delta_ns = | 469 | lapic_clockevent.min_delta_ns = |
367 | clockevent_delta2ns(0xF, &lapic_clockevent); | 470 | clockevent_delta2ns(0xF, &lapic_clockevent); |
368 | 471 | ||
369 | calibration_result = result / HZ; | 472 | calibration_result = (result * APIC_DIVISOR) / HZ; |
370 | 473 | ||
371 | /* | 474 | /* |
372 | * Do a sanity check on the APIC calibration result | 475 | * Do a sanity check on the APIC calibration result |
@@ -388,10 +491,10 @@ static int __init calibrate_APIC_clock(void) | |||
388 | void __init setup_boot_APIC_clock(void) | 491 | void __init setup_boot_APIC_clock(void) |
389 | { | 492 | { |
390 | /* | 493 | /* |
391 | * The local apic timer can be disabled via the kernel commandline. | 494 | * The local apic timer can be disabled via the kernel |
392 | * Register the lapic timer as a dummy clock event source on SMP | 495 | * commandline or from the CPU detection code. Register the lapic |
393 | * systems, so the broadcast mechanism is used. On UP systems simply | 496 | * timer as a dummy clock event source on SMP systems, so the |
394 | * ignore it. | 497 | * broadcast mechanism is used. On UP systems simply ignore it. |
395 | */ | 498 | */ |
396 | if (disable_apic_timer) { | 499 | if (disable_apic_timer) { |
397 | printk(KERN_INFO "Disabling APIC timer\n"); | 500 | printk(KERN_INFO "Disabling APIC timer\n"); |
@@ -403,7 +506,9 @@ void __init setup_boot_APIC_clock(void) | |||
403 | return; | 506 | return; |
404 | } | 507 | } |
405 | 508 | ||
406 | printk(KERN_INFO "Using local APIC timer interrupts.\n"); | 509 | apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" |
510 | "calibrating APIC timer ...\n"); | ||
511 | |||
407 | if (calibrate_APIC_clock()) { | 512 | if (calibrate_APIC_clock()) { |
408 | /* No broadcast on UP ! */ | 513 | /* No broadcast on UP ! */ |
409 | if (num_possible_cpus() > 1) | 514 | if (num_possible_cpus() > 1) |
@@ -422,6 +527,7 @@ void __init setup_boot_APIC_clock(void) | |||
422 | printk(KERN_WARNING "APIC timer registered as dummy," | 527 | printk(KERN_WARNING "APIC timer registered as dummy," |
423 | " due to nmi_watchdog=%d!\n", nmi_watchdog); | 528 | " due to nmi_watchdog=%d!\n", nmi_watchdog); |
424 | 529 | ||
530 | /* Setup the lapic or request the broadcast */ | ||
425 | setup_APIC_timer(); | 531 | setup_APIC_timer(); |
426 | } | 532 | } |
427 | 533 | ||
@@ -460,7 +566,11 @@ static void local_apic_timer_interrupt(void) | |||
460 | /* | 566 | /* |
461 | * the NMI deadlock-detector uses this. | 567 | * the NMI deadlock-detector uses this. |
462 | */ | 568 | */ |
569 | #ifdef CONFIG_X86_64 | ||
463 | add_pda(apic_timer_irqs, 1); | 570 | add_pda(apic_timer_irqs, 1); |
571 | #else | ||
572 | per_cpu(irq_stat, cpu).apic_timer_irqs++; | ||
573 | #endif | ||
464 | 574 | ||
465 | evt->event_handler(evt); | 575 | evt->event_handler(evt); |
466 | } | 576 | } |
@@ -491,6 +601,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) | |||
491 | irq_enter(); | 601 | irq_enter(); |
492 | local_apic_timer_interrupt(); | 602 | local_apic_timer_interrupt(); |
493 | irq_exit(); | 603 | irq_exit(); |
604 | |||
494 | set_irq_regs(old_regs); | 605 | set_irq_regs(old_regs); |
495 | } | 606 | } |
496 | 607 | ||
@@ -544,6 +655,13 @@ void clear_local_APIC(void) | |||
544 | apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); | 655 | apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); |
545 | } | 656 | } |
546 | 657 | ||
658 | /* lets not touch this if we didn't frob it */ | ||
659 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL) | ||
660 | if (maxlvt >= 5) { | ||
661 | v = apic_read(APIC_LVTTHMR); | ||
662 | apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED); | ||
663 | } | ||
664 | #endif | ||
547 | /* | 665 | /* |
548 | * Clean APIC state for other OSs: | 666 | * Clean APIC state for other OSs: |
549 | */ | 667 | */ |
@@ -554,8 +672,14 @@ void clear_local_APIC(void) | |||
554 | apic_write(APIC_LVTERR, APIC_LVT_MASKED); | 672 | apic_write(APIC_LVTERR, APIC_LVT_MASKED); |
555 | if (maxlvt >= 4) | 673 | if (maxlvt >= 4) |
556 | apic_write(APIC_LVTPC, APIC_LVT_MASKED); | 674 | apic_write(APIC_LVTPC, APIC_LVT_MASKED); |
557 | apic_write(APIC_ESR, 0); | 675 | |
558 | apic_read(APIC_ESR); | 676 | /* Integrated APIC (!82489DX) ? */ |
677 | if (lapic_is_integrated()) { | ||
678 | if (maxlvt > 3) | ||
679 | /* Clear ESR due to Pentium errata 3AP and 11AP */ | ||
680 | apic_write(APIC_ESR, 0); | ||
681 | apic_read(APIC_ESR); | ||
682 | } | ||
559 | } | 683 | } |
560 | 684 | ||
561 | /** | 685 | /** |
@@ -574,8 +698,28 @@ void disable_local_APIC(void) | |||
574 | value = apic_read(APIC_SPIV); | 698 | value = apic_read(APIC_SPIV); |
575 | value &= ~APIC_SPIV_APIC_ENABLED; | 699 | value &= ~APIC_SPIV_APIC_ENABLED; |
576 | apic_write(APIC_SPIV, value); | 700 | apic_write(APIC_SPIV, value); |
701 | |||
702 | #ifdef CONFIG_X86_32 | ||
703 | /* | ||
704 | * When LAPIC was disabled by the BIOS and enabled by the kernel, | ||
705 | * restore the disabled state. | ||
706 | */ | ||
707 | if (enabled_via_apicbase) { | ||
708 | unsigned int l, h; | ||
709 | |||
710 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
711 | l &= ~MSR_IA32_APICBASE_ENABLE; | ||
712 | wrmsr(MSR_IA32_APICBASE, l, h); | ||
713 | } | ||
714 | #endif | ||
577 | } | 715 | } |
578 | 716 | ||
717 | /* | ||
718 | * If Linux enabled the LAPIC against the BIOS default disable it down before | ||
719 | * re-entering the BIOS on shutdown. Otherwise the BIOS may get confused and | ||
720 | * not power-off. Additionally clear all LVT entries before disable_local_APIC | ||
721 | * for the case where Linux didn't enable the LAPIC. | ||
722 | */ | ||
579 | void lapic_shutdown(void) | 723 | void lapic_shutdown(void) |
580 | { | 724 | { |
581 | unsigned long flags; | 725 | unsigned long flags; |
@@ -585,7 +729,13 @@ void lapic_shutdown(void) | |||
585 | 729 | ||
586 | local_irq_save(flags); | 730 | local_irq_save(flags); |
587 | 731 | ||
588 | disable_local_APIC(); | 732 | #ifdef CONFIG_X86_32 |
733 | if (!enabled_via_apicbase) | ||
734 | clear_local_APIC(); | ||
735 | else | ||
736 | #endif | ||
737 | disable_local_APIC(); | ||
738 | |||
589 | 739 | ||
590 | local_irq_restore(flags); | 740 | local_irq_restore(flags); |
591 | } | 741 | } |
@@ -629,10 +779,10 @@ int __init verify_local_APIC(void) | |||
629 | /* | 779 | /* |
630 | * The ID register is read/write in a real APIC. | 780 | * The ID register is read/write in a real APIC. |
631 | */ | 781 | */ |
632 | reg0 = read_apic_id(); | 782 | reg0 = apic_read(APIC_ID); |
633 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); | 783 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0); |
634 | apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); | 784 | apic_write(APIC_ID, reg0 ^ APIC_ID_MASK); |
635 | reg1 = read_apic_id(); | 785 | reg1 = apic_read(APIC_ID); |
636 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); | 786 | apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1); |
637 | apic_write(APIC_ID, reg0); | 787 | apic_write(APIC_ID, reg0); |
638 | if (reg1 != (reg0 ^ APIC_ID_MASK)) | 788 | if (reg1 != (reg0 ^ APIC_ID_MASK)) |
@@ -656,8 +806,11 @@ int __init verify_local_APIC(void) | |||
656 | */ | 806 | */ |
657 | void __init sync_Arb_IDs(void) | 807 | void __init sync_Arb_IDs(void) |
658 | { | 808 | { |
659 | /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ | 809 | /* |
660 | if (modern_apic()) | 810 | * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not |
811 | * needed on AMD. | ||
812 | */ | ||
813 | if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD) | ||
661 | return; | 814 | return; |
662 | 815 | ||
663 | /* | 816 | /* |
@@ -666,8 +819,8 @@ void __init sync_Arb_IDs(void) | |||
666 | apic_wait_icr_idle(); | 819 | apic_wait_icr_idle(); |
667 | 820 | ||
668 | apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); | 821 | apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n"); |
669 | apic_write(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG | 822 | apic_write(APIC_ICR, APIC_DEST_ALLINC | |
670 | | APIC_DM_INIT); | 823 | APIC_INT_LEVELTRIG | APIC_DM_INIT); |
671 | } | 824 | } |
672 | 825 | ||
673 | /* | 826 | /* |
@@ -684,8 +837,6 @@ void __init init_bsp_APIC(void) | |||
684 | if (smp_found_config || !cpu_has_apic) | 837 | if (smp_found_config || !cpu_has_apic) |
685 | return; | 838 | return; |
686 | 839 | ||
687 | value = apic_read(APIC_LVR); | ||
688 | |||
689 | /* | 840 | /* |
690 | * Do not trust the local APIC being empty at bootup. | 841 | * Do not trust the local APIC being empty at bootup. |
691 | */ | 842 | */ |
@@ -697,7 +848,15 @@ void __init init_bsp_APIC(void) | |||
697 | value = apic_read(APIC_SPIV); | 848 | value = apic_read(APIC_SPIV); |
698 | value &= ~APIC_VECTOR_MASK; | 849 | value &= ~APIC_VECTOR_MASK; |
699 | value |= APIC_SPIV_APIC_ENABLED; | 850 | value |= APIC_SPIV_APIC_ENABLED; |
700 | value |= APIC_SPIV_FOCUS_DISABLED; | 851 | |
852 | #ifdef CONFIG_X86_32 | ||
853 | /* This bit is reserved on P4/Xeon and should be cleared */ | ||
854 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && | ||
855 | (boot_cpu_data.x86 == 15)) | ||
856 | value &= ~APIC_SPIV_FOCUS_DISABLED; | ||
857 | else | ||
858 | #endif | ||
859 | value |= APIC_SPIV_FOCUS_DISABLED; | ||
701 | value |= SPURIOUS_APIC_VECTOR; | 860 | value |= SPURIOUS_APIC_VECTOR; |
702 | apic_write(APIC_SPIV, value); | 861 | apic_write(APIC_SPIV, value); |
703 | 862 | ||
@@ -706,9 +865,50 @@ void __init init_bsp_APIC(void) | |||
706 | */ | 865 | */ |
707 | apic_write(APIC_LVT0, APIC_DM_EXTINT); | 866 | apic_write(APIC_LVT0, APIC_DM_EXTINT); |
708 | value = APIC_DM_NMI; | 867 | value = APIC_DM_NMI; |
868 | if (!lapic_is_integrated()) /* 82489DX */ | ||
869 | value |= APIC_LVT_LEVEL_TRIGGER; | ||
709 | apic_write(APIC_LVT1, value); | 870 | apic_write(APIC_LVT1, value); |
710 | } | 871 | } |
711 | 872 | ||
873 | static void __cpuinit lapic_setup_esr(void) | ||
874 | { | ||
875 | unsigned long oldvalue, value, maxlvt; | ||
876 | if (lapic_is_integrated() && !esr_disable) { | ||
877 | if (esr_disable) { | ||
878 | /* | ||
879 | * Something untraceable is creating bad interrupts on | ||
880 | * secondary quads ... for the moment, just leave the | ||
881 | * ESR disabled - we can't do anything useful with the | ||
882 | * errors anyway - mbligh | ||
883 | */ | ||
884 | printk(KERN_INFO "Leaving ESR disabled.\n"); | ||
885 | return; | ||
886 | } | ||
887 | /* !82489DX */ | ||
888 | maxlvt = lapic_get_maxlvt(); | ||
889 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ | ||
890 | apic_write(APIC_ESR, 0); | ||
891 | oldvalue = apic_read(APIC_ESR); | ||
892 | |||
893 | /* enables sending errors */ | ||
894 | value = ERROR_APIC_VECTOR; | ||
895 | apic_write(APIC_LVTERR, value); | ||
896 | /* | ||
897 | * spec says clear errors after enabling vector. | ||
898 | */ | ||
899 | if (maxlvt > 3) | ||
900 | apic_write(APIC_ESR, 0); | ||
901 | value = apic_read(APIC_ESR); | ||
902 | if (value != oldvalue) | ||
903 | apic_printk(APIC_VERBOSE, "ESR value before enabling " | ||
904 | "vector: 0x%08lx after: 0x%08lx\n", | ||
905 | oldvalue, value); | ||
906 | } else { | ||
907 | printk(KERN_INFO "No ESR for 82489DX.\n"); | ||
908 | } | ||
909 | } | ||
910 | |||
911 | |||
712 | /** | 912 | /** |
713 | * setup_local_APIC - setup the local APIC | 913 | * setup_local_APIC - setup the local APIC |
714 | */ | 914 | */ |
@@ -814,25 +1014,143 @@ void __cpuinit setup_local_APIC(void) | |||
814 | preempt_enable(); | 1014 | preempt_enable(); |
815 | } | 1015 | } |
816 | 1016 | ||
817 | static void __cpuinit lapic_setup_esr(void) | ||
818 | { | ||
819 | unsigned maxlvt = lapic_get_maxlvt(); | ||
820 | |||
821 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR); | ||
822 | /* | ||
823 | * spec says clear errors after enabling vector. | ||
824 | */ | ||
825 | if (maxlvt > 3) | ||
826 | apic_write(APIC_ESR, 0); | ||
827 | } | ||
828 | |||
829 | void __cpuinit end_local_APIC_setup(void) | 1017 | void __cpuinit end_local_APIC_setup(void) |
830 | { | 1018 | { |
831 | lapic_setup_esr(); | 1019 | lapic_setup_esr(); |
1020 | |||
1021 | #ifdef CONFIG_X86_32 | ||
1022 | { | ||
1023 | unsigned int value; | ||
1024 | /* Disable the local apic timer */ | ||
1025 | value = apic_read(APIC_LVTT); | ||
1026 | value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); | ||
1027 | apic_write(APIC_LVTT, value); | ||
1028 | } | ||
1029 | #endif | ||
1030 | |||
832 | setup_apic_nmi_watchdog(NULL); | 1031 | setup_apic_nmi_watchdog(NULL); |
833 | apic_pm_activate(); | 1032 | apic_pm_activate(); |
834 | } | 1033 | } |
835 | 1034 | ||
1035 | void check_x2apic(void) | ||
1036 | { | ||
1037 | int msr, msr2; | ||
1038 | |||
1039 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | ||
1040 | |||
1041 | if (msr & X2APIC_ENABLE) { | ||
1042 | printk("x2apic enabled by BIOS, switching to x2apic ops\n"); | ||
1043 | x2apic_preenabled = x2apic = 1; | ||
1044 | apic_ops = &x2apic_ops; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | void enable_x2apic(void) | ||
1049 | { | ||
1050 | int msr, msr2; | ||
1051 | |||
1052 | rdmsr(MSR_IA32_APICBASE, msr, msr2); | ||
1053 | if (!(msr & X2APIC_ENABLE)) { | ||
1054 | printk("Enabling x2apic\n"); | ||
1055 | wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0); | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | void enable_IR_x2apic(void) | ||
1060 | { | ||
1061 | #ifdef CONFIG_INTR_REMAP | ||
1062 | int ret; | ||
1063 | unsigned long flags; | ||
1064 | |||
1065 | if (!cpu_has_x2apic) | ||
1066 | return; | ||
1067 | |||
1068 | if (!x2apic_preenabled && disable_x2apic) { | ||
1069 | printk(KERN_INFO | ||
1070 | "Skipped enabling x2apic and Interrupt-remapping " | ||
1071 | "because of nox2apic\n"); | ||
1072 | return; | ||
1073 | } | ||
1074 | |||
1075 | if (x2apic_preenabled && disable_x2apic) | ||
1076 | panic("Bios already enabled x2apic, can't enforce nox2apic"); | ||
1077 | |||
1078 | if (!x2apic_preenabled && skip_ioapic_setup) { | ||
1079 | printk(KERN_INFO | ||
1080 | "Skipped enabling x2apic and Interrupt-remapping " | ||
1081 | "because of skipping io-apic setup\n"); | ||
1082 | return; | ||
1083 | } | ||
1084 | |||
1085 | ret = dmar_table_init(); | ||
1086 | if (ret) { | ||
1087 | printk(KERN_INFO | ||
1088 | "dmar_table_init() failed with %d:\n", ret); | ||
1089 | |||
1090 | if (x2apic_preenabled) | ||
1091 | panic("x2apic enabled by bios. But IR enabling failed"); | ||
1092 | else | ||
1093 | printk(KERN_INFO | ||
1094 | "Not enabling x2apic,Intr-remapping\n"); | ||
1095 | return; | ||
1096 | } | ||
1097 | |||
1098 | local_irq_save(flags); | ||
1099 | mask_8259A(); | ||
1100 | save_mask_IO_APIC_setup(); | ||
1101 | |||
1102 | ret = enable_intr_remapping(1); | ||
1103 | |||
1104 | if (ret && x2apic_preenabled) { | ||
1105 | local_irq_restore(flags); | ||
1106 | panic("x2apic enabled by bios. But IR enabling failed"); | ||
1107 | } | ||
1108 | |||
1109 | if (ret) | ||
1110 | goto end; | ||
1111 | |||
1112 | if (!x2apic) { | ||
1113 | x2apic = 1; | ||
1114 | apic_ops = &x2apic_ops; | ||
1115 | enable_x2apic(); | ||
1116 | } | ||
1117 | end: | ||
1118 | if (ret) | ||
1119 | /* | ||
1120 | * IR enabling failed | ||
1121 | */ | ||
1122 | restore_IO_APIC_setup(); | ||
1123 | else | ||
1124 | reinit_intr_remapped_IO_APIC(x2apic_preenabled); | ||
1125 | |||
1126 | unmask_8259A(); | ||
1127 | local_irq_restore(flags); | ||
1128 | |||
1129 | if (!ret) { | ||
1130 | if (!x2apic_preenabled) | ||
1131 | printk(KERN_INFO | ||
1132 | "Enabled x2apic and interrupt-remapping\n"); | ||
1133 | else | ||
1134 | printk(KERN_INFO | ||
1135 | "Enabled Interrupt-remapping\n"); | ||
1136 | } else | ||
1137 | printk(KERN_ERR | ||
1138 | "Failed to enable Interrupt-remapping and x2apic\n"); | ||
1139 | #else | ||
1140 | if (!cpu_has_x2apic) | ||
1141 | return; | ||
1142 | |||
1143 | if (x2apic_preenabled) | ||
1144 | panic("x2apic enabled prior OS handover," | ||
1145 | " enable CONFIG_INTR_REMAP"); | ||
1146 | |||
1147 | printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping " | ||
1148 | " and x2apic\n"); | ||
1149 | #endif | ||
1150 | |||
1151 | return; | ||
1152 | } | ||
1153 | |||
836 | /* | 1154 | /* |
837 | * Detect and enable local APICs on non-SMP boards. | 1155 | * Detect and enable local APICs on non-SMP boards. |
838 | * Original code written by Keir Fraser. | 1156 | * Original code written by Keir Fraser. |
@@ -872,7 +1190,7 @@ void __init early_init_lapic_mapping(void) | |||
872 | * Fetch the APIC ID of the BSP in case we have a | 1190 | * Fetch the APIC ID of the BSP in case we have a |
873 | * default configuration (or the MP table is broken). | 1191 | * default configuration (or the MP table is broken). |
874 | */ | 1192 | */ |
875 | boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); | 1193 | boot_cpu_physical_apicid = read_apic_id(); |
876 | } | 1194 | } |
877 | 1195 | ||
878 | /** | 1196 | /** |
@@ -880,6 +1198,11 @@ void __init early_init_lapic_mapping(void) | |||
880 | */ | 1198 | */ |
881 | void __init init_apic_mappings(void) | 1199 | void __init init_apic_mappings(void) |
882 | { | 1200 | { |
1201 | if (x2apic) { | ||
1202 | boot_cpu_physical_apicid = read_apic_id(); | ||
1203 | return; | ||
1204 | } | ||
1205 | |||
883 | /* | 1206 | /* |
884 | * If no local APIC can be found then set up a fake all | 1207 | * If no local APIC can be found then set up a fake all |
885 | * zeroes page to simulate the local APIC and another | 1208 | * zeroes page to simulate the local APIC and another |
@@ -899,13 +1222,15 @@ void __init init_apic_mappings(void) | |||
899 | * Fetch the APIC ID of the BSP in case we have a | 1222 | * Fetch the APIC ID of the BSP in case we have a |
900 | * default configuration (or the MP table is broken). | 1223 | * default configuration (or the MP table is broken). |
901 | */ | 1224 | */ |
902 | boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); | 1225 | boot_cpu_physical_apicid = read_apic_id(); |
903 | } | 1226 | } |
904 | 1227 | ||
905 | /* | 1228 | /* |
906 | * This initializes the IO-APIC and APIC hardware if this is | 1229 | * This initializes the IO-APIC and APIC hardware if this is |
907 | * a UP kernel. | 1230 | * a UP kernel. |
908 | */ | 1231 | */ |
1232 | int apic_version[MAX_APICS]; | ||
1233 | |||
909 | int __init APIC_init_uniprocessor(void) | 1234 | int __init APIC_init_uniprocessor(void) |
910 | { | 1235 | { |
911 | if (disable_apic) { | 1236 | if (disable_apic) { |
@@ -918,6 +1243,9 @@ int __init APIC_init_uniprocessor(void) | |||
918 | return -1; | 1243 | return -1; |
919 | } | 1244 | } |
920 | 1245 | ||
1246 | enable_IR_x2apic(); | ||
1247 | setup_apic_routing(); | ||
1248 | |||
921 | verify_local_APIC(); | 1249 | verify_local_APIC(); |
922 | 1250 | ||
923 | connect_bsp_APIC(); | 1251 | connect_bsp_APIC(); |
@@ -1004,17 +1332,57 @@ asmlinkage void smp_error_interrupt(void) | |||
1004 | } | 1332 | } |
1005 | 1333 | ||
1006 | /** | 1334 | /** |
1007 | * * connect_bsp_APIC - attach the APIC to the interrupt system | 1335 | * connect_bsp_APIC - attach the APIC to the interrupt system |
1008 | * */ | 1336 | */ |
1009 | void __init connect_bsp_APIC(void) | 1337 | void __init connect_bsp_APIC(void) |
1010 | { | 1338 | { |
1339 | #ifdef CONFIG_X86_32 | ||
1340 | if (pic_mode) { | ||
1341 | /* | ||
1342 | * Do not trust the local APIC being empty at bootup. | ||
1343 | */ | ||
1344 | clear_local_APIC(); | ||
1345 | /* | ||
1346 | * PIC mode, enable APIC mode in the IMCR, i.e. connect BSP's | ||
1347 | * local APIC to INT and NMI lines. | ||
1348 | */ | ||
1349 | apic_printk(APIC_VERBOSE, "leaving PIC mode, " | ||
1350 | "enabling APIC mode.\n"); | ||
1351 | outb(0x70, 0x22); | ||
1352 | outb(0x01, 0x23); | ||
1353 | } | ||
1354 | #endif | ||
1011 | enable_apic_mode(); | 1355 | enable_apic_mode(); |
1012 | } | 1356 | } |
1013 | 1357 | ||
1358 | /** | ||
1359 | * disconnect_bsp_APIC - detach the APIC from the interrupt system | ||
1360 | * @virt_wire_setup: indicates, whether virtual wire mode is selected | ||
1361 | * | ||
1362 | * Virtual wire mode is necessary to deliver legacy interrupts even when the | ||
1363 | * APIC is disabled. | ||
1364 | */ | ||
1014 | void disconnect_bsp_APIC(int virt_wire_setup) | 1365 | void disconnect_bsp_APIC(int virt_wire_setup) |
1015 | { | 1366 | { |
1367 | unsigned int value; | ||
1368 | |||
1369 | #ifdef CONFIG_X86_32 | ||
1370 | if (pic_mode) { | ||
1371 | /* | ||
1372 | * Put the board back into PIC mode (has an effect only on | ||
1373 | * certain older boards). Note that APIC interrupts, including | ||
1374 | * IPIs, won't work beyond this point! The only exception are | ||
1375 | * INIT IPIs. | ||
1376 | */ | ||
1377 | apic_printk(APIC_VERBOSE, "disabling APIC mode, " | ||
1378 | "entering PIC mode.\n"); | ||
1379 | outb(0x70, 0x22); | ||
1380 | outb(0x00, 0x23); | ||
1381 | return; | ||
1382 | } | ||
1383 | #endif | ||
1384 | |||
1016 | /* Go back to Virtual Wire compatibility mode */ | 1385 | /* Go back to Virtual Wire compatibility mode */ |
1017 | unsigned long value; | ||
1018 | 1386 | ||
1019 | /* For the spurious interrupt use vector F, and enable it */ | 1387 | /* For the spurious interrupt use vector F, and enable it */ |
1020 | value = apic_read(APIC_SPIV); | 1388 | value = apic_read(APIC_SPIV); |
@@ -1040,7 +1408,10 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
1040 | apic_write(APIC_LVT0, APIC_LVT_MASKED); | 1408 | apic_write(APIC_LVT0, APIC_LVT_MASKED); |
1041 | } | 1409 | } |
1042 | 1410 | ||
1043 | /* For LVT1 make it edge triggered, active high, nmi and enabled */ | 1411 | /* |
1412 | * For LVT1 make it edge triggered, active high, | ||
1413 | * nmi and enabled | ||
1414 | */ | ||
1044 | value = apic_read(APIC_LVT1); | 1415 | value = apic_read(APIC_LVT1); |
1045 | value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | | 1416 | value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | |
1046 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | | 1417 | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | |
@@ -1055,9 +1426,20 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1055 | int cpu; | 1426 | int cpu; |
1056 | cpumask_t tmp_map; | 1427 | cpumask_t tmp_map; |
1057 | 1428 | ||
1429 | /* | ||
1430 | * Validate version | ||
1431 | */ | ||
1432 | if (version == 0x0) { | ||
1433 | printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! " | ||
1434 | "fixing up to 0x10. (tell your hw vendor)\n", | ||
1435 | version); | ||
1436 | version = 0x10; | ||
1437 | } | ||
1438 | apic_version[apicid] = version; | ||
1439 | |||
1058 | if (num_processors >= NR_CPUS) { | 1440 | if (num_processors >= NR_CPUS) { |
1059 | printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." | 1441 | printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." |
1060 | " Processor ignored.\n", NR_CPUS); | 1442 | " Processor ignored.\n", NR_CPUS); |
1061 | return; | 1443 | return; |
1062 | } | 1444 | } |
1063 | 1445 | ||
@@ -1077,6 +1459,29 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1077 | if (apicid > max_physical_apicid) | 1459 | if (apicid > max_physical_apicid) |
1078 | max_physical_apicid = apicid; | 1460 | max_physical_apicid = apicid; |
1079 | 1461 | ||
1462 | #ifdef CONFIG_X86_32 | ||
1463 | /* | ||
1464 | * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y | ||
1465 | * but we need to work other dependencies like SMP_SUSPEND etc | ||
1466 | * before this can be done without some confusion. | ||
1467 | * if (CPU_HOTPLUG_ENABLED || num_processors > 8) | ||
1468 | * - Ashok Raj <ashok.raj@intel.com> | ||
1469 | */ | ||
1470 | if (max_physical_apicid >= 8) { | ||
1471 | switch (boot_cpu_data.x86_vendor) { | ||
1472 | case X86_VENDOR_INTEL: | ||
1473 | if (!APIC_XAPIC(version)) { | ||
1474 | def_to_bigsmp = 0; | ||
1475 | break; | ||
1476 | } | ||
1477 | /* If P4 and above fall through */ | ||
1478 | case X86_VENDOR_AMD: | ||
1479 | def_to_bigsmp = 1; | ||
1480 | } | ||
1481 | } | ||
1482 | #endif | ||
1483 | |||
1484 | #if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64) | ||
1080 | /* are we being called early in kernel startup? */ | 1485 | /* are we being called early in kernel startup? */ |
1081 | if (early_per_cpu_ptr(x86_cpu_to_apicid)) { | 1486 | if (early_per_cpu_ptr(x86_cpu_to_apicid)) { |
1082 | u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid); | 1487 | u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid); |
@@ -1088,20 +1493,28 @@ void __cpuinit generic_processor_info(int apicid, int version) | |||
1088 | per_cpu(x86_cpu_to_apicid, cpu) = apicid; | 1493 | per_cpu(x86_cpu_to_apicid, cpu) = apicid; |
1089 | per_cpu(x86_bios_cpu_apicid, cpu) = apicid; | 1494 | per_cpu(x86_bios_cpu_apicid, cpu) = apicid; |
1090 | } | 1495 | } |
1496 | #endif | ||
1091 | 1497 | ||
1092 | cpu_set(cpu, cpu_possible_map); | 1498 | cpu_set(cpu, cpu_possible_map); |
1093 | cpu_set(cpu, cpu_present_map); | 1499 | cpu_set(cpu, cpu_present_map); |
1094 | } | 1500 | } |
1095 | 1501 | ||
1502 | int hard_smp_processor_id(void) | ||
1503 | { | ||
1504 | return read_apic_id(); | ||
1505 | } | ||
1506 | |||
1096 | /* | 1507 | /* |
1097 | * Power management | 1508 | * Power management |
1098 | */ | 1509 | */ |
1099 | #ifdef CONFIG_PM | 1510 | #ifdef CONFIG_PM |
1100 | 1511 | ||
1101 | static struct { | 1512 | static struct { |
1102 | /* 'active' is true if the local APIC was enabled by us and | 1513 | /* |
1103 | not the BIOS; this signifies that we are also responsible | 1514 | * 'active' is true if the local APIC was enabled by us and |
1104 | for disabling it before entering apm/acpi suspend */ | 1515 | * not the BIOS; this signifies that we are also responsible |
1516 | * for disabling it before entering apm/acpi suspend | ||
1517 | */ | ||
1105 | int active; | 1518 | int active; |
1106 | /* r/w apic fields */ | 1519 | /* r/w apic fields */ |
1107 | unsigned int apic_id; | 1520 | unsigned int apic_id; |
@@ -1129,7 +1542,7 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) | |||
1129 | 1542 | ||
1130 | maxlvt = lapic_get_maxlvt(); | 1543 | maxlvt = lapic_get_maxlvt(); |
1131 | 1544 | ||
1132 | apic_pm_state.apic_id = read_apic_id(); | 1545 | apic_pm_state.apic_id = apic_read(APIC_ID); |
1133 | apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); | 1546 | apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); |
1134 | apic_pm_state.apic_ldr = apic_read(APIC_LDR); | 1547 | apic_pm_state.apic_ldr = apic_read(APIC_LDR); |
1135 | apic_pm_state.apic_dfr = apic_read(APIC_DFR); | 1548 | apic_pm_state.apic_dfr = apic_read(APIC_DFR); |
@@ -1142,10 +1555,11 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) | |||
1142 | apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); | 1555 | apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); |
1143 | apic_pm_state.apic_tmict = apic_read(APIC_TMICT); | 1556 | apic_pm_state.apic_tmict = apic_read(APIC_TMICT); |
1144 | apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); | 1557 | apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); |
1145 | #ifdef CONFIG_X86_MCE_INTEL | 1558 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) |
1146 | if (maxlvt >= 5) | 1559 | if (maxlvt >= 5) |
1147 | apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); | 1560 | apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); |
1148 | #endif | 1561 | #endif |
1562 | |||
1149 | local_irq_save(flags); | 1563 | local_irq_save(flags); |
1150 | disable_local_APIC(); | 1564 | disable_local_APIC(); |
1151 | local_irq_restore(flags); | 1565 | local_irq_restore(flags); |
@@ -1164,10 +1578,25 @@ static int lapic_resume(struct sys_device *dev) | |||
1164 | maxlvt = lapic_get_maxlvt(); | 1578 | maxlvt = lapic_get_maxlvt(); |
1165 | 1579 | ||
1166 | local_irq_save(flags); | 1580 | local_irq_save(flags); |
1167 | rdmsr(MSR_IA32_APICBASE, l, h); | 1581 | |
1168 | l &= ~MSR_IA32_APICBASE_BASE; | 1582 | #ifdef CONFIG_X86_64 |
1169 | l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; | 1583 | if (x2apic) |
1170 | wrmsr(MSR_IA32_APICBASE, l, h); | 1584 | enable_x2apic(); |
1585 | else | ||
1586 | #endif | ||
1587 | { | ||
1588 | /* | ||
1589 | * Make sure the APICBASE points to the right address | ||
1590 | * | ||
1591 | * FIXME! This will be wrong if we ever support suspend on | ||
1592 | * SMP! We'll need to do this as part of the CPU restore! | ||
1593 | */ | ||
1594 | rdmsr(MSR_IA32_APICBASE, l, h); | ||
1595 | l &= ~MSR_IA32_APICBASE_BASE; | ||
1596 | l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; | ||
1597 | wrmsr(MSR_IA32_APICBASE, l, h); | ||
1598 | } | ||
1599 | |||
1171 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); | 1600 | apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); |
1172 | apic_write(APIC_ID, apic_pm_state.apic_id); | 1601 | apic_write(APIC_ID, apic_pm_state.apic_id); |
1173 | apic_write(APIC_DFR, apic_pm_state.apic_dfr); | 1602 | apic_write(APIC_DFR, apic_pm_state.apic_dfr); |
@@ -1176,7 +1605,7 @@ static int lapic_resume(struct sys_device *dev) | |||
1176 | apic_write(APIC_SPIV, apic_pm_state.apic_spiv); | 1605 | apic_write(APIC_SPIV, apic_pm_state.apic_spiv); |
1177 | apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); | 1606 | apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); |
1178 | apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); | 1607 | apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); |
1179 | #ifdef CONFIG_X86_MCE_INTEL | 1608 | #if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL) |
1180 | if (maxlvt >= 5) | 1609 | if (maxlvt >= 5) |
1181 | apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); | 1610 | apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); |
1182 | #endif | 1611 | #endif |
@@ -1190,10 +1619,17 @@ static int lapic_resume(struct sys_device *dev) | |||
1190 | apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); | 1619 | apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr); |
1191 | apic_write(APIC_ESR, 0); | 1620 | apic_write(APIC_ESR, 0); |
1192 | apic_read(APIC_ESR); | 1621 | apic_read(APIC_ESR); |
1622 | |||
1193 | local_irq_restore(flags); | 1623 | local_irq_restore(flags); |
1624 | |||
1194 | return 0; | 1625 | return 0; |
1195 | } | 1626 | } |
1196 | 1627 | ||
1628 | /* | ||
1629 | * This device has no shutdown method - fully functioning local APICs | ||
1630 | * are needed on every CPU up until machine_halt/restart/poweroff. | ||
1631 | */ | ||
1632 | |||
1197 | static struct sysdev_class lapic_sysclass = { | 1633 | static struct sysdev_class lapic_sysclass = { |
1198 | .name = "lapic", | 1634 | .name = "lapic", |
1199 | .resume = lapic_resume, | 1635 | .resume = lapic_resume, |
@@ -1307,31 +1743,19 @@ __cpuinit int apic_is_clustered_box(void) | |||
1307 | return (clusters > 2); | 1743 | return (clusters > 2); |
1308 | } | 1744 | } |
1309 | 1745 | ||
1310 | /* | 1746 | static __init int setup_nox2apic(char *str) |
1311 | * APIC command line parameters | ||
1312 | */ | ||
1313 | static int __init apic_set_verbosity(char *str) | ||
1314 | { | 1747 | { |
1315 | if (str == NULL) { | 1748 | disable_x2apic = 1; |
1316 | skip_ioapic_setup = 0; | 1749 | clear_cpu_cap(&boot_cpu_data, X86_FEATURE_X2APIC); |
1317 | ioapic_force = 1; | ||
1318 | return 0; | ||
1319 | } | ||
1320 | if (strcmp("debug", str) == 0) | ||
1321 | apic_verbosity = APIC_DEBUG; | ||
1322 | else if (strcmp("verbose", str) == 0) | ||
1323 | apic_verbosity = APIC_VERBOSE; | ||
1324 | else { | ||
1325 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" | ||
1326 | " use apic=verbose or apic=debug\n", str); | ||
1327 | return -EINVAL; | ||
1328 | } | ||
1329 | |||
1330 | return 0; | 1750 | return 0; |
1331 | } | 1751 | } |
1332 | early_param("apic", apic_set_verbosity); | 1752 | early_param("nox2apic", setup_nox2apic); |
1753 | |||
1333 | 1754 | ||
1334 | static __init int setup_disableapic(char *str) | 1755 | /* |
1756 | * APIC command line parameters | ||
1757 | */ | ||
1758 | static int __init setup_disableapic(char *arg) | ||
1335 | { | 1759 | { |
1336 | disable_apic = 1; | 1760 | disable_apic = 1; |
1337 | setup_clear_cpu_cap(X86_FEATURE_APIC); | 1761 | setup_clear_cpu_cap(X86_FEATURE_APIC); |
@@ -1340,9 +1764,9 @@ static __init int setup_disableapic(char *str) | |||
1340 | early_param("disableapic", setup_disableapic); | 1764 | early_param("disableapic", setup_disableapic); |
1341 | 1765 | ||
1342 | /* same as disableapic, for compatibility */ | 1766 | /* same as disableapic, for compatibility */ |
1343 | static __init int setup_nolapic(char *str) | 1767 | static int __init setup_nolapic(char *arg) |
1344 | { | 1768 | { |
1345 | return setup_disableapic(str); | 1769 | return setup_disableapic(arg); |
1346 | } | 1770 | } |
1347 | early_param("nolapic", setup_nolapic); | 1771 | early_param("nolapic", setup_nolapic); |
1348 | 1772 | ||
@@ -1353,14 +1777,19 @@ static int __init parse_lapic_timer_c2_ok(char *arg) | |||
1353 | } | 1777 | } |
1354 | early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); | 1778 | early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); |
1355 | 1779 | ||
1356 | static __init int setup_noapictimer(char *str) | 1780 | static int __init parse_disable_apic_timer(char *arg) |
1357 | { | 1781 | { |
1358 | if (str[0] != ' ' && str[0] != 0) | ||
1359 | return 0; | ||
1360 | disable_apic_timer = 1; | 1782 | disable_apic_timer = 1; |
1361 | return 1; | 1783 | return 0; |
1362 | } | 1784 | } |
1363 | __setup("noapictimer", setup_noapictimer); | 1785 | early_param("noapictimer", parse_disable_apic_timer); |
1786 | |||
1787 | static int __init parse_nolapic_timer(char *arg) | ||
1788 | { | ||
1789 | disable_apic_timer = 1; | ||
1790 | return 0; | ||
1791 | } | ||
1792 | early_param("nolapic_timer", parse_nolapic_timer); | ||
1364 | 1793 | ||
1365 | static __init int setup_apicpmtimer(char *s) | 1794 | static __init int setup_apicpmtimer(char *s) |
1366 | { | 1795 | { |
@@ -1370,6 +1799,31 @@ static __init int setup_apicpmtimer(char *s) | |||
1370 | } | 1799 | } |
1371 | __setup("apicpmtimer", setup_apicpmtimer); | 1800 | __setup("apicpmtimer", setup_apicpmtimer); |
1372 | 1801 | ||
1802 | static int __init apic_set_verbosity(char *arg) | ||
1803 | { | ||
1804 | if (!arg) { | ||
1805 | #ifdef CONFIG_X86_64 | ||
1806 | skip_ioapic_setup = 0; | ||
1807 | ioapic_force = 1; | ||
1808 | return 0; | ||
1809 | #endif | ||
1810 | return -EINVAL; | ||
1811 | } | ||
1812 | |||
1813 | if (strcmp("debug", arg) == 0) | ||
1814 | apic_verbosity = APIC_DEBUG; | ||
1815 | else if (strcmp("verbose", arg) == 0) | ||
1816 | apic_verbosity = APIC_VERBOSE; | ||
1817 | else { | ||
1818 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" | ||
1819 | " use apic=verbose or apic=debug\n", arg); | ||
1820 | return -EINVAL; | ||
1821 | } | ||
1822 | |||
1823 | return 0; | ||
1824 | } | ||
1825 | early_param("apic", apic_set_verbosity); | ||
1826 | |||
1373 | static int __init lapic_insert_resource(void) | 1827 | static int __init lapic_insert_resource(void) |
1374 | { | 1828 | { |
1375 | if (!apic_phys) | 1829 | if (!apic_phys) |