iPXE
Data Structures | Defines | Functions
pcimsix.h File Reference

PCI MSI-X interrupts. More...

#include <ipxe/pci.h>

Go to the source code of this file.

Data Structures

struct  pci_msix
 PCI MSI-X capability. More...

Defines

#define PCI_MSIX_LEN   0x1000
 MSI-X BAR mapped length.
#define PCI_MSIX_VECTOR(n)   ( (n) * 0x10 )
 MSI-X vector offset.
#define PCI_MSIX_ADDRESS_LO   0x0
 MSI-X vector address low 32 bits.
#define PCI_MSIX_ADDRESS_HI   0x4
 MSI-X vector address high 32 bits.
#define PCI_MSIX_DATA   0x8
 MSI-X vector data.
#define PCI_MSIX_CONTROL   0xc
 MSI-X vector control.
#define PCI_MSIX_CONTROL_MASK   0x00000001
 Vector is masked.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int pci_msix_enable (struct pci_device *pci, struct pci_msix *msix)
 Enable MSI-X interrupts.
void pci_msix_disable (struct pci_device *pci, struct pci_msix *msix)
 Disable MSI-X interrupts.
void pci_msix_map (struct pci_msix *msix, unsigned int vector, physaddr_t address, uint32_t data)
 Map MSI-X interrupt vector.
void pci_msix_control (struct pci_msix *msix, unsigned int vector, uint32_t mask)
 Control MSI-X interrupt vector.
void pci_msix_dump (struct pci_msix *msix, unsigned int vector)
 Dump MSI-X interrupt state (for debugging)
static void pci_msix_mask (struct pci_msix *msix, unsigned int vector)
 Mask MSI-X interrupt vector.
static void pci_msix_unmask (struct pci_msix *msix, unsigned int vector)
 Unmask MSI-X interrupt vector.

Detailed Description

PCI MSI-X interrupts.

Definition in file pcimsix.h.


Define Documentation

#define PCI_MSIX_LEN   0x1000

MSI-X BAR mapped length.

Definition at line 15 of file pcimsix.h.

Referenced by pci_msix_ioremap().

#define PCI_MSIX_VECTOR (   n)    ( (n) * 0x10 )

MSI-X vector offset.

Definition at line 18 of file pcimsix.h.

Referenced by pci_msix_control(), pci_msix_dump(), and pci_msix_map().

#define PCI_MSIX_ADDRESS_LO   0x0

MSI-X vector address low 32 bits.

Definition at line 21 of file pcimsix.h.

Referenced by pci_msix_dump(), and pci_msix_map().

#define PCI_MSIX_ADDRESS_HI   0x4

MSI-X vector address high 32 bits.

Definition at line 24 of file pcimsix.h.

Referenced by pci_msix_dump(), and pci_msix_map().

#define PCI_MSIX_DATA   0x8

MSI-X vector data.

Definition at line 27 of file pcimsix.h.

Referenced by pci_msix_dump(), and pci_msix_map().

#define PCI_MSIX_CONTROL   0xc

MSI-X vector control.

Definition at line 30 of file pcimsix.h.

Referenced by pci_msix_control(), and pci_msix_dump().

#define PCI_MSIX_CONTROL_MASK   0x00000001

Vector is masked.

Definition at line 31 of file pcimsix.h.

Referenced by pci_msix_control(), pci_msix_dump(), and pci_msix_mask().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int pci_msix_enable ( struct pci_device pci,
struct pci_msix msix 
)

Enable MSI-X interrupts.

Parameters:
pciPCI device
msixMSI-X capability
Return values:
rcReturn status code

Definition at line 104 of file pcimsix.c.

References pci_msix::cap, pci_msix::count, ctrl, DBGC, ENOENT, iounmap(), pci_msix::pba, PCI_ARGS, PCI_CAP_ID_MSIX, pci_find_capability(), PCI_FMT, PCI_MSIX_CTRL, PCI_MSIX_CTRL_ENABLE, PCI_MSIX_CTRL_MASK, PCI_MSIX_CTRL_SIZE, PCI_MSIX_DESC_PBA, PCI_MSIX_DESC_TABLE, pci_msix_ioremap(), pci_read_config_word(), pci_write_config_word(), rc, and pci_msix::table.

Referenced by intelxl_msix_enable().

                                                                      {
        uint16_t ctrl;
        int rc;

        /* Locate capability */
        msix->cap = pci_find_capability ( pci, PCI_CAP_ID_MSIX );
        if ( ! msix->cap ) {
                DBGC ( msix, "MSI-X %p found no MSI-X capability in "
                       PCI_FMT "\n", msix, PCI_ARGS ( pci ) );
                rc = -ENOENT;
                goto err_cap;
        }

        /* Extract interrupt count */
        pci_read_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), &ctrl );
        msix->count = ( PCI_MSIX_CTRL_SIZE ( ctrl ) + 1 );
        DBGC ( msix, "MSI-X %p has %d vectors for " PCI_FMT "\n",
               msix, msix->count, PCI_ARGS ( pci ) );

        /* Map MSI-X table */
        msix->table = pci_msix_ioremap ( pci, msix, PCI_MSIX_DESC_TABLE );
        if ( ! msix->table ) {
                rc = -ENOENT;
                goto err_table;
        }

        /* Map pending bit array */
        msix->pba = pci_msix_ioremap ( pci, msix, PCI_MSIX_DESC_PBA );
        if ( ! msix->pba ) {
                rc = -ENOENT;
                goto err_pba;
        }

        /* Enable MSI-X */
        ctrl &= ~PCI_MSIX_CTRL_MASK;
        ctrl |= PCI_MSIX_CTRL_ENABLE;
        pci_write_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), ctrl );

        return 0;

        iounmap ( msix->pba );
 err_pba:
        iounmap ( msix->table );
 err_table:
 err_cap:
        return rc;
}
void pci_msix_disable ( struct pci_device pci,
struct pci_msix msix 
)

Disable MSI-X interrupts.

Parameters:
pciPCI device
msixMSI-X capability

Definition at line 158 of file pcimsix.c.

References pci_msix::cap, ctrl, iounmap(), pci_msix::pba, PCI_MSIX_CTRL, PCI_MSIX_CTRL_ENABLE, pci_read_config_word(), pci_write_config_word(), and pci_msix::table.

Referenced by intelxl_msix_disable().

                                                                        {
        uint16_t ctrl;

        /* Disable MSI-X */
        pci_read_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), &ctrl );
        ctrl &= ~PCI_MSIX_CTRL_ENABLE;
        pci_write_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), ctrl );

        /* Unmap pending bit array */
        iounmap ( msix->pba );

        /* Unmap MSI-X table */
        iounmap ( msix->table );
}
void pci_msix_map ( struct pci_msix msix,
unsigned int  vector,
physaddr_t  address,
uint32_t  data 
)

Map MSI-X interrupt vector.

Parameters:
msixMSI-X capability
vectorMSI-X vector
addressMessage address
dataMessage data

Definition at line 181 of file pcimsix.c.

References assert, base, count, PCI_MSIX_ADDRESS_HI, PCI_MSIX_ADDRESS_LO, PCI_MSIX_DATA, PCI_MSIX_VECTOR, pci_msix::table, and writel().

Referenced by intelxl_msix_enable().

                                                        {
        void *base;

        /* Sanity check */
        assert ( vector < msix->count );

        /* Map interrupt vector */
        base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
        writel ( ( address & 0xffffffffUL ), ( base + PCI_MSIX_ADDRESS_LO ) );
        if ( sizeof ( address ) > sizeof ( uint32_t ) ) {
                writel ( ( ( ( uint64_t ) address ) >> 32 ),
                         ( base + PCI_MSIX_ADDRESS_HI ) );
        } else {
                writel ( 0, ( base + PCI_MSIX_ADDRESS_HI ) );
        }
        writel ( data, ( base + PCI_MSIX_DATA ) );
}
void pci_msix_control ( struct pci_msix msix,
unsigned int  vector,
uint32_t  mask 
)

Control MSI-X interrupt vector.

Parameters:
msixMSI-X capability
vectorMSI-X vector
maskControl mask

Definition at line 207 of file pcimsix.c.

References base, ctrl, PCI_MSIX_CONTROL, PCI_MSIX_CONTROL_MASK, PCI_MSIX_VECTOR, readl(), pci_msix::table, and writel().

Referenced by pci_msix_mask(), and pci_msix_unmask().

                                        {
        void *base;
        uint32_t ctrl;

        /* Mask/unmask interrupt vector */
        base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
        ctrl = readl ( base + PCI_MSIX_CONTROL );
        ctrl &= ~PCI_MSIX_CONTROL_MASK;
        ctrl |= mask;
        writel ( ctrl, ( base + PCI_MSIX_CONTROL ) );
}
void pci_msix_dump ( struct pci_msix msix,
unsigned int  vector 
)

Dump MSI-X interrupt state (for debugging)

Parameters:
msixMSI-X capability
vectorMSI-X vector

Definition at line 226 of file pcimsix.c.

References address, base, ctrl, data, DBG_LOG, DBGC, pci_msix::pba, PCI_MSIX_ADDRESS_HI, PCI_MSIX_ADDRESS_LO, PCI_MSIX_CONTROL, PCI_MSIX_CONTROL_MASK, PCI_MSIX_DATA, PCI_MSIX_VECTOR, readl(), and pci_msix::table.

                                                                  {
        void *base;
        uint32_t address_hi;
        uint32_t address_lo;
        physaddr_t address;
        uint32_t data;
        uint32_t ctrl;
        uint32_t pba;

        /* Do nothing in non-debug builds */
        if ( ! DBG_LOG )
                return;

        /* Mask/unmask interrupt vector */
        base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
        address_hi = readl ( base + PCI_MSIX_ADDRESS_HI );
        address_lo = readl ( base + PCI_MSIX_ADDRESS_LO );
        data = readl ( base + PCI_MSIX_DATA );
        ctrl = readl ( base + PCI_MSIX_CONTROL );
        pba = readl ( msix->pba );
        address = ( ( ( ( uint64_t ) address_hi ) << 32 ) | address_lo );
        DBGC ( msix, "MSI-X %p vector %d %#08x => %#08lx%s%s\n",
               msix, vector, data, address,
               ( ( ctrl & PCI_MSIX_CONTROL_MASK ) ? " (masked)" : "" ),
               ( ( pba & ( 1 << vector ) ) ? " (pending)" : "" ) );
}
static void pci_msix_mask ( struct pci_msix msix,
unsigned int  vector 
) [inline, static]

Mask MSI-X interrupt vector.

Parameters:
msixMSI-X capability
vectorMSI-X vector

Definition at line 60 of file pcimsix.h.

References pci_msix_control(), and PCI_MSIX_CONTROL_MASK.

Referenced by intelxl_msix_disable().

static void pci_msix_unmask ( struct pci_msix msix,
unsigned int  vector 
) [inline, static]

Unmask MSI-X interrupt vector.

Parameters:
msixMSI-X capability
vectorMSI-X vector

Definition at line 72 of file pcimsix.h.

References pci_msix_control().

Referenced by intelxl_msix_enable().

                                                               {

        pci_msix_control ( msix, vector, 0 );
}