Next
Previous
Contents
Each PCI device that needs an interrupt comes with a fixed PCI
interrupt that can't be changed. But this PCI interrupt can be mapped
(routed or redirected) to an ISA interrupt by a chip on the
motherboard. Thus when PCI card generates a PCI interrupt, it
becomes an ISA interrupt, even if there is no ISA bus anymore.
There are two newer developments in PCI interrupts. They are
especially important for cases of more than one CPU per computer. One
is the Advanced Programmable Interrupt Controller (APIC) which can
provides 24 or more interrupts. See the file "IO-APIC" in the i386
directory of the kernel documentation and the ACPI-HOWTO. Don't
confuse APIC with ACPI (Advanced Configuration and Power Interface)
which may be used by the kernel to configure the APIC.
Another new development is Message Signalled Interrupts (MSI) where
the interrupt is just a message sent to a special address over the
main computer bus (no interrupt lines needed). But the device that
sends such a message must first gain control of the main bus so that
it can send the interrupt message. Such a message contains more info
than just "I'm sending an interrupt".
The mapping (same as routing or redirecting) of interrupts to ISA
interrupts is done by either a "programmable interrupt router" or by
and APIC. Both can be programmed by the BIOS or Linux.
PCI interrupts may be shared, meaning that two or more PCI devices
will generate the same IRQ. If feasible, it's usually better not to
share. Sharing doesn't work right for: 1. very old PCI hardware
(before 1995 ??) 2. defective PCI hardware which may have a factory
defect (it was made that way). For example, if a PCI device on IRQ9
falsely claims that any IRQ9 was intended for it, then other devices
using IRQ9 may wind up having all IRQs they issue ignored since the
bad device is falsely claiming their IRQs. With no sharing, this
problem is avoided.
For an example of sharing the same IRQ between two PCI devices. see
PCI interrupt sharing This sharing
ability is built into the hardware and all device drivers are supposed
to support it. Note that you can't share the same interrupt between
the PCI and ISA bus. However, such illegal sharing will work provided
only one of the two conflicting devices is in use at any given time.
"In use" here means that a program has "opened" the device (and hasn't
"closed" it) in its C programming code, even though such a program
could be temporarily sleeping, etc.
Here are some of the details of the PCI interrupt system. Each PCI
card (and device mounted on the motherboard) has 4 possible
interrupts: INTA#, INTB#, INTC#, INTD#. From now on we will call them
just A, B, C, and D. Each has its own pin on the edge connector of a
PCI card. Thus for a 7-slot system (for 7 cards) there could be 7 x 4
= 28 different interrupt lines for these cards. Devices built into the motherboard also have additional interrupts. But the specs permit a
fewer number of interrupt lines, so some PCI buses seem to be made
with only 4 or 8 interrupt lines. This is not too restrictive since
interrupts may be shared. For 4 interrupt line (wires, traces, or links)
LNKA, LNKB, LNKC, LNKD there is a programmable "interrupt router"
chip that routes LNKA, LNKB, LNKC, LNKD to selected IRQs. This
routing can be changed by the BIOS or Linux. For example, LNKA may
be routed to IRQ5. Suppose we designate the B interrupt from slot 3
as interrupt 3B. Then interrupts 3B and 2A could both be permanently
connected to LNKA which is routed to IRQ5. These 2 interrupts: 3B and
2A are permanently shared by hardwiring on the motherboard.
One may type "dmesg" on the command line to see how interrupt lines
like LNKA are routed (or linked) to IRQs (*5 means that it's linked to
IRQ 5). Look for "PCI Interrupt Link". Note that "link" is used
here with two meanings: 1. the linking (routing) of PCI interrupt
lines to IRQs. 2. the label of an interrupt line such as LNKB (link
B). The interrupt line labels seem to be provided by the Bios ?? and
they may have many different names like: LNKC, LNK2, APCF, LUBA, LIDE,
etc. Question: When a large number of interrupt lines are shown
disabled, do they all physically exist on the motherboard? Or do they
just exist only in the ACPI BIOS software so that the BIOS can work
with motherboards which have more interrupt lines?
One simple method of connecting (hard-wiring) these lines from PCI
devices (such as 3B) to the interrupts LNKA, etc. would be to connect
all A interrupts (INTA#) to line LNKA, all B's to LNKB, etc. This
method was once used many years ago but it is not a good solution.
Here's why. If a card only needs one interrupt, it's required that it
use A. If it needs two interrupts, it must use both A and B, etc.
Thus INTA# is used much more often than INTD#. So one winds up with
an excessive number of interrupts sharing the first line (LNKA connected
to all the INTA#). To overcome this problem one may connect them in a
more random way so that each of the 4 interrupt lines (LNKA, LNKB,
LNKC, LNKD) will share about the same number of actual PCI interrupts.
One method of doing this would be to have wire LNKA share interrupts 1A,
2B, 3C, 4D, 5A, 6B, 7C. This is done by physically connecting wire W
to wires 1A, 2B, etc. Likewise wire LNKB could be connected to wires 1B,
2C, 3D, 4A, 5B, 6C, 7D, etc. Then on startup, the BIOS maps the LNKB,
LNKA, LNKC, LNKD to IRQs. After that, it writes the IRQ that each
device uses into a hardware configuration register in each device.
From then on, any program interrogating this register can find out
what IRQ the device uses. Note that just writing the IRQ in a
register on a PCI card doesn't in any way set the IRQ for that device.
A practical use for this info is that, as a last resort, one may change
the IRQs of a PCI card by inserting it in a different slot. In the
above example, INTA# of a PCI card will be connected to wire LNKA the
card is inserted into slot 1 (1A maps to LNKA but INTA# will be
connected to wire LNKB it's inserted into slot 4 (4A maps to LNKB).
A card in a slot may have up to 8 devices on it but there are only 4
PCI interrupts for it (A, B, C, D). This is OK since interrupts may
be shared so that each of the 8 devices (if they exist) can have an
interrupt. The PCI interrupt letter of a device is often fixed and
hardwired into the device. The assignment of interrupts is done by
either the BIOS or Linux mapping the PCI interrupts to the ISA-like
interrupts as mentioned above.
If there are only 4 lines (LNKA, LNKB, LNKC, and LNKD) as in the above
example, the mapping choices that the PCI BIOS has are limited. Some
motherboards may use more lines and thus have more choices. For
example LNKA-LNKH (8 lines). The boot-time messages (and dmesg) may
display them and how they are mapped. The BIOS knows about how they
are wired.
On the PCI bus, the BIOS (or Linux) assigns IRQs (interrupts) so as to avoid
conflicts with the IRQs it knows about on the ISA bus. Sometimes the
CMOS BIOS menu may allow one to assign IRQs to PCI cards or to tell
the BIOS what IRQs are to be reserved for ISA devices. The assignments are
known as a "routing table". In MS Windows it's called "IRQ steering"
but this also covers the case of dynamic IRQ routing after boot-time.
The BIOS may support it's own IRQ steering.
You might think that since the PCI is using IRQs (designed for the ISA
bus) it might be slow since the ISA bus was slow. Not really. The ISA
Interrupt Controller Chip(s) has a direct interrupt wire going to the
CPU so it can get immediate attention. While signals on the old ISA
address and data buses are slow to get to the CPU, the IRQ interrupt
signals get there very fast. The ACPI even has a narrow bus going
directly to the CPU.
Next
Previous
Contents
|