1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun======= 4*4882a593SmuzhiyunIO-APIC 5*4882a593Smuzhiyun======= 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun:Author: Ingo Molnar <mingo@kernel.org> 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunMost (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC', 10*4882a593Smuzhiyunwhich is an enhanced interrupt controller. It enables us to route 11*4882a593Smuzhiyunhardware interrupts to multiple CPUs, or to CPU groups. Without an 12*4882a593SmuzhiyunIO-APIC, interrupts from hardware will be delivered only to the 13*4882a593SmuzhiyunCPU which boots the operating system (usually CPU#0). 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunLinux supports all variants of compliant SMP boards, including ones with 16*4882a593Smuzhiyunmultiple IO-APICs. Multiple IO-APICs are used in high-end servers to 17*4882a593Smuzhiyundistribute IRQ load further. 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunThere are (a few) known breakages in certain older boards, such bugs are 20*4882a593Smuzhiyunusually worked around by the kernel. If your MP-compliant SMP board does 21*4882a593Smuzhiyunnot boot Linux, then consult the linux-smp mailing list archives first. 22*4882a593Smuzhiyun 23*4882a593SmuzhiyunIf your box boots fine with enabled IO-APIC IRQs, then your 24*4882a593Smuzhiyun/proc/interrupts will look like this one:: 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun hell:~> cat /proc/interrupts 27*4882a593Smuzhiyun CPU0 28*4882a593Smuzhiyun 0: 1360293 IO-APIC-edge timer 29*4882a593Smuzhiyun 1: 4 IO-APIC-edge keyboard 30*4882a593Smuzhiyun 2: 0 XT-PIC cascade 31*4882a593Smuzhiyun 13: 1 XT-PIC fpu 32*4882a593Smuzhiyun 14: 1448 IO-APIC-edge ide0 33*4882a593Smuzhiyun 16: 28232 IO-APIC-level Intel EtherExpress Pro 10/100 Ethernet 34*4882a593Smuzhiyun 17: 51304 IO-APIC-level eth0 35*4882a593Smuzhiyun NMI: 0 36*4882a593Smuzhiyun ERR: 0 37*4882a593Smuzhiyun hell:~> 38*4882a593Smuzhiyun 39*4882a593SmuzhiyunSome interrupts are still listed as 'XT PIC', but this is not a problem; 40*4882a593Smuzhiyunnone of those IRQ sources is performance-critical. 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun 43*4882a593SmuzhiyunIn the unlikely case that your board does not create a working mp-table, 44*4882a593Smuzhiyunyou can use the pirq= boot parameter to 'hand-construct' IRQ entries. This 45*4882a593Smuzhiyunis non-trivial though and cannot be automated. One sample /etc/lilo.conf 46*4882a593Smuzhiyunentry:: 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun append="pirq=15,11,10" 49*4882a593Smuzhiyun 50*4882a593SmuzhiyunThe actual numbers depend on your system, on your PCI cards and on their 51*4882a593SmuzhiyunPCI slot position. Usually PCI slots are 'daisy chained' before they are 52*4882a593Smuzhiyunconnected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4 53*4882a593Smuzhiyunlines):: 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun ,-. ,-. ,-. ,-. ,-. 56*4882a593Smuzhiyun PIRQ4 ----| |-. ,-| |-. ,-| |-. ,-| |--------| | 57*4882a593Smuzhiyun |S| \ / |S| \ / |S| \ / |S| |S| 58*4882a593Smuzhiyun PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l| 59*4882a593Smuzhiyun |o| \/ |o| \/ |o| \/ |o| |o| 60*4882a593Smuzhiyun PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t| 61*4882a593Smuzhiyun |1| /\ |2| /\ |3| /\ |4| |5| 62*4882a593Smuzhiyun PIRQ1 ----| |- `----| |- `----| |- `----| |--------| | 63*4882a593Smuzhiyun `-' `-' `-' `-' `-' 64*4882a593Smuzhiyun 65*4882a593SmuzhiyunEvery PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD:: 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun ,-. 68*4882a593Smuzhiyun INTD--| | 69*4882a593Smuzhiyun |S| 70*4882a593Smuzhiyun INTC--|l| 71*4882a593Smuzhiyun |o| 72*4882a593Smuzhiyun INTB--|t| 73*4882a593Smuzhiyun |x| 74*4882a593Smuzhiyun INTA--| | 75*4882a593Smuzhiyun `-' 76*4882a593Smuzhiyun 77*4882a593SmuzhiyunThese INTA-D PCI IRQs are always 'local to the card', their real meaning 78*4882a593Smuzhiyundepends on which slot they are in. If you look at the daisy chaining diagram, 79*4882a593Smuzhiyuna card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ4 of 80*4882a593Smuzhiyunthe PCI chipset. Most cards issue INTA, this creates optimal distribution 81*4882a593Smuzhiyunbetween the PIRQ lines. (distributing IRQ sources properly is not a 82*4882a593Smuzhiyunnecessity, PCI IRQs can be shared at will, but it's a good for performance 83*4882a593Smuzhiyunto have non shared interrupts). Slot5 should be used for videocards, they 84*4882a593Smuzhiyundo not use interrupts normally, thus they are not daisy chained either. 85*4882a593Smuzhiyun 86*4882a593Smuzhiyunso if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in 87*4882a593SmuzhiyunSlot2, then you'll have to specify this pirq= line:: 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun append="pirq=11,9" 90*4882a593Smuzhiyun 91*4882a593Smuzhiyunthe following script tries to figure out such a default pirq= line from 92*4882a593Smuzhiyunyour PCI configuration:: 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g' 95*4882a593Smuzhiyun 96*4882a593Smuzhiyunnote that this script won't work if you have skipped a few slots or if your 97*4882a593Smuzhiyunboard does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins 98*4882a593Smuzhiyunconnected in some strange way). E.g. if in the above case you have your SCSI 99*4882a593Smuzhiyuncard (IRQ11) in Slot3, and have Slot1 empty:: 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun append="pirq=0,9,11" 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting) 104*4882a593Smuzhiyunslots.] 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunGenerally, it's always possible to find out the correct pirq= settings, just 107*4882a593Smuzhiyunpermute all IRQ numbers properly ... it will take some time though. An 108*4882a593Smuzhiyun'incorrect' pirq line will cause the booting process to hang, or a device 109*4882a593Smuzhiyunwon't function properly (e.g. if it's inserted as a module). 110*4882a593Smuzhiyun 111*4882a593SmuzhiyunIf you have 2 PCI buses, then you can use up to 8 pirq values, although such 112*4882a593Smuzhiyunboards tend to have a good configuration. 113*4882a593Smuzhiyun 114*4882a593SmuzhiyunBe prepared that it might happen that you need some strange pirq line:: 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun append="pirq=0,0,0,0,0,0,9,11" 117*4882a593Smuzhiyun 118*4882a593SmuzhiyunUse smart trial-and-error techniques to find out the correct pirq line ... 119*4882a593Smuzhiyun 120*4882a593SmuzhiyunGood luck and mail to linux-smp@vger.kernel.org or 121*4882a593Smuzhiyunlinux-kernel@vger.kernel.org if you have any problems that are not covered 122*4882a593Smuzhiyunby this document. 123*4882a593Smuzhiyun 124