Author: jhb
Date: Wed Sep  8 17:53:34 2010
New Revision: 212326
URL: http://svn.freebsd.org/changeset/base/212326

Log:
  - 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.   Adds
    more detailed parsing for AER, VC, and device serial numbers.
  
  MFC after:    2 weeks

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

Modified: head/sys/dev/pci/pcireg.h
==============================================================================
--- head/sys/dev/pci/pcireg.h   Wed Sep  8 17:35:06 2010        (r212325)
+++ head/sys/dev/pci/pcireg.h   Wed Sep  8 17:53:34 2010        (r212326)
@@ -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 */
@@ -117,6 +118,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
@@ -663,3 +686,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        PCIR_AER_UC_TRAINING_ERROR      0x00000001
+#define        PCIR_AER_UC_DL_PROTOCOL_ERROR   0x00000010
+#define        PCIR_AER_UC_POISONED_TLP        0x00001000
+#define        PCIR_AER_UC_FC_PROTOCOL_ERROR   0x00002000
+#define        PCIR_AER_UC_COMPLETION_TIMEOUT  0x00004000
+#define        PCIR_AER_UC_COMPLETER_ABORT     0x00008000
+#define        PCIR_AER_UC_UNEXPECTED_COMPLETION 0x00010000
+#define        PCIR_AER_UC_RECEIVER_OVERFLOW   0x00020000
+#define        PCIR_AER_UC_MALFORMED_TLP       0x00040000
+#define        PCIR_AER_UC_ECRC_ERROR          0x00080000
+#define        PCIR_AER_UC_UNSUPPORTED_REQUEST 0x00100000
+#define        PCIR_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        PCIR_AER_ROOTERR_COR_ENABLE     0x00000001
+#define        PCIR_AER_ROOTERR_NF_ENABLE      0x00000002
+#define        PCIR_AER_ROOTERR_F_ENABLE       0x00000004
+#define        PCIR_AER_ROOTERR_STATUS 0x30    /* Only for root complex ports 
*/
+#define        PCIR_AER_ROOTERR_COR_ERR        0x00000001
+#define        PCIR_AER_ROOTERR_MULTI_COR_ERR  0x00000002
+#define        PCIR_AER_ROOTERR_UC_ERR         0x00000004
+#define        PCIR_AER_ROOTERR_MULTI_UC_ERR   0x00000008
+#define        PCIR_AER_ROOTERR_FIRST_UC_FATAL 0x00000010
+#define        PCIR_AER_ROOTERR_NF_ERR         0x00000020
+#define        PCIR_AER_ROOTERR_F_ERR          0x00000040
+#define        PCIR_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: head/usr.sbin/pciconf/cap.c
==============================================================================
--- head/usr.sbin/pciconf/cap.c Wed Sep  8 17:35:06 2010        (r212325)
+++ head/usr.sbin/pciconf/cap.c Wed Sep  8 17:53:34 2010        (r212326)
@@ -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)
 {
@@ -530,4 +532,97 @@ list_caps(int fd, struct pci_conf *p)
                printf("\n");
                ptr = read_config(fd, &p->pc_sel, ptr + PCICAP_NEXTPTR, 1);
        }
+
+       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);
+       }
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to