![]() |
RT-Thread RTOS
An open source embedded real-time operating system
|
PCI message-signalled interrupts need an interrupt controller that can allocate a vector, build the MSI message (address + data), and deliver it into the same virtual IRQ space as wired IRQs.
PCI enable path: PCI MSI and MSI-X. Wiring to PIC: this page.
| Responsibility | Typical rt_pic_ops |
|---|---|
| Hand out a virtual IRQ per MSI/MSI-X vector | **irq_alloc_msi** / **irq_free_msi** |
| Tell PCI what to write to the device | **irq_compose_msi_msg**, **irq_write_msi_msg** |
| Mask / unmask at hardware | Often **irq_mask/irq_unmask** + **rt_pci_msi_*** helpers |
| Reach the CPU interrupt architecture | Usually cascade to a parent PIC line (PIC cascade and routing) or a dedicated status ISR that demuxes bits |
The PIC driver does not replace PCI config-space MSI capability setup — that stays in **pci/msi/**. The PIC side owns vector backing and message programming.
**struct rt_pci_device::msi_pic** must point at the **struct rt_pic** that implements these ops (from DT **msi-parent**, **msi-map**, or board setup).
Typical steps inside the provider:
rt_pic_config_irq(pic, index, hwirq)** — obtain global virtual IRQ for **rt_pic_attach_irq**.parent_irq = parent_pic->ops->irq_map(...)** then **rt_pic_cascade(pirq, parent_irq)** so the parent line fires when MSI is triggered.msi_desc** on **pirq** if the PCI layer needs it for mask/unmask.pci/msi/irq.c**.**irq_free_msi**: **rt_pic_uncascade**, release index, clear bitmap.
Fill **struct rt_pci_msi_msg**:
| Field | Meaning |
|---|---|
**address_lo / address_hi** | Doorbell or MSI frame write target |
**data** | Vector data written by device |
SoC-specific: address may be a dedicated MSI window or a parent SPI doorbell — implement per TRM, not in the generic framework.
| MSI | MSI-X | |
|---|---|---|
| Vectors | Often power-of-two block, may need contiguous virtual IRQs | Per-table-entry allocation common |
| Table | Config space | Often BAR-mapped table — map BAR before unmask |
| PIC | Same ops; PCI layer passes count / type | Same ops; one **irq_alloc_msi** per entry typical |
Platforms may describe:
msi-parent** — phandle to MSI-capable interrupt controllermsi-map / msi-map-mask** — map PCI requester ID to controller + specifierParsing is SoC-specific; result must be **pdev->msi_pic** before **rt_pci_msi_enable**.
| Issue | Mitigation |
|---|---|
**RT_PCI_MSI disabled** | Ops stubbed; PCI MSI APIs no-op |
**msi_pic NULL** | Set in host/PCI probe before enable |
| Return hwirq to PCI | Return virtual IRQ from **irq_alloc_msi** |
| No parent link | MSI never reaches CPU — cascade or demux ISR |
| MSI-X table unmapped | Enable only after BAR iomap in PCI setup |