Electronic – enable/disable PCI interrupts

businterruptspcie

I'm implementing a PCIe driver, and I'd like to understand at what level the interrupts can be or should be enabled/disabled. I intentionally do not specify OS, as I'm assuming it should be relevant for any platform. By levels I mean the following:

  • OS specific interrupts handling framework
  • Interrupts can be disabled or enabled in the PCI/PCIe configuration space registers, e.g. COMMAND register
  • Interrupts also can be masked at device level, for instance we can configure device not trigger certain interrupts to the host

I understand that whatever interrupt type is being used on PCIe (INTx emulation, MSI or MSI-X), it has to be delivered to the host OS.

So my question is — do we actually have to enable or disable interrupts on every layer, or it's sufficient only at the closest to hardware, e.g. in relevant PCI registers?

Best Answer

Operating systems generally complain loudly about unexpected interrupts, because these are easily detectable programming errors in drivers.

Typically, your hardware would start in some fairly inert state after reset where it waits to be configured. In this state, there is no meaningful way to generate an interrupt, because there is no mapping established yet and you do not know which interrupt.

During configuration, the interrupt mapping comes into existence, and the card is told which interrupt line to use (INTA..INTD as legacy PCI, or MSI/MSI-X), but there is still no driver to handle interrupts yet. Linux has a default handler here that complains to the system log and then disables the interrupt source, as the hardware appears to be faulty (i.e. by default, all interrupts are enabled, but only those where a handler is registered are expected to actually occur).

The driver finally registers interrupt handlers and enables the interrupts it is interested in. If the driver is no longer interested in a specific condition, it needs to disable the interrupt in the device, because that is where the device specific interrupt causes are masked -- the lower layers only know that "something happened".