next up previous
Next: Conclusion Up: PCI Interrupts for x86 Previous: PCI Message Signaled Interrupts

FreeBSD's MSI Implementation

FreeBSD implements MSI messages as SYS_RES_IRQ interrupts similar to the legacy INTx interrupts. The driver visible differences include different resource IDs (legacy INTx interrupt is rid 0, MSI messages start at rid 1) for SYS_RES_IRQ resources and new APIs for allocating and releasing MSI messages. Behind the scenes, the PCI bus driver is responsible for programming the various MSI registers. It also allocates IRQs to map MSI messages onto via requests to the parent bridge. These requests pass up through the various PCI bridge drivers (very similar to how PCI interrupt routing passes up through PCI bridges) until it finds a device that can allocate IRQs for MSI messages. Similar requests are forwarded up the device tree to release MSI IRQs no longer in use and to compute the address and data register values for an MSI IRQ.

For the x86 platforms, the PCI bridge requests bubble up through the device tree until they arrive at the nexus0 device. This device's driver proxies the requests over to the x86 MSI code. The x86 MSI code uses interrupt source objects to manage IRQs for MSI messages. It provides a single struct pic shared by all MSI interrupt sources. The MSI interrupt sources are created on the fly when a request is made by a driver to allocate MSI messages. Each MSI interrupt source is assigned an IRQ value in the range 256 - 383. These IRQ values are used to avoid conflicting with the IRQs used for legacy INTx interrupts which use a range of 0 - 255. Once an MSI interrupt source is created, it is never destroyed, but it may be reused by a different device if it is released by a driver and another driver makes a subsequent allocation request. When an MSI interrupt source is allocated, it is assigned an IDT vector. If the MSI interrupt source is released, it frees the IDT vector back to the system. If a driver requests multiple MSI messages, care must be taken to ensure that the group of MSI messages use an aligned, contiguous range of IDT vectors. An extension to MSI known as MSI-X removes this limitation since it provides for separate address and data registers for each message.


next up previous
Next: Conclusion Up: PCI Interrupts for x86 Previous: PCI Message Signaled Interrupts