summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci/pcivar.h
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-05-02 17:50:36 +0000
committerjhb <jhb@FreeBSD.org>2007-05-02 17:50:36 +0000
commitef27a042995e8ab71ff21c9b0b9714068ca9762f (patch)
tree69dac9819e24c8ebcc3298470c47cfe7cc574930 /sys/dev/pci/pcivar.h
parent7b4912a3de1bf63af580b26951df4959ff338571 (diff)
downloadFreeBSD-src-ef27a042995e8ab71ff21c9b0b9714068ca9762f.zip
FreeBSD-src-ef27a042995e8ab71ff21c9b0b9714068ca9762f.tar.gz
Revamp the MSI/MSI-X code a bit to achieve two main goals:
- Simplify the amount of work that has be done for each architecture by pushing more of the truly MI code down into the PCI bus driver. - Don't bind MSI-X indicies to IRQs so that we can allow a driver to map multiple MSI-X messages into a single IRQ when handling a message shortage. The changes include: - Add a new pcib_if method: PCIB_MAP_MSI() which is called by the PCI bus to calculate the address and data values for a given MSI/MSI-X IRQ. The x86 nexus drivers map this into a call to a new 'msi_map()' function in msi.c that does the mapping. - Retire the pcib_if method PCIB_REMAP_MSIX() and remove the 'index' parameter from PCIB_ALLOC_MSIX(). MD code no longer has any knowledge of the MSI-X index for a given MSI-X IRQ. - The PCI bus driver now stores more MSI-X state in a child's ivars. Specifically, it now stores an array of IRQs (called "message vectors" in the code) that have associated address and data values, and a small virtual version of the MSI-X table that specifies the message vector that a given MSI-X table entry uses. Sparse mappings are permitted in the virtual table. - The PCI bus driver now configures the MSI and MSI-X address/data registers directly via custom bus_setup_intr() and bus_teardown_intr() methods. pci_setup_intr() invokes PCIB_MAP_MSI() to determine the address and data values for a given message as needed. The MD code no longer has to call back down into the PCI bus code to set these values from the nexus' bus_setup_intr() handler. - The PCI bus code provides a callout (pci_remap_msi_irq()) that the MD code can call to force the PCI bus to re-invoke PCIB_MAP_MSI() to get new values of the address and data fields for a given IRQ. The x86 MSI code uses this when an MSI IRQ is moved to a different CPU, requiring a new value of the 'address' field. - The x86 MSI psuedo-driver loses a lot of code, and in fact the separate MSI/MSI-X pseudo-PICs are collapsed down into a single MSI PIC driver since the only remaining diff between the two is a substring in a bootverbose printf. - The PCI bus driver will now restore MSI-X state (including programming entries in the MSI-X table) on device resume. - The interface for pci_remap_msix() has changed. Instead of accepting indices for the allocated vectors, it accepts a mini-virtual table (with a new length parameter). This table is an array of u_ints, where each value specifies which allocated message vector to use for the corresponding MSI-X message. A vector of 0 forces a message to not have an associated IRQ. The device may choose to only use some of the IRQs assigned, in which case the unused IRQs must be at the "end" and will be released back to the system. This allows a driver to use the same remap table for different shortage values. For example, if a driver wants 4 messages, it can use the same remap table (which only uses the first two messages) for the cases when it only gets 2 or 3 messages and in the latter case the PCI bus will release the 3rd IRQ back to the system. MFC after: 1 month
Diffstat (limited to 'sys/dev/pci/pcivar.h')
-rw-r--r--sys/dev/pci/pcivar.h37
1 files changed, 27 insertions, 10 deletions
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 0b1b5ad..13401d2 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -83,18 +83,33 @@ struct pcicfg_msi {
int msi_alloc; /* Number of allocated messages. */
uint64_t msi_addr; /* Contents of address register. */
uint16_t msi_data; /* Contents of data register. */
+ u_int msi_handlers;
};
/* Interesting values for PCI MSI-X */
+struct msix_vector {
+ uint64_t mv_address; /* Contents of address register. */
+ uint32_t mv_data; /* Contents of data register. */
+ int mv_irq;
+};
+
+struct msix_table_entry {
+ u_int mte_vector; /* 1-based index into msix_vectors array. */
+ u_int mte_handlers;
+};
+
struct pcicfg_msix {
uint16_t msix_ctrl; /* Message Control */
- uint8_t msix_location; /* Offset of MSI-X capability registers. */
uint16_t msix_msgnum; /* Number of messages */
- int msix_alloc; /* Number of allocated messages. */
+ uint8_t msix_location; /* Offset of MSI-X capability registers. */
uint8_t msix_table_bar; /* BAR containing vector table. */
uint8_t msix_pba_bar; /* BAR containing PBA. */
uint32_t msix_table_offset;
uint32_t msix_pba_offset;
+ int msix_alloc; /* Number of allocated vectors. */
+ int msix_table_len; /* Length of virtual table. */
+ struct msix_table_entry *msix_table; /* Virtual table. */
+ struct msix_vector *msix_vectors; /* Array of allocated vectors. */
struct resource *msix_table_res; /* Resource containing vector table. */
struct resource *msix_pba_res; /* Resource containing PBA. */
};
@@ -403,9 +418,9 @@ pci_alloc_msix(device_t dev, int *count)
}
static __inline int
-pci_remap_msix(device_t dev, u_int *indices)
+pci_remap_msix(device_t dev, int count, const u_int *vectors)
{
- return (PCI_REMAP_MSIX(device_get_parent(dev), dev, indices));
+ return (PCI_REMAP_MSIX(device_get_parent(dev), dev, count, vectors));
}
static __inline int
@@ -429,13 +444,15 @@ pci_msix_count(device_t dev)
device_t pci_find_bsf(uint8_t, uint8_t, uint8_t);
device_t pci_find_device(uint16_t, uint16_t);
-/* Used by MD code to program MSI and MSI-X registers. */
-void pci_enable_msi(device_t dev, uint64_t address, uint16_t data);
-void pci_enable_msix(device_t dev, u_int index, uint64_t address,
- uint32_t data);
-void pci_mask_msix(device_t dev, u_int index);
+/*
+ * Can be used by MD code to request the PCI bus to re-map an MSI or
+ * MSI-X message.
+ */
+int pci_remap_msi_irq(device_t dev, u_int irq);
+
+/* Can be used by drivers to manage the MSI-X table. */
int pci_pending_msix(device_t dev, u_int index);
-void pci_unmask_msix(device_t dev, u_int index);
+
int pci_msi_device_blacklisted(device_t dev);
#endif /* _SYS_BUS_H_ */
OpenPOWER on IntegriCloud