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