FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
5892 Discussions

MSI interrupt in PCIe-MM-DMA example

OlegT
New Contributor I
2,044 Views

Hello.

I am working with C10GX developement kit. As a starting point I use AN829 - Avalon-MM DMA  ref design.

DMA works well. I want to test MSI in that design.

The design contains linux driver, but msi functionality is commented out.

I've made chanes to driver, but have no luck - ISR is not called, when DMA is finished. But status bit is set in lite_table header.

Here are detail of my situation:

1. My initialization code (altera_pci_probe function):

// enable msi in HW

// set interrupt disable for legacy
pci_read_config_dword(bk_ptr->pci_dev, 0x04, &conf_reg);
conf_reg |= (1 << 10);
pci_write_config_dword(bk_ptr->pci_dev, 0x04, conf_reg);

//Set bit[1] (Memory space) and bit[2]
conf_reg |= 0x06;
pci_write_config_dword(bk_ptr->pci_dev, 0x04, conf_reg);

// set msi Ena
pci_read_config_dword(bk_ptr->pci_dev, 0x50, &conf_reg);
conf_reg |= (1 << 16);
pci_write_config_dword(bk_ptr->pci_dev, 0x50, conf_reg);


rc = pci_enable_msi(dev); -- success here

pci_read_config_byte(dev, PCI_REVISION_ID, &bk_ptr->revision);
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &bk_ptr->irq_pin);
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &bk_ptr->irq_line);

if (!pci_set_dma_mask(dev, DMA_BIT_MASK(DMAMASK))) {
pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(DMAMASK));
}
else goto err_dma_mask;

rc = request_irq(bk_ptr->irq_line, dma_isr, IRQF_SHARED, ALTERA_DMA_DRIVER_NAME, (void *)bk_ptr); -- success here

 

2. dma_isr:

     pr_err("+++ dma_isr ++\n"); // not much so far
    return IRQ_HANDLED;

 

3. After the driver is loaded, in /proc/interrupts I can find my device:

OlegT_0-1632944558563.png

4. When I look on MSIIntfc_o[81:0] (coming from hip), I see that:

MSIIntfc_o[81]: Master enable = 1

MSIIntfc_o[80]: MSI enable = 1

MSIIntfc_o[79:64]: MSI data = 0x29
MSIIntfc_o[63:0]: MSI address = 0xFEE02004

So, the root complex had set up MSI in FPGA.

5. I've captured by signal tap the transactions on TXS interface, and found, that after DMA is finished, there are two memory writes here. The first one - to bus address of lite_table header (to set a flag). The second one - to address from MSIIntfc_o[63 : 0] with MSIIntfc_o[79 : 64] as data. It is an MSI itself.

So FPGA side seems to work correctly.

OlegT_1-1632945085878.png

As I said earlier, I could see, that flag in lite_table is set, but ISR was not called.

If I check /proc/interrupts, then there are still zeros in counters for my device.

 

Please suggest, what should I check to solve my problem.

Thank you.

1 Solution
OlegT
New Contributor I
1,924 Views

I've replaced legacy pci_enable_msi() with pci_alloc_irq_vectors(). Now ISR for single interrupts is called.

View solution in original post

0 Kudos
5 Replies
KhaiChein_Y_Intel
2,008 Views

Hi,


Do you see the MSI when all the DMA data transfers are complete?


Thanks

Best regards,

KhaiY


0 Kudos
OlegT
New Contributor I
1,997 Views

I do not see interrupt on host PC, but I see, that wr_dcm_master sends irq_data and irq_address to txs.

irq_data and irq_address are the values from MSIIntfc_o.

0 Kudos
KhaiChein_Y_Intel
1,939 Views

Hi,


It seems like the FPGA sent the correct value of MSI signals to the host but the host cannot detect it. I am afraid that I am not an expert in driver writing. We might need the community users to help you on this thread.


Thanks

Best regards,

KhaiY


0 Kudos
OlegT
New Contributor I
1,925 Views

I've replaced legacy pci_enable_msi() with pci_alloc_irq_vectors(). Now ISR for single interrupts is called.

0 Kudos
KhaiChein_Y_Intel
1,911 Views

Hi,


It is glad that you found the solution to modify the driver. Thanks for sharing the solution as it helps other users who have this problem in their driver.


Thanks

Best regards,

KhaiY


0 Kudos
Reply