[coreboot-gerrit] Change in coreboot[master]: device/pci: Add MSI-X helper functions

Philipp Deppenwiese (Code Review) gerrit at coreboot.org
Thu Jul 19 15:52:33 CEST 2018


Philipp Deppenwiese has submitted this change and it was merged. ( https://review.coreboot.org/26329 )

Change subject: device/pci: Add MSI-X helper functions
......................................................................

device/pci: Add MSI-X helper functions

Basic PCI MSI-X table helper functions.
Imported from GNU/Linux kernel PCI subsystem.

To be used on Cavium to configure MSI-X tables.

Change-Id: I94413712e7986efd17e6b11ba59f6eb390384c8c
Signed-off-by: Patrick Rudolph <patrick.rudolph at 9elements.com>
Reviewed-on: https://review.coreboot.org/26329
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki at gmail.com>
Tested-by: build bot (Jenkins) <no-reply at coreboot.org>
---
M src/device/pci_device.c
M src/include/device/pci.h
M src/include/device/pci_def.h
3 files changed, 98 insertions(+), 0 deletions(-)

Approvals:
  build bot (Jenkins): Verified
  Philipp Deppenwiese: Looks good to me, approved



diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index c18f529..5938389 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -338,6 +338,74 @@
 }
 
 /**
+ * Given a device, read the size of the MSI-X table.
+ *
+ * @param dev Pointer to the device structure.
+ * @return MSI-X table size or 0 if not MSI-X capable device
+ */
+size_t pci_msix_table_size(struct device *dev)
+{
+	const size_t pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	if (!pos)
+		return 0;
+
+	const u16 control = pci_read_config16(dev, pos + PCI_MSIX_FLAGS);
+	return (control & PCI_MSIX_FLAGS_QSIZE) + 1;
+}
+
+/**
+ * Given a device, return the table offset and bar the MSI-X tables resides in.
+ *
+ * @param dev Pointer to the device structure.
+ * @param offset Returned value gives the offset in bytes inside the PCI BAR.
+ * @param idx The returned value is the index of the PCI_BASE_ADDRESS register
+ *            the MSI-X table is located in.
+ * @return Zero on success
+ */
+int pci_msix_table_bar(struct device *dev, u32 *offset, u8 *idx)
+{
+	const size_t pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	if (!pos || !offset || !idx)
+		return 1;
+
+	*offset = pci_read_config32(dev, pos + PCI_MSIX_TABLE);
+	*idx = (u8)(*offset & PCI_MSIX_PBA_BIR);
+	*offset &= PCI_MSIX_PBA_OFFSET;
+
+	return 0;
+}
+
+/**
+ * Given a device, return a msix_entry pointer or NULL if no table was found.
+ *
+ * @param dev Pointer to the device structure.
+ *
+ * @return NULL on error
+ */
+struct msix_entry *pci_msix_get_table(struct device *dev)
+{
+	struct resource *res;
+	u32 offset;
+	u8 idx;
+
+	if (pci_msix_table_bar(dev, &offset, &idx))
+		return NULL;
+
+	if (idx > 5)
+		return NULL;
+
+	res = probe_resource(dev, idx * 4 + PCI_BASE_ADDRESS_0);
+	if (!res || !res->base || offset >= res->size)
+		return NULL;
+
+	if ((res->flags & IORESOURCE_PCI64) &&
+	    (uintptr_t)res->base != res->base)
+		return NULL;
+
+	return (struct msix_entry *)((uintptr_t)res->base + offset);
+}
+
+/**
  * Read the base address registers for a given device.
  *
  * @param dev Pointer to the dev structure.
diff --git a/src/include/device/pci.h b/src/include/device/pci.h
index 3cc2c64..f1ab91b 100644
--- a/src/include/device/pci.h
+++ b/src/include/device/pci.h
@@ -56,6 +56,20 @@
 	const unsigned short *devices;
 };
 
+struct msix_entry {
+	union {
+		struct {
+			u32 lower_addr;
+			u32 upper_addr;
+		};
+		struct {
+			u64 addr;
+		};
+	};
+	u32 data;
+	u32 vec_control;
+};
+
 #ifdef __SIMPLE_DEVICE__
 #define __pci_driver __attribute__((unused))
 #else
@@ -104,6 +118,10 @@
 const char *get_pci_class_name(struct device *dev);
 const char *get_pci_subclass_name(struct device *dev);
 
+size_t pci_msix_table_size(struct device *dev);
+int pci_msix_table_bar(struct device *dev, u32 *offset, u8 *idx);
+struct msix_entry *pci_msix_get_table(struct device *dev);
+
 #define PCI_IO_BRIDGE_ALIGN 4096
 #define PCI_MEM_BRIDGE_ALIGN (1024*1024)
 
diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h
index 60d9132..f9ce1a6 100644
--- a/src/include/device/pci_def.h
+++ b/src/include/device/pci_def.h
@@ -292,6 +292,18 @@
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
 #define PCI_MSI_MASK_BIT	16	/* Mask bits register */
 
+/* MSI-X registers */
+#define PCI_MSIX_FLAGS		2
+#define  PCI_MSIX_FLAGS_QSIZE	0x7FF	/* table size */
+#define  PCI_MSIX_FLAGS_MASKALL	0x4000	/* Mask all vectors for this function */
+#define  PCI_MSIX_FLAGS_ENABLE	0x8000	/* MSI-X enable */
+#define PCI_MSIX_TABLE		4	/* Table offset */
+#define PCI_MSIX_PBA		8	/* Pending Bit Array offset */
+#define  PCI_MSIX_PBA_BIR	0x7	/* BAR index */
+#define  PCI_MSIX_PBA_OFFSET	~0x7	/* Offset into specified BAR */
+#define PCI_CAP_MSIX_SIZEOF	12	/* size of MSIX registers */
+
+
 /* CompactPCI Hotswap Register */
 
 #define PCI_CHSWP_CSR		2	/* Control and Status Register */

-- 
To view, visit https://review.coreboot.org/26329
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I94413712e7986efd17e6b11ba59f6eb390384c8c
Gerrit-Change-Number: 26329
Gerrit-PatchSet: 17
Gerrit-Owner: Patrick Rudolph <patrick.rudolph at 9elements.com>
Gerrit-Reviewer: Aaron Durbin <adurbin at chromium.org>
Gerrit-Reviewer: Julius Werner <jwerner at chromium.org>
Gerrit-Reviewer: Patrick Rudolph <patrick.rudolph at 9elements.com>
Gerrit-Reviewer: Paul Menzel <paulepanter at users.sourceforge.net>
Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki at gmail.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply at coreboot.org>
Gerrit-CC: Nico Huber <nico.h at gmx.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180719/02b60b36/attachment.html>


More information about the coreboot-gerrit mailing list