3.1.7. Message Signaled Interrupt
Two different modules generate the signal for the MSI line. The DMA controller in the PCIe hard IP core generates the DMA's MSI. The PCI Express interrupt request (IRQ) module (that is, the INTELFPGAOCLSDKROOT/board/a10_ref/hardware/a10gx/ip/irq_controller directory) generates the kernel interface's MSI.
For more information about the PCI Express IRQ module, refer to Handling PCIe Interrupts webpage.
In INTELFPGAOCLSDKROOT/board/a10_ref/hardware/a10gx/board.qsys, the DMA MSI is connected internally; however, you must connect the kernel interface interrupt manually. For the kernel interface interrupt, the PCI Express IRQ module is instantiated as pcie_irq_0 in board.qsys. The kernel interface interrupts connections are as follows:
- The kernel_irq_to_host port from the OpenCL Kernel Interface (kernel_interface) connects to the interrupt receiver, which allows the OpenCL kernels to signal the PCI Express IRQ module to send an MSI.
- The PCIe hard IP's msi_intfc port connects to the MSI_Interface port in the PCI Express IRQ module. The kernel interface interrupt receives the MSI address and the data necessary to generate the interrupt via msi_intfc.
- The IRQ_Gen_Host port on the PCI Express IRQ module, which is used to write the MSI, connects to the txs port on the PCIe hard IP.
- The IRQ_Read_Agent and IRQ_Mask_Agent ports connect to the pipe_stage_host_ctrl module on Bar 4. After receiving an MSI, the user driver can read the IRQ_Read_Agent port to check the status of the kernel interface interrupt, and read the IRQ_Mask_Agent port to mask the interrupt.
The interrupt service routine in the Linux driver checks which module generates the interrupt. For the DMA's MSI, the driver reads the DMA descriptor table's status bit in local memory, as specified in the Read DMA Example section of the Intel® Arria® 10 Avalon-MM DMA Interface for PCIe Solutions User Guide. For kernel interface's MSI, the driver reads the interrupt line sent by the kernel interface.
The interrupt service routine involves the following tasks:
- Check DMA status on the DMA descriptor table.
- Read the kernel status from the IRQ_READ_Agent port on the PCI Express IRQ module.
- If a kernel interrupt was triggered, mask the interrupt by writing to the IRQ_MASK_Agent port on the PCI Express IRQ module. Then, execute the kernel interrupt service routine.
- If a DMA interrupt was triggered, reset the DMA descriptor table and execute the DMA interrupt service routine.
- If applicable, unmask a masked kernel interrupt.