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>