diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-19 23:50:41 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:52:55 -0400 |
commit | 047c8fdb8718890e3340073b178d0859d0c7f91f (patch) | |
tree | 12386f7d380da5212d720d7a2d7e9ca1c64473bb /arch/x86/kernel/io_apic_64.c | |
parent | aa45f97b1bb40adae1288669e73350907ffae85e (diff) |
x86: make io_apic_64.c and io_apic_32.c the same
all the same except INTR_REMAPPING related and ioapic io resource.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/io_apic_64.c')
-rw-r--r-- | arch/x86/kernel/io_apic_64.c | 663 |
1 files changed, 630 insertions, 33 deletions
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index b70fd8232185..940c4167b325 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -94,18 +94,22 @@ struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; | |||
94 | /* # of MP IRQ source entries */ | 94 | /* # of MP IRQ source entries */ |
95 | int mp_irq_entries; | 95 | int mp_irq_entries; |
96 | 96 | ||
97 | #if defined (CONFIG_MCA) || defined (CONFIG_EISA) | ||
98 | int mp_bus_id_to_type[MAX_MP_BUSSES]; | ||
99 | #endif | ||
100 | |||
97 | DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); | 101 | DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); |
98 | 102 | ||
99 | int skip_ioapic_setup; | 103 | int skip_ioapic_setup; |
100 | 104 | ||
101 | static int __init parse_noapic(char *str) | 105 | static int __init parse_noapic(char *str) |
102 | { | 106 | { |
107 | /* disable IO-APIC */ | ||
103 | disable_ioapic_setup(); | 108 | disable_ioapic_setup(); |
104 | return 0; | 109 | return 0; |
105 | } | 110 | } |
106 | early_param("noapic", parse_noapic); | 111 | early_param("noapic", parse_noapic); |
107 | 112 | ||
108 | |||
109 | struct irq_cfg; | 113 | struct irq_cfg; |
110 | struct irq_pin_list; | 114 | struct irq_pin_list; |
111 | struct irq_cfg { | 115 | struct irq_cfg { |
@@ -374,6 +378,8 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i | |||
374 | /* | 378 | /* |
375 | * Re-write a value: to be used for read-modify-write | 379 | * Re-write a value: to be used for read-modify-write |
376 | * cycles where the read already set up the index register. | 380 | * cycles where the read already set up the index register. |
381 | * | ||
382 | * Older SiS APIC requires we rewrite the index register | ||
377 | */ | 383 | */ |
378 | static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) | 384 | static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) |
379 | { | 385 | { |
@@ -383,6 +389,7 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned | |||
383 | writel(value, &io_apic->data); | 389 | writel(value, &io_apic->data); |
384 | } | 390 | } |
385 | 391 | ||
392 | #ifdef CONFIG_X86_64 | ||
386 | static bool io_apic_level_ack_pending(unsigned int irq) | 393 | static bool io_apic_level_ack_pending(unsigned int irq) |
387 | { | 394 | { |
388 | struct irq_pin_list *entry; | 395 | struct irq_pin_list *entry; |
@@ -412,6 +419,7 @@ static bool io_apic_level_ack_pending(unsigned int irq) | |||
412 | 419 | ||
413 | return false; | 420 | return false; |
414 | } | 421 | } |
422 | #endif | ||
415 | 423 | ||
416 | union entry_union { | 424 | union entry_union { |
417 | struct { u32 w1, w2; }; | 425 | struct { u32 w1, w2; }; |
@@ -509,7 +517,7 @@ static int assign_irq_vector(int irq, cpumask_t mask); | |||
509 | 517 | ||
510 | static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | 518 | static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) |
511 | { | 519 | { |
512 | struct irq_cfg *cfg = irq_cfg(irq); | 520 | struct irq_cfg *cfg; |
513 | unsigned long flags; | 521 | unsigned long flags; |
514 | unsigned int dest; | 522 | unsigned int dest; |
515 | cpumask_t tmp; | 523 | cpumask_t tmp; |
@@ -519,12 +527,12 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | |||
519 | if (cpus_empty(tmp)) | 527 | if (cpus_empty(tmp)) |
520 | return; | 528 | return; |
521 | 529 | ||
530 | cfg = irq_cfg(irq); | ||
522 | if (assign_irq_vector(irq, mask)) | 531 | if (assign_irq_vector(irq, mask)) |
523 | return; | 532 | return; |
524 | 533 | ||
525 | cpus_and(tmp, cfg->domain, mask); | 534 | cpus_and(tmp, cfg->domain, mask); |
526 | dest = cpu_mask_to_apicid(tmp); | 535 | dest = cpu_mask_to_apicid(tmp); |
527 | |||
528 | /* | 536 | /* |
529 | * Only the high 8 bits are valid. | 537 | * Only the high 8 bits are valid. |
530 | */ | 538 | */ |
@@ -536,7 +544,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) | |||
536 | desc->affinity = mask; | 544 | desc->affinity = mask; |
537 | spin_unlock_irqrestore(&ioapic_lock, flags); | 545 | spin_unlock_irqrestore(&ioapic_lock, flags); |
538 | } | 546 | } |
539 | #endif | 547 | #endif /* CONFIG_SMP */ |
540 | 548 | ||
541 | /* | 549 | /* |
542 | * The common case is 1:1 IRQ<->pin mappings. Sometimes there are | 550 | * The common case is 1:1 IRQ<->pin mappings. Sometimes there are |
@@ -602,6 +610,7 @@ static void __init replace_pin_at_irq(unsigned int irq, | |||
602 | add_pin_to_irq(irq, newapic, newpin); | 610 | add_pin_to_irq(irq, newapic, newpin); |
603 | } | 611 | } |
604 | 612 | ||
613 | #ifdef CONFIG_X86_64 | ||
605 | /* | 614 | /* |
606 | * Synchronize the IO-APIC and the CPU by doing | 615 | * Synchronize the IO-APIC and the CPU by doing |
607 | * a dummy read from the IO-APIC | 616 | * a dummy read from the IO-APIC |
@@ -647,6 +656,58 @@ DO_ACTION(__mask, 0, |= IO_APIC_REDIR_MASKED, io_apic_sync(entry->apic)) | |||
647 | /* mask = 0 */ | 656 | /* mask = 0 */ |
648 | DO_ACTION(__unmask, 0, &= ~IO_APIC_REDIR_MASKED, ) | 657 | DO_ACTION(__unmask, 0, &= ~IO_APIC_REDIR_MASKED, ) |
649 | 658 | ||
659 | #else | ||
660 | |||
661 | static void __modify_IO_APIC_irq(unsigned int irq, unsigned long enable, unsigned long disable) | ||
662 | { | ||
663 | struct irq_cfg *cfg; | ||
664 | struct irq_pin_list *entry; | ||
665 | unsigned int pin, reg; | ||
666 | |||
667 | cfg = irq_cfg(irq); | ||
668 | entry = cfg->irq_2_pin; | ||
669 | for (;;) { | ||
670 | if (!entry) | ||
671 | break; | ||
672 | pin = entry->pin; | ||
673 | reg = io_apic_read(entry->apic, 0x10 + pin*2); | ||
674 | reg &= ~disable; | ||
675 | reg |= enable; | ||
676 | io_apic_modify(entry->apic, 0x10 + pin*2, reg); | ||
677 | if (!entry->next) | ||
678 | break; | ||
679 | entry = entry->next; | ||
680 | } | ||
681 | } | ||
682 | |||
683 | /* mask = 1 */ | ||
684 | static void __mask_IO_APIC_irq(unsigned int irq) | ||
685 | { | ||
686 | __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED, 0); | ||
687 | } | ||
688 | |||
689 | /* mask = 0 */ | ||
690 | static void __unmask_IO_APIC_irq(unsigned int irq) | ||
691 | { | ||
692 | __modify_IO_APIC_irq(irq, 0, IO_APIC_REDIR_MASKED); | ||
693 | } | ||
694 | |||
695 | /* mask = 1, trigger = 0 */ | ||
696 | static void __mask_and_edge_IO_APIC_irq(unsigned int irq) | ||
697 | { | ||
698 | __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED, | ||
699 | IO_APIC_REDIR_LEVEL_TRIGGER); | ||
700 | } | ||
701 | |||
702 | /* mask = 0, trigger = 1 */ | ||
703 | static void __unmask_and_level_IO_APIC_irq(unsigned int irq) | ||
704 | { | ||
705 | __modify_IO_APIC_irq(irq, IO_APIC_REDIR_LEVEL_TRIGGER, | ||
706 | IO_APIC_REDIR_MASKED); | ||
707 | } | ||
708 | |||
709 | #endif | ||
710 | |||
650 | static void mask_IO_APIC_irq (unsigned int irq) | 711 | static void mask_IO_APIC_irq (unsigned int irq) |
651 | { | 712 | { |
652 | unsigned long flags; | 713 | unsigned long flags; |
@@ -688,6 +749,64 @@ static void clear_IO_APIC (void) | |||
688 | clear_IO_APIC_pin(apic, pin); | 749 | clear_IO_APIC_pin(apic, pin); |
689 | } | 750 | } |
690 | 751 | ||
752 | #if !defined(CONFIG_SMP) && defined(CONFIG_X86_32) | ||
753 | void send_IPI_self(int vector) | ||
754 | { | ||
755 | unsigned int cfg; | ||
756 | |||
757 | /* | ||
758 | * Wait for idle. | ||
759 | */ | ||
760 | apic_wait_icr_idle(); | ||
761 | cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL; | ||
762 | /* | ||
763 | * Send the IPI. The write to APIC_ICR fires this off. | ||
764 | */ | ||
765 | apic_write(APIC_ICR, cfg); | ||
766 | } | ||
767 | #endif /* !CONFIG_SMP && CONFIG_X86_32*/ | ||
768 | |||
769 | #ifdef CONFIG_X86_32 | ||
770 | /* | ||
771 | * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to | ||
772 | * specific CPU-side IRQs. | ||
773 | */ | ||
774 | |||
775 | #define MAX_PIRQS 8 | ||
776 | static int pirq_entries [MAX_PIRQS]; | ||
777 | static int pirqs_enabled; | ||
778 | |||
779 | static int __init ioapic_pirq_setup(char *str) | ||
780 | { | ||
781 | int i, max; | ||
782 | int ints[MAX_PIRQS+1]; | ||
783 | |||
784 | get_options(str, ARRAY_SIZE(ints), ints); | ||
785 | |||
786 | for (i = 0; i < MAX_PIRQS; i++) | ||
787 | pirq_entries[i] = -1; | ||
788 | |||
789 | pirqs_enabled = 1; | ||
790 | apic_printk(APIC_VERBOSE, KERN_INFO | ||
791 | "PIRQ redirection, working around broken MP-BIOS.\n"); | ||
792 | max = MAX_PIRQS; | ||
793 | if (ints[0] < MAX_PIRQS) | ||
794 | max = ints[0]; | ||
795 | |||
796 | for (i = 0; i < max; i++) { | ||
797 | apic_printk(APIC_VERBOSE, KERN_DEBUG | ||
798 | "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); | ||
799 | /* | ||
800 | * PIRQs are mapped upside down, usually. | ||
801 | */ | ||
802 | pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; | ||
803 | } | ||
804 | return 1; | ||
805 | } | ||
806 | |||
807 | __setup("pirq=", ioapic_pirq_setup); | ||
808 | #endif /* CONFIG_X86_32 */ | ||
809 | |||
691 | #ifdef CONFIG_INTR_REMAP | 810 | #ifdef CONFIG_INTR_REMAP |
692 | /* I/O APIC RTE contents at the OS boot up */ | 811 | /* I/O APIC RTE contents at the OS boot up */ |
693 | static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; | 812 | static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; |
@@ -861,18 +980,51 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) | |||
861 | return best_guess; | 980 | return best_guess; |
862 | } | 981 | } |
863 | 982 | ||
983 | EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector); | ||
984 | |||
985 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) | ||
986 | /* | ||
987 | * EISA Edge/Level control register, ELCR | ||
988 | */ | ||
989 | static int EISA_ELCR(unsigned int irq) | ||
990 | { | ||
991 | if (irq < 16) { | ||
992 | unsigned int port = 0x4d0 + (irq >> 3); | ||
993 | return (inb(port) >> (irq & 7)) & 1; | ||
994 | } | ||
995 | apic_printk(APIC_VERBOSE, KERN_INFO | ||
996 | "Broken MPtable reports ISA irq %d\n", irq); | ||
997 | return 0; | ||
998 | } | ||
999 | |||
1000 | #endif | ||
1001 | |||
864 | /* ISA interrupts are always polarity zero edge triggered, | 1002 | /* ISA interrupts are always polarity zero edge triggered, |
865 | * when listed as conforming in the MP table. */ | 1003 | * when listed as conforming in the MP table. */ |
866 | 1004 | ||
867 | #define default_ISA_trigger(idx) (0) | 1005 | #define default_ISA_trigger(idx) (0) |
868 | #define default_ISA_polarity(idx) (0) | 1006 | #define default_ISA_polarity(idx) (0) |
869 | 1007 | ||
1008 | /* EISA interrupts are always polarity zero and can be edge or level | ||
1009 | * trigger depending on the ELCR value. If an interrupt is listed as | ||
1010 | * EISA conforming in the MP table, that means its trigger type must | ||
1011 | * be read in from the ELCR */ | ||
1012 | |||
1013 | #define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mp_srcbusirq)) | ||
1014 | #define default_EISA_polarity(idx) default_ISA_polarity(idx) | ||
1015 | |||
870 | /* PCI interrupts are always polarity one level triggered, | 1016 | /* PCI interrupts are always polarity one level triggered, |
871 | * when listed as conforming in the MP table. */ | 1017 | * when listed as conforming in the MP table. */ |
872 | 1018 | ||
873 | #define default_PCI_trigger(idx) (1) | 1019 | #define default_PCI_trigger(idx) (1) |
874 | #define default_PCI_polarity(idx) (1) | 1020 | #define default_PCI_polarity(idx) (1) |
875 | 1021 | ||
1022 | /* MCA interrupts are always polarity zero level triggered, | ||
1023 | * when listed as conforming in the MP table. */ | ||
1024 | |||
1025 | #define default_MCA_trigger(idx) (1) | ||
1026 | #define default_MCA_polarity(idx) default_ISA_polarity(idx) | ||
1027 | |||
876 | static int MPBIOS_polarity(int idx) | 1028 | static int MPBIOS_polarity(int idx) |
877 | { | 1029 | { |
878 | int bus = mp_irqs[idx].mp_srcbus; | 1030 | int bus = mp_irqs[idx].mp_srcbus; |
@@ -930,6 +1082,36 @@ static int MPBIOS_trigger(int idx) | |||
930 | trigger = default_ISA_trigger(idx); | 1082 | trigger = default_ISA_trigger(idx); |
931 | else | 1083 | else |
932 | trigger = default_PCI_trigger(idx); | 1084 | trigger = default_PCI_trigger(idx); |
1085 | #if defined(CONFIG_EISA) || defined(CONFIG_MCA) | ||
1086 | switch (mp_bus_id_to_type[bus]) { | ||
1087 | case MP_BUS_ISA: /* ISA pin */ | ||
1088 | { | ||
1089 | /* set before the switch */ | ||
1090 | break; | ||
1091 | } | ||
1092 | case MP_BUS_EISA: /* EISA pin */ | ||
1093 | { | ||
1094 | trigger = default_EISA_trigger(idx); | ||
1095 | break; | ||
1096 | } | ||
1097 | case MP_BUS_PCI: /* PCI pin */ | ||
1098 | { | ||
1099 | /* set before the switch */ | ||
1100 | break; | ||
1101 | } | ||
1102 | case MP_BUS_MCA: /* MCA pin */ | ||
1103 | { | ||
1104 | trigger = default_MCA_trigger(idx); | ||
1105 | break; | ||
1106 | } | ||
1107 | default: | ||
1108 | { | ||
1109 | printk(KERN_WARNING "broken BIOS!!\n"); | ||
1110 | trigger = 1; | ||
1111 | break; | ||
1112 | } | ||
1113 | } | ||
1114 | #endif | ||
933 | break; | 1115 | break; |
934 | case 1: /* edge */ | 1116 | case 1: /* edge */ |
935 | { | 1117 | { |
@@ -967,6 +1149,7 @@ static inline int irq_trigger(int idx) | |||
967 | return MPBIOS_trigger(idx); | 1149 | return MPBIOS_trigger(idx); |
968 | } | 1150 | } |
969 | 1151 | ||
1152 | int (*ioapic_renumber_irq)(int ioapic, int irq); | ||
970 | static int pin_2_irq(int idx, int apic, int pin) | 1153 | static int pin_2_irq(int idx, int apic, int pin) |
971 | { | 1154 | { |
972 | int irq, i; | 1155 | int irq, i; |
@@ -988,7 +1171,32 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
988 | while (i < apic) | 1171 | while (i < apic) |
989 | irq += nr_ioapic_registers[i++]; | 1172 | irq += nr_ioapic_registers[i++]; |
990 | irq += pin; | 1173 | irq += pin; |
1174 | /* | ||
1175 | * For MPS mode, so far only needed by ES7000 platform | ||
1176 | */ | ||
1177 | if (ioapic_renumber_irq) | ||
1178 | irq = ioapic_renumber_irq(apic, irq); | ||
991 | } | 1179 | } |
1180 | |||
1181 | #ifdef CONFIG_X86_32 | ||
1182 | /* | ||
1183 | * PCI IRQ command line redirection. Yes, limits are hardcoded. | ||
1184 | */ | ||
1185 | if ((pin >= 16) && (pin <= 23)) { | ||
1186 | if (pirq_entries[pin-16] != -1) { | ||
1187 | if (!pirq_entries[pin-16]) { | ||
1188 | apic_printk(APIC_VERBOSE, KERN_DEBUG | ||
1189 | "disabling PIRQ%d\n", pin-16); | ||
1190 | } else { | ||
1191 | irq = pirq_entries[pin-16]; | ||
1192 | apic_printk(APIC_VERBOSE, KERN_DEBUG | ||
1193 | "using PIRQ%d -> IRQ %d\n", | ||
1194 | pin-16, irq); | ||
1195 | } | ||
1196 | } | ||
1197 | } | ||
1198 | #endif | ||
1199 | |||
992 | return irq; | 1200 | return irq; |
993 | } | 1201 | } |
994 | 1202 | ||
@@ -1058,8 +1266,13 @@ next: | |||
1058 | } | 1266 | } |
1059 | if (unlikely(current_vector == vector)) | 1267 | if (unlikely(current_vector == vector)) |
1060 | continue; | 1268 | continue; |
1269 | #ifdef CONFIG_X86_64 | ||
1061 | if (vector == IA32_SYSCALL_VECTOR) | 1270 | if (vector == IA32_SYSCALL_VECTOR) |
1062 | goto next; | 1271 | goto next; |
1272 | #else | ||
1273 | if (vector == SYSCALL_VECTOR) | ||
1274 | goto next; | ||
1275 | #endif | ||
1063 | for_each_cpu_mask_nr(new_cpu, new_mask) | 1276 | for_each_cpu_mask_nr(new_cpu, new_mask) |
1064 | if (per_cpu(vector_irq, new_cpu)[vector] != -1) | 1277 | if (per_cpu(vector_irq, new_cpu)[vector] != -1) |
1065 | goto next; | 1278 | goto next; |
@@ -1140,6 +1353,34 @@ static struct irq_chip ioapic_chip; | |||
1140 | static struct irq_chip ir_ioapic_chip; | 1353 | static struct irq_chip ir_ioapic_chip; |
1141 | #endif | 1354 | #endif |
1142 | 1355 | ||
1356 | #define IOAPIC_AUTO -1 | ||
1357 | #define IOAPIC_EDGE 0 | ||
1358 | #define IOAPIC_LEVEL 1 | ||
1359 | |||
1360 | #ifdef CONFIG_X86_32 | ||
1361 | static inline int IO_APIC_irq_trigger(int irq) | ||
1362 | { | ||
1363 | int apic, idx, pin; | ||
1364 | |||
1365 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
1366 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | ||
1367 | idx = find_irq_entry(apic, pin, mp_INT); | ||
1368 | if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin))) | ||
1369 | return irq_trigger(idx); | ||
1370 | } | ||
1371 | } | ||
1372 | /* | ||
1373 | * nonexistent IRQs are edge default | ||
1374 | */ | ||
1375 | return 0; | ||
1376 | } | ||
1377 | #else | ||
1378 | static inline int IO_APIC_irq_trigger(int irq) | ||
1379 | { | ||
1380 | return 1; | ||
1381 | } | ||
1382 | #endif | ||
1383 | |||
1143 | static void ioapic_register_intr(int irq, unsigned long trigger) | 1384 | static void ioapic_register_intr(int irq, unsigned long trigger) |
1144 | { | 1385 | { |
1145 | struct irq_desc *desc; | 1386 | struct irq_desc *desc; |
@@ -1150,7 +1391,8 @@ static void ioapic_register_intr(int irq, unsigned long trigger) | |||
1150 | else | 1391 | else |
1151 | desc = irq_to_desc_alloc(irq); | 1392 | desc = irq_to_desc_alloc(irq); |
1152 | 1393 | ||
1153 | if (trigger) | 1394 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1395 | trigger == IOAPIC_LEVEL) | ||
1154 | desc->status |= IRQ_LEVEL; | 1396 | desc->status |= IRQ_LEVEL; |
1155 | else | 1397 | else |
1156 | desc->status &= ~IRQ_LEVEL; | 1398 | desc->status &= ~IRQ_LEVEL; |
@@ -1168,7 +1410,8 @@ static void ioapic_register_intr(int irq, unsigned long trigger) | |||
1168 | return; | 1410 | return; |
1169 | } | 1411 | } |
1170 | #endif | 1412 | #endif |
1171 | if (trigger) | 1413 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1414 | trigger == IOAPIC_LEVEL) | ||
1172 | set_irq_chip_and_handler_name(irq, &ioapic_chip, | 1415 | set_irq_chip_and_handler_name(irq, &ioapic_chip, |
1173 | handle_fasteoi_irq, | 1416 | handle_fasteoi_irq, |
1174 | "fasteoi"); | 1417 | "fasteoi"); |
@@ -1303,6 +1546,10 @@ static void __init setup_IO_APIC_irqs(void) | |||
1303 | } | 1546 | } |
1304 | 1547 | ||
1305 | irq = pin_2_irq(idx, apic, pin); | 1548 | irq = pin_2_irq(idx, apic, pin); |
1549 | #ifdef CONFIG_X86_32 | ||
1550 | if (multi_timer_check(apic, irq)) | ||
1551 | continue; | ||
1552 | #endif | ||
1306 | add_pin_to_irq(irq, apic, pin); | 1553 | add_pin_to_irq(irq, apic, pin); |
1307 | 1554 | ||
1308 | setup_IO_APIC_irq(apic, pin, irq, | 1555 | setup_IO_APIC_irq(apic, pin, irq, |
@@ -1360,6 +1607,7 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
1360 | union IO_APIC_reg_00 reg_00; | 1607 | union IO_APIC_reg_00 reg_00; |
1361 | union IO_APIC_reg_01 reg_01; | 1608 | union IO_APIC_reg_01 reg_01; |
1362 | union IO_APIC_reg_02 reg_02; | 1609 | union IO_APIC_reg_02 reg_02; |
1610 | union IO_APIC_reg_03 reg_03; | ||
1363 | unsigned long flags; | 1611 | unsigned long flags; |
1364 | struct irq_cfg *cfg; | 1612 | struct irq_cfg *cfg; |
1365 | 1613 | ||
@@ -1384,6 +1632,8 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
1384 | reg_01.raw = io_apic_read(apic, 1); | 1632 | reg_01.raw = io_apic_read(apic, 1); |
1385 | if (reg_01.bits.version >= 0x10) | 1633 | if (reg_01.bits.version >= 0x10) |
1386 | reg_02.raw = io_apic_read(apic, 2); | 1634 | reg_02.raw = io_apic_read(apic, 2); |
1635 | if (reg_01.bits.version >= 0x20) | ||
1636 | reg_03.raw = io_apic_read(apic, 3); | ||
1387 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1637 | spin_unlock_irqrestore(&ioapic_lock, flags); |
1388 | 1638 | ||
1389 | printk("\n"); | 1639 | printk("\n"); |
@@ -1399,11 +1649,27 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
1399 | printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); | 1649 | printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); |
1400 | printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); | 1650 | printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); |
1401 | 1651 | ||
1402 | if (reg_01.bits.version >= 0x10) { | 1652 | /* |
1653 | * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, | ||
1654 | * but the value of reg_02 is read as the previous read register | ||
1655 | * value, so ignore it if reg_02 == reg_01. | ||
1656 | */ | ||
1657 | if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { | ||
1403 | printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); | 1658 | printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); |
1404 | printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); | 1659 | printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); |
1405 | } | 1660 | } |
1406 | 1661 | ||
1662 | /* | ||
1663 | * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 | ||
1664 | * or reg_03, but the value of reg_0[23] is read as the previous read | ||
1665 | * register value, so ignore it if reg_03 == reg_0[12]. | ||
1666 | */ | ||
1667 | if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw && | ||
1668 | reg_03.raw != reg_01.raw) { | ||
1669 | printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); | ||
1670 | printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); | ||
1671 | } | ||
1672 | |||
1407 | printk(KERN_DEBUG ".... IRQ redirection table:\n"); | 1673 | printk(KERN_DEBUG ".... IRQ redirection table:\n"); |
1408 | 1674 | ||
1409 | printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol" | 1675 | printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol" |
@@ -1475,7 +1741,7 @@ __apicdebuginit(void) print_APIC_bitfield(int base) | |||
1475 | __apicdebuginit(void) print_local_APIC(void *dummy) | 1741 | __apicdebuginit(void) print_local_APIC(void *dummy) |
1476 | { | 1742 | { |
1477 | unsigned int v, ver, maxlvt; | 1743 | unsigned int v, ver, maxlvt; |
1478 | unsigned long icr; | 1744 | u64 icr; |
1479 | 1745 | ||
1480 | if (apic_verbosity == APIC_QUIET) | 1746 | if (apic_verbosity == APIC_QUIET) |
1481 | return; | 1747 | return; |
@@ -1492,11 +1758,13 @@ __apicdebuginit(void) print_local_APIC(void *dummy) | |||
1492 | v = apic_read(APIC_TASKPRI); | 1758 | v = apic_read(APIC_TASKPRI); |
1493 | printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK); | 1759 | printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK); |
1494 | 1760 | ||
1495 | v = apic_read(APIC_ARBPRI); | 1761 | if (APIC_INTEGRATED(ver)) { /* !82489DX */ |
1496 | printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v, | 1762 | v = apic_read(APIC_ARBPRI); |
1497 | v & APIC_ARBPRI_MASK); | 1763 | printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v, |
1498 | v = apic_read(APIC_PROCPRI); | 1764 | v & APIC_ARBPRI_MASK); |
1499 | printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v); | 1765 | v = apic_read(APIC_PROCPRI); |
1766 | printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v); | ||
1767 | } | ||
1500 | 1768 | ||
1501 | v = apic_read(APIC_EOI); | 1769 | v = apic_read(APIC_EOI); |
1502 | printk(KERN_DEBUG "... APIC EOI: %08x\n", v); | 1770 | printk(KERN_DEBUG "... APIC EOI: %08x\n", v); |
@@ -1516,8 +1784,13 @@ __apicdebuginit(void) print_local_APIC(void *dummy) | |||
1516 | printk(KERN_DEBUG "... APIC IRR field:\n"); | 1784 | printk(KERN_DEBUG "... APIC IRR field:\n"); |
1517 | print_APIC_bitfield(APIC_IRR); | 1785 | print_APIC_bitfield(APIC_IRR); |
1518 | 1786 | ||
1519 | v = apic_read(APIC_ESR); | 1787 | if (APIC_INTEGRATED(ver)) { /* !82489DX */ |
1520 | printk(KERN_DEBUG "... APIC ESR: %08x\n", v); | 1788 | if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */ |
1789 | apic_write(APIC_ESR, 0); | ||
1790 | |||
1791 | v = apic_read(APIC_ESR); | ||
1792 | printk(KERN_DEBUG "... APIC ESR: %08x\n", v); | ||
1793 | } | ||
1521 | 1794 | ||
1522 | icr = apic_icr_read(); | 1795 | icr = apic_icr_read(); |
1523 | printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr); | 1796 | printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr); |
@@ -1608,6 +1881,13 @@ void __init enable_IO_APIC(void) | |||
1608 | int apic; | 1881 | int apic; |
1609 | unsigned long flags; | 1882 | unsigned long flags; |
1610 | 1883 | ||
1884 | #ifdef CONFIG_X86_32 | ||
1885 | int i; | ||
1886 | if (!pirqs_enabled) | ||
1887 | for (i = 0; i < MAX_PIRQS; i++) | ||
1888 | pirq_entries[i] = -1; | ||
1889 | #endif | ||
1890 | |||
1611 | /* | 1891 | /* |
1612 | * The number of IO-APIC IRQ registers (== #pins): | 1892 | * The number of IO-APIC IRQ registers (== #pins): |
1613 | */ | 1893 | */ |
@@ -1636,6 +1916,10 @@ void __init enable_IO_APIC(void) | |||
1636 | } | 1916 | } |
1637 | found_i8259: | 1917 | found_i8259: |
1638 | /* Look to see what if the MP table has reported the ExtINT */ | 1918 | /* Look to see what if the MP table has reported the ExtINT */ |
1919 | /* If we could not find the appropriate pin by looking at the ioapic | ||
1920 | * the i8259 probably is not connected the ioapic but give the | ||
1921 | * mptable a chance anyway. | ||
1922 | */ | ||
1639 | i8259_pin = find_isa_irq_pin(0, mp_ExtINT); | 1923 | i8259_pin = find_isa_irq_pin(0, mp_ExtINT); |
1640 | i8259_apic = find_isa_irq_apic(0, mp_ExtINT); | 1924 | i8259_apic = find_isa_irq_apic(0, mp_ExtINT); |
1641 | /* Trust the MP table if nothing is setup in the hardware */ | 1925 | /* Trust the MP table if nothing is setup in the hardware */ |
@@ -1695,6 +1979,122 @@ void disable_IO_APIC(void) | |||
1695 | disconnect_bsp_APIC(ioapic_i8259.pin != -1); | 1979 | disconnect_bsp_APIC(ioapic_i8259.pin != -1); |
1696 | } | 1980 | } |
1697 | 1981 | ||
1982 | #ifdef CONFIG_X86_32 | ||
1983 | /* | ||
1984 | * function to set the IO-APIC physical IDs based on the | ||
1985 | * values stored in the MPC table. | ||
1986 | * | ||
1987 | * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999 | ||
1988 | */ | ||
1989 | |||
1990 | static void __init setup_ioapic_ids_from_mpc(void) | ||
1991 | { | ||
1992 | union IO_APIC_reg_00 reg_00; | ||
1993 | physid_mask_t phys_id_present_map; | ||
1994 | int apic; | ||
1995 | int i; | ||
1996 | unsigned char old_id; | ||
1997 | unsigned long flags; | ||
1998 | |||
1999 | if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids()) | ||
2000 | return; | ||
2001 | |||
2002 | /* | ||
2003 | * Don't check I/O APIC IDs for xAPIC systems. They have | ||
2004 | * no meaning without the serial APIC bus. | ||
2005 | */ | ||
2006 | if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | ||
2007 | || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) | ||
2008 | return; | ||
2009 | /* | ||
2010 | * This is broken; anything with a real cpu count has to | ||
2011 | * circumvent this idiocy regardless. | ||
2012 | */ | ||
2013 | phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map); | ||
2014 | |||
2015 | /* | ||
2016 | * Set the IOAPIC ID to the value stored in the MPC table. | ||
2017 | */ | ||
2018 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
2019 | |||
2020 | /* Read the register 0 value */ | ||
2021 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2022 | reg_00.raw = io_apic_read(apic, 0); | ||
2023 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2024 | |||
2025 | old_id = mp_ioapics[apic].mp_apicid; | ||
2026 | |||
2027 | if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) { | ||
2028 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", | ||
2029 | apic, mp_ioapics[apic].mp_apicid); | ||
2030 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", | ||
2031 | reg_00.bits.ID); | ||
2032 | mp_ioapics[apic].mp_apicid = reg_00.bits.ID; | ||
2033 | } | ||
2034 | |||
2035 | /* | ||
2036 | * Sanity check, is the ID really free? Every APIC in a | ||
2037 | * system must have a unique ID or we get lots of nice | ||
2038 | * 'stuck on smp_invalidate_needed IPI wait' messages. | ||
2039 | */ | ||
2040 | if (check_apicid_used(phys_id_present_map, | ||
2041 | mp_ioapics[apic].mp_apicid)) { | ||
2042 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", | ||
2043 | apic, mp_ioapics[apic].mp_apicid); | ||
2044 | for (i = 0; i < get_physical_broadcast(); i++) | ||
2045 | if (!physid_isset(i, phys_id_present_map)) | ||
2046 | break; | ||
2047 | if (i >= get_physical_broadcast()) | ||
2048 | panic("Max APIC ID exceeded!\n"); | ||
2049 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", | ||
2050 | i); | ||
2051 | physid_set(i, phys_id_present_map); | ||
2052 | mp_ioapics[apic].mp_apicid = i; | ||
2053 | } else { | ||
2054 | physid_mask_t tmp; | ||
2055 | tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid); | ||
2056 | apic_printk(APIC_VERBOSE, "Setting %d in the " | ||
2057 | "phys_id_present_map\n", | ||
2058 | mp_ioapics[apic].mp_apicid); | ||
2059 | physids_or(phys_id_present_map, phys_id_present_map, tmp); | ||
2060 | } | ||
2061 | |||
2062 | |||
2063 | /* | ||
2064 | * We need to adjust the IRQ routing table | ||
2065 | * if the ID changed. | ||
2066 | */ | ||
2067 | if (old_id != mp_ioapics[apic].mp_apicid) | ||
2068 | for (i = 0; i < mp_irq_entries; i++) | ||
2069 | if (mp_irqs[i].mp_dstapic == old_id) | ||
2070 | mp_irqs[i].mp_dstapic | ||
2071 | = mp_ioapics[apic].mp_apicid; | ||
2072 | |||
2073 | /* | ||
2074 | * Read the right value from the MPC table and | ||
2075 | * write it into the ID register. | ||
2076 | */ | ||
2077 | apic_printk(APIC_VERBOSE, KERN_INFO | ||
2078 | "...changing IO-APIC physical APIC ID to %d ...", | ||
2079 | mp_ioapics[apic].mp_apicid); | ||
2080 | |||
2081 | reg_00.bits.ID = mp_ioapics[apic].mp_apicid; | ||
2082 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2083 | |||
2084 | /* | ||
2085 | * Sanity check | ||
2086 | */ | ||
2087 | spin_lock_irqsave(&ioapic_lock, flags); | ||
2088 | reg_00.raw = io_apic_read(apic, 0); | ||
2089 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
2090 | if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid) | ||
2091 | printk("could not set ID!\n"); | ||
2092 | else | ||
2093 | apic_printk(APIC_VERBOSE, " ok.\n"); | ||
2094 | } | ||
2095 | } | ||
2096 | #endif | ||
2097 | |||
1698 | int no_timer_check __initdata; | 2098 | int no_timer_check __initdata; |
1699 | 2099 | ||
1700 | static int __init notimercheck(char *s) | 2100 | static int __init notimercheck(char *s) |
@@ -1780,8 +2180,10 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
1780 | return was_pending; | 2180 | return was_pending; |
1781 | } | 2181 | } |
1782 | 2182 | ||
2183 | #ifdef CONFIG_X86_64 | ||
1783 | static int ioapic_retrigger_irq(unsigned int irq) | 2184 | static int ioapic_retrigger_irq(unsigned int irq) |
1784 | { | 2185 | { |
2186 | |||
1785 | struct irq_cfg *cfg = irq_cfg(irq); | 2187 | struct irq_cfg *cfg = irq_cfg(irq); |
1786 | unsigned long flags; | 2188 | unsigned long flags; |
1787 | 2189 | ||
@@ -1791,6 +2193,14 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
1791 | 2193 | ||
1792 | return 1; | 2194 | return 1; |
1793 | } | 2195 | } |
2196 | #else | ||
2197 | static int ioapic_retrigger_irq(unsigned int irq) | ||
2198 | { | ||
2199 | send_IPI_self(irq_cfg(irq)->vector); | ||
2200 | |||
2201 | return 1; | ||
2202 | } | ||
2203 | #endif | ||
1794 | 2204 | ||
1795 | /* | 2205 | /* |
1796 | * Level and edge triggered IO-APIC interrupts need different handling, | 2206 | * Level and edge triggered IO-APIC interrupts need different handling, |
@@ -1952,7 +2362,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) | |||
1952 | { | 2362 | { |
1953 | unsigned vector, me; | 2363 | unsigned vector, me; |
1954 | ack_APIC_irq(); | 2364 | ack_APIC_irq(); |
2365 | #ifdef CONFIG_X86_64 | ||
1955 | exit_idle(); | 2366 | exit_idle(); |
2367 | #endif | ||
1956 | irq_enter(); | 2368 | irq_enter(); |
1957 | 2369 | ||
1958 | me = smp_processor_id(); | 2370 | me = smp_processor_id(); |
@@ -2024,6 +2436,7 @@ static void ack_apic_edge(unsigned int irq) | |||
2024 | ack_APIC_irq(); | 2436 | ack_APIC_irq(); |
2025 | } | 2437 | } |
2026 | 2438 | ||
2439 | #ifdef CONFIG_X86_64 | ||
2027 | static void ack_apic_level(unsigned int irq) | 2440 | static void ack_apic_level(unsigned int irq) |
2028 | { | 2441 | { |
2029 | int do_unmask_irq = 0; | 2442 | int do_unmask_irq = 0; |
@@ -2076,6 +2489,49 @@ static void ack_apic_level(unsigned int irq) | |||
2076 | unmask_IO_APIC_irq(irq); | 2489 | unmask_IO_APIC_irq(irq); |
2077 | } | 2490 | } |
2078 | } | 2491 | } |
2492 | #else | ||
2493 | atomic_t irq_mis_count; | ||
2494 | static void ack_apic_level(unsigned int irq) | ||
2495 | { | ||
2496 | unsigned long v; | ||
2497 | int i; | ||
2498 | |||
2499 | irq_complete_move(irq); | ||
2500 | move_native_irq(irq); | ||
2501 | /* | ||
2502 | * It appears there is an erratum which affects at least version 0x11 | ||
2503 | * of I/O APIC (that's the 82093AA and cores integrated into various | ||
2504 | * chipsets). Under certain conditions a level-triggered interrupt is | ||
2505 | * erroneously delivered as edge-triggered one but the respective IRR | ||
2506 | * bit gets set nevertheless. As a result the I/O unit expects an EOI | ||
2507 | * message but it will never arrive and further interrupts are blocked | ||
2508 | * from the source. The exact reason is so far unknown, but the | ||
2509 | * phenomenon was observed when two consecutive interrupt requests | ||
2510 | * from a given source get delivered to the same CPU and the source is | ||
2511 | * temporarily disabled in between. | ||
2512 | * | ||
2513 | * A workaround is to simulate an EOI message manually. We achieve it | ||
2514 | * by setting the trigger mode to edge and then to level when the edge | ||
2515 | * trigger mode gets detected in the TMR of a local APIC for a | ||
2516 | * level-triggered interrupt. We mask the source for the time of the | ||
2517 | * operation to prevent an edge-triggered interrupt escaping meanwhile. | ||
2518 | * The idea is from Manfred Spraul. --macro | ||
2519 | */ | ||
2520 | i = irq_cfg(irq)->vector; | ||
2521 | |||
2522 | v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); | ||
2523 | |||
2524 | ack_APIC_irq(); | ||
2525 | |||
2526 | if (!(v & (1 << (i & 0x1f)))) { | ||
2527 | atomic_inc(&irq_mis_count); | ||
2528 | spin_lock(&ioapic_lock); | ||
2529 | __mask_and_edge_IO_APIC_irq(irq); | ||
2530 | __unmask_and_level_IO_APIC_irq(irq); | ||
2531 | spin_unlock(&ioapic_lock); | ||
2532 | } | ||
2533 | } | ||
2534 | #endif | ||
2079 | 2535 | ||
2080 | static struct irq_chip ioapic_chip __read_mostly = { | 2536 | static struct irq_chip ioapic_chip __read_mostly = { |
2081 | .name = "IO-APIC", | 2537 | .name = "IO-APIC", |
@@ -2141,20 +2597,24 @@ static inline void init_IO_APIC_traps(void) | |||
2141 | } | 2597 | } |
2142 | } | 2598 | } |
2143 | 2599 | ||
2144 | static void unmask_lapic_irq(unsigned int irq) | 2600 | /* |
2601 | * The local APIC irq-chip implementation: | ||
2602 | */ | ||
2603 | |||
2604 | static void mask_lapic_irq(unsigned int irq) | ||
2145 | { | 2605 | { |
2146 | unsigned long v; | 2606 | unsigned long v; |
2147 | 2607 | ||
2148 | v = apic_read(APIC_LVT0); | 2608 | v = apic_read(APIC_LVT0); |
2149 | apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); | 2609 | apic_write(APIC_LVT0, v | APIC_LVT_MASKED); |
2150 | } | 2610 | } |
2151 | 2611 | ||
2152 | static void mask_lapic_irq(unsigned int irq) | 2612 | static void unmask_lapic_irq(unsigned int irq) |
2153 | { | 2613 | { |
2154 | unsigned long v; | 2614 | unsigned long v; |
2155 | 2615 | ||
2156 | v = apic_read(APIC_LVT0); | 2616 | v = apic_read(APIC_LVT0); |
2157 | apic_write(APIC_LVT0, v | APIC_LVT_MASKED); | 2617 | apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); |
2158 | } | 2618 | } |
2159 | 2619 | ||
2160 | static void ack_lapic_irq (unsigned int irq) | 2620 | static void ack_lapic_irq (unsigned int irq) |
@@ -2182,19 +2642,19 @@ static void lapic_register_intr(int irq) | |||
2182 | static void __init setup_nmi(void) | 2642 | static void __init setup_nmi(void) |
2183 | { | 2643 | { |
2184 | /* | 2644 | /* |
2185 | * Dirty trick to enable the NMI watchdog ... | 2645 | * Dirty trick to enable the NMI watchdog ... |
2186 | * We put the 8259A master into AEOI mode and | 2646 | * We put the 8259A master into AEOI mode and |
2187 | * unmask on all local APICs LVT0 as NMI. | 2647 | * unmask on all local APICs LVT0 as NMI. |
2188 | * | 2648 | * |
2189 | * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') | 2649 | * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire') |
2190 | * is from Maciej W. Rozycki - so we do not have to EOI from | 2650 | * is from Maciej W. Rozycki - so we do not have to EOI from |
2191 | * the NMI handler or the timer interrupt. | 2651 | * the NMI handler or the timer interrupt. |
2192 | */ | 2652 | */ |
2193 | printk(KERN_INFO "activating NMI Watchdog ..."); | 2653 | apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); |
2194 | 2654 | ||
2195 | enable_NMI_through_LVT0(); | 2655 | enable_NMI_through_LVT0(); |
2196 | 2656 | ||
2197 | printk(" done.\n"); | 2657 | apic_printk(APIC_VERBOSE, " done.\n"); |
2198 | } | 2658 | } |
2199 | 2659 | ||
2200 | /* | 2660 | /* |
@@ -2211,12 +2671,17 @@ static inline void __init unlock_ExtINT_logic(void) | |||
2211 | unsigned char save_control, save_freq_select; | 2671 | unsigned char save_control, save_freq_select; |
2212 | 2672 | ||
2213 | pin = find_isa_irq_pin(8, mp_INT); | 2673 | pin = find_isa_irq_pin(8, mp_INT); |
2674 | if (pin == -1) { | ||
2675 | WARN_ON_ONCE(1); | ||
2676 | return; | ||
2677 | } | ||
2214 | apic = find_isa_irq_apic(8, mp_INT); | 2678 | apic = find_isa_irq_apic(8, mp_INT); |
2215 | if (pin == -1) | 2679 | if (apic == -1) { |
2680 | WARN_ON_ONCE(1); | ||
2216 | return; | 2681 | return; |
2682 | } | ||
2217 | 2683 | ||
2218 | entry0 = ioapic_read_entry(apic, pin); | 2684 | entry0 = ioapic_read_entry(apic, pin); |
2219 | |||
2220 | clear_IO_APIC_pin(apic, pin); | 2685 | clear_IO_APIC_pin(apic, pin); |
2221 | 2686 | ||
2222 | memset(&entry1, 0, sizeof(entry1)); | 2687 | memset(&entry1, 0, sizeof(entry1)); |
@@ -2268,17 +2733,21 @@ int timer_through_8259 __initdata; | |||
2268 | * is so screwy. Thanks to Brian Perkins for testing/hacking this beast | 2733 | * is so screwy. Thanks to Brian Perkins for testing/hacking this beast |
2269 | * fanatically on his truly buggy board. | 2734 | * fanatically on his truly buggy board. |
2270 | * | 2735 | * |
2271 | * FIXME: really need to revamp this for modern platforms only. | 2736 | * FIXME: really need to revamp this for all platforms. |
2272 | */ | 2737 | */ |
2273 | static inline void __init check_timer(void) | 2738 | static inline void __init check_timer(void) |
2274 | { | 2739 | { |
2275 | struct irq_cfg *cfg = irq_cfg(0); | 2740 | struct irq_cfg *cfg = irq_cfg(0); |
2276 | int apic1, pin1, apic2, pin2; | 2741 | int apic1, pin1, apic2, pin2; |
2277 | unsigned long flags; | 2742 | unsigned long flags; |
2743 | unsigned int ver; | ||
2278 | int no_pin1 = 0; | 2744 | int no_pin1 = 0; |
2279 | 2745 | ||
2280 | local_irq_save(flags); | 2746 | local_irq_save(flags); |
2281 | 2747 | ||
2748 | ver = apic_read(APIC_LVR); | ||
2749 | ver = GET_APIC_VERSION(ver); | ||
2750 | |||
2282 | /* | 2751 | /* |
2283 | * get/set the timer IRQ vector: | 2752 | * get/set the timer IRQ vector: |
2284 | */ | 2753 | */ |
@@ -2287,10 +2756,18 @@ static inline void __init check_timer(void) | |||
2287 | 2756 | ||
2288 | /* | 2757 | /* |
2289 | * As IRQ0 is to be enabled in the 8259A, the virtual | 2758 | * As IRQ0 is to be enabled in the 8259A, the virtual |
2290 | * wire has to be disabled in the local APIC. | 2759 | * wire has to be disabled in the local APIC. Also |
2760 | * timer interrupts need to be acknowledged manually in | ||
2761 | * the 8259A for the i82489DX when using the NMI | ||
2762 | * watchdog as that APIC treats NMIs as level-triggered. | ||
2763 | * The AEOI mode will finish them in the 8259A | ||
2764 | * automatically. | ||
2291 | */ | 2765 | */ |
2292 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); | 2766 | apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); |
2293 | init_8259A(1); | 2767 | init_8259A(1); |
2768 | #ifdef CONFIG_X86_32 | ||
2769 | timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); | ||
2770 | #endif | ||
2294 | 2771 | ||
2295 | pin1 = find_isa_irq_pin(0, mp_INT); | 2772 | pin1 = find_isa_irq_pin(0, mp_INT); |
2296 | apic1 = find_isa_irq_apic(0, mp_INT); | 2773 | apic1 = find_isa_irq_apic(0, mp_INT); |
@@ -2382,6 +2859,9 @@ static inline void __init check_timer(void) | |||
2382 | "through the IO-APIC - disabling NMI Watchdog!\n"); | 2859 | "through the IO-APIC - disabling NMI Watchdog!\n"); |
2383 | nmi_watchdog = NMI_NONE; | 2860 | nmi_watchdog = NMI_NONE; |
2384 | } | 2861 | } |
2862 | #ifdef CONFIG_X86_32 | ||
2863 | timer_ack = 0; | ||
2864 | #endif | ||
2385 | 2865 | ||
2386 | apic_printk(APIC_QUIET, KERN_INFO | 2866 | apic_printk(APIC_QUIET, KERN_INFO |
2387 | "...trying to set up timer as Virtual Wire IRQ...\n"); | 2867 | "...trying to set up timer as Virtual Wire IRQ...\n"); |
@@ -2435,19 +2915,29 @@ out: | |||
2435 | * the I/O APIC in all cases now. No actual device should request | 2915 | * the I/O APIC in all cases now. No actual device should request |
2436 | * it anyway. --macro | 2916 | * it anyway. --macro |
2437 | */ | 2917 | */ |
2438 | #define PIC_IRQS (1<<2) | 2918 | #define PIC_IRQS (1 << PIC_CASCADE_IR) |
2439 | 2919 | ||
2440 | void __init setup_IO_APIC(void) | 2920 | void __init setup_IO_APIC(void) |
2441 | { | 2921 | { |
2442 | 2922 | ||
2923 | #ifdef CONFIG_X86_32 | ||
2924 | enable_IO_APIC(); | ||
2925 | #else | ||
2443 | /* | 2926 | /* |
2444 | * calling enable_IO_APIC() is moved to setup_local_APIC for BP | 2927 | * calling enable_IO_APIC() is moved to setup_local_APIC for BP |
2445 | */ | 2928 | */ |
2929 | #endif | ||
2446 | 2930 | ||
2447 | io_apic_irqs = ~PIC_IRQS; | 2931 | io_apic_irqs = ~PIC_IRQS; |
2448 | 2932 | ||
2449 | apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); | 2933 | apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); |
2450 | 2934 | /* | |
2935 | * Set up IO-APIC IRQ routing. | ||
2936 | */ | ||
2937 | #ifdef CONFIG_X86_32 | ||
2938 | if (!acpi_ioapic) | ||
2939 | setup_ioapic_ids_from_mpc(); | ||
2940 | #endif | ||
2451 | sync_Arb_IDs(); | 2941 | sync_Arb_IDs(); |
2452 | setup_IO_APIC_irqs(); | 2942 | setup_IO_APIC_irqs(); |
2453 | init_IO_APIC_traps(); | 2943 | init_IO_APIC_traps(); |
@@ -3128,7 +3618,93 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
3128 | 3618 | ||
3129 | #ifdef CONFIG_ACPI | 3619 | #ifdef CONFIG_ACPI |
3130 | 3620 | ||
3131 | #define IO_APIC_MAX_ID 0xFE | 3621 | #ifdef CONFIG_X86_32 |
3622 | int __init io_apic_get_unique_id(int ioapic, int apic_id) | ||
3623 | { | ||
3624 | union IO_APIC_reg_00 reg_00; | ||
3625 | static physid_mask_t apic_id_map = PHYSID_MASK_NONE; | ||
3626 | physid_mask_t tmp; | ||
3627 | unsigned long flags; | ||
3628 | int i = 0; | ||
3629 | |||
3630 | /* | ||
3631 | * The P4 platform supports up to 256 APIC IDs on two separate APIC | ||
3632 | * buses (one for LAPICs, one for IOAPICs), where predecessors only | ||
3633 | * supports up to 16 on one shared APIC bus. | ||
3634 | * | ||
3635 | * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full | ||
3636 | * advantage of new APIC bus architecture. | ||
3637 | */ | ||
3638 | |||
3639 | if (physids_empty(apic_id_map)) | ||
3640 | apic_id_map = ioapic_phys_id_map(phys_cpu_present_map); | ||
3641 | |||
3642 | spin_lock_irqsave(&ioapic_lock, flags); | ||
3643 | reg_00.raw = io_apic_read(ioapic, 0); | ||
3644 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
3645 | |||
3646 | if (apic_id >= get_physical_broadcast()) { | ||
3647 | printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " | ||
3648 | "%d\n", ioapic, apic_id, reg_00.bits.ID); | ||
3649 | apic_id = reg_00.bits.ID; | ||
3650 | } | ||
3651 | |||
3652 | /* | ||
3653 | * Every APIC in a system must have a unique ID or we get lots of nice | ||
3654 | * 'stuck on smp_invalidate_needed IPI wait' messages. | ||
3655 | */ | ||
3656 | if (check_apicid_used(apic_id_map, apic_id)) { | ||
3657 | |||
3658 | for (i = 0; i < get_physical_broadcast(); i++) { | ||
3659 | if (!check_apicid_used(apic_id_map, i)) | ||
3660 | break; | ||
3661 | } | ||
3662 | |||
3663 | if (i == get_physical_broadcast()) | ||
3664 | panic("Max apic_id exceeded!\n"); | ||
3665 | |||
3666 | printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " | ||
3667 | "trying %d\n", ioapic, apic_id, i); | ||
3668 | |||
3669 | apic_id = i; | ||
3670 | } | ||
3671 | |||
3672 | tmp = apicid_to_cpu_present(apic_id); | ||
3673 | physids_or(apic_id_map, apic_id_map, tmp); | ||
3674 | |||
3675 | if (reg_00.bits.ID != apic_id) { | ||
3676 | reg_00.bits.ID = apic_id; | ||
3677 | |||
3678 | spin_lock_irqsave(&ioapic_lock, flags); | ||
3679 | io_apic_write(ioapic, 0, reg_00.raw); | ||
3680 | reg_00.raw = io_apic_read(ioapic, 0); | ||
3681 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
3682 | |||
3683 | /* Sanity check */ | ||
3684 | if (reg_00.bits.ID != apic_id) { | ||
3685 | printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic); | ||
3686 | return -1; | ||
3687 | } | ||
3688 | } | ||
3689 | |||
3690 | apic_printk(APIC_VERBOSE, KERN_INFO | ||
3691 | "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); | ||
3692 | |||
3693 | return apic_id; | ||
3694 | } | ||
3695 | |||
3696 | int __init io_apic_get_version(int ioapic) | ||
3697 | { | ||
3698 | union IO_APIC_reg_01 reg_01; | ||
3699 | unsigned long flags; | ||
3700 | |||
3701 | spin_lock_irqsave(&ioapic_lock, flags); | ||
3702 | reg_01.raw = io_apic_read(ioapic, 1); | ||
3703 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
3704 | |||
3705 | return reg_01.bits.version; | ||
3706 | } | ||
3707 | #endif | ||
3132 | 3708 | ||
3133 | int __init io_apic_get_redir_entries (int ioapic) | 3709 | int __init io_apic_get_redir_entries (int ioapic) |
3134 | { | 3710 | { |
@@ -3226,6 +3802,7 @@ void __init setup_ioapic_dest(void) | |||
3226 | } | 3802 | } |
3227 | #endif | 3803 | #endif |
3228 | 3804 | ||
3805 | #ifdef CONFIG_X86_64 | ||
3229 | #define IOAPIC_RESOURCE_NAME_SIZE 11 | 3806 | #define IOAPIC_RESOURCE_NAME_SIZE 11 |
3230 | 3807 | ||
3231 | static struct resource *ioapic_resources; | 3808 | static struct resource *ioapic_resources; |
@@ -3261,36 +3838,56 @@ static struct resource * __init ioapic_setup_resources(void) | |||
3261 | 3838 | ||
3262 | return res; | 3839 | return res; |
3263 | } | 3840 | } |
3841 | #endif | ||
3264 | 3842 | ||
3265 | void __init ioapic_init_mappings(void) | 3843 | void __init ioapic_init_mappings(void) |
3266 | { | 3844 | { |
3267 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; | 3845 | unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; |
3268 | struct resource *ioapic_res; | ||
3269 | int i; | 3846 | int i; |
3847 | #ifdef CONFIG_X86_64 | ||
3848 | struct resource *ioapic_res; | ||
3270 | 3849 | ||
3271 | ioapic_res = ioapic_setup_resources(); | 3850 | ioapic_res = ioapic_setup_resources(); |
3851 | #endif | ||
3272 | for (i = 0; i < nr_ioapics; i++) { | 3852 | for (i = 0; i < nr_ioapics; i++) { |
3273 | if (smp_found_config) { | 3853 | if (smp_found_config) { |
3274 | ioapic_phys = mp_ioapics[i].mp_apicaddr; | 3854 | ioapic_phys = mp_ioapics[i].mp_apicaddr; |
3855 | #ifdef CONFIG_X86_32 | ||
3856 | if (!ioapic_phys) { | ||
3857 | printk(KERN_ERR | ||
3858 | "WARNING: bogus zero IO-APIC " | ||
3859 | "address found in MPTABLE, " | ||
3860 | "disabling IO/APIC support!\n"); | ||
3861 | smp_found_config = 0; | ||
3862 | skip_ioapic_setup = 1; | ||
3863 | goto fake_ioapic_page; | ||
3864 | } | ||
3865 | #endif | ||
3275 | } else { | 3866 | } else { |
3867 | #ifdef CONFIG_X86_32 | ||
3868 | fake_ioapic_page: | ||
3869 | #endif | ||
3276 | ioapic_phys = (unsigned long) | 3870 | ioapic_phys = (unsigned long) |
3277 | alloc_bootmem_pages(PAGE_SIZE); | 3871 | alloc_bootmem_pages(PAGE_SIZE); |
3278 | ioapic_phys = __pa(ioapic_phys); | 3872 | ioapic_phys = __pa(ioapic_phys); |
3279 | } | 3873 | } |
3280 | set_fixmap_nocache(idx, ioapic_phys); | 3874 | set_fixmap_nocache(idx, ioapic_phys); |
3281 | apic_printk(APIC_VERBOSE, | 3875 | apic_printk(APIC_VERBOSE, |
3282 | "mapped IOAPIC to %016lx (%016lx)\n", | 3876 | "mapped IOAPIC to %08lx (%08lx)\n", |
3283 | __fix_to_virt(idx), ioapic_phys); | 3877 | __fix_to_virt(idx), ioapic_phys); |
3284 | idx++; | 3878 | idx++; |
3285 | 3879 | ||
3880 | #ifdef CONFIG_X86_64 | ||
3286 | if (ioapic_res != NULL) { | 3881 | if (ioapic_res != NULL) { |
3287 | ioapic_res->start = ioapic_phys; | 3882 | ioapic_res->start = ioapic_phys; |
3288 | ioapic_res->end = ioapic_phys + (4 * 1024) - 1; | 3883 | ioapic_res->end = ioapic_phys + (4 * 1024) - 1; |
3289 | ioapic_res++; | 3884 | ioapic_res++; |
3290 | } | 3885 | } |
3886 | #endif | ||
3291 | } | 3887 | } |
3292 | } | 3888 | } |
3293 | 3889 | ||
3890 | #ifdef CONFIG_X86_64 | ||
3294 | static int __init ioapic_insert_resources(void) | 3891 | static int __init ioapic_insert_resources(void) |
3295 | { | 3892 | { |
3296 | int i; | 3893 | int i; |
@@ -3313,4 +3910,4 @@ static int __init ioapic_insert_resources(void) | |||
3313 | /* Insert the IO APIC resources after PCI initialization has occured to handle | 3910 | /* Insert the IO APIC resources after PCI initialization has occured to handle |
3314 | * IO APICS that are mapped in on a BAR in PCI space. */ | 3911 | * IO APICS that are mapped in on a BAR in PCI space. */ |
3315 | late_initcall(ioapic_insert_resources); | 3912 | late_initcall(ioapic_insert_resources); |
3316 | 3913 | #endif | |