]> mj.ucw.cz Git - pciutils.git/blobdiff - ls-ecaps.c
pciutils: Decode Compute eXpress Link DVSEC
[pciutils.git] / ls-ecaps.c
index a26ea035d505a3f058bff1739c00654460d16e0d..fca19211b3ad8acf35f2aa98c04e3dc5401b38ef 100644 (file)
@@ -77,19 +77,19 @@ cap_ltr(struct device *d, int where)
 }
 
 static void
-cap_sec(struct device *d, int where, int type)
+cap_sec(struct device *d, int where)
 {
   u32 ctrl3, lane_err_stat;
   u8 lane;
   printf("Secondary PCI Express\n");
-  if (verbose < 2 && type == 0)
+  if (verbose < 2)
     return;
 
   if (!config_fetch(d, where + PCI_SEC_LNKCTL3, 12))
     return;
 
   ctrl3 = get_conf_word(d, where + PCI_SEC_LNKCTL3);
-  printf("\t\tLnkCtl3: LnkEquIntrruptEn%c, PerformEqu%c\n",
+  printf("\t\tLnkCtl3: LnkEquIntrruptEn%c PerformEqu%c\n",
        FLAG(ctrl3, PCI_SEC_LNKCTL3_LNK_EQU_REQ_INTR_EN),
        FLAG(ctrl3, PCI_SEC_LNKCTL3_PERFORM_LINK_EQU));
 
@@ -97,7 +97,7 @@ cap_sec(struct device *d, int where, int type)
   printf("\t\tLaneErrStat: ");
   if (lane_err_stat)
     {
-      printf("LaneErr at Lane:");
+      printf("LaneErr at lane:");
       for (lane = 0; lane_err_stat; lane_err_stat >>= 1, lane += 1)
         if (BITS(lane_err_stat, 0, 1))
           printf(" %u", lane);
@@ -634,6 +634,80 @@ cap_rclink(struct device *d, int where)
     }
 }
 
+static void
+cap_cxl(struct device *d, int where)
+{
+  u16 l;
+
+  printf("CXL Designated Vendor-Specific:\n");
+  if (verbose < 2)
+    return;
+
+  if (!config_fetch(d, where + PCI_CXL_CAP, 12))
+    return;
+
+  l = get_conf_word(d, where + PCI_CXL_CAP);
+  printf("\t\tCXLCap:\tCache%c IO%c Mem%c Mem HW Init%c HDMCount %d Viral%c\n",
+    FLAG(l, PCI_CXL_CAP_CACHE), FLAG(l, PCI_CXL_CAP_IO), FLAG(l, PCI_CXL_CAP_MEM),
+    FLAG(l, PCI_CXL_CAP_MEM_HWINIT), PCI_CXL_CAP_HDM_CNT(l), FLAG(l, PCI_CXL_CAP_VIRAL));
+
+  l = get_conf_word(d, where + PCI_CXL_CTRL);
+  printf("\t\tCXLCtl:\tCache%c IO%c Mem%c Cache SF Cov %d Cache SF Gran %d Cache Clean%c Viral%c\n",
+    FLAG(l, PCI_CXL_CTRL_CACHE), FLAG(l, PCI_CXL_CTRL_IO), FLAG(l, PCI_CXL_CTRL_MEM),
+    PCI_CXL_CTRL_CACHE_SF_COV(l), PCI_CXL_CTRL_CACHE_SF_GRAN(l), FLAG(l, PCI_CXL_CTRL_CACHE_CLN),
+    FLAG(l, PCI_CXL_CTRL_VIRAL));
+
+  l = get_conf_word(d, where + PCI_CXL_STATUS);
+  printf("\t\tCXLSta:\tViral%c\n", FLAG(l, PCI_CXL_STATUS_VIRAL));
+}
+
+static int
+is_cxl_cap(struct device *d, int where)
+{
+  u32 hdr;
+  u16 w;
+
+  if (!config_fetch(d, where + PCI_DVSEC_HEADER1, 8))
+    return 0;
+
+  /* Check for supported Vendor */
+  hdr = get_conf_long(d, where + PCI_DVSEC_HEADER1);
+  w = BITS(hdr, 0, 16);
+  if (w != PCI_VENDOR_ID_INTEL)
+    return 0;
+
+  /* Check for Designated Vendor-Specific ID */
+  hdr = get_conf_long(d, where + PCI_DVSEC_HEADER2);
+  w = BITS(hdr, 0, 16);
+  if (w == PCI_DVSEC_INTEL_CXL)
+    return 1;
+
+  return 0;
+}
+
+static void
+cap_dvsec(struct device *d, int where)
+{
+  u32 hdr;
+
+  printf("Designated Vendor-Specific:\n");
+  if (!config_fetch(d, where + PCI_DVSEC_HEADER1, 8))
+    {
+      printf("<unreadable>\n");
+      return;
+    }
+
+  hdr = get_conf_long(d, where + PCI_DVSEC_HEADER1);
+  printf("\t\tDVSEC Vendor ID=%04x Rev=%d Len=%03x <?>\n",
+    BITS(hdr, 0, 16),
+    BITS(hdr, 16, 4),
+    BITS(hdr, 20, 12));
+
+  hdr = get_conf_long(d, where + PCI_DVSEC_HEADER2);
+  printf("\t\tDVSEC ID=%04x <?>\n",
+    BITS(hdr, 0, 16));
+}
+
 static void
 cap_evendor(struct device *d, int where)
 {
@@ -711,17 +785,19 @@ cap_l1pm(struct device *d, int where)
     FLAG(val, PCI_L1PM_SUBSTAT_CTL1_ASPM_L11));
 
   if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
-    printf("\t\t\t   T_CommonMode=%dus", BITS(val, 8, 8));
-
-  if (l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
     {
-      scale = BITS(val, 29, 3);
-      if (scale > 5)
-       printf(" LTR1.2_Threshold=<error>");
-      else
-       printf(" LTR1.2_Threshold=%lldns", BITS(val, 16, 10) * (unsigned long long) cap_ltr_scale(scale));
+      printf("\t\t\t   T_CommonMode=%dus", BITS(val, 8, 8));
+
+      if (l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
+       {
+         scale = BITS(val, 29, 3);
+         if (scale > 5)
+           printf(" LTR1.2_Threshold=<error>");
+         else
+           printf(" LTR1.2_Threshold=%lldns", BITS(val, 16, 10) * (unsigned long long) cap_ltr_scale(scale));
+       }
+      printf("\n");
     }
-  printf("\n");
 
   val = get_conf_long(d, where + PCI_L1PM_SUBSTAT_CTL2);
   printf("\t\tL1SubCtl2:");
@@ -895,7 +971,7 @@ show_ext_caps(struct device *d, int type)
            cap_ltr(d, where);
            break;
          case PCI_EXT_CAP_ID_SECPCI:
-           cap_sec(d, where, type);
+           cap_sec(d, where);
            break;
          case PCI_EXT_CAP_ID_PMUX:
            printf("Protocol Multiplexing <?>\n");
@@ -922,7 +998,10 @@ show_ext_caps(struct device *d, int type)
            printf("Readiness Time Reporting <?>\n");
            break;
          case PCI_EXT_CAP_ID_DVSEC:
-           printf("Designated Vendor-Specific <?>\n");
+           if (is_cxl_cap(d, where))
+             cap_cxl(d, where);
+           else
+             cap_dvsec(d, where);
            break;
          case PCI_EXT_CAP_ID_VF_REBAR:
            printf("VF Resizable BAR <?>\n");