((unsigned long long)nosnoop & PCI_LTR_VALUE_MASK) * scale);
}
+static void
+cap_sec(struct device *d, int where)
+{
+ u32 ctrl3, lane_err_stat;
+ u8 lane;
+ printf("Secondary PCI Express\n");
+ 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",
+ FLAG(ctrl3, PCI_SEC_LNKCTL3_LNK_EQU_REQ_INTR_EN),
+ FLAG(ctrl3, PCI_SEC_LNKCTL3_PERFORM_LINK_EQU));
+
+ lane_err_stat = get_conf_word(d, where + PCI_SEC_LANE_ERR);
+ printf("\t\tLaneErrStat: ");
+ if (lane_err_stat)
+ {
+ 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);
+ }
+ else
+ printf("0");
+ printf("\n");
+}
+
static void
cap_dsn(struct device *d, int where)
{
PCI_IOV_MSA_BIR(l));
}
+static void
+cap_multicast(struct device *d, int where, int type)
+{
+ u16 w;
+ u32 l;
+ u64 bar, rcv, block;
+
+ printf("Multicast\n");
+ if (verbose < 2)
+ return;
+
+ if (!config_fetch(d, where + PCI_MCAST_CAP, 0x30))
+ return;
+
+ w = get_conf_word(d, where + PCI_MCAST_CAP);
+ printf("\t\tMcastCap: MaxGroups %d", PCI_MCAST_CAP_MAX_GROUP(w) + 1);
+ if (type == PCI_EXP_TYPE_ENDPOINT || type == PCI_EXP_TYPE_ROOT_INT_EP)
+ printf(", WindowSz %d (%d bytes)",
+ PCI_MCAST_CAP_WIN_SIZE(w), 1 << PCI_MCAST_CAP_WIN_SIZE(w));
+ if (type == PCI_EXP_TYPE_ROOT_PORT ||
+ type == PCI_EXP_TYPE_UPSTREAM || type == PCI_EXP_TYPE_DOWNSTREAM)
+ printf(", ECRCRegen%c\n", FLAG(w, PCI_MCAST_CAP_ECRC));
+ w = get_conf_word(d, where + PCI_MCAST_CTRL);
+ printf("\t\tMcastCtl: NumGroups %d, Enable%c\n",
+ PCI_MCAST_CTRL_NUM_GROUP(w) + 1, FLAG(w, PCI_MCAST_CTRL_ENABLE));
+ bar = get_conf_long(d, where + PCI_MCAST_BAR);
+ l = get_conf_long(d, where + PCI_MCAST_BAR + 4);
+ bar |= (u64) l << 32;
+ printf("\t\tMcastBAR: IndexPos %d, BaseAddr %016" PCI_U64_FMT_X "\n",
+ PCI_MCAST_BAR_INDEX_POS(bar), bar & PCI_MCAST_BAR_MASK);
+ rcv = get_conf_long(d, where + PCI_MCAST_RCV);
+ l = get_conf_long(d, where + PCI_MCAST_RCV + 4);
+ rcv |= (u64) l << 32;
+ printf("\t\tMcastReceiveVec: %016" PCI_U64_FMT_X "\n", rcv);
+ block = get_conf_long(d, where + PCI_MCAST_BLOCK);
+ l = get_conf_long(d, where + PCI_MCAST_BLOCK + 4);
+ block |= (u64) l << 32;
+ printf("\t\tMcastBlockAllVec: %016" PCI_U64_FMT_X "\n", block);
+ block = get_conf_long(d, where + PCI_MCAST_BLOCK_UNTRANS);
+ l = get_conf_long(d, where + PCI_MCAST_BLOCK_UNTRANS + 4);
+ block |= (u64) l << 32;
+ printf("\t\tMcastBlockUntransVec: %016" PCI_U64_FMT_X "\n", block);
+
+ if (type == PCI_EXP_TYPE_ENDPOINT || type == PCI_EXP_TYPE_ROOT_INT_EP)
+ return;
+ bar = get_conf_long(d, where + PCI_MCAST_OVL_BAR);
+ l = get_conf_long(d, where + PCI_MCAST_OVL_BAR + 4);
+ bar |= (u64) l << 32;
+ printf("\t\tMcastOverlayBAR: OverlaySize %d ", PCI_MCAST_OVL_SIZE(bar));
+ if (PCI_MCAST_OVL_SIZE(bar) >= 6)
+ printf("(%d bytes)", 1 << PCI_MCAST_OVL_SIZE(bar));
+ else
+ printf("(disabled)");
+ printf(", BaseAddr %016" PCI_U64_FMT_X "\n", bar & PCI_MCAST_OVL_MASK);
+}
+
static void
cap_vc(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)
{
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:");
case PCI_EXT_CAP_ID_MFVC:
printf("Multi-Function Virtual Channel <?>\n");
break;
- case PCI_EXT_CAP_ID_RBCB:
- printf("Root Bridge Control Block <?>\n");
+ case PCI_EXT_CAP_ID_RCRB:
+ printf("Root Complex Register Block <?>\n");
break;
case PCI_EXT_CAP_ID_VNDR:
cap_evendor(d, where);
case PCI_EXT_CAP_ID_MRIOV:
printf("Multi-Root I/O Virtualization <?>\n");
break;
+ case PCI_EXT_CAP_ID_MCAST:
+ cap_multicast(d, where, type);
+ break;
case PCI_EXT_CAP_ID_PRI:
cap_pri(d, where);
break;
cap_ltr(d, where);
break;
case PCI_EXT_CAP_ID_SECPCI:
- printf("Secondary PCI Express <?>\n");
+ cap_sec(d, where);
break;
case PCI_EXT_CAP_ID_PMUX:
printf("Protocol Multiplexing <?>\n");
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");