|
iPXE
|
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... | |
PCI MSI-X interrupts.
Interrupts as such are not used in iPXE, which operates in polling mode. However, some network cards (such as the Intel 40GbE and 100GbE NICs) will defer writing out completions until the point of asserting an MSI-X interrupt.
From the point of view of the PCI device, asserting an MSI-X interrupt is just a 32-bit DMA write of an opaque value to an opaque target address. The PCI device has no know to know whether or not the target address corresponds to a real APIC.
We can therefore trick the PCI device into believing that it is asserting an MSI-X interrupt, by configuring it to write an opaque 32-bit value to a dummy target address in host memory. This is sufficient to trigger the associated write of the completions to host memory.
When running in a virtual machine, the hypervisor will intercept our attempt to configure MSI-X on the PCI device. The physical hardware will be configured to raise an interrupt under the hypervisor's control, which will then be reflected back into the virtual machine. The opaque value that we write will be assumed to indicate an interrupt vector number (as would normally be the case when configuring MSI-X), and the opaque address will generally be ignored. The reflected interrupt will be ignored (since it is not enabled within the virtual machine), but the device still asserts an MSI-X interrupt and so still triggers the associated write of the completions to host memory.
Note that since the opaque target address will generally be ignored by the hypervisor, we cannot examine the value present at the dummy target address to find out whether or not an interrupt has been raised.
Definition in file pcimsix.c.
| FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
|
static |
Get MSI-X descriptor name (for debugging)
| cfg | Configuration space offset |
| name | Descriptor name |
Definition at line 76 of file pcimsix.c.
References cfg, PCI_MSIX_DESC_PBA, and PCI_MSIX_DESC_TABLE.
Referenced by pci_msix_ioremap().
|
static |
Map MSI-X BAR portion.
| pci | PCI device |
| msix | MSI-X capability |
| cfg | Configuration space offset |
| io | I/O address |
Definition at line 93 of file pcimsix.c.
References base, pci_msix::cap, cfg, DBGC, desc, NULL, offset, pci_bar_start(), PCI_BASE_ADDRESS, pci_ioremap(), 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().
| int pci_msix_enable | ( | struct pci_device * | pci, |
| struct pci_msix * | msix | ||
| ) |
Enable MSI-X interrupts.
| pci | PCI device |
| msix | MSI-X capability |
| rc | Return status code |
Definition at line 136 of file pcimsix.c.
References pci_msix::cap, pci_msix::count, ctrl, DBGC, pci_device::dma, dma(), dma_alloc(), dma_free(), ENOENT, ENOMEM, iounmap(), pci_msix::map, pci_msix::msg, msg(), 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_msix_map(), pci_read_config_word(), pci_write_config_word(), rc, and pci_msix::table.
Referenced by gve_probe(), and intelxl_msix_enable().
| void pci_msix_disable | ( | struct pci_device * | pci, |
| struct pci_msix * | msix | ||
| ) |
Disable MSI-X interrupts.
| pci | PCI device |
| msix | MSI-X capability |
Definition at line 207 of file pcimsix.c.
References pci_msix::cap, ctrl, dma_free(), iounmap(), pci_msix::map, pci_msix::msg, pci_msix::pba, PCI_MSIX_CTRL, PCI_MSIX_CTRL_ENABLE, pci_read_config_word(), pci_write_config_word(), and pci_msix::table.
Referenced by gve_probe(), gve_remove(), intelxl_msix_disable(), and intelxl_msix_enable().
| void pci_msix_map | ( | struct pci_msix * | msix, |
| unsigned int | vector, | ||
| physaddr_t | address, | ||
| uint32_t | data | ||
| ) |
Map MSI-X interrupt vector.
| msix | MSI-X capability |
| vector | MSI-X vector |
| address | Message address |
| data | Message data |
Definition at line 233 of file pcimsix.c.
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 pci_msix_enable().
Control MSI-X interrupt vector.
| msix | MSI-X capability |
| vector | MSI-X vector |
| mask | Control mask |
Definition at line 259 of file pcimsix.c.
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().
| void pci_msix_dump | ( | struct pci_msix * | msix, |
| unsigned int | vector | ||
| ) |
Dump MSI-X interrupt state (for debugging)
| msix | MSI-X capability |
| vector | MSI-X vector |
Definition at line 278 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(), pci_msix::table, and vector.
1.8.15