xref: /OK3568_Linux_fs/kernel/Documentation/x86/i386/IO-APIC.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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