iPXE
Functions
pcimsix.c File Reference

PCI MSI-X interrupts. More...

#include <stdint.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/pci.h>
#include <ipxe/pcimsix.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static const char * pci_msix_name (unsigned int cfg)
 Get MSI-X descriptor name (for debugging) More...
 
static void * pci_msix_ioremap (struct pci_device *pci, struct pci_msix *msix, unsigned int cfg)
 Map MSI-X BAR portion. More...
 
int pci_msix_enable (struct pci_device *pci, struct pci_msix *msix)
 Enable MSI-X interrupts. More...
 
void pci_msix_disable (struct pci_device *pci, struct pci_msix *msix)
 Disable MSI-X interrupts. More...
 
void pci_msix_map (struct pci_msix *msix, unsigned int vector, physaddr_t address, uint32_t data)
 Map MSI-X interrupt vector. More...
 
void pci_msix_control (struct pci_msix *msix, unsigned int vector, uint32_t mask)
 Control MSI-X interrupt vector. More...
 
void pci_msix_dump (struct pci_msix *msix, unsigned int vector)
 Dump MSI-X interrupt state (for debugging) More...
 

Detailed Description

PCI MSI-X interrupts.

Definition in file pcimsix.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ pci_msix_name()

static const char* pci_msix_name ( unsigned int  cfg)
static

Get MSI-X descriptor name (for debugging)

Parameters
cfgConfiguration space offset
Return values
nameDescriptor name

Definition at line 44 of file pcimsix.c.

44  {
45 
46  switch ( cfg ) {
47  case PCI_MSIX_DESC_TABLE: return "table";
48  case PCI_MSIX_DESC_PBA: return "PBA";
49  default: return "<UNKNOWN>";
50  }
51 }
Definition: sis900.h:23
#define PCI_MSIX_DESC_PBA
Definition: pci.h:119
#define PCI_MSIX_DESC_TABLE
Definition: pci.h:118

References cfg, PCI_MSIX_DESC_PBA, and PCI_MSIX_DESC_TABLE.

Referenced by pci_msix_ioremap().

◆ pci_msix_ioremap()

static void* pci_msix_ioremap ( struct pci_device pci,
struct pci_msix msix,
unsigned int  cfg 
)
static

Map MSI-X BAR portion.

Parameters
pciPCI device
msixMSI-X capability
cfgConfiguration space offset
Return values
ioI/O address

Definition at line 61 of file pcimsix.c.

62  {
63  uint32_t desc;
64  unsigned int bar;
65  unsigned long start;
66  unsigned long offset;
67  unsigned long base;
68  void *io;
69 
70  /* Read descriptor */
71  pci_read_config_dword ( pci, ( msix->cap + cfg ), &desc );
72 
73  /* Get BAR */
74  bar = PCI_MSIX_DESC_BIR ( desc );
75  offset = PCI_MSIX_DESC_OFFSET ( desc );
76  start = pci_bar_start ( pci, PCI_BASE_ADDRESS ( bar ) );
77  if ( ! start ) {
78  DBGC ( msix, "MSI-X %p %s could not find BAR%d\n",
79  msix, pci_msix_name ( cfg ), bar );
80  return NULL;
81  }
82  base = ( start + offset );
83  DBGC ( msix, "MSI-X %p %s at %#08lx (BAR%d+%#lx)\n",
84  msix, pci_msix_name ( cfg ), base, bar, offset );
85 
86  /* Map BAR portion */
87  io = ioremap ( ( start + offset ), PCI_MSIX_LEN );
88  if ( ! io ) {
89  DBGC ( msix, "MSI-X %p %s could not map %#08lx\n",
90  msix, pci_msix_name ( cfg ), base );
91  return NULL;
92  }
93 
94  return io;
95 }
#define DBGC(...)
Definition: compiler.h:505
#define PCI_MSIX_DESC_BIR(x)
BAR index.
Definition: pci.h:120
#define PCI_BASE_ADDRESS(n)
PCI base address registers.
Definition: pci.h:60
uint32_t start
Starting offset.
Definition: netvsc.h:12
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition: pci.c:96
unsigned int cap
Capability offset.
Definition: pcimsix.h:36
unsigned int uint32_t
Definition: stdint.h:12
uint16_t base
Base address.
Definition: edd.h:14
#define PCI_MSIX_LEN
MSI-X BAR mapped length.
Definition: pcimsix.h:15
Definition: sis900.h:23
#define PCI_MSIX_DESC_OFFSET(x)
BAR offset.
Definition: pci.h:121
void * ioremap(unsigned long bus_addr, size_t len)
Map bus address as an I/O address.
static const char * pci_msix_name(unsigned int cfg)
Get MSI-X descriptor name (for debugging)
Definition: pcimsix.c:44
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References base, pci_msix::cap, cfg, DBGC, ioremap(), NULL, offset, pci_bar_start(), PCI_BASE_ADDRESS, PCI_MSIX_DESC_BIR, PCI_MSIX_DESC_OFFSET, PCI_MSIX_LEN, pci_msix_name(), pci_read_config_dword(), and start.

Referenced by pci_msix_enable().

◆ pci_msix_enable()

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.

104  {
105  uint16_t ctrl;
106  int rc;
107 
108  /* Locate capability */
109  msix->cap = pci_find_capability ( pci, PCI_CAP_ID_MSIX );
110  if ( ! msix->cap ) {
111  DBGC ( msix, "MSI-X %p found no MSI-X capability in "
112  PCI_FMT "\n", msix, PCI_ARGS ( pci ) );
113  rc = -ENOENT;
114  goto err_cap;
115  }
116 
117  /* Extract interrupt count */
118  pci_read_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), &ctrl );
119  msix->count = ( PCI_MSIX_CTRL_SIZE ( ctrl ) + 1 );
120  DBGC ( msix, "MSI-X %p has %d vectors for " PCI_FMT "\n",
121  msix, msix->count, PCI_ARGS ( pci ) );
122 
123  /* Map MSI-X table */
124  msix->table = pci_msix_ioremap ( pci, msix, PCI_MSIX_DESC_TABLE );
125  if ( ! msix->table ) {
126  rc = -ENOENT;
127  goto err_table;
128  }
129 
130  /* Map pending bit array */
131  msix->pba = pci_msix_ioremap ( pci, msix, PCI_MSIX_DESC_PBA );
132  if ( ! msix->pba ) {
133  rc = -ENOENT;
134  goto err_pba;
135  }
136 
137  /* Enable MSI-X */
140  pci_write_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), ctrl );
141 
142  return 0;
143 
144  iounmap ( msix->pba );
145  err_pba:
146  iounmap ( msix->table );
147  err_table:
148  err_cap:
149  return rc;
150 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
int pci_find_capability(struct pci_device *pci, int cap)
Look for a PCI capability.
Definition: pciextra.c:36
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
#define PCI_MSIX_CTRL
MSI-X interrupts.
Definition: pci.h:114
unsigned int cap
Capability offset.
Definition: pcimsix.h:36
#define PCI_MSIX_CTRL_SIZE(x)
Table size.
Definition: pci.h:117
#define PCI_MSIX_CTRL_MASK
Mask all interrupts.
Definition: pci.h:116
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:287
void * table
MSI-X table.
Definition: pcimsix.h:40
static unsigned int ctrl
Definition: intel.h:270
static void * pci_msix_ioremap(struct pci_device *pci, struct pci_msix *msix, unsigned int cfg)
Map MSI-X BAR portion.
Definition: pcimsix.c:61
#define PCI_CAP_ID_MSIX
MSI-X.
Definition: pci.h:97
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:290
void iounmap(volatile const void *io_addr)
Unmap I/O address.
#define PCI_MSIX_CTRL_ENABLE
Enable MSI-X.
Definition: pci.h:115
#define PCI_MSIX_DESC_PBA
Definition: pci.h:119
void * pba
Pending bit array.
Definition: pcimsix.h:42
unsigned int count
Number of vectors.
Definition: pcimsix.h:38
#define PCI_MSIX_DESC_TABLE
Definition: pci.h:118

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().

◆ pci_msix_disable()

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.

158  {
159  uint16_t ctrl;
160 
161  /* Disable MSI-X */
162  pci_read_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), &ctrl );
164  pci_write_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), ctrl );
165 
166  /* Unmap pending bit array */
167  iounmap ( msix->pba );
168 
169  /* Unmap MSI-X table */
170  iounmap ( msix->table );
171 }
unsigned short uint16_t
Definition: stdint.h:11
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
#define PCI_MSIX_CTRL
MSI-X interrupts.
Definition: pci.h:114
unsigned int cap
Capability offset.
Definition: pcimsix.h:36
void * table
MSI-X table.
Definition: pcimsix.h:40
static unsigned int ctrl
Definition: intel.h:270
void iounmap(volatile const void *io_addr)
Unmap I/O address.
#define PCI_MSIX_CTRL_ENABLE
Enable MSI-X.
Definition: pci.h:115
void * pba
Pending bit array.
Definition: pcimsix.h:42

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().

◆ pci_msix_map()

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.

182  {
183  void *base;
184 
185  /* Sanity check */
186  assert ( vector < msix->count );
187 
188  /* Map interrupt vector */
189  base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
190  writel ( ( address & 0xffffffffUL ), ( base + PCI_MSIX_ADDRESS_LO ) );
191  if ( sizeof ( address ) > sizeof ( uint32_t ) ) {
192  writel ( ( ( ( uint64_t ) address ) >> 32 ),
193  ( base + PCI_MSIX_ADDRESS_HI ) );
194  } else {
195  writel ( 0, ( base + PCI_MSIX_ADDRESS_HI ) );
196  }
197  writel ( data, ( base + PCI_MSIX_DATA ) );
198 }
uint32_t vector
MSI-X vector.
Definition: ena.h:20
uint64_t address
Base address.
Definition: ena.h:24
unsigned long long uint64_t
Definition: stdint.h:13
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
#define PCI_MSIX_VECTOR(n)
MSI-X vector offset.
Definition: pcimsix.h:18
void * table
MSI-X table.
Definition: pcimsix.h:40
unsigned int uint32_t
Definition: stdint.h:12
uint16_t base
Base address.
Definition: edd.h:14
#define PCI_MSIX_ADDRESS_LO
MSI-X vector address low 32 bits.
Definition: pcimsix.h:21
#define PCI_MSIX_DATA
MSI-X vector data.
Definition: pcimsix.h:27
uint16_t count
Number of entries.
Definition: ena.h:22
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define PCI_MSIX_ADDRESS_HI
MSI-X vector address high 32 bits.
Definition: pcimsix.h:24

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

Referenced by intelxl_msix_enable().

◆ pci_msix_control()

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.

208  {
209  void *base;
210  uint32_t ctrl;
211 
212  /* Mask/unmask interrupt vector */
213  base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
216  ctrl |= mask;
217  writel ( ctrl, ( base + PCI_MSIX_CONTROL ) );
218 }
uint32_t vector
MSI-X vector.
Definition: ena.h:20
uint32_t readl(volatile uint32_t *io_addr)
Read 32-bit dword from memory-mapped device.
#define PCI_MSIX_CONTROL
MSI-X vector control.
Definition: pcimsix.h:30
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
#define PCI_MSIX_VECTOR(n)
MSI-X vector offset.
Definition: pcimsix.h:18
void * table
MSI-X table.
Definition: pcimsix.h:40
unsigned int uint32_t
Definition: stdint.h:12
uint16_t base
Base address.
Definition: edd.h:14
static unsigned int ctrl
Definition: intel.h:270
#define PCI_MSIX_CONTROL_MASK
Vector is masked.
Definition: pcimsix.h:31

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

Referenced by pci_msix_mask(), and pci_msix_unmask().

◆ pci_msix_dump()

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.

226  {
227  void *base;
228  uint32_t address_hi;
229  uint32_t address_lo;
231  uint32_t data;
232  uint32_t ctrl;
233  uint32_t pba;
234 
235  /* Do nothing in non-debug builds */
236  if ( ! DBG_LOG )
237  return;
238 
239  /* Mask/unmask interrupt vector */
240  base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
241  address_hi = readl ( base + PCI_MSIX_ADDRESS_HI );
242  address_lo = readl ( base + PCI_MSIX_ADDRESS_LO );
243  data = readl ( base + PCI_MSIX_DATA );
245  pba = readl ( msix->pba );
246  address = ( ( ( ( uint64_t ) address_hi ) << 32 ) | address_lo );
247  DBGC ( msix, "MSI-X %p vector %d %#08x => %#08lx%s%s\n",
248  msix, vector, data, address,
249  ( ( ctrl & PCI_MSIX_CONTROL_MASK ) ? " (masked)" : "" ),
250  ( ( pba & ( 1 << vector ) ) ? " (pending)" : "" ) );
251 }
uint32_t vector
MSI-X vector.
Definition: ena.h:20
uint64_t address
Base address.
Definition: ena.h:24
uint32_t readl(volatile uint32_t *io_addr)
Read 32-bit dword from memory-mapped device.
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
#define PCI_MSIX_CONTROL
MSI-X vector control.
Definition: pcimsix.h:30
#define PCI_MSIX_VECTOR(n)
MSI-X vector offset.
Definition: pcimsix.h:18
void * table
MSI-X table.
Definition: pcimsix.h:40
unsigned int uint32_t
Definition: stdint.h:12
uint16_t base
Base address.
Definition: edd.h:14
#define PCI_MSIX_ADDRESS_LO
MSI-X vector address low 32 bits.
Definition: pcimsix.h:21
unsigned long physaddr_t
Definition: stdint.h:20
static unsigned int ctrl
Definition: intel.h:270
#define PCI_MSIX_DATA
MSI-X vector data.
Definition: pcimsix.h:27
#define PCI_MSIX_CONTROL_MASK
Vector is masked.
Definition: pcimsix.h:31
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define DBG_LOG
Definition: compiler.h:317
#define PCI_MSIX_ADDRESS_HI
MSI-X vector address high 32 bits.
Definition: pcimsix.h:24
void * pba
Pending bit array.
Definition: pcimsix.h:42

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(), pci_msix::table, and vector.