Interrupt Aggregation Ring - 4.0 English

QDMA Subsystem for PCI Express Product Guide (PG302)

Document ID
PG302
Release Date
2022-05-20
Version
4.0 English

For the indirect interrupt, it does interrupt aggregation. The following are some restrictions for the interrupt aggregation.

  • Each Interrupt Aggregation Ring can only be associated with one function. But multiple rings can be associated with the same function.
  • The interrupt engine supports up to three interrupts from the same source, until the software services the interrupts.

The Interrupt Engine processes the indirect interrupt with the following steps.

  • Interrupt source provides the index to which interrupt ring it belongs too.
  • Reads interrupt context for that queue.
  • Writes to the Interrupt Aggregation Ring.
  • Sends out the PCIe MSI-X message.

This following figure shows the indirect interrupt block diagram.

Figure 1. Indirect Interrupt

The Interrupt Context includes the information of the Interrupt Aggregation Ring. It has 256 entries to support up to 256 Interrupt Aggregation Rings.

Color bit is added so software does not read more entries that what it should read. When the software allocates the memory space for the Interrupt Aggregation Ring, the coal_color starts with 1'b0. The software needs to initialize the color bit of the Interrupt Context to be 1'b1. When the hardware completes the entire ring and flips to first entry in the next pass, it also flips the color value to 0 and starts writing 0 in color bit space. The software does the same after it completes the last entry with a color value 1, and goes to the first entry in the second pass and expects a color value 0. If the software does not see a color value 0,which indicates an old entry, it waits for new entry with a color value 0.

The software reads the Interrupt Aggregation Ring to get the Qid, and the int_type (H2C or C2H). From the Qid, the software can identify whether the queue is stream or MM.

The stat_desc in the Interrupt Aggregation Ring is the status descriptor from the Interrupt source. When the status descriptor is disabled, the software can get the status descriptor information from the Interrupt Aggregation Ring.

There can be two cases:

  • The interrupt source is C2H stream. Then it is the status descriptor of the C2H Completion Ring. The software can read the pidx of the C2H Completion Ring.
  • The interrupt source is others (H2C stream, H2C MM, C2H MM). Then it is the status descriptor of that source. The software can read the cidx.

Finally, the Interrupt Engine sends out the PCIe MSI-X message using the interrupt vector from the Interrupt Context. When there is an interrupt from any source, the interrupt engine updates PIDX and check for int_st of that interrupt context. If int_st is 0 (WAITING_TRIGGER) then the interrupt engine will send a interrupt. If int_st is 1 (ISR_RUNNING), the interrupt engine will not send interrupt. If the interrupt engine sends interrupt it will update int_sts to 1 and once software updated CIDX and CIDX matches PIDX int_sts will be cleared. The process is explained below.

When the PCIe MSI-X interrupt is received by the Host, the software reads the Interrupt Aggregation Ring to determine which queue needs service. After the software reads the ring, it will do a dynamic pointer update for the software CIDX to indicate the cumulative pointer that the software reads to. The software does the dynamic pointer update using the register QDMA_DMAP_SEL_INT_CIDX[2048] (0x18000). If the software CIDX is equal to the PIDX, this will trigger a write to the Interrupt Context to clear int_ston the interrupt state of that queue. This is to indicate the QDMA that the software already reads all of the entries in the Interrupt Aggregation Ring. If the software CIDX is not equal to the PIDX, the interrupt engine will send out another PCIe MSI-X message. Therefore, the software can read the Interrupt Aggregation Ring again. After that, the software can do a pointer update of the interrupt source ring. For example, if it is C2H stream interrupt, the software will update pointer of the interrupt source ring, which is the C2H Completion Ring.

These are the steps for the software:

  1. After the software gets the PCIe MSI-X message, it reads the Interrupt Aggregation Ring entries.
  2. The software uses the coal_color bit to identify the written entries. Each entry has Qid and Int_type (H2C or C2H). From the Qid and Int_type, the software can check if it is stream or MM. This points to a corresponding source ring. For example, if it is C2H stream, the source ring is the C2H Completion Ring. The software can then read the source ring to get information, and do a dynamic pointer update of the source ring after that.
  3. After the software finishes reading of all written entries in the Interrupt Aggregation Ring, it does one dynamic pointer update of the software cidx using the register QDMA_DMAP_SEL_INT_CIDX[2048] (0x18000). This communicates to the hardware of the Interrupt Aggregation Ring pointer used by the software.

    If the software cidx is not equal to the pidx, the hardware will send out another PCIe MSI-X message, so that the software can read the Interrupt Aggregation Ring again.

When the software does the dynamic pointer update for the Interrupt Aggregation Ring using the register QDMA_DMAP_SEL_INT_CIDX[2048] (0x18000), it sends the ring index of the Interrupt Aggregation Ring.

The following diagram shows the indirect interrupt flow. The Interrupt module gets the interrupt requests. It first writes to the Interrupt Aggregation Ring. Then it waits for the write completions. After that, it sends out the PCIe MSI-X message. The interrupt requests can keep on coming, and the Interrupt module keeps on processing them. In the meantime, the software reads the Interrupt Aggregation Ring, and it does the dynamic pointer update. If the software CIDX is not equal to the PIDX, it will send out another PCIe MSI-X message.