mariuszp wrote:
Would this work:
1. if an IRQ handler thread exists, it is woken up. if not, an EOI is sent and the interrupt ignored.
2. the IRQ handler thread is responsible for sending the EOI.
Yes, that works. But per-IRQ (or per-device) masking is much better than sending EOI after the driver thread ran. If you mask the IRQ you can still receive IRQs from other devices. If you delay EOI then all IRQs are blocked. I'd really encourage you to mask the IRQ. Its not really hard to do; it's just a simple bit in the I/O APIC
.
mariuszp wrote:
Also, there may be multiple PCI devices connected to the same IRQ. Does that mean a driver should check whether its device has triggered the interrupt, and only send the EOI if so? Isn't there, therefore, a race condition, where the device may trigger an interrupt on the same line after another device has issued its own, and then the driver for device A will send the EOI even though it was actually device B sending the interrupt?
Yes, that can happen. But it is not a problem because both IRQs are level-triggered. So device B is still pulling its IRQ line low (as you did not touch its hardware registers yet) and the PIC will issue another IRQ once you send EOI and unmask.
mariuszp wrote:
I set the level-triggered/active-low flags based on the ACPI tables.
That is nice. But I have to warn you that there is some hardware that does not report PCI interrupts in the MADT. Here is a dump of my OS running on one of my PCs:
Code:
thor: Dumping MADT
Local APIC id: 0
Local APIC id: 1
Local APIC id: 130 (disabled)
Local APIC id: 131 (disabled)
I/O APIC id: 2, sytem interrupt base: 0
Int override: ISA IRQ 0 is mapped to GSI 2 (Polarity: default, trigger mode: default)
Int override: ISA IRQ 9 is mapped to GSI 9 (Polarity: high, trigger mode: level)
thor: Configuring I/O APICs.
thor: I/O APIC supports 24 pins
[...]
thor: Configuring ISA IRQs.
thor: Configuring IRQ io-apic.2 to trigger mode: 1, polarity: 1
thor: Configuring IRQ io-apic.1 to trigger mode: 1, polarity: 1
thor: Configuring IRQ io-apic.4 to trigger mode: 1, polarity: 1
thor: Configuring IRQ io-apic.9 to trigger mode: 2, polarity: 1
thor: Configuring IRQ io-apic.12 to trigger mode: 1, polarity: 1
[...]
thor: Installing handler for ACPI IRQ 9
thor: Found PCI host bridge
Route for slot 1, pin 0: \_SB_.LNKA[0]
Route for slot 1, pin 1: \_SB_.LNKB[0]
Route for slot 1, pin 2: \_SB_.LNKC[0]
Route for slot 1, pin 3: \_SB_.LNKD[0]
Route for slot 6, pin 0: \_SB_.LNKA[0]
Route for slot 6, pin 1: \_SB_.LNKB[0]
Route for slot 6, pin 2: \_SB_.LNKC[0]
Route for slot 6, pin 3: \_SB_.LNKD[0]
Route for slot 31, pin 0: \_SB_.LNKC[0]
Route for slot 31, pin 1: \_SB_.LNKD[0]
Route for slot 29, pin 0: \_SB_.LNKH[0]
Route for slot 30, pin 0: \_SB_.LNKB[0]
Route for slot 30, pin 1: \_SB_.LNKE[0]
Route for slot 27, pin 0: \_SB_.LNKA[0]
Route for slot 28, pin 0: \_SB_.LNKA[0]
Route for slot 28, pin 1: \_SB_.LNKB[0]
Route for slot 28, pin 2: \_SB_.LNKC[0]
Route for slot 28, pin 3: \_SB_.LNKD[0]
Route for slot 2, pin 0: \_SB_.LNKA[0]
Route for slot 29, pin 1: \_SB_.LNKD[0]
Route for slot 29, pin 2: \_SB_.LNKC[0]
Route for slot 29, pin 3: \_SB_.LNKA[0]
Configurating link device \_SB_.LNKA.
Resource: Irq 10, trigger mode: 2, polarity: 2
Configurating link device \_SB_.LNKB.
Device is not enabled.
Configurating link device \_SB_.LNKC.
Resource: Irq 11, trigger mode: 2, polarity: 2
Configurating link device \_SB_.LNKD.
Resource: Irq 3, trigger mode: 2, polarity: 2
Configurating link device \_SB_.LNKH.
Resource: Irq 5, trigger mode: 2, polarity: 2
Configurating link device \_SB_.LNKE.
Device is not enabled.
thor: Configuring IRQ io-apic.10 to trigger mode: 2, polarity: 2
thor: Configuring IRQ io-apic.11 to trigger mode: 2, polarity: 2
thor: Configuring IRQ io-apic.3 to trigger mode: 2, polarity: 2
thor: Configuring IRQ io-apic.5 to trigger mode: 2, polarity: 2
That means that it is necessary to run AML code (the _CRS method of the LNK{A-H} devices) to get the correct IRQs. Hopefully your hardware is not as nasty as this one but it still makes sense to check if the MADT contains all PCI interrupts.