irq: MSI first, and poll the INTx lines that never arrive
PCI drivers took their interrupt from INTERRUPT_LINE. On real hardware that is the 8259's number, not the IOAPIC pin the device is wired to (that is in ACPI _PRT, which needs AML), so nothing ever arrived. xHCI is entirely interrupt-driven, so the USB keyboard and a USB root would have hung even on a clean boot. Under QEMU the two numbers agree, which is why it never showed. - pci_irq_attach()/pci_irq_detach(): MSI, then MSI-X if the driver allows it, then INTx. The handler is registered before MSI is enabled, so no edge is lost. xHCI, e1000, r8169 and rtl8139 use it. - Lines 24-29 are MSI vectors. The LAPIC error vector moves from 19, which is a PCI pin on Intel chipsets, to 30. Nothing is placed at or above vector 64 (T_SYSCALL). - A storming line is masked and its handlers are polled instead of being left to eat the CPU. A level line that has had a handler for 2 s and never fired is polled every tick by a kernel thread. Tested in QEMU q35 with the root on a USB stick: xHCI and e1000e on MSI; then MSI disabled and INTx deliberately misrouted, where xHCI got zero interrupts and the root still mounted through the poller. i440fx INTx and the rtl8139 hand-over are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HH7xukt4aaiGj1nQEAoQf1
This commit is contained in:
parent
94c936ed98
commit
7e8d5e2821
11 changed files with 407 additions and 35 deletions
|
|
@ -266,6 +266,57 @@ existing mechanisms for keeping that true mechanically rather than by intention.
|
|||
|
||||
---
|
||||
|
||||
## Interrupts
|
||||
|
||||
A PCI driver connects its interrupt with one call, `pci_irq_attach()`, and
|
||||
does not choose how. In order of preference:
|
||||
|
||||
1. **MSI**: the device writes a vector to the local APIC. No pin, no routing,
|
||||
nothing to share.
|
||||
2. **MSI-X**, but only if the driver passes `PCI_IRQF_MSIX`. Some parts change
|
||||
how they report interrupt causes in that mode; the 82574 needs its IVAR
|
||||
programmed, which `e1000` does not do, so it does not ask.
|
||||
3. **INTx**, on the line named by the device's `INTERRUPT_LINE` register.
|
||||
|
||||
MSI comes first because INTx on real hardware is **the wrong pin**.
|
||||
`INTERRUPT_LINE` holds the number the firmware gave the 8259. In APIC mode the
|
||||
device is wired to an IOAPIC input that only ACPI's `_PRT` describes, and
|
||||
reading `_PRT` takes an AML interpreter, which SchOS does not have. Under QEMU
|
||||
the two numbers happen to agree, which is why this went unnoticed until the
|
||||
drivers were read with a real board in mind.
|
||||
|
||||
INTx is therefore backed by the poller in `kernel/dev/irq.c`:
|
||||
|
||||
- A level-triggered line that has had a handler for two seconds and has never
|
||||
fired gets its handlers called every tick, from a kernel thread with
|
||||
interrupts off.
|
||||
- A line that **storms** (an idle ISA input configured active-low reads as
|
||||
asserted forever) is masked and polled instead of being reported and left
|
||||
running.
|
||||
|
||||
Every handler already has to cope with being called when its device is idle,
|
||||
because lines are shared, so a spurious call costs only a register read.
|
||||
`/proc/interrupts` marks such a line `[polled]`, and an MSI line `msi`.
|
||||
|
||||
The vector layout:
|
||||
|
||||
| Lines | What they are |
|
||||
|---|---|
|
||||
| 0–23 | IOAPIC pins |
|
||||
| 24–29 | MSI vectors, allocated by `irq_alloc_msi()` |
|
||||
| 30 | LAPIC error (it was 19, which is a PCI pin on Intel chipsets) |
|
||||
| 31 | spurious |
|
||||
|
||||
Nothing goes as high as vector 64, which is `T_SYSCALL`.
|
||||
|
||||
Tested under QEMU q35 with the root filesystem on a USB stick, in three
|
||||
configurations:
|
||||
|
||||
- xHCI and e1000e on MSI.
|
||||
- MSI disabled and the INTx line deliberately misrouted. xHCI took no
|
||||
interrupts at all, the poller carried every transfer, and the root still
|
||||
mounted.
|
||||
- The old INTx path, unchanged on i440fx.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue