Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Dec 2019 23:47:00 +0000 (UTC)
From:      Scott Long <scottl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r355741 - in head: sys/dev/pci usr.sbin/pciconf
Message-ID:  <201912132347.xBDNl0Cb019267@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: scottl
Date: Fri Dec 13 23:46:59 2019
New Revision: 355741
URL: https://svnweb.freebsd.org/changeset/base/355741

Log:
  Add accessors for the Vendor Specific Extended Capability (VSEC)
  Parse out the VSEC.  If the user invokes a second -c command line option,
  do a hex dump of the vendor data.
  
  Reviewed by:	imp
  MFC after:	3 days
  Sponsored by:	Intel
  Differential Revision:	http://reviews.freebsd.org/D22808

Modified:
  head/sys/dev/pci/pcireg.h
  head/usr.sbin/pciconf/cap.c
  head/usr.sbin/pciconf/pciconf.8
  head/usr.sbin/pciconf/pciconf.c
  head/usr.sbin/pciconf/pciconf.h

Modified: head/sys/dev/pci/pcireg.h
==============================================================================
--- head/sys/dev/pci/pcireg.h	Fri Dec 13 23:33:54 2019	(r355740)
+++ head/sys/dev/pci/pcireg.h	Fri Dec 13 23:46:59 2019	(r355741)
@@ -1049,6 +1049,13 @@
 #define	PCIR_SRIOV_BARS		0x24
 #define	PCIR_SRIOV_BAR(x)	(PCIR_SRIOV_BARS + (x) * 4)
 
+/* Extended Capability Vendor-Specific definitions */
+#define PCIR_VSEC_HEADER	0x04
+#define PCIR_VSEC_ID(hdr)	((hdr) & 0xffff)
+#define PCIR_VSEC_REV(hdr)	(((hdr) & 0xf0000) >> 16)
+#define PCIR_VSEC_LENGTH(hdr)	(((hdr) & 0xfff00000) >> 20)
+#define PCIR_VSEC_DATA		0x08
+
 /*
  * PCI Express Firmware Interface definitions
  */

Modified: head/usr.sbin/pciconf/cap.c
==============================================================================
--- head/usr.sbin/pciconf/cap.c	Fri Dec 13 23:33:54 2019	(r355740)
+++ head/usr.sbin/pciconf/cap.c	Fri Dec 13 23:46:59 2019	(r355741)
@@ -50,6 +50,8 @@ static const char rcsid[] =
 
 static void	list_ecaps(int fd, struct pci_conf *p);
 
+static int cap_level;
+
 static void
 cap_power(int fd, struct pci_conf *p, uint8_t ptr)
 {
@@ -729,7 +731,7 @@ cap_ea(int fd, struct pci_conf *p, uint8_t ptr)
 }
 
 void
-list_caps(int fd, struct pci_conf *p)
+list_caps(int fd, struct pci_conf *p, int level)
 {
 	int express;
 	uint16_t sta;
@@ -740,6 +742,8 @@ list_caps(int fd, struct pci_conf *p)
 	if (!(sta & PCIM_STATUS_CAPPRESENT))
 		return;
 
+	cap_level = level;
+
 	switch (p->pc_hdr & PCIM_HDRTYPE) {
 	case PCIM_HDRTYPE_NORMAL:
 	case PCIM_HDRTYPE_BRIDGE:
@@ -875,13 +879,33 @@ ecap_sernum(int fd, struct pci_conf *p, uint16_t ptr, 
 static void
 ecap_vendor(int fd, struct pci_conf *p, uint16_t ptr, uint8_t ver)
 {
-	uint32_t val;
+	uint32_t val, hdr;
+	uint16_t nextptr, len;
+	int i;
 
-	printf("Vendor %d", ver);
-	if (ver < 1)
+	val = read_config(fd, &p->pc_sel, ptr, 4);
+	nextptr = PCI_EXTCAP_NEXTPTR(val);
+	hdr = read_config(fd, &p->pc_sel, ptr + PCIR_VSEC_HEADER, 4);
+	len = PCIR_VSEC_LENGTH(hdr);
+	if (len == 0) {
+		if (nextptr == 0)
+			nextptr = 0x1000;
+		len = nextptr - ptr;
+	}
+
+	printf("Vendor [%d] ID %04x Rev %d Length %d\n", ver,
+	    PCIR_VSEC_ID(hdr), PCIR_VSEC_REV(hdr), len);
+	if ((ver < 1) || (cap_level <= 1))
 		return;
-	val = read_config(fd, &p->pc_sel, ptr + 4, 4);
-	printf(" ID %d\n", val & 0xffff);
+	for (i = 0; i < len; i += 4) {
+		val = read_config(fd, &p->pc_sel, ptr + PCIR_VSEC_DATA + i, 4);
+		if ((i % 16) == 0)
+			printf("                 ");
+		printf("%02x %02x %02x %02x ", val & 0xff, (val >> 8) & 0xff,
+		    (val >> 16) & 0xff, (val >> 24) & 0xff);
+		if ((((i + 4) % 16) == 0 ) || ((i + 4) >= len))
+			printf("\n");
+	}
 }
 
 static void

Modified: head/usr.sbin/pciconf/pciconf.8
==============================================================================
--- head/usr.sbin/pciconf/pciconf.8	Fri Dec 13 23:33:54 2019	(r355740)
+++ head/usr.sbin/pciconf/pciconf.8	Fri Dec 13 23:46:59 2019	(r355741)
@@ -177,6 +177,9 @@ If the
 option is supplied,
 .Nm
 will list any capabilities supported by each device.
+A second invocation of
+.Fl c
+will print additional data for certain capabilities.
 Each capability is enumerated via a line in the following format:
 .Bd -literal
     cap 10[40] = PCI-Express 1 root port

Modified: head/usr.sbin/pciconf/pciconf.c
==============================================================================
--- head/usr.sbin/pciconf/pciconf.c	Fri Dec 13 23:33:54 2019	(r355740)
+++ head/usr.sbin/pciconf/pciconf.c	Fri Dec 13 23:46:59 2019	(r355741)
@@ -131,7 +131,7 @@ main(int argc, char **argv)
 			break;
 
 		case 'c':
-			caps = 1;
+			caps++;
 			break;
 
 		case 'D':
@@ -282,7 +282,7 @@ list_devs(const char *name, int verbose, int bars, int
 			if (bridge)
 				list_bridge(fd, p);
 			if (caps)
-				list_caps(fd, p);
+				list_caps(fd, p, caps);
 			if (errors)
 				list_errors(fd, p);
 			if (vpd)

Modified: head/usr.sbin/pciconf/pciconf.h
==============================================================================
--- head/usr.sbin/pciconf/pciconf.h	Fri Dec 13 23:33:54 2019	(r355740)
+++ head/usr.sbin/pciconf/pciconf.h	Fri Dec 13 23:46:59 2019	(r355741)
@@ -35,7 +35,7 @@
 #ifndef __PCICONF_H__
 #define	__PCICONF_H__
 
-void	list_caps(int fd, struct pci_conf *p);
+void	list_caps(int fd, struct pci_conf *p, int level);
 void	list_errors(int fd, struct pci_conf *p);
 uint8_t	pci_find_cap(int fd, struct pci_conf *p, uint8_t id);
 uint16_t pcie_find_cap(int fd, struct pci_conf *p, uint16_t id);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201912132347.xBDNl0Cb019267>