1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/config.h>
16#include <linux/init.h>
17
18#include <linux/mm.h>
19#include <linux/irq.h>
20#include <linux/delay.h>
21#include <linux/bootmem.h>
22#include <linux/smp_lock.h>
23#include <linux/interrupt.h>
24#include <linux/mc146818rtc.h>
25#include <linux/kernel_stat.h>
26
27#include <asm/atomic.h>
28#include <asm/smp.h>
29#include <asm/mtrr.h>
30#include <asm/mpspec.h>
31#include <asm/pgalloc.h>
32#include <asm/smpboot.h>
33
34
35int using_apic_timer = 0;
36
37int prof_multiplier[NR_CPUS] = { 1, };
38int prof_old_multiplier[NR_CPUS] = { 1, };
39int prof_counter[NR_CPUS] = { 1, };
40
41int get_maxlvt(void)
42{
43 unsigned int v, ver, maxlvt;
44
45 v = apic_read(APIC_LVR);
46 ver = GET_APIC_VERSION(v);
47
48 maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(v) : 2;
49 return maxlvt;
50}
51
52void clear_local_APIC(void)
53{
54 int maxlvt;
55 unsigned long v;
56
57 maxlvt = get_maxlvt();
58
59
60
61
62
63 if (maxlvt >= 3) {
64 v = ERROR_APIC_VECTOR;
65 apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
66 }
67
68
69
70
71 v = apic_read(APIC_LVTT);
72 apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
73 v = apic_read(APIC_LVT0);
74 apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
75 v = apic_read(APIC_LVT1);
76 apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED);
77 if (maxlvt >= 4) {
78 v = apic_read(APIC_LVTPC);
79 apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
80 }
81
82
83
84
85 apic_write_around(APIC_LVTT, APIC_LVT_MASKED);
86 apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
87 apic_write_around(APIC_LVT1, APIC_LVT_MASKED);
88 if (maxlvt >= 3)
89 apic_write_around(APIC_LVTERR, APIC_LVT_MASKED);
90 if (maxlvt >= 4)
91 apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
92 v = GET_APIC_VERSION(apic_read(APIC_LVR));
93 if (APIC_INTEGRATED(v)) {
94 if (maxlvt > 3)
95 apic_write(APIC_ESR, 0);
96 apic_read(APIC_ESR);
97 }
98}
99
100void __init connect_bsp_APIC(void)
101{
102 if (pic_mode) {
103
104
105
106 clear_local_APIC();
107
108
109
110
111 printk("leaving PIC mode, enabling APIC mode.\n");
112 outb(0x70, 0x22);
113 outb(0x01, 0x23);
114 }
115}
116
117void disconnect_bsp_APIC(void)
118{
119 if (pic_mode) {
120
121
122
123
124
125
126 printk("disabling APIC mode, entering PIC mode.\n");
127 outb(0x70, 0x22);
128 outb(0x00, 0x23);
129 }
130}
131
132void disable_local_APIC(void)
133{
134 unsigned long value;
135
136 clear_local_APIC();
137
138
139
140
141
142 value = apic_read(APIC_SPIV);
143 value &= ~APIC_SPIV_APIC_ENABLED;
144 apic_write_around(APIC_SPIV, value);
145}
146
147
148
149
150
151
152int __init verify_local_APIC(void)
153{
154 unsigned int reg0, reg1;
155
156
157
158
159 reg0 = apic_read(APIC_LVR);
160 Dprintk("Getting VERSION: %x\n", reg0);
161 apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
162 reg1 = apic_read(APIC_LVR);
163 Dprintk("Getting VERSION: %x\n", reg1);
164
165
166
167
168
169
170 if (reg1 != reg0)
171 return 0;
172
173
174
175
176 reg1 = GET_APIC_VERSION(reg0);
177 if (reg1 == 0x00 || reg1 == 0xff)
178 return 0;
179 reg1 = get_maxlvt();
180 if (reg1 < 0x02 || reg1 == 0xff)
181 return 0;
182
183
184
185
186 reg0 = apic_read(APIC_ID);
187 Dprintk("Getting ID: %x\n", reg0);
188 apic_write(APIC_ID, reg0 ^ APIC_ID_MASK);
189 reg1 = apic_read(APIC_ID);
190 Dprintk("Getting ID: %x\n", reg1);
191 apic_write(APIC_ID, reg0);
192 if (reg1 != (reg0 ^ APIC_ID_MASK))
193 return 0;
194
195
196
197
198
199
200 reg0 = apic_read(APIC_LVT0);
201 Dprintk("Getting LVT0: %x\n", reg0);
202 reg1 = apic_read(APIC_LVT1);
203 Dprintk("Getting LVT1: %x\n", reg1);
204
205 return 1;
206}
207
208void __init sync_Arb_IDs(void)
209{
210
211
212
213 apic_wait_icr_idle();
214
215 Dprintk("Synchronizing Arb IDs.\n");
216 apic_write_around(APIC_ICR, APIC_DEST_ALLINC | APIC_INT_LEVELTRIG
217 | APIC_DM_INIT);
218}
219
220extern void __error_in_apic_c (void);
221
222
223
224
225void __init init_bsp_APIC(void)
226{
227 unsigned long value, ver;
228
229
230
231
232
233 if (smp_found_config || !cpu_has_apic)
234 return;
235
236 value = apic_read(APIC_LVR);
237 ver = GET_APIC_VERSION(value);
238
239
240
241
242 clear_local_APIC();
243
244
245
246
247 value = apic_read(APIC_SPIV);
248 value &= ~APIC_VECTOR_MASK;
249 value |= APIC_SPIV_APIC_ENABLED;
250 value |= APIC_SPIV_FOCUS_DISABLED;
251 value |= SPURIOUS_APIC_VECTOR;
252 apic_write_around(APIC_SPIV, value);
253
254
255
256
257 apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
258 value = APIC_DM_NMI;
259 if (!APIC_INTEGRATED(ver))
260 value |= APIC_LVT_LEVEL_TRIGGER;
261 apic_write_around(APIC_LVT1, value);
262}
263
264static unsigned long calculate_ldr(unsigned long old)
265{
266 unsigned long id;
267 if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
268 id = physical_to_logical_apicid(hard_smp_processor_id());
269 else
270 id = 1UL << smp_processor_id();
271 return (old & ~APIC_LDR_MASK)|SET_APIC_LOGICAL_ID(id);
272}
273
274void __init setup_local_APIC (void)
275{
276 unsigned long value, ver, maxlvt;
277
278
279 if (esr_disable) {
280 apic_write(APIC_ESR, 0);
281 apic_write(APIC_ESR, 0);
282 apic_write(APIC_ESR, 0);
283 apic_write(APIC_ESR, 0);
284 }
285
286 value = apic_read(APIC_LVR);
287 ver = GET_APIC_VERSION(value);
288
289 if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f)
290 __error_in_apic_c();
291
292
293
294
295
296 if (!clustered_apic_mode &&
297 !test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
298 BUG();
299
300
301
302
303
304
305 if (clustered_apic_mode != CLUSTERED_APIC_NUMAQ) {
306
307
308
309
310
311 if(clustered_apic_mode == CLUSTERED_APIC_XAPIC)
312 apic_write_around(APIC_DFR, APIC_DFR_CLUSTER);
313 else
314 apic_write_around(APIC_DFR, APIC_DFR_FLAT);
315
316
317
318
319 value = apic_read(APIC_LDR);
320 apic_write_around(APIC_LDR, calculate_ldr(value));
321 }
322
323
324
325
326
327 value = apic_read(APIC_TASKPRI);
328 value &= ~APIC_TPRI_MASK;
329 apic_write_around(APIC_TASKPRI, value);
330
331
332
333
334 value = apic_read(APIC_SPIV);
335 value &= ~APIC_VECTOR_MASK;
336
337
338
339 value |= APIC_SPIV_APIC_ENABLED;
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360#if 1
361
362 value &= ~APIC_SPIV_FOCUS_DISABLED;
363#else
364
365 value |= APIC_SPIV_FOCUS_DISABLED;
366#endif
367
368
369
370 value |= SPURIOUS_APIC_VECTOR;
371 apic_write_around(APIC_SPIV, value);
372
373
374
375
376
377
378
379
380
381
382
383 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
384 if (!smp_processor_id() && (pic_mode || !value)) {
385 value = APIC_DM_EXTINT;
386 printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
387 } else {
388 value = APIC_DM_EXTINT | APIC_LVT_MASKED;
389 printk("masked ExtINT on CPU#%d\n", smp_processor_id());
390 }
391 apic_write_around(APIC_LVT0, value);
392
393
394
395
396 if (!smp_processor_id())
397 value = APIC_DM_NMI;
398 else
399 value = APIC_DM_NMI | APIC_LVT_MASKED;
400 if (!APIC_INTEGRATED(ver))
401 value |= APIC_LVT_LEVEL_TRIGGER;
402 apic_write_around(APIC_LVT1, value);
403
404 if (APIC_INTEGRATED(ver) && !esr_disable) {
405 maxlvt = get_maxlvt();
406 if (maxlvt > 3)
407 apic_write(APIC_ESR, 0);
408 value = apic_read(APIC_ESR);
409 printk("ESR value before enabling vector: %08lx\n", value);
410
411 value = ERROR_APIC_VECTOR;
412 apic_write_around(APIC_LVTERR, value);
413
414
415
416 if (maxlvt > 3)
417 apic_write(APIC_ESR, 0);
418 value = apic_read(APIC_ESR);
419 printk("ESR value after enabling vector: %08lx\n", value);
420 } else {
421 if (esr_disable)
422
423
424
425
426
427
428 printk("Leaving ESR disabled.\n");
429 else
430 printk("No ESR for 82489DX.\n");
431 }
432
433 if (nmi_watchdog == NMI_LOCAL_APIC)
434 setup_apic_nmi_watchdog();
435}
436
437#ifdef CONFIG_PM
438
439#include <linux/slab.h>
440#include <linux/pm.h>
441
442static struct {
443
444
445
446 int active;
447
448
449 struct pm_dev *perfctr_pmdev;
450
451 unsigned int apic_id;
452 unsigned int apic_taskpri;
453 unsigned int apic_ldr;
454 unsigned int apic_dfr;
455 unsigned int apic_spiv;
456 unsigned int apic_lvtt;
457 unsigned int apic_lvtpc;
458 unsigned int apic_lvt0;
459 unsigned int apic_lvt1;
460 unsigned int apic_lvterr;
461 unsigned int apic_tmict;
462 unsigned int apic_tdcr;
463} apic_pm_state;
464
465static void apic_pm_suspend(void *data)
466{
467 unsigned int l, h;
468 unsigned long flags;
469
470 if (apic_pm_state.perfctr_pmdev)
471 pm_send(apic_pm_state.perfctr_pmdev, PM_SUSPEND, data);
472 apic_pm_state.apic_id = apic_read(APIC_ID);
473 apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
474 apic_pm_state.apic_ldr = apic_read(APIC_LDR);
475 apic_pm_state.apic_dfr = apic_read(APIC_DFR);
476 apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
477 apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
478 apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
479 apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
480 apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
481 apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
482 apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
483 apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
484 __save_flags(flags);
485 __cli();
486 disable_local_APIC();
487 rdmsr(MSR_IA32_APICBASE, l, h);
488 l &= ~MSR_IA32_APICBASE_ENABLE;
489 wrmsr(MSR_IA32_APICBASE, l, h);
490 __restore_flags(flags);
491}
492
493static void apic_pm_resume(void *data)
494{
495 unsigned int l, h;
496 unsigned long flags;
497
498 __save_flags(flags);
499 __cli();
500 rdmsr(MSR_IA32_APICBASE, l, h);
501 l &= ~MSR_IA32_APICBASE_BASE;
502 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
503 wrmsr(MSR_IA32_APICBASE, l, h);
504 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
505 apic_write(APIC_ID, apic_pm_state.apic_id);
506 apic_write(APIC_DFR, apic_pm_state.apic_dfr);
507 apic_write(APIC_LDR, apic_pm_state.apic_ldr);
508 apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri);
509 apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
510 apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
511 apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
512 apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
513 apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
514 apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
515 apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
516 apic_write(APIC_ESR, 0);
517 apic_read(APIC_ESR);
518 apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
519 apic_write(APIC_ESR, 0);
520 apic_read(APIC_ESR);
521 __restore_flags(flags);
522 if (apic_pm_state.perfctr_pmdev)
523 pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data);
524}
525
526static int apic_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
527{
528 switch (rqst) {
529 case PM_SUSPEND:
530 apic_pm_suspend(data);
531 break;
532 case PM_RESUME:
533 apic_pm_resume(data);
534 break;
535 }
536 return 0;
537}
538
539
540struct pm_dev *apic_pm_register(pm_dev_t type,
541 unsigned long id,
542 pm_callback callback)
543{
544 struct pm_dev *dev;
545
546 if (!apic_pm_state.active)
547 return pm_register(type, id, callback);
548 if (apic_pm_state.perfctr_pmdev)
549 return NULL;
550 dev = kmalloc(sizeof(struct pm_dev), GFP_KERNEL);
551 if (dev) {
552 memset(dev, 0, sizeof(*dev));
553 dev->type = type;
554 dev->id = id;
555 dev->callback = callback;
556 apic_pm_state.perfctr_pmdev = dev;
557 }
558 return dev;
559}
560
561
562void apic_pm_unregister(struct pm_dev *dev)
563{
564 if (!apic_pm_state.active) {
565 pm_unregister(dev);
566 } else if (dev == apic_pm_state.perfctr_pmdev) {
567 apic_pm_state.perfctr_pmdev = NULL;
568 kfree(dev);
569 }
570}
571
572static void __init apic_pm_init1(void)
573{
574
575
576 apic_pm_state.active = 1;
577}
578
579static void __init apic_pm_init2(void)
580{
581 if (apic_pm_state.active)
582 pm_register(PM_SYS_DEV, 0, apic_pm_callback);
583}
584
585#else
586
587static inline void apic_pm_init1(void) { }
588static inline void apic_pm_init2(void) { }
589
590#endif
591
592
593
594
595
596int dont_enable_local_apic __initdata = 0;
597
598static int __init detect_init_APIC (void)
599{
600 u32 h, l, features;
601 extern void get_cpu_vendor(struct cpuinfo_x86*);
602
603
604 if (dont_enable_local_apic)
605 return -1;
606
607
608 get_cpu_vendor(&boot_cpu_data);
609
610 switch (boot_cpu_data.x86_vendor) {
611 case X86_VENDOR_AMD:
612 if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1)
613 break;
614 if (boot_cpu_data.x86 == 15 && cpu_has_apic)
615 break;
616 goto no_apic;
617 case X86_VENDOR_INTEL:
618 if (boot_cpu_data.x86 == 6 ||
619 (boot_cpu_data.x86 == 15 && cpu_has_apic) ||
620 (boot_cpu_data.x86 == 5 && cpu_has_apic))
621 break;
622 goto no_apic;
623 default:
624 goto no_apic;
625 }
626
627 if (!cpu_has_apic) {
628
629
630
631
632
633 rdmsr(MSR_IA32_APICBASE, l, h);
634 if (!(l & MSR_IA32_APICBASE_ENABLE)) {
635 printk("Local APIC disabled by BIOS -- reenabling.\n");
636 l &= ~MSR_IA32_APICBASE_BASE;
637 l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
638 wrmsr(MSR_IA32_APICBASE, l, h);
639 }
640 }
641
642
643
644
645 features = cpuid_edx(1);
646 if (!(features & (1 << X86_FEATURE_APIC))) {
647 printk("Could not enable APIC!\n");
648 return -1;
649 }
650 set_bit(X86_FEATURE_APIC, &boot_cpu_data.x86_capability);
651 mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
652 if (nmi_watchdog != NMI_NONE)
653 nmi_watchdog = NMI_LOCAL_APIC;
654
655 printk("Found and enabled local APIC!\n");
656
657 apic_pm_init1();
658
659 return 0;
660
661no_apic:
662 printk("No local APIC present or hardware disabled\n");
663 return -1;
664}
665
666void __init init_apic_mappings(void)
667{
668 unsigned long apic_phys;
669
670
671
672
673
674
675 if (!smp_found_config && detect_init_APIC()) {
676 apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
677 apic_phys = __pa(apic_phys);
678 } else
679 apic_phys = mp_lapic_addr;
680
681 set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
682 Dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
683
684
685
686
687
688 if (boot_cpu_physical_apicid == -1U)
689 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
690
691#ifdef CONFIG_X86_IO_APIC
692 {
693 unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
694 int i;
695
696 for (i = 0; i < nr_ioapics; i++) {
697 if (smp_found_config) {
698 ioapic_phys = mp_ioapics[i].mpc_apicaddr;
699 if (!ioapic_phys) {
700 printk(KERN_ERR "WARNING: bogus zero IO-APIC address found in MPTABLE, disabling IO/APIC support!\n");
701
702 smp_found_config = 0;
703 skip_ioapic_setup = 1;
704 goto fake_ioapic_page;
705 }
706 } else {
707fake_ioapic_page:
708 ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
709 ioapic_phys = __pa(ioapic_phys);
710 }
711 set_fixmap_nocache(idx, ioapic_phys);
712 Dprintk("mapped IOAPIC to %08lx (%08lx)\n",
713 __fix_to_virt(idx), ioapic_phys);
714 idx++;
715 }
716 }
717#endif
718}
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734static unsigned int __init get_8254_timer_count(void)
735{
736 extern spinlock_t i8253_lock;
737 unsigned long flags;
738
739 unsigned int count;
740
741 spin_lock_irqsave(&i8253_lock, flags);
742
743 outb_p(0x00, 0x43);
744 count = inb_p(0x40);
745 count |= inb_p(0x40) << 8;
746
747 spin_unlock_irqrestore(&i8253_lock, flags);
748
749 return count;
750}
751
752void __init wait_8254_wraparound(void)
753{
754 unsigned int curr_count, prev_count=~0;
755 int delta;
756
757 curr_count = get_8254_timer_count();
758
759 do {
760 prev_count = curr_count;
761 curr_count = get_8254_timer_count();
762 delta = curr_count-prev_count;
763
764
765
766
767
768
769
770 } while (delta < 300);
771}
772
773
774
775
776
777
778
779
780
781
782
783
784#define APIC_DIVISOR 16
785
786void __setup_APIC_LVTT(unsigned int clocks)
787{
788 unsigned int lvtt1_value, tmp_value;
789
790 lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
791 APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
792 apic_write_around(APIC_LVTT, lvtt1_value);
793
794
795
796
797 tmp_value = apic_read(APIC_TDCR);
798 apic_write_around(APIC_TDCR, (tmp_value
799 & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
800 | APIC_TDR_DIV_16);
801
802 apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
803}
804
805void setup_APIC_timer(void * data)
806{
807 unsigned int clocks = (unsigned int) data, slice, t0, t1;
808 unsigned long flags;
809 int delta;
810
811 __save_flags(flags);
812 __sti();
813
814
815
816
817
818
819
820
821
822
823 slice = clocks / (smp_num_cpus+1);
824 printk("cpu: %d, clocks: %d, slice: %d\n", smp_processor_id(), clocks, slice);
825
826
827
828
829 wait_8254_wraparound();
830
831 __setup_APIC_LVTT(clocks);
832
833 t0 = apic_read(APIC_TMICT)*APIC_DIVISOR;
834
835 do {
836 t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
837 delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
838 } while (delta >= 0);
839
840 do {
841 t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
842 delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
843 } while (delta < 0);
844
845 __setup_APIC_LVTT(clocks);
846
847 printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n", smp_processor_id(), t0, t1, delta, slice, clocks);
848
849 __restore_flags(flags);
850}
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865int __init calibrate_APIC_clock(void)
866{
867 unsigned long long t1 = 0, t2 = 0;
868 long tt1, tt2;
869 long result;
870 int i;
871 const int LOOPS = HZ/10;
872
873 printk("calibrating APIC timer ...\n");
874
875
876
877
878
879
880 __setup_APIC_LVTT(1000000000);
881
882
883
884
885
886
887
888 wait_8254_wraparound();
889
890
891
892
893 if (cpu_has_tsc)
894 rdtscll(t1);
895 tt1 = apic_read(APIC_TMCCT);
896
897
898
899
900 for (i = 0; i < LOOPS; i++)
901 wait_8254_wraparound();
902
903 tt2 = apic_read(APIC_TMCCT);
904 if (cpu_has_tsc)
905 rdtscll(t2);
906
907
908
909
910
911
912
913
914
915 result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
916
917 if (cpu_has_tsc)
918 printk("..... CPU clock speed is %ld.%04ld MHz.\n",
919 ((long)(t2-t1)/LOOPS)/(1000000/HZ),
920 ((long)(t2-t1)/LOOPS)%(1000000/HZ));
921
922 printk("..... host bus clock speed is %ld.%04ld MHz.\n",
923 result/(1000000/HZ),
924 result%(1000000/HZ));
925
926 return result;
927}
928
929static unsigned int calibration_result;
930
931int dont_use_local_apic_timer __initdata = 0;
932
933void __init setup_APIC_clocks (void)
934{
935
936 if (dont_use_local_apic_timer)
937 return;
938
939 printk("Using local APIC timer interrupts.\n");
940 using_apic_timer = 1;
941
942 __cli();
943
944 calibration_result = calibrate_APIC_clock();
945
946
947
948 setup_APIC_timer((void *)calibration_result);
949
950 __sti();
951
952
953 smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
954}
955
956void __init disable_APIC_timer(void)
957{
958 if (using_apic_timer) {
959 unsigned long v;
960
961 v = apic_read(APIC_LVTT);
962 apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
963 }
964}
965
966void enable_APIC_timer(void)
967{
968 if (using_apic_timer) {
969 unsigned long v;
970
971 v = apic_read(APIC_LVTT);
972 apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
973 }
974}
975
976
977
978
979
980int setup_profiling_timer(unsigned int multiplier)
981{
982 int i;
983
984
985
986
987
988
989 if ( (!multiplier) || (calibration_result/multiplier < 500))
990 return -EINVAL;
991
992
993
994
995
996
997
998 for (i = 0; i < NR_CPUS; ++i)
999 prof_multiplier[i] = multiplier;
1000
1001 return 0;
1002}
1003
1004#undef APIC_DIVISOR
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016inline void smp_local_timer_interrupt(struct pt_regs * regs)
1017{
1018 int user = user_mode(regs);
1019 int cpu = smp_processor_id();
1020
1021
1022
1023
1024
1025
1026
1027 if (!user)
1028 x86_do_profile(regs->eip);
1029
1030 if (--prof_counter[cpu] <= 0) {
1031
1032
1033
1034
1035
1036
1037
1038
1039 prof_counter[cpu] = prof_multiplier[cpu];
1040 if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
1041 __setup_APIC_LVTT(calibration_result/prof_counter[cpu]);
1042 prof_old_multiplier[cpu] = prof_counter[cpu];
1043 }
1044
1045#ifdef CONFIG_SMP
1046 update_process_times(user);
1047#endif
1048 }
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060}
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070unsigned int apic_timer_irqs [NR_CPUS];
1071
1072void smp_apic_timer_interrupt(struct pt_regs * regs)
1073{
1074 int cpu = smp_processor_id();
1075
1076
1077
1078
1079 apic_timer_irqs[cpu]++;
1080
1081
1082
1083
1084
1085 ack_APIC_irq();
1086
1087
1088
1089
1090
1091 irq_enter(cpu, 0);
1092 smp_local_timer_interrupt(regs);
1093 irq_exit(cpu, 0);
1094
1095 if (softirq_pending(cpu))
1096 do_softirq();
1097}
1098
1099
1100
1101
1102asmlinkage void smp_spurious_interrupt(void)
1103{
1104 unsigned long v;
1105
1106
1107
1108
1109
1110
1111 v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
1112 if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
1113 ack_APIC_irq();
1114
1115
1116 printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n",
1117 smp_processor_id());
1118}
1119
1120
1121
1122
1123
1124asmlinkage void smp_error_interrupt(void)
1125{
1126 unsigned long v, v1;
1127
1128
1129 v = apic_read(APIC_ESR);
1130 apic_write(APIC_ESR, 0);
1131 v1 = apic_read(APIC_ESR);
1132 ack_APIC_irq();
1133 atomic_inc(&irq_err_count);
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 printk (KERN_ERR "APIC error on CPU%d: %02lx(%02lx)\n",
1146 smp_processor_id(), v , v1);
1147}
1148
1149
1150
1151
1152
1153int __init APIC_init_uniprocessor (void)
1154{
1155 if (!smp_found_config && !cpu_has_apic)
1156 return -1;
1157
1158
1159
1160
1161 if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
1162 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
1163 boot_cpu_physical_apicid);
1164 return -1;
1165 }
1166
1167 verify_local_APIC();
1168
1169 connect_bsp_APIC();
1170
1171 phys_cpu_present_map = 1 << boot_cpu_physical_apicid;
1172
1173 apic_pm_init2();
1174
1175 setup_local_APIC();
1176
1177 if (nmi_watchdog == NMI_LOCAL_APIC)
1178 check_nmi_watchdog();
1179#ifdef CONFIG_X86_IO_APIC
1180 if (smp_found_config)
1181 if (!skip_ioapic_setup && nr_ioapics)
1182 setup_IO_APIC();
1183#endif
1184 setup_APIC_clocks();
1185
1186 return 0;
1187}
1188