Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20704 Discussions

How to request multiply MSI interrupts?

Altera_Forum
Honored Contributor II
4,650 Views

Hi !!! 

 

Developing a network device driver on Arria2 GX (Avalon-ST). 

Is it possible to set a vector of 8 MSI interrupts , if the design supports only MSI interrupts, not MSI - X? 

 

From the side of device driver developer - to request 8 separate interrupt handlers, to handle 8 packet queues. 

 

pci_enable_msi_block() returns 1.This means, that it's possible to request only 1 interrupt line. 

 

The capabilities of device: 

 

Capabilities: [78] Power Management version 3 

Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) 

Status: D0 PME-Enable- DSel=0 DScale=0 PME- 

Capabilities: [80] Express (v1) Endpoint, MSI 00 

DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us 

ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- 

DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- 

RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ 

MaxPayload 128 bytes, MaxReadReq 512 bytes 

DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend- 

LnkCap: Port# 1, Speed 2.5GT/s, Width x4, ASPM L0s, Latency L0 unlimited, L1 unlimited 

ClockPM- Suprise- LLActRep- BwNot- 

LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+ 

ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- 

LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- 

 

Developing under Linux. 

 

Best Regards,  

Igor
0 Kudos
39 Replies
Altera_Forum
Honored Contributor II
2,088 Views

The Capabilities' field imply that you only have one MSI enabled on your FPGA. It should read MSI 07 instead of MSI 00.

0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Hi, 

Thank's for reply 

 

I've missed that piece of lspci. 

 

Capabilities: [50] Message Signalled Interrupts: Mask- 64bit+ Queue=0/5 Enable+ 

Address: 00000000fee0300c Data: 41a1 

 

Now I am able to request multiply MSI's.  

There is a kernel patch , which allow's multiply MSI's on x86 arch.
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Hi 

 

please I am newbie on MSI with ALTERA: 

Do you have a piece of code as example implementing PCIe Driver with MSI?
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

HI  

 

pci_enable_msi (struct pci_dev * dev); 

pci_enable_msi_block (struct pci_dev * dev, unsigned int nvec); (On x86 arch patch is needed). 

 

If H/W is capable, use MSI-X interrupts instead MSI. 

 

Regards,  

Igor
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Ok but with my Cyclone IV GX I have MSI= 1 

1) what that means? Vector or just one Interrupt? 

can handled multiple Interrupts with this capabilty parameter? 

 

2) Secondly How can I set the MSIx Interrupt Handling instead of MSI with ALTERA.(with my software or is there any configuration setting with PCI Express Compiler)
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

You have to choose MSI-X or MSI in Quartus. Also to set number of vectors. Driver than is able to request irqs, which you have specified in yours design. Are you writing driver for Linux?

0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

MSI = 1 means that the driver if able to request 1 interrupt line.

0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Linux Device Driver Third Edition , Essential Linux Device drivers will help you

0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Ok  

 

I already know about this book. Now my concern is to  

create a simple design which handle MSI for test purpose first. 

Hopefully the Interrupt Request Line (MSI=1) would be enough for the driver to handle several I/O Devices(6 UARTs, 1 CAN, others). 

 

That is for my Internship.
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Hi guys, 

 

Please could anybody help me by giving me some advice on the way to generate MSI Interrupts with ST Interface? (piece of code)
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Hi, 

 

Once more thanks a lot for your advice about Linux Driver Programming. Rigth now how to deal with Interrupt Service Routine because I have 8 MSI Source. Should I write 8 ISR? 

 

Here is a piece of my code 

 

--- Quote Start ---  

 

 

------------------------------------------------------------------------------------------ 

/* Interrupt Handler */ 

 

void LATTICE_pci_intr_handler (int irq, void *dev_id, struct pt_regs *regs) 

unsigned long intr_flag; 

 

/* Lese Interrupt-Flag, um zu pruefen, ob das LATTICE PCI-Board ueberhaupt */ 

/* Quelle des Interrupts ist. (Moeglicherweise Shared Interrupt!) */ 

intr_flag = readl (LATTICE_pci_dev.virt_addr + LATTICE_INTR_REG_ADDR) & 1; 

 

if (intr_flag) return; /* Kein Interrupt durch das LATTICE PCI-Board */ 

 

/* Hier beginnt die eigentliche Interrupt-Bearbeitung... */ 

printk ("LATTICE PCI-Board: Interrupt!\n"); 

}  

........ 

/* Interrupt-Handler registrieren */ 

if (request_irq (LATTICE_pci_dev.intr_line, LATTICE_pci_intr_handler,  

SA_SHIRQ, LATTICE_PCI_NAME, &LATTICE_pci_dev)) 

printk ("LATTICE PCI-Board: can't get assigned IRQ %d.\n", LATTICE_pci_dev.intr_line); 

result = -EIO; 

goto exit1; 

}  

 

 

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Hi 

 

In your case , the LATTICE_pci_intr_handler function will handle the MSI irq.  

int irq - the number of MSI irq, which you received. 

 

If you want to use 8 MSI, this code is probably correct. 

if 8 MSI-X, you need to request_irq on every interrupt line.  

 

Regards,  

Igor
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Ok! 

 

it means my LATTICE_pci_intr_handler function handle all the MSI(0-7) GENERATED IRQ. 

But let assume I want to test my CAN and UART by a simple function to make sure the appropriate function will be called depending on which device assert the Interrupt.  

void testCAN() { printf ("Called by CAN BUS!\n"); } and 

void testUART() { printf ("Called by UART!\n"); } How can I implemented these 2 functions within the Interrupt Handler or should I simply test the IRQ Number and called the related function ?? 

0--CAN 

1--UART 

...
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Yes. 

If you have a single MSI vector, you have to register 1 interrupt line. 

If you want to test CAN, UART interrupts, than write your kernel module. 

Request irq for CAN, than for UART, with interrupt handlers.  

For ex: 

 

static irqreturn_t can_isr ( int irq, void *dev ) 

void testCAN(); 

 

printk(KERN_DEBUG " CAN received irq = %d \n", irq);  

 

return IRQ_HANDLED; 

 

 

static irqreturn_t uart_isr ( int irq, void *dev ) 

void testUART(); 

 

printk(KERN_DEBUG " UART received irq = %d \n", irq);  

 

return IRQ_HANDLED; 

 

}
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Hi, 

 

I can understand the code on Linux, where it has to acquire the IRQ for the MSI and it needs the ISR handler to perform interrupt function when it receive particular interrupt signal from the IRQ allocated. 

 

However, I need some guidelines on  

1) how to generate MSI interrupt in Altera? Please anyone if have any recommended examples. 

 

2) and what values should be configured to these signals? 

 

app_msi_tc[2:0] in Application MSI traffic class:  

This signal indicates the Traffic Class (TC) used to send the MSI 

(unlike INTx interrupts, any TC can be used to send MSIs). 

 

app_msi_num[4:0] in Application MSI Offset Number:  

This signal is used by the Application to determine the offset 

between the base message data and the MSI to send. 

 

3) how to make sure that the MSI that I generate is after DMA write from FPGA to PC completed? so that it wont corrupt my DMA write data. 

 

Advice needed and thank you.
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

Ok for the advice!  

 

Now 

I finally implemented my first MSI Interrupt. 

 

But  

1 ) why I can not get pci-msi-edge on my device after the linux command:cat /proc/interrupts while it looks good with the command lspci -d 1204:ec30 -v -xxx ( see the 2 outputs below) 

 

2) I permanently get an error by implementing pci_enable_msi_block (struct pci_dev * dev, unsigned int nvec) where can I get the related patch for arch x86? 

 

# lspci -d 1204:ec30 -v -xxx 04:00.0 Non-VGA unclassified device: Lattice Semiconductor Corporation Device ec30 Subsystem: Lattice Semiconductor Corporation Device 3030 Physical Slot: 3 Flags: bus master, fast devsel, latency 0, IRQ 30 Memory at d0440000 (32-bit, non-prefetchable) Memory at d0400000 (32-bit, non-prefetchable) Capabilities: Power Management version 3 Capabilities: MSI: Enable+ Count=1/1 Maskable- 64bit+ Capabilities: Express Endpoint, MSI 00 Capabilities: Device Serial Number 00-00-00-00-00-00-00-00 00: 04 12 30 ec 07 04 10 00 00 00 00 00 10 00 00 00 10: 00 00 44 d0 00 00 40 d0 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 04 12 30 30 30: 00 00 00 00 50 00 00 00 00 00 00 00 07 01 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 01 70 03 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 05 90 81 00 0c 10 e0 fe 00 00 00 00 a9 41 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 10 00 01 00 00 80 00 00 00 00 00 00 11 74 00 00 a0: 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # cat /proc/interrupts CPU0 0: 116261 IO-APIC-edge timer 1: 2 IO-APIC-edge i8042 3: 2 IO-APIC-edge 4: 2 IO-APIC-edge 5: 0 IO-APIC-edge parport0 7: 0 IO-APIC-edge LATTICE_pci 8: 1 IO-APIC-edge rtc0 9: 0 IO-APIC-fasteoi acpi 12: 4 IO-APIC-edge i8042 16: 79998 IO-APIC-fasteoi pciehp, pciehp, pciehp, pciehp, ehci_hcd:usb2, ohci_hcd:usb6, ohci_hcd:usb7, ohci_hcd:usb8, HDA Intel 18: 0 IO-APIC-fasteoi mmc0, mmc1 19: 13861 IO-APIC-fasteoi ehci_hcd:usb1, ohci_hcd:usb3, ohci_hcd:usb4, ohci_hcd:usb5 24: 0 PCI-MSI-edge aerdrv 25: 2 PCI-MSI-edge aerdrv, pciehp  

 

--- Quote Start ---  

Yes. 

If you have a single MSI vector, you have to register 1 interrupt line. 

If you want to test CAN, UART interrupts, than write your kernel module. 

Request irq for CAN, than for UART, with interrupt handlers.  

For ex: 

 

static irqreturn_t can_isr ( int irq, void *dev ) 

void testCAN(); 

 

printk(KERN_DEBUG " CAN received irq = %d \n", irq);  

 

return IRQ_HANDLED; 

 

 

static irqreturn_t uart_isr ( int irq, void *dev ) 

void testUART(); 

 

printk(KERN_DEBUG " UART received irq = %d \n", irq);  

 

return IRQ_HANDLED; 

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

What does pci_enable_msi_block return ?

0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

 

--- Quote Start ---  

7: 0 IO-APIC-edge LATTICE_pci 

--- Quote End ---  

You enabled Legacy interrupts. Not MSI
0 Kudos
Altera_Forum
Honored Contributor II
2,088 Views

It seems to be disable by executing the command cat /proc/interrupts 

 

But in the other hand my msi is enabled by the following command 

lspci -d 1204:ec30 -v -xxx (see output below) ? 

 

# lspci -d 1204:ec30 -v -xxx 04:00.0 Non-VGA unclassified device: Lattice Semiconductor Corporation Device ec30 Subsystem: Lattice Semiconductor Corporation Device 3030 Physical Slot: 3 Flags: bus master, fast devsel, latency 0, IRQ 30 Memory at d0440000 (32-bit, non-prefetchable) Memory at d0400000 (32-bit, non-prefetchable) Capabilities: Power Management version 3 Capabilities: MSI: Enable+ Count=1/1 Maskable- 64bit+ Capabilities: Express Endpoint, MSI 00 Capabilities: Device Serial Number 00-00-00-00-00-00-00-00 00: 04 12 30 ec 07 04 10 00 00 00 00 00 10 00 00 00 10: 00 00 44 d0 00 00 40 d0 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 04 12 30 30 30: 00 00 00 00 50 00 00 00 00 00 00 00 07 01 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 01 70 03 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 05 90 81 00 0c 10 e0 fe 00 00 00 00 a9 41 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 10 00 01 00 00 80 00 00 00 00 00 00 11 74 00 00 a0: 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0 Kudos
Altera_Forum
Honored Contributor II
1,895 Views

Advice: Output based on one msi 

 

# lspci -d 1204:ec30 -v -xxx 04:00.0 Non-VGA unclassified device: Lattice Semiconductor Corporation Device ec30 Subsystem: Lattice Semiconductor Corporation Device 3030 Physical Slot: 3 Flags: bus master, fast devsel, latency 0, IRQ 30 Memory at d0440000 (32-bit, non-prefetchable) Memory at d0400000 (32-bit, non-prefetchable) Capabilities: Power Management version 3 Capabilities: MSI: Enable+ Count=1/1 Maskable- 64bit+ Capabilities: Express Endpoint, MSI 00 Capabilities: Device Serial Number 00-00-00-00-00-00-00-00 00: 04 12 30 ec 07 04 10 00 00 00 00 00 10 00 00 00 10: 00 00 44 d0 00 00 40 d0 00 00 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 04 12 30 30 30: 00 00 00 00 50 00 00 00 00 00 00 00 07 01 00 00 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 01 70 03 00 00 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70: 05 90 81 00 0c 10 e0 fe 00 00 00 00 a9 41 00 00 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90: 10 00 01 00 00 80 00 00 00 00 00 00 11 74 00 00 a0: 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0 Kudos
Reply