svn commit: r355741 - in head: sys/dev/pci usr.sbin/pciconf
Scott Long
scottl at FreeBSD.org
Fri Dec 13 23:47:01 UTC 2019
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);
More information about the svn-src-head
mailing list