aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/io_apic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/io_apic.c')
-rw-r--r--arch/x86_64/kernel/io_apic.c258
1 files changed, 138 insertions, 120 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index c80081a6ba41..2a1dcd5f69c2 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -55,10 +55,6 @@ int sis_apic_bug; /* not actually supported, dummy for compile */
55 55
56static int no_timer_check; 56static int no_timer_check;
57 57
58static int disable_timer_pin_1 __initdata;
59
60int timer_over_8254 __initdata = 1;
61
62/* Where if anywhere is the i8259 connect in external int mode */ 58/* Where if anywhere is the i8259 connect in external int mode */
63static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; 59static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
64 60
@@ -178,14 +174,20 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
178 * the interrupt, and we need to make sure the entry is fully populated 174 * the interrupt, and we need to make sure the entry is fully populated
179 * before that happens. 175 * before that happens.
180 */ 176 */
181static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) 177static void
178__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
182{ 179{
183 unsigned long flags;
184 union entry_union eu; 180 union entry_union eu;
185 eu.entry = e; 181 eu.entry = e;
186 spin_lock_irqsave(&ioapic_lock, flags);
187 io_apic_write(apic, 0x11 + 2*pin, eu.w2); 182 io_apic_write(apic, 0x11 + 2*pin, eu.w2);
188 io_apic_write(apic, 0x10 + 2*pin, eu.w1); 183 io_apic_write(apic, 0x10 + 2*pin, eu.w1);
184}
185
186static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
187{
188 unsigned long flags;
189 spin_lock_irqsave(&ioapic_lock, flags);
190 __ioapic_write_entry(apic, pin, e);
189 spin_unlock_irqrestore(&ioapic_lock, flags); 191 spin_unlock_irqrestore(&ioapic_lock, flags);
190} 192}
191 193
@@ -348,29 +350,6 @@ static int __init disable_ioapic_setup(char *str)
348} 350}
349early_param("noapic", disable_ioapic_setup); 351early_param("noapic", disable_ioapic_setup);
350 352
351/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
352static int __init disable_timer_pin_setup(char *arg)
353{
354 disable_timer_pin_1 = 1;
355 return 1;
356}
357__setup("disable_timer_pin_1", disable_timer_pin_setup);
358
359static int __init setup_disable_8254_timer(char *s)
360{
361 timer_over_8254 = -1;
362 return 1;
363}
364static int __init setup_enable_8254_timer(char *s)
365{
366 timer_over_8254 = 2;
367 return 1;
368}
369
370__setup("disable_8254_timer", setup_disable_8254_timer);
371__setup("enable_8254_timer", setup_enable_8254_timer);
372
373
374/* 353/*
375 * Find the IRQ entry number of a certain pin. 354 * Find the IRQ entry number of a certain pin.
376 */ 355 */
@@ -750,6 +729,22 @@ static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
750 return vector; 729 return vector;
751} 730}
752 731
732static void __clear_irq_vector(int irq)
733{
734 cpumask_t mask;
735 int cpu, vector;
736
737 BUG_ON(!irq_vector[irq]);
738
739 vector = irq_vector[irq];
740 cpus_and(mask, irq_domain[irq], cpu_online_map);
741 for_each_cpu_mask(cpu, mask)
742 per_cpu(vector_irq, cpu)[vector] = -1;
743
744 irq_vector[irq] = 0;
745 irq_domain[irq] = CPU_MASK_NONE;
746}
747
753void __setup_vector_irq(int cpu) 748void __setup_vector_irq(int cpu)
754{ 749{
755 /* Initialize vector_irq on a new cpu */ 750 /* Initialize vector_irq on a new cpu */
@@ -794,27 +789,65 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
794 handle_edge_irq, "edge"); 789 handle_edge_irq, "edge");
795 } 790 }
796} 791}
797 792static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq)
798static void __init setup_IO_APIC_irqs(void)
799{ 793{
800 struct IO_APIC_route_entry entry; 794 struct IO_APIC_route_entry entry;
801 int apic, pin, idx, irq, first_notcon = 1, vector; 795 int vector;
802 unsigned long flags; 796 unsigned long flags;
803 797
804 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
805 798
806 for (apic = 0; apic < nr_ioapics; apic++) { 799 /*
807 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 800 * add it to the IO-APIC irq-routing table:
801 */
802 memset(&entry,0,sizeof(entry));
808 803
809 /* 804 entry.delivery_mode = INT_DELIVERY_MODE;
810 * add it to the IO-APIC irq-routing table: 805 entry.dest_mode = INT_DEST_MODE;
811 */ 806 entry.mask = 0; /* enable IRQ */
812 memset(&entry,0,sizeof(entry)); 807 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
808
809 entry.trigger = irq_trigger(idx);
810 entry.polarity = irq_polarity(idx);
813 811
814 entry.delivery_mode = INT_DELIVERY_MODE; 812 if (irq_trigger(idx)) {
815 entry.dest_mode = INT_DEST_MODE; 813 entry.trigger = 1;
816 entry.mask = 0; /* enable IRQ */ 814 entry.mask = 1;
817 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); 815 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
816 }
817
818 if (!apic && !IO_APIC_IRQ(irq))
819 return;
820
821 if (IO_APIC_IRQ(irq)) {
822 cpumask_t mask;
823 vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
824 if (vector < 0)
825 return;
826
827 entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
828 entry.vector = vector;
829
830 ioapic_register_intr(irq, vector, IOAPIC_AUTO);
831 if (!apic && (irq < 16))
832 disable_8259A_irq(irq);
833 }
834
835 ioapic_write_entry(apic, pin, entry);
836
837 spin_lock_irqsave(&ioapic_lock, flags);
838 set_native_irq_info(irq, TARGET_CPUS);
839 spin_unlock_irqrestore(&ioapic_lock, flags);
840
841}
842
843static void __init setup_IO_APIC_irqs(void)
844{
845 int apic, pin, idx, irq, first_notcon = 1;
846
847 apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
848
849 for (apic = 0; apic < nr_ioapics; apic++) {
850 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
818 851
819 idx = find_irq_entry(apic,pin,mp_INT); 852 idx = find_irq_entry(apic,pin,mp_INT);
820 if (idx == -1) { 853 if (idx == -1) {
@@ -826,39 +859,11 @@ static void __init setup_IO_APIC_irqs(void)
826 continue; 859 continue;
827 } 860 }
828 861
829 entry.trigger = irq_trigger(idx);
830 entry.polarity = irq_polarity(idx);
831
832 if (irq_trigger(idx)) {
833 entry.trigger = 1;
834 entry.mask = 1;
835 entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
836 }
837
838 irq = pin_2_irq(idx, apic, pin); 862 irq = pin_2_irq(idx, apic, pin);
839 add_pin_to_irq(irq, apic, pin); 863 add_pin_to_irq(irq, apic, pin);
840 864
841 if (!apic && !IO_APIC_IRQ(irq)) 865 setup_IO_APIC_irq(apic, pin, idx, irq);
842 continue;
843
844 if (IO_APIC_IRQ(irq)) {
845 cpumask_t mask;
846 vector = assign_irq_vector(irq, TARGET_CPUS, &mask);
847 if (vector < 0)
848 continue;
849
850 entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask);
851 entry.vector = vector;
852
853 ioapic_register_intr(irq, vector, IOAPIC_AUTO);
854 if (!apic && (irq < 16))
855 disable_8259A_irq(irq);
856 }
857 ioapic_write_entry(apic, pin, entry);
858 866
859 spin_lock_irqsave(&ioapic_lock, flags);
860 set_native_irq_info(irq, TARGET_CPUS);
861 spin_unlock_irqrestore(&ioapic_lock, flags);
862 } 867 }
863 } 868 }
864 869
@@ -1563,10 +1568,33 @@ static inline void unlock_ExtINT_logic(void)
1563 * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ 1568 * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ
1564 * is so screwy. Thanks to Brian Perkins for testing/hacking this beast 1569 * is so screwy. Thanks to Brian Perkins for testing/hacking this beast
1565 * fanatically on his truly buggy board. 1570 * fanatically on his truly buggy board.
1566 *
1567 * FIXME: really need to revamp this for modern platforms only.
1568 */ 1571 */
1569static inline void check_timer(void) 1572
1573static int try_apic_pin(int apic, int pin, char *msg)
1574{
1575 apic_printk(APIC_VERBOSE, KERN_INFO
1576 "..TIMER: trying IO-APIC=%d PIN=%d %s",
1577 apic, pin, msg);
1578
1579 /*
1580 * Ok, does IRQ0 through the IOAPIC work?
1581 */
1582 if (!no_timer_check && timer_irq_works()) {
1583 nmi_watchdog_default();
1584 if (nmi_watchdog == NMI_IO_APIC) {
1585 disable_8259A_irq(0);
1586 setup_nmi();
1587 enable_8259A_irq(0);
1588 }
1589 return 1;
1590 }
1591 clear_IO_APIC_pin(apic, pin);
1592 apic_printk(APIC_QUIET, KERN_ERR " .. failed\n");
1593 return 0;
1594}
1595
1596/* The function from hell */
1597static void check_timer(void)
1570{ 1598{
1571 int apic1, pin1, apic2, pin2; 1599 int apic1, pin1, apic2, pin2;
1572 int vector; 1600 int vector;
@@ -1587,61 +1615,43 @@ static inline void check_timer(void)
1587 */ 1615 */
1588 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); 1616 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
1589 init_8259A(1); 1617 init_8259A(1);
1590 if (timer_over_8254 > 0)
1591 enable_8259A_irq(0);
1592 1618
1593 pin1 = find_isa_irq_pin(0, mp_INT); 1619 pin1 = find_isa_irq_pin(0, mp_INT);
1594 apic1 = find_isa_irq_apic(0, mp_INT); 1620 apic1 = find_isa_irq_apic(0, mp_INT);
1595 pin2 = ioapic_i8259.pin; 1621 pin2 = ioapic_i8259.pin;
1596 apic2 = ioapic_i8259.apic; 1622 apic2 = ioapic_i8259.apic;
1597 1623
1598 apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", 1624 /* Do this first, otherwise we get double interrupts on ATI boards */
1599 vector, apic1, pin1, apic2, pin2); 1625 if ((pin1 != -1) && try_apic_pin(apic1, pin1,"with 8259 IRQ0 disabled"))
1626 return;
1600 1627
1601 if (pin1 != -1) { 1628 /* Now try again with IRQ0 8259A enabled.
1602 /* 1629 Assumes timer is on IO-APIC 0 ?!? */
1603 * Ok, does IRQ0 through the IOAPIC work? 1630 enable_8259A_irq(0);
1604 */ 1631 unmask_IO_APIC_irq(0);
1605 unmask_IO_APIC_irq(0); 1632 if (try_apic_pin(apic1, pin1, "with 8259 IRQ0 enabled"))
1606 if (!no_timer_check && timer_irq_works()) { 1633 return;
1607 nmi_watchdog_default(); 1634 disable_8259A_irq(0);
1608 if (nmi_watchdog == NMI_IO_APIC) { 1635
1609 disable_8259A_irq(0); 1636 /* Always try pin0 and pin2 on APIC 0 to handle buggy timer overrides
1610 setup_nmi(); 1637 on Nvidia boards */
1611 enable_8259A_irq(0); 1638 if (!(apic1 == 0 && pin1 == 0) &&
1612 } 1639 try_apic_pin(0, 0, "fallback with 8259 IRQ0 disabled"))
1613 if (disable_timer_pin_1 > 0) 1640 return;
1614 clear_IO_APIC_pin(0, pin1); 1641 if (!(apic1 == 0 && pin1 == 2) &&
1615 return; 1642 try_apic_pin(0, 2, "fallback with 8259 IRQ0 disabled"))
1616 } 1643 return;
1617 clear_IO_APIC_pin(apic1, pin1);
1618 apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: 8254 timer not "
1619 "connected to IO-APIC\n");
1620 }
1621 1644
1622 apic_printk(APIC_VERBOSE,KERN_INFO "...trying to set up timer (IRQ0) " 1645 /* Then try pure 8259A routing on the 8259 as reported by BIOS*/
1623 "through the 8259A ... "); 1646 enable_8259A_irq(0);
1624 if (pin2 != -1) { 1647 if (pin2 != -1) {
1625 apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...",
1626 apic2, pin2);
1627 /*
1628 * legacy devices should be connected to IO APIC #0
1629 */
1630 setup_ExtINT_IRQ0_pin(apic2, pin2, vector); 1648 setup_ExtINT_IRQ0_pin(apic2, pin2, vector);
1631 if (timer_irq_works()) { 1649 if (try_apic_pin(apic2,pin2,"8259A broadcast ExtINT from BIOS"))
1632 apic_printk(APIC_VERBOSE," works.\n");
1633 nmi_watchdog_default();
1634 if (nmi_watchdog == NMI_IO_APIC) {
1635 setup_nmi();
1636 }
1637 return; 1650 return;
1638 }
1639 /*
1640 * Cleanup, just in case ...
1641 */
1642 clear_IO_APIC_pin(apic2, pin2);
1643 } 1651 }
1644 apic_printk(APIC_VERBOSE," failed.\n"); 1652
1653 /* Tried all possibilities to go through the IO-APIC. Now come the
1654 really cheesy fallbacks. */
1645 1655
1646 if (nmi_watchdog == NMI_IO_APIC) { 1656 if (nmi_watchdog == NMI_IO_APIC) {
1647 printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); 1657 printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n");
@@ -1837,7 +1847,7 @@ void destroy_irq(unsigned int irq)
1837 dynamic_irq_cleanup(irq); 1847 dynamic_irq_cleanup(irq);
1838 1848
1839 spin_lock_irqsave(&vector_lock, flags); 1849 spin_lock_irqsave(&vector_lock, flags);
1840 irq_vector[irq] = 0; 1850 __clear_irq_vector(irq);
1841 spin_unlock_irqrestore(&vector_lock, flags); 1851 spin_unlock_irqrestore(&vector_lock, flags);
1842} 1852}
1843 1853
@@ -2139,7 +2149,15 @@ void __init setup_ioapic_dest(void)
2139 if (irq_entry == -1) 2149 if (irq_entry == -1)
2140 continue; 2150 continue;
2141 irq = pin_2_irq(irq_entry, ioapic, pin); 2151 irq = pin_2_irq(irq_entry, ioapic, pin);
2142 set_ioapic_affinity_irq(irq, TARGET_CPUS); 2152
2153 /* setup_IO_APIC_irqs could fail to get vector for some device
2154 * when you have too many devices, because at that time only boot
2155 * cpu is online.
2156 */
2157 if(!irq_vector[irq])
2158 setup_IO_APIC_irq(ioapic, pin, irq_entry, irq);
2159 else
2160 set_ioapic_affinity_irq(irq, TARGET_CPUS);
2143 } 2161 }
2144 2162
2145 } 2163 }