Module Name:    src
Committed By:   matt
Date:           Fri Jan  7 02:26:15 UTC 2011

Modified Files:
        src/sys/dev/pci [matt-nb5-pq3]: pci_subr.c pcireg.h pcivar.h

Log Message:
Add/define some MSI support


To generate a diff of this commit:
cvs rdiff -u -r1.75.10.1 -r1.75.10.1.8.1 src/sys/dev/pci/pci_subr.c
cvs rdiff -u -r1.57.20.1 -r1.57.20.1.2.1 src/sys/dev/pci/pcireg.h
cvs rdiff -u -r1.83 -r1.83.18.1 src/sys/dev/pci/pcivar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/pci_subr.c
diff -u src/sys/dev/pci/pci_subr.c:1.75.10.1 src/sys/dev/pci/pci_subr.c:1.75.10.1.8.1
--- src/sys/dev/pci/pci_subr.c:1.75.10.1	Tue Feb 24 03:50:48 2009
+++ src/sys/dev/pci/pci_subr.c	Fri Jan  7 02:26:15 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_subr.c,v 1.75.10.1 2009/02/24 03:50:48 snj Exp $	*/
+/*	$NetBSD: pci_subr.c,v 1.75.10.1.8.1 2011/01/07 02:26:15 matt Exp $	*/
 
 /*
  * Copyright (c) 1997 Zubin D. Dittia.  All rights reserved.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.75.10.1 2009/02/24 03:50:48 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.75.10.1.8.1 2011/01/07 02:26:15 matt Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_pci.h"
@@ -433,8 +433,9 @@
 
 #define	i2o(i)	((i) * 4)
 #define	o2i(o)	((o) / 4)
-#define	onoff(str, bit)							\
-	printf("      %s: %s\n", (str), (rval & (bit)) ? "on" : "off");
+#define	onoff2(str, bit, onstr, offstr)					\
+	printf("      %s: %s\n", (str), (rval & (bit)) ? onstr : offstr);
+#define	onoff(str, bit)	onoff2(str, bit, "on", "off")
 
 static void
 pci_conf_print_common(
@@ -477,6 +478,7 @@
 	onoff("Interrupt disable", PCI_COMMAND_INTERRUPT_DISABLE);
 
 	printf("    Status register: 0x%04x\n", (rval >> 16) & 0xffff);
+	onoff2("Interrupt status", PCI_STATUS_INT_STATUS, "active", "inactive");
 	onoff("Capability List support", PCI_STATUS_CAPLIST_SUPPORT);
 	onoff("66 MHz capable", PCI_STATUS_66MHZ_SUPPORT);
 	onoff("User Definable Features (UDF) support", PCI_STATUS_UDF_SUPPORT);
@@ -819,6 +821,29 @@
 		printf("    Slot implemented\n");
 	printf("    Interrupt Message Number: %x\n",
 	    (unsigned int)((regs[o2i(capoff)] & 0x4e000000) >> 27));
+	printf("    Link Capabilities Register: 0x%08x\n",
+	    regs[o2i(capoff + 0x0c)]);
+	printf("      Maximum Link Speed: ");
+	if ((regs[o2i(capoff + 0x0c)] & 0x000f) != 1) {
+		printf("unknown %u value\n", 
+		    (regs[o2i(capoff + 0x0c)] & 0x000f));
+	} else {
+		printf("2.5Gb/s\n");
+	}
+	printf("      Maximum Link Width: x%u lanes\n",
+	    (regs[o2i(capoff + 0x0c)] & 0x03f0) >> 4);
+	printf("      Port Number: %u\n", regs[o2i(capoff + 0x0c)] >> 24);
+	printf("    Link Status Register: 0x%04x\n",
+	    regs[o2i(capoff + 0x10)] >> 16);
+	printf("      Negotiated Link Speed: ");
+	if (((regs[o2i(capoff + 0x10)] >> 16) & 0x000f) != 1) {
+		printf("unknown %u value\n", 
+		    (regs[o2i(capoff + 0x10)] >> 16) & 0x000f);
+	} else {
+		printf("2.5Gb/s\n");
+	}
+	printf("      Negotiated Link Width: x%u lanes\n",
+	    (regs[o2i(capoff + 0x10)] >> 20) & 0x003f);
 	if ((regs[o2i(capoff + 0x18)] & 0x07ff) != 0) {
 		printf("    Slot Control Register:\n");
 		if ((regs[o2i(capoff + 0x18)] & 0x0001) != 0)
@@ -934,6 +959,41 @@
 }
 
 static void
+pci_conf_print_msi_cap(const pcireg_t *regs, int capoff)
+{
+	uint32_t ctl, mmc, mme;
+
+	regs += o2i(capoff);
+	ctl = *regs++;
+	mmc = (ctl >> PCI_MSI_CTL_MMC_SHIFT) & PCI_MSI_CTL_MMC_MASK;
+	mme = (ctl >> PCI_MSI_CTL_MME_SHIFT) & PCI_MSI_CTL_MME_MASK;
+
+	printf("\n  PCI Message Signaled Interrupt\n");
+
+	printf("    Message Control register: 0x%04x\n", ctl >> 16);
+	printf("      MSI Enabled: %s\n",
+	    ctl & PCI_MSI_CTL_MSI_ENABLE ? "yes" : "no");
+	printf("      Multiple Message Capable: %s (%d vector%s)\n",
+	    mmc > 0 ? "yes" : "no", 1 << mmc, mmc > 0 ? "s" : "");
+	printf("      Multiple Message Enabled: %s (%d vector%s)\n",
+	    mme > 0 ? "on" : "off", 1 << mme, mme > 0 ? "s" : "");
+	printf("      64 Bit Address Capable: %s\n",
+	    ctl & PCI_MSI_CTL_64BIT_ADDR ? "yes" : "no");
+	printf("      Per-Vector Masking Capable: %s\n",
+	    ctl & PCI_MSI_CTL_PERVEC_MASK ? "yes" : "no");
+	printf("    Message Address %sregister: 0x%08x\n",
+	    ctl & PCI_MSI_CTL_64BIT_ADDR ? "(lower) " : "", *regs++);
+	if (ctl & PCI_MSI_CTL_64BIT_ADDR) {
+		printf("    Message Address %sregister: 0x%08x\n",
+		    "(upper) ", *regs++);
+	}
+	printf("    Message Data register: 0x%08x\n", *regs++);
+	if (ctl & PCI_MSI_CTL_PERVEC_MASK) {
+		printf("    Vector Mask register: 0x%08x\n", *regs++);
+		printf("    Vector Pending register: 0x%08x\n", *regs++);
+	}
+}
+static void
 pci_conf_print_caplist(
 #ifdef _KERNEL
     pci_chipset_tag_t pc, pcitag_t tag,
@@ -942,7 +1002,7 @@
 {
 	int off;
 	pcireg_t rval;
-	int pcie_off = -1, pcipm_off = -1;
+	int pcie_off = -1, pcipm_off = -1, msi_off = -1;
 
 	for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]);
 	     off != 0;
@@ -973,6 +1033,7 @@
 			break;
 		case PCI_CAP_MSI:
 			printf("MSI");
+			msi_off = off;
 			break;
 		case PCI_CAP_CPCI_HOTSWAP:
 			printf("CompactPCI Hot-swapping");
@@ -1013,6 +1074,8 @@
 		}
 		printf(")\n");
 	}
+	if (msi_off != -1)
+		pci_conf_print_msi_cap(regs, msi_off);
 	if (pcipm_off != -1)
 		pci_conf_print_pcipm_cap(regs, pcipm_off);
 	if (pcie_off != -1)

Index: src/sys/dev/pci/pcireg.h
diff -u src/sys/dev/pci/pcireg.h:1.57.20.1 src/sys/dev/pci/pcireg.h:1.57.20.1.2.1
--- src/sys/dev/pci/pcireg.h:1.57.20.1	Fri Nov 19 23:40:28 2010
+++ src/sys/dev/pci/pcireg.h	Fri Jan  7 02:26:15 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcireg.h,v 1.57.20.1 2010/11/19 23:40:28 riz Exp $	*/
+/*	$NetBSD: pcireg.h,v 1.57.20.1.2.1 2011/01/07 02:26:15 matt Exp $	*/
 
 /*
  * Copyright (c) 1995, 1996, 1999, 2000
@@ -87,6 +87,7 @@
 #define	PCI_COMMAND_BACKTOBACK_ENABLE		0x00000200
 #define	PCI_COMMAND_INTERRUPT_DISABLE		0x00000400
 
+#define	PCI_STATUS_INT_STATUS			0x00080000
 #define	PCI_STATUS_CAPLIST_SUPPORT		0x00100000
 #define	PCI_STATUS_66MHZ_SUPPORT		0x00200000
 #define	PCI_STATUS_UDF_SUPPORT			0x00400000
@@ -338,9 +339,12 @@
 /*
  * PCI header type
  */
-#define PCI_HDRTYPE_DEVICE	0
-#define PCI_HDRTYPE_PPB		1
-#define PCI_HDRTYPE_PCB		2
+#define PCI_HDRTYPE_DEVICE	0	/* PCI/PCIX/Cardbus */
+#define PCI_HDRTYPE_PPB		1	/* PCI/PCIX/Cardbus */
+#define PCI_HDRTYPE_PCB		2	/* PCI/PCIX/Cardbus */
+#define	PCI_HDRTYPE_EP		0	/* PCI Express */
+#define	PCI_HDRTYPE_RC		1	/* PCI Express */
+
 
 /*
  * Mapping registers
@@ -351,6 +355,15 @@
 #define	PCI_MAPREG_PPB_END		0x18
 #define	PCI_MAPREG_PCB_END		0x14
 
+#define PCI_BAR0		0x10
+#define PCI_BAR1		0x14
+#define PCI_BAR2		0x18
+#define PCI_BAR3		0x1C
+#define PCI_BAR4		0x20
+#define PCI_BAR5		0x24
+
+#define	PCI_BAR(__n)		(0x10 + 4 * (__n))
+
 #define	PCI_MAPREG_TYPE(mr)						\
 	    ((mr) & PCI_MAPREG_TYPE_MASK)
 #define	PCI_MAPREG_TYPE_MASK			0x00000001
@@ -448,6 +461,49 @@
 #define	PCI_VPD_DATAREG(ofs)	((ofs) + 4)
 #define	PCI_VPD_OPFLAG		0x80000000
 
+#define	PCI_MSI_CTL_PERVEC_MASK	0x01000000
+#define	PCI_MSI_CTL_64BIT_ADDR	0x00800000
+#define	PCI_MSI_CTL_MME_MASK	0x7
+#define	PCI_MSI_CTL_MME_SHIFT	20
+#define	PCI_MSI_CTL_MME(ofs)	(((ofs) & PCI_MSI_CTL_MME_MASK) << PCI_MSI_CTL_MME_SHIFT)
+#define	PCI_MSI_CTL_MMC_MASK	0x7
+#define	PCI_MSI_CTL_MMC_SHIFT	17
+#define	PCI_MSI_CTL_MMC(ofs)	(((ofs) >> PCI_MSI_CTL_MME_SHIFT) & PCI_MSI_CTL_MME_MASK)
+#define	PCI_MSI_CTL_MSI_ENABLE	0x00010000
+/*
+ * MSI Message Address is at offset 4.
+ * MSI Message Upper Address (if 64bit) is at offset 8.
+ * MSI Message data is at offset 8 or 12 and is 16 bits.
+ * [16 bit reserved field]
+ * MSI Mask Bits (32 bit field)
+ * MSI Pending Bits (32 bit field)
+ */
+
+#define	PCI_MSIX_CTL_ENABLE	0x80000000
+#define	PCI_MSIX_CTL_FUNCMASK	0x40000000
+#define	PCI_MSIX_CTL_TBLSIZE_MASK 0x07ff0000
+#define	PCI_MSIX_CTL_TBLSIZE_SHIFT 16
+#define	PCI_MSIX_CTL_TBLSIZE(ofs)	(((ofs) >> PCI_MSIX_CTL_TBLSIZE_SHIFT) & PCI_MSIX_CTL_TBLSIZE_MASK)
+/*
+ * 2nd DWORD is the Table Offset
+ */
+#define	PCI_MSIX_TBLOFFSET_MASK	0xfffffff8
+#define	PCI_MSIX_TBLBIR_MASK	0x00000007
+/*
+ * 3rd DWORD is the Pending Bitmap Array Offset
+ */
+#define	PCI_MSIX_PBAOFFSET_MASK	0xfffffff8
+#define	PCI_MSIX_PBABIR_MASK	0x00000007
+
+struct pci_msix_table_entry {
+	uint32_t pci_msix_addr_lo;
+	uint32_t pci_msix_addr_hi;
+	uint32_t pci_msix_value;
+	uint32_t pci_msix_vendor_control;
+};
+#define	PCI_MSIX_VENDCTL_MASK	0x00000001
+
+
 /*
  * Power Management Capability; access via capability pointer.
  */

Index: src/sys/dev/pci/pcivar.h
diff -u src/sys/dev/pci/pcivar.h:1.83 src/sys/dev/pci/pcivar.h:1.83.18.1
--- src/sys/dev/pci/pcivar.h:1.83	Tue Jul 22 04:52:19 2008
+++ src/sys/dev/pci/pcivar.h	Fri Jan  7 02:26:15 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pcivar.h,v 1.83 2008/07/22 04:52:19 bjs Exp $	*/
+/*	$NetBSD: pcivar.h,v 1.83.18.1 2011/01/07 02:26:15 matt Exp $	*/
 
 /*
  * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
@@ -128,6 +128,10 @@
 #define	PCI_FLAGS_MRM_OKAY	0x08		/* Memory Read Multiple okay */
 #define	PCI_FLAGS_MWI_OKAY	0x10		/* Memory Write and Invalidate
 						   okay */
+#define	PCI_FLAGS_MSI_OKAY	0x20		/* Message Signaled Interrupts
+						   okay */
+#define	PCI_FLAGS_MSIX_OKAY	0x40		/* Message Signaled Interrupts
+						   (Extended) okay */
 
 /*
  * PCI device 'quirks'.

Reply via email to