svn commit: r212923 - in stable/8: sys/dev/pci usr.sbin/pciconf

John Baldwin jhb at FreeBSD.org
Mon Sep 20 19:29:49 UTC 2010


Author: jhb
Date: Mon Sep 20 19:29:48 2010
New Revision: 212923
URL: http://svn.freebsd.org/changeset/base/212923

Log:
  MFC 209907,212326,212368,212749:
  - Provide more defines for PCI-Express device ctrl.
  - Add register definitions related to extended capability IDs in
    PCI-express.  I used PCIZ_* for ID constants (plain capability IDs use
    PCIY_*).
  - Add register definitions for the Advanced Error Reporting, Virtual
    Channels, and Device Serial Number extended capabilities.
  - Teach pciconf -c to list extended as well as plain capabilities for
    PCI-express devices.   Adds more detailed parsing for AER, VC, and
    device serial numbers.

Modified:
  stable/8/sys/dev/pci/pcireg.h
  stable/8/usr.sbin/pciconf/cap.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/usr.sbin/pciconf/   (props changed)

Modified: stable/8/sys/dev/pci/pcireg.h
==============================================================================
--- stable/8/sys/dev/pci/pcireg.h	Mon Sep 20 19:25:27 2010	(r212922)
+++ stable/8/sys/dev/pci/pcireg.h	Mon Sep 20 19:29:48 2010	(r212923)
@@ -36,6 +36,7 @@
  * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
  * PCID_xxx: device ID
  * PCIY_xxx: capability identification number
+ * PCIZ_xxx: extended capability identification number
  */
 
 /* some PCI bus constants */
@@ -66,7 +67,8 @@
 #define	PCIM_STATUS_CAPPRESENT	0x0010
 #define	PCIM_STATUS_66CAPABLE	0x0020
 #define	PCIM_STATUS_BACKTOBACK	0x0080
-#define	PCIM_STATUS_PERRREPORT	0x0100
+#define	PCIM_STATUS_MDPERR	0x0100
+#define	PCIM_STATUS_PERRREPORT	PCIM_STATUS_MDPERR
 #define	PCIM_STATUS_SEL_FAST	0x0000
 #define	PCIM_STATUS_SEL_MEDIMUM	0x0200
 #define	PCIM_STATUS_SEL_SLOW	0x0400
@@ -117,6 +119,28 @@
 #define	PCIY_SATA	0x12	/* SATA */
 #define	PCIY_PCIAF	0x13	/* PCI Advanced Features */
 
+/* Extended Capability Register Fields */
+
+#define	PCIR_EXTCAP	0x100
+#define	PCIM_EXTCAP_ID		0x0000ffff
+#define	PCIM_EXTCAP_VER		0x000f0000
+#define	PCIM_EXTCAP_NEXTPTR	0xfff00000
+#define	PCI_EXTCAP_ID(ecap)	((ecap) & PCIM_EXTCAP_ID)
+#define	PCI_EXTCAP_VER(ecap)	(((ecap) & PCIM_EXTCAP_VER) >> 16)
+#define	PCI_EXTCAP_NEXTPTR(ecap) (((ecap) & PCIM_EXTCAP_NEXTPTR) >> 20)
+
+/* Extended Capability Identification Numbers */
+
+#define	PCIZ_AER	0x0001	/* Advanced Error Reporting */
+#define	PCIZ_VC		0x0002	/* Virtual Channel */
+#define	PCIZ_SERNUM	0x0003	/* Device Serial Number */
+#define	PCIZ_PWRBDGT	0x0004	/* Power Budgeting */
+#define	PCIZ_VENDOR	0x000b	/* Vendor Unique */
+#define	PCIZ_ACS	0x000d	/* Access Control Services */
+#define	PCIZ_ARI	0x000e	/* Alternative Routing-ID Interpretation */
+#define	PCIZ_ATS	0x000f	/* Address Translation Services */
+#define	PCIZ_SRIOV	0x0010	/* Single Root IO Virtualization */
+
 /* config registers for header type 0 devices */
 
 #define	PCIR_BARS	0x10
@@ -605,6 +629,9 @@
 #define	PCIR_EXPRESS_DEVICE_CAP	0x4
 #define	PCIM_EXP_CAP_MAX_PAYLOAD	0x0007
 #define	PCIR_EXPRESS_DEVICE_CTL	0x8
+#define	PCIM_EXP_CTL_NFER_ENABLE	0x0002
+#define	PCIM_EXP_CTL_FER_ENABLE		0x0004
+#define	PCIM_EXP_CTL_URR_ENABLE		0x0008
 #define	PCIM_EXP_CTL_RELAXED_ORD_ENABLE	0x0010
 #define	PCIM_EXP_CTL_MAX_PAYLOAD	0x00e0
 #define	PCIM_EXP_CTL_NOSNOOP_ENABLE	0x0800
@@ -660,3 +687,64 @@
 #define	PCIR_PCIAFCTRL_FLR	0x01
 #define	PCIR_PCIAF_STATUS	0x5
 #define	PCIR_PCIAFSTATUS_TP	0x01
+
+/* Advanced Error Reporting */
+#define	PCIR_AER_UC_STATUS	0x04
+#define	PCIM_AER_UC_TRAINING_ERROR	0x00000001
+#define	PCIM_AER_UC_DL_PROTOCOL_ERROR	0x00000010
+#define	PCIM_AER_UC_POISONED_TLP	0x00001000
+#define	PCIM_AER_UC_FC_PROTOCOL_ERROR	0x00002000
+#define	PCIM_AER_UC_COMPLETION_TIMEOUT	0x00004000
+#define	PCIM_AER_UC_COMPLETER_ABORT	0x00008000
+#define	PCIM_AER_UC_UNEXPECTED_COMPLETION 0x00010000
+#define	PCIM_AER_UC_RECEIVER_OVERFLOW	0x00020000
+#define	PCIM_AER_UC_MALFORMED_TLP	0x00040000
+#define	PCIM_AER_UC_ECRC_ERROR		0x00080000
+#define	PCIM_AER_UC_UNSUPPORTED_REQUEST	0x00100000
+#define	PCIM_AER_UC_ACS_VIOLATION	0x00200000
+#define	PCIR_AER_UC_MASK	0x08	/* Shares bits with UC_STATUS */
+#define	PCIR_AER_UC_SEVERITY	0x0c	/* Shares bits with UC_STATUS */
+#define	PCIR_AER_COR_STATUS	0x10
+#define	PCIM_AER_COR_RECEIVER_ERROR	0x00000001
+#define	PCIM_AER_COR_BAD_TLP		0x00000040
+#define	PCIM_AER_COR_BAD_DLLP		0x00000080
+#define	PCIM_AER_COR_REPLAY_ROLLOVER	0x00000100
+#define	PCIM_AER_COR_REPLAY_TIMEOUT	0x00001000
+#define	PCIR_AER_COR_MASK	0x14	/* Shares bits with COR_STATUS */
+#define	PCIR_AER_CAP_CONTROL	0x18
+#define	PCIM_AER_FIRST_ERROR_PTR	0x0000001f
+#define	PCIM_AER_ECRC_GEN_CAPABLE	0x00000020
+#define	PCIM_AER_ECRC_GEN_ENABLE	0x00000040
+#define	PCIM_AER_ECRC_CHECK_CAPABLE	0x00000080
+#define	PCIM_AER_ECRC_CHECK_ENABLE	0x00000100
+#define	PCIR_AER_HEADER_LOG	0x1c
+#define	PCIR_AER_ROOTERR_CMD	0x2c	/* Only for root complex ports */
+#define	PCIM_AER_ROOTERR_COR_ENABLE	0x00000001
+#define	PCIM_AER_ROOTERR_NF_ENABLE	0x00000002
+#define	PCIM_AER_ROOTERR_F_ENABLE	0x00000004
+#define	PCIR_AER_ROOTERR_STATUS	0x30	/* Only for root complex ports */
+#define	PCIM_AER_ROOTERR_COR_ERR	0x00000001
+#define	PCIM_AER_ROOTERR_MULTI_COR_ERR	0x00000002
+#define	PCIM_AER_ROOTERR_UC_ERR		0x00000004
+#define	PCIM_AER_ROOTERR_MULTI_UC_ERR	0x00000008
+#define	PCIM_AER_ROOTERR_FIRST_UC_FATAL	0x00000010
+#define	PCIM_AER_ROOTERR_NF_ERR		0x00000020
+#define	PCIM_AER_ROOTERR_F_ERR		0x00000040
+#define	PCIM_AER_ROOTERR_INT_MESSAGE	0xf8000000
+#define	PCIR_AER_COR_SOURCE_ID	0x34	/* Only for root complex ports */
+#define	PCIR_AER_ERR_SOURCE_ID	0x36	/* Only for root complex ports */
+
+/* Virtual Channel definitions */
+#define	PCIR_VC_CAP1		0x04
+#define	PCIM_VC_CAP1_EXT_COUNT		0x00000007
+#define	PCIM_VC_CAP1_LOWPRI_EXT_COUNT	0x00000070
+#define	PCIR_VC_CAP2		0x08
+#define	PCIR_VC_CONTROL		0x0C
+#define	PCIR_VC_STATUS		0x0E
+#define	PCIR_VC_RESOURCE_CAP(n)	(0x10 + (n) * 0x0C)
+#define	PCIR_VC_RESOURCE_CTL(n)	(0x14 + (n) * 0x0C)
+#define	PCIR_VC_RESOURCE_STA(n)	(0x18 + (n) * 0x0C)
+
+/* Serial Number definitions */
+#define	PCIR_SERIAL_LOW		0x04
+#define	PCIR_SERIAL_HIGH	0x08

Modified: stable/8/usr.sbin/pciconf/cap.c
==============================================================================
--- stable/8/usr.sbin/pciconf/cap.c	Mon Sep 20 19:25:27 2010	(r212922)
+++ stable/8/usr.sbin/pciconf/cap.c	Mon Sep 20 19:29:48 2010	(r212923)
@@ -45,6 +45,8 @@ static const char rcsid[] =
 
 #include "pciconf.h"
 
+static void	list_ecaps(int fd, struct pci_conf *p);
+
 static void
 cap_power(int fd, struct pci_conf *p, uint8_t ptr)
 {
@@ -458,6 +460,7 @@ cap_pciaf(int fd, struct pci_conf *p, ui
 void
 list_caps(int fd, struct pci_conf *p)
 {
+	int express;
 	uint16_t sta;
 	uint8_t ptr, cap;
 
@@ -479,6 +482,7 @@ list_caps(int fd, struct pci_conf *p)
 	}
 
 	/* Walk the capability list. */
+	express = 0;
 	ptr = read_config(fd, &p->pc_sel, ptr, 1);
 	while (ptr != 0 && ptr != 0xff) {
 		cap = read_config(fd, &p->pc_sel, ptr + PCICAP_ID, 1);
@@ -512,6 +516,7 @@ list_caps(int fd, struct pci_conf *p)
 			cap_subvendor(fd, p, ptr);
 			break;
 		case PCIY_EXPRESS:
+			express = 1;
 			cap_express(fd, p, ptr);
 			break;
 		case PCIY_MSIX:
@@ -530,4 +535,98 @@ list_caps(int fd, struct pci_conf *p)
 		printf("\n");
 		ptr = read_config(fd, &p->pc_sel, ptr + PCICAP_NEXTPTR, 1);
 	}
+
+	if (express)
+		list_ecaps(fd, p);
+}
+
+/* From <sys/systm.h>. */
+static __inline uint32_t
+bitcount32(uint32_t x)
+{
+
+	x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
+	x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
+	x = (x + (x >> 4)) & 0x0f0f0f0f;
+	x = (x + (x >> 8));
+	x = (x + (x >> 16)) & 0x000000ff;
+	return (x);
+}
+
+static void
+ecap_aer(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver)
+{
+	uint32_t sta, mask;
+
+	printf("AER %d", ver);
+	if (ver != 1)
+		return;
+	sta = read_config(fd, &p->pc_sel, ptr + PCIR_AER_UC_STATUS, 4);
+	mask = read_config(fd, &p->pc_sel, ptr + PCIR_AER_UC_SEVERITY, 4);
+	printf(" %d fatal", bitcount32(sta & mask));
+	printf(" %d non-fatal", bitcount32(sta & ~mask));
+	sta = read_config(fd, &p->pc_sel, ptr + PCIR_AER_COR_STATUS, 4);
+	printf(" %d corrected", bitcount32(sta));
+}
+
+static void
+ecap_vc(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver)
+{
+	uint32_t cap1;
+
+	printf("VC %d", ver);
+	if (ver != 1)
+		return;
+	cap1 = read_config(fd, &p->pc_sel, ptr + PCIR_VC_CAP1, 4);
+	printf(" max VC%d", cap1 & PCIM_VC_CAP1_EXT_COUNT);
+	if ((cap1 & PCIM_VC_CAP1_LOWPRI_EXT_COUNT) != 0)
+		printf(" lowpri VC0-VC%d",
+		    (cap1 & PCIM_VC_CAP1_LOWPRI_EXT_COUNT) >> 4);
+}
+
+static void
+ecap_sernum(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver)
+{
+	uint32_t high, low;
+
+	printf("Serial %d", ver);
+	if (ver != 1)
+		return;
+	low = read_config(fd, &p->pc_sel, ptr + PCIR_SERIAL_LOW, 4);
+	high = read_config(fd, &p->pc_sel, ptr + PCIR_SERIAL_HIGH, 4);
+	printf(" %08x%08x", high, low);
+}
+
+static void
+list_ecaps(int fd, struct pci_conf *p)
+{
+	uint32_t ecap;
+	uint16_t ptr;
+
+	ptr = PCIR_EXTCAP;
+	ecap = read_config(fd, &p->pc_sel, ptr, 4);
+	if (ecap == 0xffffffff || ecap == 0)
+		return;
+	for (;;) {
+		printf("ecap %04x[%03x] = ", PCI_EXTCAP_ID(ecap), ptr);
+		switch (PCI_EXTCAP_ID(ecap)) {
+		case PCIZ_AER:
+			ecap_aer(fd, p, ptr, PCI_EXTCAP_VER(ecap));
+			break;
+		case PCIZ_VC:
+			ecap_vc(fd, p, ptr, PCI_EXTCAP_VER(ecap));
+			break;
+		case PCIZ_SERNUM:
+			ecap_sernum(fd, p, ptr, PCI_EXTCAP_VER(ecap));
+			break;
+		default:
+			printf("unknown %d", PCI_EXTCAP_VER(ecap));
+			break;
+		}
+		printf("\n");
+		ptr = PCI_EXTCAP_NEXTPTR(ecap);
+		if (ptr == 0)
+			break;
+		ecap = read_config(fd, &p->pc_sel, ptr, 4);
+	}
 }


More information about the svn-src-all mailing list