1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/mm.h>
23#include <linux/irq.h>
24#include <linux/interrupt.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/sched.h>
28#include <linux/config.h>
29#include <linux/smp_lock.h>
30#include <linux/mc146818rtc.h>
31
32#include <asm/io.h>
33#include <asm/smp.h>
34#include <asm/desc.h>
35#include <asm/smpboot.h>
36
37#undef APIC_LOCKUP_DEBUG
38
39#define APIC_LOCKUP_DEBUG
40
41static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
42
43unsigned int int_dest_addr_mode = APIC_DEST_LOGICAL;
44unsigned char int_delivery_mode = dest_LowestPrio;
45
46
47
48
49
50int nr_ioapic_registers[MAX_IO_APICS];
51
52
53
54
55
56#define MAX_PLUS_SHARED_IRQS NR_IRQS
57#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
58
59
60
61
62
63
64
65
66static struct irq_pin_list {
67 int apic, pin, next;
68} irq_2_pin[PIN_MAP_SIZE];
69
70
71
72
73
74
75static void __init add_pin_to_irq(unsigned int irq, int apic, int pin)
76{
77 static int first_free_entry = NR_IRQS;
78 struct irq_pin_list *entry = irq_2_pin + irq;
79
80 while (entry->next)
81 entry = irq_2_pin + entry->next;
82
83 if (entry->pin != -1) {
84 entry->next = first_free_entry;
85 entry = irq_2_pin + entry->next;
86 if (++first_free_entry >= PIN_MAP_SIZE)
87 panic("io_apic.c: whoops");
88 }
89 entry->apic = apic;
90 entry->pin = pin;
91}
92
93
94
95
96static void __init replace_pin_at_irq(unsigned int irq,
97 int oldapic, int oldpin,
98 int newapic, int newpin)
99{
100 struct irq_pin_list *entry = irq_2_pin + irq;
101
102 while (1) {
103 if (entry->apic == oldapic && entry->pin == oldpin) {
104 entry->apic = newapic;
105 entry->pin = newpin;
106 }
107 if (!entry->next)
108 break;
109 entry = irq_2_pin + entry->next;
110 }
111}
112
113#define __DO_ACTION(R, ACTION, FINAL) \
114 \
115{ \
116 int pin; \
117 struct irq_pin_list *entry = irq_2_pin + irq; \
118 \
119 for (;;) { \
120 unsigned int reg; \
121 pin = entry->pin; \
122 if (pin == -1) \
123 break; \
124 reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \
125 reg ACTION; \
126 io_apic_modify(entry->apic, reg); \
127 if (!entry->next) \
128 break; \
129 entry = irq_2_pin + entry->next; \
130 } \
131 FINAL; \
132}
133
134#define DO_ACTION(name,R,ACTION, FINAL) \
135 \
136 static void name##_IO_APIC_irq (unsigned int irq) \
137 __DO_ACTION(R, ACTION, FINAL)
138
139DO_ACTION( __mask, 0, |= 0x00010000, io_apic_sync(entry->apic) )
140
141DO_ACTION( __unmask, 0, &= 0xfffeffff, )
142
143DO_ACTION( __mask_and_edge, 0, = (reg & 0xffff7fff) | 0x00010000, )
144
145DO_ACTION( __unmask_and_level, 0, = (reg & 0xfffeffff) | 0x00008000, )
146
147
148static void mask_IO_APIC_irq (unsigned int irq)
149{
150 unsigned long flags;
151
152 spin_lock_irqsave(&ioapic_lock, flags);
153 __mask_IO_APIC_irq(irq);
154 spin_unlock_irqrestore(&ioapic_lock, flags);
155}
156
157static void unmask_IO_APIC_irq (unsigned int irq)
158{
159 unsigned long flags;
160
161 spin_lock_irqsave(&ioapic_lock, flags);
162 __unmask_IO_APIC_irq(irq);
163 spin_unlock_irqrestore(&ioapic_lock, flags);
164}
165
166void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
167{
168 struct IO_APIC_route_entry entry;
169 unsigned long flags;
170
171
172
173
174 memset(&entry, 0, sizeof(entry));
175 entry.mask = 1;
176 spin_lock_irqsave(&ioapic_lock, flags);
177 io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
178 io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
179 spin_unlock_irqrestore(&ioapic_lock, flags);
180}
181
182static void clear_IO_APIC (void)
183{
184 int apic, pin;
185
186 for (apic = 0; apic < nr_ioapics; apic++)
187 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
188 clear_IO_APIC_pin(apic, pin);
189}
190
191
192
193
194
195
196#define MAX_PIRQS 8
197int pirq_entries [MAX_PIRQS];
198int pirqs_enabled;
199int skip_ioapic_setup;
200
201static int __init noioapic_setup(char *str)
202{
203 skip_ioapic_setup = 1;
204 return 1;
205}
206
207__setup("noapic", noioapic_setup);
208
209static int __init ioapic_setup(char *str)
210{
211 skip_ioapic_setup = 0;
212 return 1;
213}
214
215__setup("apic", ioapic_setup);
216
217static int __init ioapic_pirq_setup(char *str)
218{
219 int i, max;
220 int ints[MAX_PIRQS+1];
221
222 get_options(str, ARRAY_SIZE(ints), ints);
223
224 for (i = 0; i < MAX_PIRQS; i++)
225 pirq_entries[i] = -1;
226
227 pirqs_enabled = 1;
228 printk(KERN_INFO "PIRQ redirection, working around broken MP-BIOS.\n");
229 max = MAX_PIRQS;
230 if (ints[0] < MAX_PIRQS)
231 max = ints[0];
232
233 for (i = 0; i < max; i++) {
234 printk(KERN_DEBUG "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
235
236
237
238 pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
239 }
240 return 1;
241}
242
243__setup("pirq=", ioapic_pirq_setup);
244
245
246
247
248static int __init find_irq_entry(int apic, int pin, int type)
249{
250 int i;
251
252 for (i = 0; i < mp_irq_entries; i++)
253 if (mp_irqs[i].mpc_irqtype == type &&
254 (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid ||
255 mp_irqs[i].mpc_dstapic == MP_APIC_ALL) &&
256 mp_irqs[i].mpc_dstirq == pin)
257 return i;
258
259 return -1;
260}
261
262
263
264
265static int __init find_isa_irq_pin(int irq, int type)
266{
267 int i;
268
269 for (i = 0; i < mp_irq_entries; i++) {
270 int lbus = mp_irqs[i].mpc_srcbus;
271
272 if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA ||
273 mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
274 mp_bus_id_to_type[lbus] == MP_BUS_MCA) &&
275 (mp_irqs[i].mpc_irqtype == type) &&
276 (mp_irqs[i].mpc_srcbusirq == irq))
277
278 return mp_irqs[i].mpc_dstirq;
279 }
280 return -1;
281}
282
283
284
285
286
287static int pin_2_irq(int idx, int apic, int pin);
288
289int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
290{
291 int apic, i, best_guess = -1;
292
293 Dprintk("querying PCI -> IRQ mapping bus:%d, slot:%d, pin:%d.\n",
294 bus, slot, pin);
295 if ((mp_bus_id_to_pci_bus==NULL) || (mp_bus_id_to_pci_bus[bus] == -1)) {
296 printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
297 return -1;
298 }
299 for (i = 0; i < mp_irq_entries; i++) {
300 int lbus = mp_irqs[i].mpc_srcbus;
301
302 for (apic = 0; apic < nr_ioapics; apic++)
303 if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic ||
304 mp_irqs[i].mpc_dstapic == MP_APIC_ALL)
305 break;
306
307 if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
308 !mp_irqs[i].mpc_irqtype &&
309 (bus == lbus) &&
310 (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
311 int irq = pin_2_irq(i,apic,mp_irqs[i].mpc_dstirq);
312
313 if (!(apic || IO_APIC_IRQ(irq)))
314 continue;
315
316 if (pin == (mp_irqs[i].mpc_srcbusirq & 3))
317 return irq;
318
319
320
321
322 if (best_guess < 0)
323 best_guess = irq;
324 }
325 }
326 return best_guess;
327}
328
329
330
331
332static int __init EISA_ELCR(unsigned int irq)
333{
334 if (irq < 16) {
335 unsigned int port = 0x4d0 + (irq >> 3);
336 return (inb(port) >> (irq & 7)) & 1;
337 }
338 printk(KERN_INFO "Broken MPtable reports ISA irq %d\n", irq);
339 return 0;
340}
341
342
343
344
345
346
347#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq))
348#define default_EISA_polarity(idx) (0)
349
350
351
352
353#define default_ISA_trigger(idx) (0)
354#define default_ISA_polarity(idx) (0)
355
356
357
358
359#define default_PCI_trigger(idx) (1)
360#define default_PCI_polarity(idx) (1)
361
362
363
364
365#define default_MCA_trigger(idx) (1)
366#define default_MCA_polarity(idx) (0)
367
368static int __init MPBIOS_polarity(int idx)
369{
370 int bus = mp_irqs[idx].mpc_srcbus;
371 int polarity;
372
373
374
375
376 switch (mp_irqs[idx].mpc_irqflag & 3)
377 {
378 case 0:
379 {
380 switch (mp_bus_id_to_type[bus])
381 {
382 case MP_BUS_ISA:
383 {
384 polarity = default_ISA_polarity(idx);
385 break;
386 }
387 case MP_BUS_EISA:
388 {
389 polarity = default_EISA_polarity(idx);
390 break;
391 }
392 case MP_BUS_PCI:
393 {
394 polarity = default_PCI_polarity(idx);
395 break;
396 }
397 case MP_BUS_MCA:
398 {
399 polarity = default_MCA_polarity(idx);
400 break;
401 }
402 default:
403 {
404 printk(KERN_WARNING "broken BIOS!!\n");
405 polarity = 1;
406 break;
407 }
408 }
409 break;
410 }
411 case 1:
412 {
413 polarity = 0;
414 break;
415 }
416 case 2:
417 {
418 printk(KERN_WARNING "broken BIOS!!\n");
419 polarity = 1;
420 break;
421 }
422 case 3:
423 {
424 polarity = 1;
425 break;
426 }
427 default:
428 {
429 printk(KERN_WARNING "broken BIOS!!\n");
430 polarity = 1;
431 break;
432 }
433 }
434 return polarity;
435}
436
437static int __init MPBIOS_trigger(int idx)
438{
439 int bus = mp_irqs[idx].mpc_srcbus;
440 int trigger;
441
442
443
444
445 switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
446 {
447 case 0:
448 {
449 switch (mp_bus_id_to_type[bus])
450 {
451 case MP_BUS_ISA:
452 {
453 trigger = default_ISA_trigger(idx);
454 break;
455 }
456 case MP_BUS_EISA:
457 {
458 trigger = default_EISA_trigger(idx);
459 break;
460 }
461 case MP_BUS_PCI:
462 {
463 trigger = default_PCI_trigger(idx);
464 break;
465 }
466 case MP_BUS_MCA:
467 {
468 trigger = default_MCA_trigger(idx);
469 break;
470 }
471 default:
472 {
473 printk(KERN_WARNING "broken BIOS!!\n");
474 trigger = 1;
475 break;
476 }
477 }
478 break;
479 }
480 case 1:
481 {
482 trigger = 0;
483 break;
484 }
485 case 2:
486 {
487 printk(KERN_WARNING "broken BIOS!!\n");
488 trigger = 1;
489 break;
490 }
491 case 3:
492 {
493 trigger = 1;
494 break;
495 }
496 default:
497 {
498 printk(KERN_WARNING "broken BIOS!!\n");
499 trigger = 0;
500 break;
501 }
502 }
503 return trigger;
504}
505
506static inline int irq_polarity(int idx)
507{
508 return MPBIOS_polarity(idx);
509}
510
511static inline int irq_trigger(int idx)
512{
513 return MPBIOS_trigger(idx);
514}
515
516static int pin_2_irq(int idx, int apic, int pin)
517{
518 int irq, i;
519 int bus = mp_irqs[idx].mpc_srcbus;
520
521
522
523
524 if (mp_irqs[idx].mpc_dstirq != pin)
525 printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
526
527 switch (mp_bus_id_to_type[bus])
528 {
529 case MP_BUS_ISA:
530 case MP_BUS_EISA:
531 case MP_BUS_MCA:
532 {
533 irq = mp_irqs[idx].mpc_srcbusirq;
534 break;
535 }
536 case MP_BUS_PCI:
537 {
538
539
540
541 i = irq = 0;
542 while (i < apic)
543 irq += nr_ioapic_registers[i++];
544 irq += pin;
545 break;
546 }
547 default:
548 {
549 printk(KERN_ERR "unknown bus type %d.\n",bus);
550 irq = 0;
551 break;
552 }
553 }
554
555
556
557
558 if ((pin >= 16) && (pin <= 23)) {
559 if (pirq_entries[pin-16] != -1) {
560 if (!pirq_entries[pin-16]) {
561 printk(KERN_DEBUG "disabling PIRQ%d\n", pin-16);
562 } else {
563 irq = pirq_entries[pin-16];
564 printk(KERN_DEBUG "using PIRQ%d -> IRQ %d\n",
565 pin-16, irq);
566 }
567 }
568 }
569 return irq;
570}
571
572static inline int IO_APIC_irq_trigger(int irq)
573{
574 int apic, idx, pin;
575
576 for (apic = 0; apic < nr_ioapics; apic++) {
577 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
578 idx = find_irq_entry(apic,pin,mp_INT);
579 if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin)))
580 return irq_trigger(idx);
581 }
582 }
583
584
585
586 return 0;
587}
588
589int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 };
590
591static int __init assign_irq_vector(int irq)
592{
593 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
594 if (IO_APIC_VECTOR(irq) > 0)
595 return IO_APIC_VECTOR(irq);
596next:
597 current_vector += 8;
598 if (current_vector == SYSCALL_VECTOR)
599 goto next;
600
601 if (current_vector > FIRST_SYSTEM_VECTOR) {
602 offset++;
603 current_vector = FIRST_DEVICE_VECTOR + offset;
604 }
605
606 if (current_vector == FIRST_SYSTEM_VECTOR)
607 panic("ran out of interrupt sources!");
608
609 IO_APIC_VECTOR(irq) = current_vector;
610 return current_vector;
611}
612
613extern void (*interrupt[NR_IRQS])(void);
614static struct hw_interrupt_type ioapic_level_irq_type;
615static struct hw_interrupt_type ioapic_edge_irq_type;
616
617void __init setup_IO_APIC_irqs(void)
618{
619 struct IO_APIC_route_entry entry;
620 int apic, pin, idx, irq, first_notcon = 1, vector;
621 unsigned long flags;
622
623 printk(KERN_DEBUG "init IO_APIC IRQs\n");
624
625 for (apic = 0; apic < nr_ioapics; apic++) {
626 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
627
628
629
630
631 memset(&entry,0,sizeof(entry));
632
633 entry.delivery_mode = INT_DELIVERY_MODE;
634 entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
635 entry.mask = 0;
636 entry.dest.logical.logical_dest = target_cpus();
637
638 idx = find_irq_entry(apic,pin,mp_INT);
639 if (idx == -1) {
640 if (first_notcon) {
641 printk(KERN_DEBUG " IO-APIC (apicid-pin) %d-%d", mp_ioapics[apic].mpc_apicid, pin);
642 first_notcon = 0;
643 } else
644 printk(", %d-%d", mp_ioapics[apic].mpc_apicid, pin);
645 continue;
646 }
647
648 entry.trigger = irq_trigger(idx);
649 entry.polarity = irq_polarity(idx);
650
651 if (irq_trigger(idx)) {
652 entry.trigger = 1;
653 entry.mask = 1;
654 }
655
656 irq = pin_2_irq(idx, apic, pin);
657
658
659
660
661 if ((clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
662 && (apic != 0) && (irq == 0))
663 continue;
664 else
665 add_pin_to_irq(irq, apic, pin);
666
667 if (!apic && !IO_APIC_IRQ(irq))
668 continue;
669
670 if (IO_APIC_IRQ(irq)) {
671 vector = assign_irq_vector(irq);
672 entry.vector = vector;
673
674 if (IO_APIC_irq_trigger(irq))
675 irq_desc[irq].handler = &ioapic_level_irq_type;
676 else
677 irq_desc[irq].handler = &ioapic_edge_irq_type;
678
679 set_intr_gate(vector, interrupt[irq]);
680
681 if (!apic && (irq < 16))
682 disable_8259A_irq(irq);
683 }
684 spin_lock_irqsave(&ioapic_lock, flags);
685 io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
686 io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
687 spin_unlock_irqrestore(&ioapic_lock, flags);
688 }
689 }
690
691 if (!first_notcon)
692 printk(" not connected.\n");
693}
694
695
696
697
698
699void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
700{
701 struct IO_APIC_route_entry entry;
702 unsigned long flags;
703
704 memset(&entry,0,sizeof(entry));
705
706 disable_8259A_irq(0);
707
708
709 apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
710
711
712
713
714
715 entry.dest_mode = (INT_DEST_ADDR_MODE != 0);
716 entry.mask = 0;
717 entry.dest.logical.logical_dest = target_cpus();
718 entry.delivery_mode = INT_DELIVERY_MODE;
719 entry.polarity = 0;
720 entry.trigger = 0;
721 entry.vector = vector;
722
723
724
725
726
727 irq_desc[0].handler = &ioapic_edge_irq_type;
728
729
730
731
732 spin_lock_irqsave(&ioapic_lock, flags);
733 io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
734 io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
735 spin_unlock_irqrestore(&ioapic_lock, flags);
736
737 enable_8259A_irq(0);
738}
739
740void __init UNEXPECTED_IO_APIC(void)
741{
742 printk(KERN_WARNING
743 "An unexpected IO-APIC was found. If this kernel release is less than\n"
744 "three months old please report this to linux-smp@vger.kernel.org\n");
745}
746
747void __init print_IO_APIC(void)
748{
749 int apic, i;
750 struct IO_APIC_reg_00 reg_00;
751 struct IO_APIC_reg_01 reg_01;
752 struct IO_APIC_reg_02 reg_02;
753 unsigned long flags;
754
755 printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
756 for (i = 0; i < nr_ioapics; i++)
757 printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
758 mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]);
759
760
761
762
763
764 printk(KERN_INFO "testing the IO APIC.......................\n");
765
766 for (apic = 0; apic < nr_ioapics; apic++) {
767
768 spin_lock_irqsave(&ioapic_lock, flags);
769 *(int *)®_00 = io_apic_read(apic, 0);
770 *(int *)®_01 = io_apic_read(apic, 1);
771 if (reg_01.version >= 0x10)
772 *(int *)®_02 = io_apic_read(apic, 2);
773 spin_unlock_irqrestore(&ioapic_lock, flags);
774
775 printk("\n");
776 printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
777 printk(KERN_DEBUG ".... register #00: %08X\n", *(int *)®_00);
778 printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.ID);
779 printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.delivery_type);
780 printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.LTS);
781 if (reg_00.__reserved_0 || reg_00.__reserved_1 || reg_00.__reserved_2)
782 UNEXPECTED_IO_APIC();
783
784 printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)®_01);
785 printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.entries);
786 if ( (reg_01.entries != 0x0f) &&
787 (reg_01.entries != 0x17) &&
788 (reg_01.entries != 0x1b) &&
789 (reg_01.entries != 0x1f) &&
790 (reg_01.entries != 0x22) &&
791 (reg_01.entries != 0x2E) &&
792 (reg_01.entries != 0x3F)
793 )
794 UNEXPECTED_IO_APIC();
795
796 printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.PRQ);
797 printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.version);
798 if ( (reg_01.version != 0x01) &&
799 (reg_01.version != 0x02) &&
800 (reg_01.version != 0x03) &&
801 (reg_01.version != 0x10) &&
802 (reg_01.version != 0x11) &&
803 (reg_01.version != 0x13) &&
804 (reg_01.version != 0x20)
805 )
806 UNEXPECTED_IO_APIC();
807 if (reg_01.__reserved_1 || reg_01.__reserved_2)
808 UNEXPECTED_IO_APIC();
809
810 if (reg_01.version >= 0x10) {
811 printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)®_02);
812 printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.arbitration);
813 if (reg_02.__reserved_1 || reg_02.__reserved_2)
814 UNEXPECTED_IO_APIC();
815 }
816
817 printk(KERN_DEBUG ".... IRQ redirection table:\n");
818
819 printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
820 " Stat Dest Deli Vect: \n");
821
822 for (i = 0; i <= reg_01.entries; i++) {
823 struct IO_APIC_route_entry entry;
824
825 spin_lock_irqsave(&ioapic_lock, flags);
826 *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2);
827 *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2);
828 spin_unlock_irqrestore(&ioapic_lock, flags);
829
830 printk(KERN_DEBUG " %02x %03X %02X ",
831 i,
832 entry.dest.logical.logical_dest,
833 entry.dest.physical.physical_dest
834 );
835
836 printk("%1d %1d %1d %1d %1d %1d %1d %02X\n",
837 entry.mask,
838 entry.trigger,
839 entry.irr,
840 entry.polarity,
841 entry.delivery_status,
842 entry.dest_mode,
843 entry.delivery_mode,
844 entry.vector
845 );
846 }
847 }
848 printk(KERN_DEBUG "IRQ to pin mappings:\n");
849 for (i = 0; i < NR_IRQS; i++) {
850 struct irq_pin_list *entry = irq_2_pin + i;
851 if (entry->pin < 0)
852 continue;
853 printk(KERN_DEBUG "IRQ%d ", i);
854 for (;;) {
855 printk("-> %d:%d", entry->apic, entry->pin);
856 if (!entry->next)
857 break;
858 entry = irq_2_pin + entry->next;
859 }
860 printk("\n");
861 }
862
863 printk(KERN_INFO ".................................... done.\n");
864
865 return;
866}
867
868static void print_APIC_bitfield (int base)
869{
870 unsigned int v;
871 int i, j;
872
873 printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
874 for (i = 0; i < 8; i++) {
875 v = apic_read(base + i*0x10);
876 for (j = 0; j < 32; j++) {
877 if (v & (1<<j))
878 printk("1");
879 else
880 printk("0");
881 }
882 printk("\n");
883 }
884}
885
886void print_local_APIC(void * dummy)
887{
888 unsigned int v, ver, maxlvt;
889
890 printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
891 smp_processor_id(), hard_smp_processor_id());
892 v = apic_read(APIC_ID);
893 printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v, GET_APIC_ID(v));
894 v = apic_read(APIC_LVR);
895 printk(KERN_INFO "... APIC VERSION: %08x\n", v);
896 ver = GET_APIC_VERSION(v);
897 maxlvt = get_maxlvt();
898
899 v = apic_read(APIC_TASKPRI);
900 printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
901
902 if (APIC_INTEGRATED(ver)) {
903 v = apic_read(APIC_ARBPRI);
904 printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
905 v & APIC_ARBPRI_MASK);
906 v = apic_read(APIC_PROCPRI);
907 printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
908 }
909
910 v = apic_read(APIC_EOI);
911 printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
912 v = apic_read(APIC_RRR);
913 printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
914 v = apic_read(APIC_LDR);
915 printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
916 v = apic_read(APIC_DFR);
917 printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
918 v = apic_read(APIC_SPIV);
919 printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
920
921 printk(KERN_DEBUG "... APIC ISR field:\n");
922 print_APIC_bitfield(APIC_ISR);
923 printk(KERN_DEBUG "... APIC TMR field:\n");
924 print_APIC_bitfield(APIC_TMR);
925 printk(KERN_DEBUG "... APIC IRR field:\n");
926 print_APIC_bitfield(APIC_IRR);
927
928 if (APIC_INTEGRATED(ver)) {
929 if (maxlvt > 3)
930 apic_write(APIC_ESR, 0);
931 v = apic_read(APIC_ESR);
932 printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
933 }
934
935 v = apic_read(APIC_ICR);
936 printk(KERN_DEBUG "... APIC ICR: %08x\n", v);
937 v = apic_read(APIC_ICR2);
938 printk(KERN_DEBUG "... APIC ICR2: %08x\n", v);
939
940 v = apic_read(APIC_LVTT);
941 printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
942
943 if (maxlvt > 3) {
944 v = apic_read(APIC_LVTPC);
945 printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v);
946 }
947 v = apic_read(APIC_LVT0);
948 printk(KERN_DEBUG "... APIC LVT0: %08x\n", v);
949 v = apic_read(APIC_LVT1);
950 printk(KERN_DEBUG "... APIC LVT1: %08x\n", v);
951
952 if (maxlvt > 2) {
953 v = apic_read(APIC_LVTERR);
954 printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v);
955 }
956
957 v = apic_read(APIC_TMICT);
958 printk(KERN_DEBUG "... APIC TMICT: %08x\n", v);
959 v = apic_read(APIC_TMCCT);
960 printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
961 v = apic_read(APIC_TDCR);
962 printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
963 printk("\n");
964}
965
966void print_all_local_APICs (void)
967{
968 smp_call_function(print_local_APIC, NULL, 1, 1);
969 print_local_APIC(NULL);
970}
971
972void print_PIC(void)
973{
974 extern spinlock_t i8259A_lock;
975 unsigned int v, flags;
976
977 printk(KERN_DEBUG "\nprinting PIC contents\n");
978
979 spin_lock_irqsave(&i8259A_lock, flags);
980
981 v = inb(0xa1) << 8 | inb(0x21);
982 printk(KERN_DEBUG "... PIC IMR: %04x\n", v);
983
984 v = inb(0xa0) << 8 | inb(0x20);
985 printk(KERN_DEBUG "... PIC IRR: %04x\n", v);
986
987 outb(0x0b,0xa0);
988 outb(0x0b,0x20);
989 v = inb(0xa0) << 8 | inb(0x20);
990 outb(0x0a,0xa0);
991 outb(0x0a,0x20);
992
993 spin_unlock_irqrestore(&i8259A_lock, flags);
994
995 printk(KERN_DEBUG "... PIC ISR: %04x\n", v);
996
997 v = inb(0x4d1) << 8 | inb(0x4d0);
998 printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
999}
1000
1001static void __init enable_IO_APIC(void)
1002{
1003 struct IO_APIC_reg_01 reg_01;
1004 int i;
1005 unsigned long flags;
1006
1007 for (i = 0; i < PIN_MAP_SIZE; i++) {
1008 irq_2_pin[i].pin = -1;
1009 irq_2_pin[i].next = 0;
1010 }
1011 if (!pirqs_enabled)
1012 for (i = 0; i < MAX_PIRQS; i++)
1013 pirq_entries[i] = -1;
1014
1015
1016
1017
1018 for (i = 0; i < nr_ioapics; i++) {
1019 spin_lock_irqsave(&ioapic_lock, flags);
1020 *(int *)®_01 = io_apic_read(i, 1);
1021 spin_unlock_irqrestore(&ioapic_lock, flags);
1022 nr_ioapic_registers[i] = reg_01.entries+1;
1023 }
1024
1025
1026
1027
1028 clear_IO_APIC();
1029}
1030
1031
1032
1033
1034void disable_IO_APIC(void)
1035{
1036
1037
1038
1039 clear_IO_APIC();
1040
1041 disconnect_bsp_APIC();
1042}
1043
1044
1045
1046
1047
1048
1049
1050
1051static void __init setup_ioapic_ids_from_mpc (void)
1052{
1053 struct IO_APIC_reg_00 reg_00;
1054 unsigned long phys_id_present_map = phys_cpu_present_map;
1055 int apic;
1056 int i;
1057 unsigned char old_id;
1058 unsigned long flags;
1059
1060 if (clustered_apic_mode)
1061
1062 phys_id_present_map = (u_long) 0xf;
1063
1064
1065
1066 for (apic = 0; apic < nr_ioapics; apic++) {
1067
1068
1069 spin_lock_irqsave(&ioapic_lock, flags);
1070 *(int *)®_00 = io_apic_read(apic, 0);
1071 spin_unlock_irqrestore(&ioapic_lock, flags);
1072
1073 old_id = mp_ioapics[apic].mpc_apicid;
1074
1075 if (mp_ioapics[apic].mpc_apicid >= apic_broadcast_id) {
1076 printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
1077 apic, mp_ioapics[apic].mpc_apicid);
1078 printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
1079 reg_00.ID);
1080 mp_ioapics[apic].mpc_apicid = reg_00.ID;
1081 }
1082
1083
1084
1085
1086
1087
1088
1089 if ((clustered_apic_mode != CLUSTERED_APIC_XAPIC) &&
1090 (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid))) {
1091 printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
1092 apic, mp_ioapics[apic].mpc_apicid);
1093 for (i = 0; i < 0xf; i++)
1094 if (!(phys_id_present_map & (1 << i)))
1095 break;
1096 if (i >= apic_broadcast_id)
1097 panic("Max APIC ID exceeded!\n");
1098 printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
1099 i);
1100 phys_id_present_map |= 1 << i;
1101 mp_ioapics[apic].mpc_apicid = i;
1102 } else {
1103 printk("Setting %d in the phys_id_present_map\n", mp_ioapics[apic].mpc_apicid);
1104 phys_id_present_map |= 1 << mp_ioapics[apic].mpc_apicid;
1105 }
1106
1107
1108
1109
1110
1111
1112 if (old_id != mp_ioapics[apic].mpc_apicid)
1113 for (i = 0; i < mp_irq_entries; i++)
1114 if (mp_irqs[i].mpc_dstapic == old_id)
1115 mp_irqs[i].mpc_dstapic
1116 = mp_ioapics[apic].mpc_apicid;
1117
1118
1119
1120
1121
1122 printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...",
1123 mp_ioapics[apic].mpc_apicid);
1124
1125 reg_00.ID = mp_ioapics[apic].mpc_apicid;
1126 spin_lock_irqsave(&ioapic_lock, flags);
1127 io_apic_write(apic, 0, *(int *)®_00);
1128 spin_unlock_irqrestore(&ioapic_lock, flags);
1129
1130
1131
1132
1133 spin_lock_irqsave(&ioapic_lock, flags);
1134 *(int *)®_00 = io_apic_read(apic, 0);
1135 spin_unlock_irqrestore(&ioapic_lock, flags);
1136 if (reg_00.ID != mp_ioapics[apic].mpc_apicid)
1137 panic("could not set ID!\n");
1138 else
1139 printk(" ok.\n");
1140 }
1141}
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151static int __init timer_irq_works(void)
1152{
1153 unsigned int t1 = jiffies;
1154
1155 sti();
1156
1157 mdelay((10 * 1000) / HZ);
1158
1159
1160
1161
1162
1163
1164
1165
1166 if (jiffies - t1 > 4)
1167 return 1;
1168
1169 return 0;
1170}
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184#define enable_edge_ioapic_irq unmask_IO_APIC_irq
1185
1186static void disable_edge_ioapic_irq (unsigned int irq) { }
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198static unsigned int startup_edge_ioapic_irq(unsigned int irq)
1199{
1200 int was_pending = 0;
1201 unsigned long flags;
1202
1203 spin_lock_irqsave(&ioapic_lock, flags);
1204 if (irq < 16) {
1205 disable_8259A_irq(irq);
1206 if (i8259A_irq_pending(irq))
1207 was_pending = 1;
1208 }
1209 __unmask_IO_APIC_irq(irq);
1210 spin_unlock_irqrestore(&ioapic_lock, flags);
1211
1212 return was_pending;
1213}
1214
1215#define shutdown_edge_ioapic_irq disable_edge_ioapic_irq
1216
1217
1218
1219
1220
1221
1222static void ack_edge_ioapic_irq(unsigned int irq)
1223{
1224 if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
1225 == (IRQ_PENDING | IRQ_DISABLED))
1226 mask_IO_APIC_irq(irq);
1227 ack_APIC_irq();
1228}
1229
1230static void end_edge_ioapic_irq (unsigned int i) { }
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247static unsigned int startup_level_ioapic_irq (unsigned int irq)
1248{
1249 unmask_IO_APIC_irq(irq);
1250
1251 return 0;
1252}
1253
1254#define shutdown_level_ioapic_irq mask_IO_APIC_irq
1255#define enable_level_ioapic_irq unmask_IO_APIC_irq
1256#define disable_level_ioapic_irq mask_IO_APIC_irq
1257
1258static void end_level_ioapic_irq (unsigned int irq)
1259{
1260 unsigned long v;
1261 int i;
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282 i = IO_APIC_VECTOR(irq);
1283 v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
1284
1285 ack_APIC_irq();
1286
1287 if (!(v & (1 << (i & 0x1f)))) {
1288#ifdef APIC_LOCKUP_DEBUG
1289 struct irq_pin_list *entry;
1290#endif
1291
1292#ifdef APIC_MISMATCH_DEBUG
1293 atomic_inc(&irq_mis_count);
1294#endif
1295 spin_lock(&ioapic_lock);
1296 __mask_and_edge_IO_APIC_irq(irq);
1297#ifdef APIC_LOCKUP_DEBUG
1298 for (entry = irq_2_pin + irq;;) {
1299 unsigned int reg;
1300
1301 if (entry->pin == -1)
1302 break;
1303 reg = io_apic_read(entry->apic, 0x10 + entry->pin * 2);
1304 if (reg & 0x00004000)
1305 printk(KERN_CRIT "Aieee!!! Remote IRR"
1306 " still set after unlock!\n");
1307 if (!entry->next)
1308 break;
1309 entry = irq_2_pin + entry->next;
1310 }
1311#endif
1312 __unmask_and_level_IO_APIC_irq(irq);
1313 spin_unlock(&ioapic_lock);
1314 }
1315}
1316
1317static void mask_and_ack_level_ioapic_irq (unsigned int irq) { }
1318
1319static void set_ioapic_affinity (unsigned int irq, unsigned long mask)
1320{
1321 unsigned long flags;
1322
1323
1324
1325 mask = mask << 24;
1326
1327 spin_lock_irqsave(&ioapic_lock, flags);
1328 __DO_ACTION(1, = mask, )
1329 spin_unlock_irqrestore(&ioapic_lock, flags);
1330}
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341static struct hw_interrupt_type ioapic_edge_irq_type = {
1342 "IO-APIC-edge",
1343 startup_edge_ioapic_irq,
1344 shutdown_edge_ioapic_irq,
1345 enable_edge_ioapic_irq,
1346 disable_edge_ioapic_irq,
1347 ack_edge_ioapic_irq,
1348 end_edge_ioapic_irq,
1349 set_ioapic_affinity,
1350};
1351
1352static struct hw_interrupt_type ioapic_level_irq_type = {
1353 "IO-APIC-level",
1354 startup_level_ioapic_irq,
1355 shutdown_level_ioapic_irq,
1356 enable_level_ioapic_irq,
1357 disable_level_ioapic_irq,
1358 mask_and_ack_level_ioapic_irq,
1359 end_level_ioapic_irq,
1360 set_ioapic_affinity,
1361};
1362
1363static inline void init_IO_APIC_traps(void)
1364{
1365 int irq;
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378 for (irq = 0; irq < NR_IRQS ; irq++) {
1379 if (IO_APIC_IRQ(irq) && !IO_APIC_VECTOR(irq)) {
1380
1381
1382
1383
1384
1385 if (irq < 16)
1386 make_8259A_irq(irq);
1387 else
1388
1389 irq_desc[irq].handler = &no_irq_type;
1390 }
1391 }
1392}
1393
1394static void enable_lapic_irq (unsigned int irq)
1395{
1396 unsigned long v;
1397
1398 v = apic_read(APIC_LVT0);
1399 apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
1400}
1401
1402static void disable_lapic_irq (unsigned int irq)
1403{
1404 unsigned long v;
1405
1406 v = apic_read(APIC_LVT0);
1407 apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
1408}
1409
1410static void ack_lapic_irq (unsigned int irq)
1411{
1412 ack_APIC_irq();
1413}
1414
1415static void end_lapic_irq (unsigned int i) { }
1416
1417static struct hw_interrupt_type lapic_irq_type = {
1418 "local-APIC-edge",
1419 NULL,
1420 NULL,
1421 enable_lapic_irq,
1422 disable_lapic_irq,
1423 ack_lapic_irq,
1424 end_lapic_irq
1425};
1426
1427static void enable_NMI_through_LVT0 (void * dummy)
1428{
1429 unsigned int v, ver;
1430
1431 ver = apic_read(APIC_LVR);
1432 ver = GET_APIC_VERSION(ver);
1433 v = APIC_DM_NMI;
1434 if (!APIC_INTEGRATED(ver))
1435 v |= APIC_LVT_LEVEL_TRIGGER;
1436 apic_write_around(APIC_LVT0, v);
1437}
1438
1439static void setup_nmi (void)
1440{
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450 printk(KERN_INFO "activating NMI Watchdog ...");
1451
1452 smp_call_function(enable_NMI_through_LVT0, NULL, 1, 1);
1453 enable_NMI_through_LVT0(NULL);
1454
1455 printk(" done.\n");
1456}
1457
1458
1459
1460
1461
1462
1463
1464
1465static inline void unlock_ExtINT_logic(void)
1466{
1467 int pin, i;
1468 struct IO_APIC_route_entry entry0, entry1;
1469 unsigned char save_control, save_freq_select;
1470 unsigned long flags;
1471
1472 pin = find_isa_irq_pin(8, mp_INT);
1473 if (pin == -1)
1474 return;
1475
1476 spin_lock_irqsave(&ioapic_lock, flags);
1477 *(((int *)&entry0) + 1) = io_apic_read(0, 0x11 + 2 * pin);
1478 *(((int *)&entry0) + 0) = io_apic_read(0, 0x10 + 2 * pin);
1479 spin_unlock_irqrestore(&ioapic_lock, flags);
1480 clear_IO_APIC_pin(0, pin);
1481
1482 memset(&entry1, 0, sizeof(entry1));
1483
1484 entry1.dest_mode = 0;
1485 entry1.mask = 0;
1486 entry1.dest.physical.physical_dest = hard_smp_processor_id();
1487 entry1.delivery_mode = dest_ExtINT;
1488 entry1.polarity = entry0.polarity;
1489 entry1.trigger = 0;
1490 entry1.vector = 0;
1491
1492 spin_lock_irqsave(&ioapic_lock, flags);
1493 io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
1494 io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
1495 spin_unlock_irqrestore(&ioapic_lock, flags);
1496
1497 save_control = CMOS_READ(RTC_CONTROL);
1498 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
1499 CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6,
1500 RTC_FREQ_SELECT);
1501 CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL);
1502
1503 i = 100;
1504 while (i-- > 0) {
1505 mdelay(10);
1506 if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF)
1507 i -= 10;
1508 }
1509
1510 CMOS_WRITE(save_control, RTC_CONTROL);
1511 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
1512 clear_IO_APIC_pin(0, pin);
1513
1514 spin_lock_irqsave(&ioapic_lock, flags);
1515 io_apic_write(0, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
1516 io_apic_write(0, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
1517 spin_unlock_irqrestore(&ioapic_lock, flags);
1518}
1519
1520
1521
1522
1523
1524
1525
1526static inline void check_timer(void)
1527{
1528 extern int timer_ack;
1529 int pin1, pin2;
1530 int vector;
1531
1532
1533
1534
1535 disable_8259A_irq(0);
1536 vector = assign_irq_vector(0);
1537 set_intr_gate(vector, interrupt[0]);
1538
1539
1540
1541
1542
1543
1544
1545
1546 apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
1547 init_8259A(1);
1548 timer_ack = 1;
1549 enable_8259A_irq(0);
1550
1551 pin1 = find_isa_irq_pin(0, mp_INT);
1552 pin2 = find_isa_irq_pin(0, mp_ExtINT);
1553
1554 printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
1555
1556 if (pin1 != -1) {
1557
1558
1559
1560 unmask_IO_APIC_irq(0);
1561 if (timer_irq_works()) {
1562 if (nmi_watchdog == NMI_IO_APIC) {
1563 disable_8259A_irq(0);
1564 setup_nmi();
1565 enable_8259A_irq(0);
1566 check_nmi_watchdog();
1567 }
1568 return;
1569 }
1570 clear_IO_APIC_pin(0, pin1);
1571 printk(KERN_ERR "..MP-BIOS bug: 8254 timer not connected to IO-APIC\n");
1572 }
1573
1574 printk(KERN_INFO "...trying to set up timer (IRQ0) through the 8259A ... ");
1575 if (pin2 != -1) {
1576 printk("\n..... (found pin %d) ...", pin2);
1577
1578
1579
1580 setup_ExtINT_IRQ0_pin(pin2, vector);
1581 if (timer_irq_works()) {
1582 printk("works.\n");
1583 if (pin1 != -1)
1584 replace_pin_at_irq(0, 0, pin1, 0, pin2);
1585 else
1586 add_pin_to_irq(0, 0, pin2);
1587 if (nmi_watchdog == NMI_IO_APIC) {
1588 setup_nmi();
1589 check_nmi_watchdog();
1590 }
1591 return;
1592 }
1593
1594
1595
1596 clear_IO_APIC_pin(0, pin2);
1597 }
1598 printk(" failed.\n");
1599
1600 if (nmi_watchdog) {
1601 printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
1602 nmi_watchdog = 0;
1603 }
1604
1605 printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
1606
1607 disable_8259A_irq(0);
1608 irq_desc[0].handler = &lapic_irq_type;
1609 apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);
1610 enable_8259A_irq(0);
1611
1612 if (timer_irq_works()) {
1613 printk(" works.\n");
1614 return;
1615 }
1616 apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
1617 printk(" failed.\n");
1618
1619 printk(KERN_INFO "...trying to set up timer as ExtINT IRQ...");
1620
1621 init_8259A(0);
1622 make_8259A_irq(0);
1623 apic_write_around(APIC_LVT0, APIC_DM_EXTINT);
1624
1625 unlock_ExtINT_logic();
1626
1627 if (timer_irq_works()) {
1628 printk(" works.\n");
1629 return;
1630 }
1631 printk(" failed :(.\n");
1632 panic("IO-APIC + timer doesn't work! pester mingo@redhat.com");
1633}
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650#define PIC_IRQS (1<<2)
1651
1652void __init setup_IO_APIC(void)
1653{
1654 enable_IO_APIC();
1655
1656 io_apic_irqs = ~PIC_IRQS;
1657 printk("ENABLING IO-APIC IRQs\n");
1658
1659
1660
1661
1662
1663 setup_ioapic_ids_from_mpc();
1664 sync_Arb_IDs();
1665 setup_IO_APIC_irqs();
1666 init_IO_APIC_traps();
1667 check_timer();
1668 print_IO_APIC();
1669}
1670