162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci======= 462306a36Sopenharmony_ciIO-APIC 562306a36Sopenharmony_ci======= 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci:Author: Ingo Molnar <mingo@kernel.org> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciMost (all) Intel-MP compliant SMP boards have the so-called 'IO-APIC', 1062306a36Sopenharmony_ciwhich is an enhanced interrupt controller. It enables us to route 1162306a36Sopenharmony_cihardware interrupts to multiple CPUs, or to CPU groups. Without an 1262306a36Sopenharmony_ciIO-APIC, interrupts from hardware will be delivered only to the 1362306a36Sopenharmony_ciCPU which boots the operating system (usually CPU#0). 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciLinux supports all variants of compliant SMP boards, including ones with 1662306a36Sopenharmony_cimultiple IO-APICs. Multiple IO-APICs are used in high-end servers to 1762306a36Sopenharmony_cidistribute IRQ load further. 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciThere are (a few) known breakages in certain older boards, such bugs are 2062306a36Sopenharmony_ciusually worked around by the kernel. If your MP-compliant SMP board does 2162306a36Sopenharmony_cinot boot Linux, then consult the linux-smp mailing list archives first. 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciIf your box boots fine with enabled IO-APIC IRQs, then your 2462306a36Sopenharmony_ci/proc/interrupts will look like this one:: 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci hell:~> cat /proc/interrupts 2762306a36Sopenharmony_ci CPU0 2862306a36Sopenharmony_ci 0: 1360293 IO-APIC-edge timer 2962306a36Sopenharmony_ci 1: 4 IO-APIC-edge keyboard 3062306a36Sopenharmony_ci 2: 0 XT-PIC cascade 3162306a36Sopenharmony_ci 13: 1 XT-PIC fpu 3262306a36Sopenharmony_ci 14: 1448 IO-APIC-edge ide0 3362306a36Sopenharmony_ci 16: 28232 IO-APIC-level Intel EtherExpress Pro 10/100 Ethernet 3462306a36Sopenharmony_ci 17: 51304 IO-APIC-level eth0 3562306a36Sopenharmony_ci NMI: 0 3662306a36Sopenharmony_ci ERR: 0 3762306a36Sopenharmony_ci hell:~> 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ciSome interrupts are still listed as 'XT PIC', but this is not a problem; 4062306a36Sopenharmony_cinone of those IRQ sources is performance-critical. 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciIn the unlikely case that your board does not create a working mp-table, 4462306a36Sopenharmony_ciyou can use the pirq= boot parameter to 'hand-construct' IRQ entries. This 4562306a36Sopenharmony_ciis non-trivial though and cannot be automated. One sample /etc/lilo.conf 4662306a36Sopenharmony_cientry:: 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci append="pirq=15,11,10" 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciThe actual numbers depend on your system, on your PCI cards and on their 5162306a36Sopenharmony_ciPCI slot position. Usually PCI slots are 'daisy chained' before they are 5262306a36Sopenharmony_ciconnected to the PCI chipset IRQ routing facility (the incoming PIRQ1-4 5362306a36Sopenharmony_cilines):: 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci ,-. ,-. ,-. ,-. ,-. 5662306a36Sopenharmony_ci PIRQ4 ----| |-. ,-| |-. ,-| |-. ,-| |--------| | 5762306a36Sopenharmony_ci |S| \ / |S| \ / |S| \ / |S| |S| 5862306a36Sopenharmony_ci PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l| 5962306a36Sopenharmony_ci |o| \/ |o| \/ |o| \/ |o| |o| 6062306a36Sopenharmony_ci PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t| 6162306a36Sopenharmony_ci |1| /\ |2| /\ |3| /\ |4| |5| 6262306a36Sopenharmony_ci PIRQ1 ----| |- `----| |- `----| |- `----| |--------| | 6362306a36Sopenharmony_ci `-' `-' `-' `-' `-' 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciEvery PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD:: 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci ,-. 6862306a36Sopenharmony_ci INTD--| | 6962306a36Sopenharmony_ci |S| 7062306a36Sopenharmony_ci INTC--|l| 7162306a36Sopenharmony_ci |o| 7262306a36Sopenharmony_ci INTB--|t| 7362306a36Sopenharmony_ci |x| 7462306a36Sopenharmony_ci INTA--| | 7562306a36Sopenharmony_ci `-' 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ciThese INTA-D PCI IRQs are always 'local to the card', their real meaning 7862306a36Sopenharmony_cidepends on which slot they are in. If you look at the daisy chaining diagram, 7962306a36Sopenharmony_cia card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ4 of 8062306a36Sopenharmony_cithe PCI chipset. Most cards issue INTA, this creates optimal distribution 8162306a36Sopenharmony_cibetween the PIRQ lines. (distributing IRQ sources properly is not a 8262306a36Sopenharmony_cinecessity, PCI IRQs can be shared at will, but it's a good for performance 8362306a36Sopenharmony_cito have non shared interrupts). Slot5 should be used for videocards, they 8462306a36Sopenharmony_cido not use interrupts normally, thus they are not daisy chained either. 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciso if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in 8762306a36Sopenharmony_ciSlot2, then you'll have to specify this pirq= line:: 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci append="pirq=11,9" 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cithe following script tries to figure out such a default pirq= line from 9262306a36Sopenharmony_ciyour PCI configuration:: 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g' 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cinote that this script won't work if you have skipped a few slots or if your 9762306a36Sopenharmony_ciboard does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins 9862306a36Sopenharmony_ciconnected in some strange way). E.g. if in the above case you have your SCSI 9962306a36Sopenharmony_cicard (IRQ11) in Slot3, and have Slot1 empty:: 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci append="pirq=0,9,11" 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting) 10462306a36Sopenharmony_cislots.] 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ciGenerally, it's always possible to find out the correct pirq= settings, just 10762306a36Sopenharmony_cipermute all IRQ numbers properly ... it will take some time though. An 10862306a36Sopenharmony_ci'incorrect' pirq line will cause the booting process to hang, or a device 10962306a36Sopenharmony_ciwon't function properly (e.g. if it's inserted as a module). 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciIf you have 2 PCI buses, then you can use up to 8 pirq values, although such 11262306a36Sopenharmony_ciboards tend to have a good configuration. 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ciBe prepared that it might happen that you need some strange pirq line:: 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci append="pirq=0,0,0,0,0,0,9,11" 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciUse smart trial-and-error techniques to find out the correct pirq line ... 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ciGood luck and mail to linux-smp@vger.kernel.org or 12162306a36Sopenharmony_cilinux-kernel@vger.kernel.org if you have any problems that are not covered 12262306a36Sopenharmony_ciby this document. 12362306a36Sopenharmony_ci 124