2 * The PCI Utilities -- Show Extended Capabilities
4 * Copyright (c) 1997--2022 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL v2+.
8 * SPDX-License-Identifier: GPL-2.0-or-later
17 cap_tph(struct device
*d
, int where
)
20 printf("Transaction Processing Hints\n");
24 if (!config_fetch(d
, where
+ PCI_TPH_CAPABILITIES
, 4))
27 tph_cap
= get_conf_long(d
, where
+ PCI_TPH_CAPABILITIES
);
29 if (tph_cap
& PCI_TPH_INTVEC_SUP
)
30 printf("\t\tInterrupt vector mode supported\n");
31 if (tph_cap
& PCI_TPH_DEV_SUP
)
32 printf("\t\tDevice specific mode supported\n");
33 if (tph_cap
& PCI_TPH_EXT_REQ_SUP
)
34 printf("\t\tExtended requester support\n");
36 switch (tph_cap
& PCI_TPH_ST_LOC_MASK
) {
38 printf("\t\tNo steering table available\n");
41 printf("\t\tSteering table in TPH capability structure\n");
44 printf("\t\tSteering table in MSI-X table\n");
47 printf("\t\tReserved steering table location\n");
53 cap_ltr_scale(u8 scale
)
55 return 1 << (scale
* 5);
59 cap_ltr(struct device
*d
, int where
)
63 printf("Latency Tolerance Reporting\n");
67 if (!config_fetch(d
, where
+ PCI_LTR_MAX_SNOOP
, 4))
70 snoop
= get_conf_word(d
, where
+ PCI_LTR_MAX_SNOOP
);
71 scale
= cap_ltr_scale((snoop
>> PCI_LTR_SCALE_SHIFT
) & PCI_LTR_SCALE_MASK
);
72 printf("\t\tMax snoop latency: %" PCI_U64_FMT_U
"ns\n",
73 ((u64
)snoop
& PCI_LTR_VALUE_MASK
) * scale
);
75 nosnoop
= get_conf_word(d
, where
+ PCI_LTR_MAX_NOSNOOP
);
76 scale
= cap_ltr_scale((nosnoop
>> PCI_LTR_SCALE_SHIFT
) & PCI_LTR_SCALE_MASK
);
77 printf("\t\tMax no snoop latency: %" PCI_U64_FMT_U
"ns\n",
78 ((u64
)nosnoop
& PCI_LTR_VALUE_MASK
) * scale
);
82 cap_sec(struct device
*d
, int where
)
84 u32 ctrl3
, lane_err_stat
;
86 printf("Secondary PCI Express\n");
90 if (!config_fetch(d
, where
+ PCI_SEC_LNKCTL3
, 12))
93 ctrl3
= get_conf_word(d
, where
+ PCI_SEC_LNKCTL3
);
94 printf("\t\tLnkCtl3: LnkEquIntrruptEn%c PerformEqu%c\n",
95 FLAG(ctrl3
, PCI_SEC_LNKCTL3_LNK_EQU_REQ_INTR_EN
),
96 FLAG(ctrl3
, PCI_SEC_LNKCTL3_PERFORM_LINK_EQU
));
98 lane_err_stat
= get_conf_word(d
, where
+ PCI_SEC_LANE_ERR
);
99 printf("\t\tLaneErrStat: ");
102 printf("LaneErr at lane:");
103 for (lane
= 0; lane_err_stat
; lane_err_stat
>>= 1, lane
+= 1)
104 if (BITS(lane_err_stat
, 0, 1))
113 cap_dsn(struct device
*d
, int where
)
116 if (!config_fetch(d
, where
+ 4, 8))
118 t1
= get_conf_long(d
, where
+ 4);
119 t2
= get_conf_long(d
, where
+ 8);
120 printf("Device Serial Number %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
121 t2
>> 24, (t2
>> 16) & 0xff, (t2
>> 8) & 0xff, t2
& 0xff,
122 t1
>> 24, (t1
>> 16) & 0xff, (t1
>> 8) & 0xff, t1
& 0xff);
126 cap_aer(struct device
*d
, int where
, int type
)
128 u32 l
, l0
, l1
, l2
, l3
;
131 printf("Advanced Error Reporting\n");
135 if (!config_fetch(d
, where
+ PCI_ERR_UNCOR_STATUS
, 40))
138 l
= get_conf_long(d
, where
+ PCI_ERR_UNCOR_STATUS
);
139 printf("\t\tUESta:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c MalfTLP%c\n"
140 "\t\t\tECRC%c UnsupReq%c ACSViol%c UncorrIntErr%c BlockedTLP%c AtomicOpBlocked%c TLPBlockedErr%c\n"
141 "\t\t\tPoisonTLPBlocked%c DMWrReqBlocked%c IDECheck%c MisIDETLP%c PCRC_CHECK%c TLPXlatBlocked%c\n",
142 FLAG(l
, PCI_ERR_UNC_DLP
), FLAG(l
, PCI_ERR_UNC_SDES
), FLAG(l
, PCI_ERR_UNC_POISON_TLP
),
143 FLAG(l
, PCI_ERR_UNC_FCP
), FLAG(l
, PCI_ERR_UNC_COMP_TIME
), FLAG(l
, PCI_ERR_UNC_COMP_ABORT
),
144 FLAG(l
, PCI_ERR_UNC_UNX_COMP
), FLAG(l
, PCI_ERR_UNC_RX_OVER
), FLAG(l
, PCI_ERR_UNC_MALF_TLP
),
145 FLAG(l
, PCI_ERR_UNC_ECRC
), FLAG(l
, PCI_ERR_UNC_UNSUP
), FLAG(l
, PCI_ERR_UNC_ACS_VIOL
),
146 FLAG(l
, PCI_ERR_UNC_INTERNAL
), FLAG(l
, PCI_ERR_UNC_MC_BLOCKED_TLP
),
147 FLAG(l
, PCI_ERR_UNC_ATOMICOP_EGRESS_BLOCKED
), FLAG(l
, PCI_ERR_UNC_TLP_PREFIX_BLOCKED
),
148 FLAG(l
, PCI_ERR_UNC_POISONED_TLP_EGRESS
), FLAG(l
, PCI_ERR_UNC_DMWR_REQ_EGRESS_BLOCKED
),
149 FLAG(l
, PCI_ERR_UNC_IDE_CHECK
), FLAG(l
, PCI_ERR_UNC_MISR_IDE_TLP
), FLAG(l
, PCI_ERR_UNC_PCRC_CHECK
),
150 FLAG(l
, PCI_ERR_UNC_TLP_XLAT_EGRESS_BLOCKED
));
151 l
= get_conf_long(d
, where
+ PCI_ERR_UNCOR_MASK
);
152 printf("\t\tUEMsk:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c MalfTLP%c\n"
153 "\t\t\tECRC%c UnsupReq%c ACSViol%c UncorrIntErr%c BlockedTLP%c AtomicOpBlocked%c TLPBlockedErr%c\n"
154 "\t\t\tPoisonTLPBlocked%c DMWrReqBlocked%c IDECheck%c MisIDETLP%c PCRC_CHECK%c TLPXlatBlocked%c\n",
155 FLAG(l
, PCI_ERR_UNC_DLP
), FLAG(l
, PCI_ERR_UNC_SDES
), FLAG(l
, PCI_ERR_UNC_POISON_TLP
),
156 FLAG(l
, PCI_ERR_UNC_FCP
), FLAG(l
, PCI_ERR_UNC_COMP_TIME
), FLAG(l
, PCI_ERR_UNC_COMP_ABORT
),
157 FLAG(l
, PCI_ERR_UNC_UNX_COMP
), FLAG(l
, PCI_ERR_UNC_RX_OVER
), FLAG(l
, PCI_ERR_UNC_MALF_TLP
),
158 FLAG(l
, PCI_ERR_UNC_ECRC
), FLAG(l
, PCI_ERR_UNC_UNSUP
), FLAG(l
, PCI_ERR_UNC_ACS_VIOL
),
159 FLAG(l
, PCI_ERR_UNC_INTERNAL
), FLAG(l
, PCI_ERR_UNC_MC_BLOCKED_TLP
),
160 FLAG(l
, PCI_ERR_UNC_ATOMICOP_EGRESS_BLOCKED
), FLAG(l
, PCI_ERR_UNC_TLP_PREFIX_BLOCKED
),
161 FLAG(l
, PCI_ERR_UNC_POISONED_TLP_EGRESS
), FLAG(l
, PCI_ERR_UNC_DMWR_REQ_EGRESS_BLOCKED
),
162 FLAG(l
, PCI_ERR_UNC_IDE_CHECK
), FLAG(l
, PCI_ERR_UNC_MISR_IDE_TLP
), FLAG(l
, PCI_ERR_UNC_PCRC_CHECK
),
163 FLAG(l
, PCI_ERR_UNC_TLP_XLAT_EGRESS_BLOCKED
));
164 l
= get_conf_long(d
, where
+ PCI_ERR_UNCOR_SEVER
);
165 printf("\t\tUESvrt:\tDLP%c SDES%c TLP%c FCP%c CmpltTO%c CmpltAbrt%c UnxCmplt%c RxOF%c MalfTLP%c\n"
166 "\t\t\tECRC%c UnsupReq%c ACSViol%c UncorrIntErr%c BlockedTLP%c AtomicOpBlocked%c TLPBlockedErr%c\n"
167 "\t\t\tPoisonTLPBlocked%c DMWrReqBlocked%c IDECheck%c MisIDETLP%c PCRC_CHECK%c TLPXlatBlocked%c\n",
168 FLAG(l
, PCI_ERR_UNC_DLP
), FLAG(l
, PCI_ERR_UNC_SDES
), FLAG(l
, PCI_ERR_UNC_POISON_TLP
),
169 FLAG(l
, PCI_ERR_UNC_FCP
), FLAG(l
, PCI_ERR_UNC_COMP_TIME
), FLAG(l
, PCI_ERR_UNC_COMP_ABORT
),
170 FLAG(l
, PCI_ERR_UNC_UNX_COMP
), FLAG(l
, PCI_ERR_UNC_RX_OVER
), FLAG(l
, PCI_ERR_UNC_MALF_TLP
),
171 FLAG(l
, PCI_ERR_UNC_ECRC
), FLAG(l
, PCI_ERR_UNC_UNSUP
), FLAG(l
, PCI_ERR_UNC_ACS_VIOL
),
172 FLAG(l
, PCI_ERR_UNC_INTERNAL
), FLAG(l
, PCI_ERR_UNC_MC_BLOCKED_TLP
),
173 FLAG(l
, PCI_ERR_UNC_ATOMICOP_EGRESS_BLOCKED
), FLAG(l
, PCI_ERR_UNC_TLP_PREFIX_BLOCKED
),
174 FLAG(l
, PCI_ERR_UNC_POISONED_TLP_EGRESS
), FLAG(l
, PCI_ERR_UNC_DMWR_REQ_EGRESS_BLOCKED
),
175 FLAG(l
, PCI_ERR_UNC_IDE_CHECK
), FLAG(l
, PCI_ERR_UNC_MISR_IDE_TLP
), FLAG(l
, PCI_ERR_UNC_PCRC_CHECK
),
176 FLAG(l
, PCI_ERR_UNC_TLP_XLAT_EGRESS_BLOCKED
));
177 l
= get_conf_long(d
, where
+ PCI_ERR_COR_STATUS
);
178 printf("\t\tCESta:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c AdvNonFatalErr%c "
179 "CorrIntErr%c HeaderOF%c\n",
180 FLAG(l
, PCI_ERR_COR_RCVR
), FLAG(l
, PCI_ERR_COR_BAD_TLP
), FLAG(l
, PCI_ERR_COR_BAD_DLLP
),
181 FLAG(l
, PCI_ERR_COR_REP_ROLL
), FLAG(l
, PCI_ERR_COR_REP_TIMER
), FLAG(l
, PCI_ERR_COR_REP_ANFE
),
182 FLAG(l
, PCI_ERR_COR_INTERNAL
), FLAG(l
, PCI_ERR_COR_HDRLOG_OVER
));
183 l
= get_conf_long(d
, where
+ PCI_ERR_COR_MASK
);
184 printf("\t\tCEMsk:\tRxErr%c BadTLP%c BadDLLP%c Rollover%c Timeout%c AdvNonFatalErr%c "
185 "CorrIntErr%c HeaderOF%c\n",
186 FLAG(l
, PCI_ERR_COR_RCVR
), FLAG(l
, PCI_ERR_COR_BAD_TLP
), FLAG(l
, PCI_ERR_COR_BAD_DLLP
),
187 FLAG(l
, PCI_ERR_COR_REP_ROLL
), FLAG(l
, PCI_ERR_COR_REP_TIMER
), FLAG(l
, PCI_ERR_COR_REP_ANFE
),
188 FLAG(l
, PCI_ERR_COR_INTERNAL
), FLAG(l
, PCI_ERR_COR_HDRLOG_OVER
));
189 l
= get_conf_long(d
, where
+ PCI_ERR_CAP
);
190 printf("\t\tAERCap:\tFirst Error Pointer: %02x, ECRCGenCap%c ECRCGenEn%c ECRCChkCap%c ECRCChkEn%c\n"
191 "\t\t\tMultHdrRecCap%c MultHdrRecEn%c TLPPfxPres%c HdrLogCap%c\n",
192 PCI_ERR_CAP_FEP(l
), FLAG(l
, PCI_ERR_CAP_ECRC_GENC
), FLAG(l
, PCI_ERR_CAP_ECRC_GENE
),
193 FLAG(l
, PCI_ERR_CAP_ECRC_CHKC
), FLAG(l
, PCI_ERR_CAP_ECRC_CHKE
),
194 FLAG(l
, PCI_ERR_CAP_MULT_HDRC
), FLAG(l
, PCI_ERR_CAP_MULT_HDRE
),
195 FLAG(l
, PCI_ERR_CAP_TLP_PFX
), FLAG(l
, PCI_ERR_CAP_HDR_LOG
));
197 l0
= get_conf_long(d
, where
+ PCI_ERR_HEADER_LOG
);
198 l1
= get_conf_long(d
, where
+ PCI_ERR_HEADER_LOG
+ 4);
199 l2
= get_conf_long(d
, where
+ PCI_ERR_HEADER_LOG
+ 8);
200 l3
= get_conf_long(d
, where
+ PCI_ERR_HEADER_LOG
+ 12);
201 printf("\t\tHeaderLog: %08x %08x %08x %08x\n", l0
, l1
, l2
, l3
);
203 if (type
== PCI_EXP_TYPE_ROOT_PORT
|| type
== PCI_EXP_TYPE_ROOT_EC
)
205 if (!config_fetch(d
, where
+ PCI_ERR_ROOT_COMMAND
, 12))
208 l
= get_conf_long(d
, where
+ PCI_ERR_ROOT_COMMAND
);
209 printf("\t\tRootCmd: CERptEn%c NFERptEn%c FERptEn%c\n",
210 FLAG(l
, PCI_ERR_ROOT_CMD_COR_EN
),
211 FLAG(l
, PCI_ERR_ROOT_CMD_NONFATAL_EN
),
212 FLAG(l
, PCI_ERR_ROOT_CMD_FATAL_EN
));
214 l
= get_conf_long(d
, where
+ PCI_ERR_ROOT_STATUS
);
215 printf("\t\tRootSta: CERcvd%c MultCERcvd%c UERcvd%c MultUERcvd%c\n"
216 "\t\t\t FirstFatal%c NonFatalMsg%c FatalMsg%c IntMsgNum %d\n",
217 FLAG(l
, PCI_ERR_ROOT_COR_RCV
),
218 FLAG(l
, PCI_ERR_ROOT_MULTI_COR_RCV
),
219 FLAG(l
, PCI_ERR_ROOT_UNCOR_RCV
),
220 FLAG(l
, PCI_ERR_ROOT_MULTI_UNCOR_RCV
),
221 FLAG(l
, PCI_ERR_ROOT_FIRST_FATAL
),
222 FLAG(l
, PCI_ERR_ROOT_NONFATAL_RCV
),
223 FLAG(l
, PCI_ERR_ROOT_FATAL_RCV
),
226 w
= get_conf_word(d
, where
+ PCI_ERR_ROOT_COR_SRC
);
227 printf("\t\tErrorSrc: ERR_COR: %04x ", w
);
229 w
= get_conf_word(d
, where
+ PCI_ERR_ROOT_SRC
);
230 printf("ERR_FATAL/NONFATAL: %04x\n", w
);
234 static void cap_dpc(struct device
*d
, int where
)
238 printf("Downstream Port Containment\n");
242 if (!config_fetch(d
, where
+ PCI_DPC_CAP
, 8))
245 l
= get_conf_word(d
, where
+ PCI_DPC_CAP
);
246 printf("\t\tDpcCap:\tIntMsgNum %d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
247 PCI_DPC_CAP_INT_MSG(l
), FLAG(l
, PCI_DPC_CAP_RP_EXT
), FLAG(l
, PCI_DPC_CAP_TLP_BLOCK
),
248 FLAG(l
, PCI_DPC_CAP_SW_TRIGGER
), PCI_DPC_CAP_RP_LOG(l
), FLAG(l
, PCI_DPC_CAP_DL_ACT_ERR
));
250 l
= get_conf_word(d
, where
+ PCI_DPC_CTL
);
251 printf("\t\tDpcCtl:\tTrigger:%x Cmpl%c INT%c ErrCor%c PoisonedTLP%c SwTrigger%c DL_ActiveErr%c\n",
252 PCI_DPC_CTL_TRIGGER(l
), FLAG(l
, PCI_DPC_CTL_CMPL
), FLAG(l
, PCI_DPC_CTL_INT
),
253 FLAG(l
, PCI_DPC_CTL_ERR_COR
), FLAG(l
, PCI_DPC_CTL_TLP
), FLAG(l
, PCI_DPC_CTL_SW_TRIGGER
),
254 FLAG(l
, PCI_DPC_CTL_DL_ACTIVE
));
256 l
= get_conf_word(d
, where
+ PCI_DPC_STATUS
);
257 printf("\t\tDpcSta:\tTrigger%c Reason:%02x INT%c RPBusy%c TriggerExt:%02x RP PIO ErrPtr:%02x\n",
258 FLAG(l
, PCI_DPC_STS_TRIGGER
), PCI_DPC_STS_REASON(l
), FLAG(l
, PCI_DPC_STS_INT
),
259 FLAG(l
, PCI_DPC_STS_RP_BUSY
), PCI_DPC_STS_TRIGGER_EXT(l
), PCI_DPC_STS_PIO_FEP(l
));
261 l
= get_conf_word(d
, where
+ PCI_DPC_SOURCE
);
262 printf("\t\tSource:\t%04x\n", l
);
266 cap_acs(struct device
*d
, int where
)
270 printf("Access Control Services\n");
274 if (!config_fetch(d
, where
+ PCI_ACS_CAP
, 4))
277 w
= get_conf_word(d
, where
+ PCI_ACS_CAP
);
278 printf("\t\tACSCap:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
280 FLAG(w
, PCI_ACS_CAP_VALID
), FLAG(w
, PCI_ACS_CAP_BLOCK
), FLAG(w
, PCI_ACS_CAP_REQ_RED
),
281 FLAG(w
, PCI_ACS_CAP_CMPLT_RED
), FLAG(w
, PCI_ACS_CAP_FORWARD
), FLAG(w
, PCI_ACS_CAP_EGRESS
),
282 FLAG(w
, PCI_ACS_CAP_TRANS
));
283 w
= get_conf_word(d
, where
+ PCI_ACS_CTRL
);
284 printf("\t\tACSCtl:\tSrcValid%c TransBlk%c ReqRedir%c CmpltRedir%c UpstreamFwd%c EgressCtrl%c "
286 FLAG(w
, PCI_ACS_CTRL_VALID
), FLAG(w
, PCI_ACS_CTRL_BLOCK
), FLAG(w
, PCI_ACS_CTRL_REQ_RED
),
287 FLAG(w
, PCI_ACS_CTRL_CMPLT_RED
), FLAG(w
, PCI_ACS_CTRL_FORWARD
), FLAG(w
, PCI_ACS_CTRL_EGRESS
),
288 FLAG(w
, PCI_ACS_CTRL_TRANS
));
292 cap_ari(struct device
*d
, int where
)
296 printf("Alternative Routing-ID Interpretation (ARI)\n");
300 if (!config_fetch(d
, where
+ PCI_ARI_CAP
, 4))
303 w
= get_conf_word(d
, where
+ PCI_ARI_CAP
);
304 printf("\t\tARICap:\tMFVC%c ACS%c, Next Function: %d\n",
305 FLAG(w
, PCI_ARI_CAP_MFVC
), FLAG(w
, PCI_ARI_CAP_ACS
),
307 w
= get_conf_word(d
, where
+ PCI_ARI_CTRL
);
308 printf("\t\tARICtl:\tMFVC%c ACS%c, Function Group: %d\n",
309 FLAG(w
, PCI_ARI_CTRL_MFVC
), FLAG(w
, PCI_ARI_CTRL_ACS
),
314 cap_ats(struct device
*d
, int where
)
318 printf("Address Translation Service (ATS)\n");
322 if (!config_fetch(d
, where
+ PCI_ATS_CAP
, 4))
325 w
= get_conf_word(d
, where
+ PCI_ATS_CAP
);
326 printf("\t\tATSCap:\tInvalidate Queue Depth: %02x\n", PCI_ATS_CAP_IQD(w
));
327 w
= get_conf_word(d
, where
+ PCI_ATS_CTRL
);
328 printf("\t\tATSCtl:\tEnable%c, Smallest Translation Unit: %02x\n",
329 FLAG(w
, PCI_ATS_CTRL_ENABLE
), PCI_ATS_CTRL_STU(w
));
333 cap_pri(struct device
*d
, int where
)
338 printf("Page Request Interface (PRI)\n");
342 if (!config_fetch(d
, where
+ PCI_PRI_CTRL
, 0xc))
345 w
= get_conf_word(d
, where
+ PCI_PRI_CTRL
);
346 printf("\t\tPRICtl: Enable%c Reset%c\n",
347 FLAG(w
, PCI_PRI_CTRL_ENABLE
), FLAG(w
, PCI_PRI_CTRL_RESET
));
348 w
= get_conf_word(d
, where
+ PCI_PRI_STATUS
);
349 printf("\t\tPRISta: RF%c UPRGI%c Stopped%c PASID%c\n",
350 FLAG(w
, PCI_PRI_STATUS_RF
), FLAG(w
, PCI_PRI_STATUS_UPRGI
),
351 FLAG(w
, PCI_PRI_STATUS_STOPPED
), FLAG(w
, PCI_PRI_STATUS_PASID
));
352 l
= get_conf_long(d
, where
+ PCI_PRI_MAX_REQ
);
353 printf("\t\tPage Request Capacity: %08x, ", l
);
354 l
= get_conf_long(d
, where
+ PCI_PRI_ALLOC_REQ
);
355 printf("Page Request Allocation: %08x\n", l
);
359 cap_pasid(struct device
*d
, int where
)
363 printf("Process Address Space ID (PASID)\n");
367 if (!config_fetch(d
, where
+ PCI_PASID_CAP
, 4))
370 w
= get_conf_word(d
, where
+ PCI_PASID_CAP
);
371 printf("\t\tPASIDCap: Exec%c Priv%c, Max PASID Width: %02x\n",
372 FLAG(w
, PCI_PASID_CAP_EXEC
), FLAG(w
, PCI_PASID_CAP_PRIV
),
373 PCI_PASID_CAP_WIDTH(w
));
374 w
= get_conf_word(d
, where
+ PCI_PASID_CTRL
);
375 printf("\t\tPASIDCtl: Enable%c Exec%c Priv%c\n",
376 FLAG(w
, PCI_PASID_CTRL_ENABLE
), FLAG(w
, PCI_PASID_CTRL_EXEC
),
377 FLAG(w
, PCI_PASID_CTRL_PRIV
));
381 cap_sriov(struct device
*d
, int where
)
388 printf("Single Root I/O Virtualization (SR-IOV)\n");
392 if (!config_fetch(d
, where
+ PCI_IOV_CAP
, 0x3c))
395 l
= get_conf_long(d
, where
+ PCI_IOV_CAP
);
396 printf("\t\tIOVCap:\tMigration%c 10BitTagReq%c IntMsgNum %d\n",
397 FLAG(l
, PCI_IOV_CAP_VFM
), FLAG(l
, PCI_IOV_CAP_VF_10BIT_TAG_REQ
), PCI_IOV_CAP_IMN(l
));
398 w
= get_conf_word(d
, where
+ PCI_IOV_CTRL
);
399 printf("\t\tIOVCtl:\tEnable%c Migration%c Interrupt%c MSE%c ARIHierarchy%c 10BitTagReq%c\n",
400 FLAG(w
, PCI_IOV_CTRL_VFE
), FLAG(w
, PCI_IOV_CTRL_VFME
),
401 FLAG(w
, PCI_IOV_CTRL_VFMIE
), FLAG(w
, PCI_IOV_CTRL_MSE
),
402 FLAG(w
, PCI_IOV_CTRL_ARI
), FLAG(w
, PCI_IOV_CTRL_VF_10BIT_TAG_REQ_EN
));
403 w
= get_conf_word(d
, where
+ PCI_IOV_STATUS
);
404 printf("\t\tIOVSta:\tMigration%c\n", FLAG(w
, PCI_IOV_STATUS_MS
));
405 w
= get_conf_word(d
, where
+ PCI_IOV_INITIALVF
);
406 printf("\t\tInitial VFs: %d, ", w
);
407 w
= get_conf_word(d
, where
+ PCI_IOV_TOTALVF
);
408 printf("Total VFs: %d, ", w
);
409 w
= get_conf_word(d
, where
+ PCI_IOV_NUMVF
);
410 printf("Number of VFs: %d, ", w
);
411 b
= get_conf_byte(d
, where
+ PCI_IOV_FDL
);
412 printf("Function Dependency Link: %02x\n", b
);
413 w
= get_conf_word(d
, where
+ PCI_IOV_OFFSET
);
414 printf("\t\tVF offset: %d, ", w
);
415 w
= get_conf_word(d
, where
+ PCI_IOV_STRIDE
);
416 printf("stride: %d, ", w
);
417 w
= get_conf_word(d
, where
+ PCI_IOV_DID
);
418 printf("Device ID: %04x\n", w
);
419 l
= get_conf_long(d
, where
+ PCI_IOV_SUPPS
);
420 printf("\t\tSupported Page Size: %08x, ", l
);
421 l
= get_conf_long(d
, where
+ PCI_IOV_SYSPS
);
422 printf("System Page Size: %08x\n", l
);
424 for (i
=0; i
< PCI_IOV_NUM_BAR
; i
++)
429 l
= get_conf_long(d
, where
+ PCI_IOV_BAR_BASE
+ 4*i
);
434 printf("\t\tRegion %d: Memory at ", i
);
435 addr
= l
& PCI_ADDR_MEM_MASK
;
436 type
= l
& PCI_BASE_ADDRESS_MEM_TYPE_MASK
;
437 if (type
== PCI_BASE_ADDRESS_MEM_TYPE_64
)
440 h
= get_conf_long(d
, where
+ PCI_IOV_BAR_BASE
+ (i
*4));
443 printf("%08x (%s-bit, %sprefetchable)\n",
445 (type
== PCI_BASE_ADDRESS_MEM_TYPE_32
) ? "32" : "64",
446 (l
& PCI_BASE_ADDRESS_MEM_PREFETCH
) ? "" : "non-");
449 l
= get_conf_long(d
, where
+ PCI_IOV_MSAO
);
450 printf("\t\tVF Migration: offset: %08x, BIR: %x\n", PCI_IOV_MSA_OFFSET(l
),
455 cap_multicast(struct device
*d
, int where
, int type
)
461 printf("Multicast\n");
465 if (!config_fetch(d
, where
+ PCI_MCAST_CAP
, 0x30))
468 w
= get_conf_word(d
, where
+ PCI_MCAST_CAP
);
469 printf("\t\tMcastCap: MaxGroups %d", PCI_MCAST_CAP_MAX_GROUP(w
) + 1);
470 if (type
== PCI_EXP_TYPE_ENDPOINT
|| type
== PCI_EXP_TYPE_ROOT_INT_EP
)
471 printf(", WindowSz %d (%d bytes)",
472 PCI_MCAST_CAP_WIN_SIZE(w
), 1 << PCI_MCAST_CAP_WIN_SIZE(w
));
473 if (type
== PCI_EXP_TYPE_ROOT_PORT
||
474 type
== PCI_EXP_TYPE_UPSTREAM
|| type
== PCI_EXP_TYPE_DOWNSTREAM
)
475 printf(", ECRCRegen%c\n", FLAG(w
, PCI_MCAST_CAP_ECRC
));
476 w
= get_conf_word(d
, where
+ PCI_MCAST_CTRL
);
477 printf("\t\tMcastCtl: NumGroups %d, Enable%c\n",
478 PCI_MCAST_CTRL_NUM_GROUP(w
) + 1, FLAG(w
, PCI_MCAST_CTRL_ENABLE
));
479 bar
= get_conf_long(d
, where
+ PCI_MCAST_BAR
);
480 l
= get_conf_long(d
, where
+ PCI_MCAST_BAR
+ 4);
481 bar
|= (u64
) l
<< 32;
482 printf("\t\tMcastBAR: IndexPos %d, BaseAddr %016" PCI_U64_FMT_X
"\n",
483 PCI_MCAST_BAR_INDEX_POS(bar
), bar
& PCI_MCAST_BAR_MASK
);
484 rcv
= get_conf_long(d
, where
+ PCI_MCAST_RCV
);
485 l
= get_conf_long(d
, where
+ PCI_MCAST_RCV
+ 4);
486 rcv
|= (u64
) l
<< 32;
487 printf("\t\tMcastReceiveVec: %016" PCI_U64_FMT_X
"\n", rcv
);
488 block
= get_conf_long(d
, where
+ PCI_MCAST_BLOCK
);
489 l
= get_conf_long(d
, where
+ PCI_MCAST_BLOCK
+ 4);
490 block
|= (u64
) l
<< 32;
491 printf("\t\tMcastBlockAllVec: %016" PCI_U64_FMT_X
"\n", block
);
492 block
= get_conf_long(d
, where
+ PCI_MCAST_BLOCK_UNTRANS
);
493 l
= get_conf_long(d
, where
+ PCI_MCAST_BLOCK_UNTRANS
+ 4);
494 block
|= (u64
) l
<< 32;
495 printf("\t\tMcastBlockUntransVec: %016" PCI_U64_FMT_X
"\n", block
);
497 if (type
== PCI_EXP_TYPE_ENDPOINT
|| type
== PCI_EXP_TYPE_ROOT_INT_EP
)
499 bar
= get_conf_long(d
, where
+ PCI_MCAST_OVL_BAR
);
500 l
= get_conf_long(d
, where
+ PCI_MCAST_OVL_BAR
+ 4);
501 bar
|= (u64
) l
<< 32;
502 printf("\t\tMcastOverlayBAR: OverlaySize %d ", PCI_MCAST_OVL_SIZE(bar
));
503 if (PCI_MCAST_OVL_SIZE(bar
) >= 6)
504 printf("(%d bytes)", 1 << PCI_MCAST_OVL_SIZE(bar
));
506 printf("(disabled)");
507 printf(", BaseAddr %016" PCI_U64_FMT_X
"\n", bar
& PCI_MCAST_OVL_MASK
);
511 cap_vc(struct device
*d
, int where
)
518 static const char ref_clocks
[][6] = { "100ns" };
519 static const char arb_selects
[8][7] = { "Fixed", "WRR32", "WRR64", "WRR128", "??4", "??5", "??6", "??7" };
520 static const char vc_arb_selects
[8][8] = { "Fixed", "WRR32", "WRR64", "WRR128", "TWRR128", "WRR256", "??6", "??7" };
523 printf("Virtual Channel\n");
527 if (!config_fetch(d
, where
+ 4, 0x1c - 4))
530 cr1
= get_conf_long(d
, where
+ PCI_VC_PORT_REG1
);
531 cr2
= get_conf_long(d
, where
+ PCI_VC_PORT_REG2
);
532 ctrl
= get_conf_word(d
, where
+ PCI_VC_PORT_CTRL
);
533 status
= get_conf_word(d
, where
+ PCI_VC_PORT_STATUS
);
535 evc_cnt
= BITS(cr1
, 0, 3);
536 printf("\t\tCaps:\tLPEVC=%d RefClk=%s PATEntryBits=%d\n",
538 TABLE(ref_clocks
, BITS(cr1
, 8, 2), buf
),
539 1 << BITS(cr1
, 10, 2));
543 if (arb_selects
[i
][0] != '?' || cr2
& (1 << i
))
544 printf("%c%s%c", (i
? ' ' : '\t'), arb_selects
[i
], FLAG(cr2
, 1 << i
));
545 arb_table_pos
= BITS(cr2
, 24, 8);
547 printf("\n\t\tCtrl:\tArbSelect=%s\n", TABLE(arb_selects
, BITS(ctrl
, 1, 3), buf
));
548 printf("\t\tStatus:\tInProgress%c\n", FLAG(status
, 1));
552 arb_table_pos
= where
+ 16*arb_table_pos
;
553 printf("\t\tPort Arbitration Table [%x] <?>\n", arb_table_pos
);
556 for (i
=0; i
<=evc_cnt
; i
++)
558 int pos
= where
+ PCI_VC_RES_CAP
+ 12*i
;
563 printf("\t\tVC%d:\t", i
);
564 if (!config_fetch(d
, pos
, 12))
566 printf("<unreadable>\n");
569 rcap
= get_conf_long(d
, pos
);
570 rctrl
= get_conf_long(d
, pos
+4);
571 rstatus
= get_conf_word(d
, pos
+10);
573 pat_pos
= BITS(rcap
, 24, 8);
574 printf("Caps:\tPATOffset=%02x MaxTimeSlots=%d RejSnoopTrans%c\n",
576 BITS(rcap
, 16, 7) + 1,
577 FLAG(rcap
, 1 << 15));
579 printf("\t\t\tArb:");
581 if (vc_arb_selects
[j
][0] != '?' || rcap
& (1 << j
))
582 printf("%c%s%c", (j
? ' ' : '\t'), vc_arb_selects
[j
], FLAG(rcap
, 1 << j
));
584 printf("\n\t\t\tCtrl:\tEnable%c ID=%d ArbSelect=%s TC/VC=%02x\n",
585 FLAG(rctrl
, 1 << 31),
587 TABLE(vc_arb_selects
, BITS(rctrl
, 17, 3), buf
),
590 printf("\t\t\tStatus:\tNegoPending%c InProgress%c\n",
595 printf("\t\t\tPort Arbitration Table <?>\n");
600 cap_rclink(struct device
*d
, int where
)
605 static const char elt_types
[][9] = { "Config", "Egress", "Internal" };
608 printf("Root Complex Link\n");
612 if (!config_fetch(d
, where
+ 4, PCI_RCLINK_LINK1
- 4))
615 esd
= get_conf_long(d
, where
+ PCI_RCLINK_ESD
);
616 num_links
= BITS(esd
, 8, 8);
617 printf("\t\tDesc:\tPortNumber=%02x ComponentID=%02x EltType=%s\n",
620 TABLE(elt_types
, BITS(esd
, 0, 8), buf
));
622 for (i
=0; i
<num_links
; i
++)
624 int pos
= where
+ PCI_RCLINK_LINK1
+ i
*PCI_RCLINK_LINK_SIZE
;
626 u32 addr_lo
, addr_hi
;
628 printf("\t\tLink%d:\t", i
);
629 if (!config_fetch(d
, pos
, PCI_RCLINK_LINK_SIZE
))
631 printf("<unreadable>\n");
634 desc
= get_conf_long(d
, pos
+ PCI_RCLINK_LINK_DESC
);
635 addr_lo
= get_conf_long(d
, pos
+ PCI_RCLINK_LINK_ADDR
);
636 addr_hi
= get_conf_long(d
, pos
+ PCI_RCLINK_LINK_ADDR
+ 4);
638 printf("Desc:\tTargetPort=%02x TargetComponent=%02x AssocRCRB%c LinkType=%s LinkValid%c\n",
642 ((desc
& 2) ? "Config" : "MemMapped"),
650 printf("\t\t\tAddr:\t%02x:%02x.%d CfgSpace=%08x%08x\n",
651 BITS(addr_lo
, 20, n
),
652 BITS(addr_lo
, 15, 5),
653 BITS(addr_lo
, 12, 3),
657 printf("\t\t\tAddr:\t%08x%08x\n", addr_hi
, addr_lo
);
662 cap_rcec(struct device
*d
, int where
)
664 printf("Root Complex Event Collector Endpoint Association\n");
668 if (!config_fetch(d
, where
, 12))
671 u32 hdr
= get_conf_long(d
, where
);
672 byte cap_ver
= PCI_RCEC_EP_CAP_VER(hdr
);
673 u32 bmap
= get_conf_long(d
, where
+ PCI_RCEC_RCIEP_BMAP
);
674 printf("\t\tRCiEPBitmap: ");
680 printf("RCiEP at Device(s):");
681 for (int dev
=0; dev
< 32; dev
++)
683 if (BITS(bmap
, dev
, 1))
686 printf("%s %u", (prevmatched
) ? "," : "", dev
);
694 printf("-%u", prevdev
);
700 printf("%s", (verbose
> 2) ? "00000000 [none]" : "[none]");
703 if (cap_ver
< PCI_RCEC_BUSN_REG_VER
)
706 u32 busn
= get_conf_long(d
, where
+ PCI_RCEC_BUSN_REG
);
707 u8 lastbusn
= BITS(busn
, 16, 8);
708 u8 nextbusn
= BITS(busn
, 8, 8);
710 if ((lastbusn
== 0x00) && (nextbusn
== 0xff))
711 printf("\t\tAssociatedBusNumbers: %s\n", (verbose
> 2) ? "ff-00 [none]" : "[none]");
713 printf("\t\tAssociatedBusNumbers: %02x-%02x\n", nextbusn
, lastbusn
);
717 cap_lmr(struct device
*d
, int where
)
719 printf("Lane Margining at the Receiver\n");
724 if (!config_fetch(d
, where
, 8))
727 u16 port_caps
= get_conf_word(d
, where
+ PCI_LMR_CAPS
);
728 u16 port_status
= get_conf_word(d
, where
+ PCI_LMR_PORT_STS
);
730 printf("\t\tPortCap: Uses Driver%c\n", FLAG(port_caps
, PCI_LMR_CAPS_DRVR
));
731 printf("\t\tPortSta: MargReady%c MargSoftReady%c\n",
732 FLAG(port_status
, PCI_LMR_PORT_STS_READY
),
733 FLAG(port_status
, PCI_LMR_PORT_STS_SOFT_READY
));
737 cap_phy_16gt(struct device
*d
, int where
)
739 printf("Physical Layer 16.0 GT/s\n");
744 if (!config_fetch(d
, where
+ PCI_16GT_CAP
, 0x18)) {
745 printf("\t\t<unreadable>\n");
749 u32 status
= get_conf_long(d
, where
+ PCI_16GT_STATUS
);
751 printf("\t\tPhy16Sta: EquComplete%c EquPhase1%c EquPhase2%c EquPhase3%c LinkEquRequest%c\n",
752 FLAG(status
, PCI_16GT_STATUS_EQU_COMP
),
753 FLAG(status
, PCI_16GT_STATUS_EQU_PHASE1
),
754 FLAG(status
, PCI_16GT_STATUS_EQU_PHASE2
),
755 FLAG(status
, PCI_16GT_STATUS_EQU_PHASE3
),
756 FLAG(status
, PCI_16GT_STATUS_EQU_REQ
));
760 cap_phy_32gt(struct device
*d
, int where
)
762 static const char * const mod_ts_modes
[] = {
764 "Training Set Messages",
765 "Alternate Protocol Negotiation"
767 static const char * const enh_link_ctl
[] = {
768 "Full Equalization required",
769 "Equalization bypass to highest rate support",
770 "No Equalization Needed",
771 "Modified TS1/TS2 Ordered Sets supported"
775 printf("Physical Layer 32.0 GT/s\n");
780 if (!config_fetch(d
, where
+ PCI_32GT_CAP
, 0x1C)) {
781 printf("\t\t<unreadable>\n");
785 u32 cap
= get_conf_long(d
, where
+ PCI_32GT_CAP
);
786 u32 ctl
= get_conf_long(d
, where
+ PCI_32GT_CTL
);
787 u32 status
= get_conf_long(d
, where
+ PCI_32GT_STATUS
);
789 printf("\t\tPhy32Cap: EqualizationBypass%c NoEqualizationNeeded%c\n"
790 "\t\t\t ModTsMode0%c ModTsMode1%c ModTsMode2%c\n",
791 FLAG(cap
, PCI_32GT_CAP_EQU_BYPASS
),
792 FLAG(cap
, PCI_32GT_CAP_NO_EQU_NEEDED
),
793 FLAG(cap
, PCI_32GT_CAP_MOD_TS_MODE_0
),
794 FLAG(cap
, PCI_32GT_CAP_MOD_TS_MODE_1
),
795 FLAG(cap
, PCI_32GT_CAP_MOD_TS_MODE_2
));
797 printf("\t\tPhy32Ctl: EqualizationBypassDis%c NoEqualizationNeededDis%c\n"
798 "\t\t\t Modified TS Usage Mode: %s\n",
799 FLAG(ctl
, PCI_32GT_CTL_EQU_BYPASS_DIS
),
800 FLAG(ctl
, PCI_32GT_CTL_NO_EQU_NEEDED_DIS
),
801 TABLE(mod_ts_modes
, PCI_32GT_CTL_MOD_TS_MODE(ctl
), buf
));
803 printf("\t\tPhy32Sta: EquComplete%c EquPhase1%c EquPhase2%c EquPhase3%c LinkEquRequest%c\n"
804 "\t\t\t Received Enhanced Link Behavior Control: %s\n"
805 "\t\t\t ModTsRecv%c TxPrecodeOn%c TxPrecodeReq%c NoEqualizationNeededRecv%c\n",
806 FLAG(status
, PCI_32GT_STATUS_EQU_COMP
),
807 FLAG(status
, PCI_32GT_STATUS_EQU_PHASE1
),
808 FLAG(status
, PCI_32GT_STATUS_EQU_PHASE2
),
809 FLAG(status
, PCI_32GT_STATUS_EQU_PHASE3
),
810 FLAG(status
, PCI_32GT_STATUS_EQU_REQ
),
811 TABLE(enh_link_ctl
, PCI_32GT_STATUS_RCV_ENH_LINK(status
), buf
),
812 FLAG(status
, PCI_32GT_STATUS_MOD_TS
),
813 FLAG(status
, PCI_32GT_STATUS_TX_PRE_ON
),
814 FLAG(status
, PCI_32GT_STATUS_TX_PRE_REQ
),
815 FLAG(status
, PCI_32GT_STATUS_NO_EQU
));
819 cap_phy_64gt(struct device
*d
, int where
)
821 printf("Physical Layer 64.0 GT/s\n");
826 if (!config_fetch(d
, where
+ PCI_64GT_CAP
, 0x0C)) {
827 printf("\t\t<unreadable>\n");
831 u32 status
= get_conf_long(d
, where
+ PCI_64GT_STATUS
);
833 printf("\t\tPhy64Sta: EquComplete%c EquPhase1%c EquPhase2%c EquPhase3%c LinkEquRequest%c\n"
834 "\t\t\t TxPrecodeOn%c TxPrecodeReq%c NoEqualizationNeededRecv%c\n",
835 FLAG(status
, PCI_64GT_STATUS_EQU_COMP
),
836 FLAG(status
, PCI_64GT_STATUS_EQU_PHASE1
),
837 FLAG(status
, PCI_64GT_STATUS_EQU_PHASE2
),
838 FLAG(status
, PCI_64GT_STATUS_EQU_PHASE3
),
839 FLAG(status
, PCI_64GT_STATUS_EQU_REQ
),
840 FLAG(status
, PCI_64GT_STATUS_TX_PRE_ON
),
841 FLAG(status
, PCI_64GT_STATUS_TX_PRE_REQ
),
842 FLAG(status
, PCI_64GT_STATUS_NO_EQU
));
846 cxl_range(u64 base
, u64 size
, int n
)
848 u32 interleave
[] = { 0, 256, 4096, 512, 1024, 2048, 8192, 16384 };
849 const char * const type
[] = { "Volatile", "Non-volatile", "CDAT" };
850 const char * const class[] = { "DRAM", "Storage", "CDAT" };
855 size
&= ~0x0fffffffULL
;
857 printf("\t\tRange%d: %016"PCI_U64_FMT_X
"-%016"PCI_U64_FMT_X
" [size=0x%"PCI_U64_FMT_X
"]\n", n
, base
, base
+ size
- 1, size
);
858 printf("\t\t\tValid%c Active%c Type=%s Class=%s interleave=%d timeout=%ds\n",
859 FLAG(w
, PCI_CXL_RANGE_VALID
), FLAG(w
, PCI_CXL_RANGE_ACTIVE
),
860 type
[PCI_CXL_RANGE_TYPE(w
)], class[PCI_CXL_RANGE_CLASS(w
)],
861 interleave
[PCI_CXL_RANGE_INTERLEAVE(w
)],
862 1 << (PCI_CXL_RANGE_TIMEOUT(w
) * 2));
866 dvsec_cxl_device(struct device
*d
, int rev
, int where
, int len
)
868 u32 cache_size
, cache_unit_size
;
869 u64 range_base
, range_size
;
872 /* Legacy 1.1 revs aren't handled */
876 if (rev
>= 1 && len
>= PCI_CXL_DEV_LEN
)
878 w
= get_conf_word(d
, where
+ PCI_CXL_DEV_CAP
);
879 printf("\t\tCXLCap:\tCache%c IO%c Mem%c MemHWInit%c HDMCount %d Viral%c\n",
880 FLAG(w
, PCI_CXL_DEV_CAP_CACHE
), FLAG(w
, PCI_CXL_DEV_CAP_IO
), FLAG(w
, PCI_CXL_DEV_CAP_MEM
),
881 FLAG(w
, PCI_CXL_DEV_CAP_MEM_HWINIT
), PCI_CXL_DEV_CAP_HDM_CNT(w
), FLAG(w
, PCI_CXL_DEV_CAP_VIRAL
));
883 w
= get_conf_word(d
, where
+ PCI_CXL_DEV_CTRL
);
884 printf("\t\tCXLCtl:\tCache%c IO%c Mem%c CacheSFCov %d CacheSFGran %d CacheClean%c Viral%c\n",
885 FLAG(w
, PCI_CXL_DEV_CTRL_CACHE
), FLAG(w
, PCI_CXL_DEV_CTRL_IO
), FLAG(w
, PCI_CXL_DEV_CTRL_MEM
),
886 PCI_CXL_DEV_CTRL_CACHE_SF_COV(w
), PCI_CXL_DEV_CTRL_CACHE_SF_GRAN(w
), FLAG(w
, PCI_CXL_DEV_CTRL_CACHE_CLN
),
887 FLAG(w
, PCI_CXL_DEV_CTRL_VIRAL
));
889 w
= get_conf_word(d
, where
+ PCI_CXL_DEV_STATUS
);
890 printf("\t\tCXLSta:\tViral%c\n", FLAG(w
, PCI_CXL_DEV_STATUS_VIRAL
));
892 w
= get_conf_word(d
, where
+ PCI_CXL_DEV_CTRL2
);
893 printf("\t\tCXLCtl2:\tDisableCaching%c InitCacheWB&Inval%c InitRst%c RstMemClrEn%c",
894 FLAG(w
, PCI_CXL_DEV_CTRL2_DISABLE_CACHING
),
895 FLAG(w
, PCI_CXL_DEV_CTRL2_INIT_WB_INVAL
),
896 FLAG(w
, PCI_CXL_DEV_CTRL2_INIT_CXL_RST
),
897 FLAG(w
, PCI_CXL_DEV_CTRL2_INIT_CXL_RST_CLR_EN
));
899 printf(" DesiredVolatileHDMStateAfterHotReset%c", FLAG(w
, PCI_CXL_DEV_CTRL2_INIT_CXL_HDM_STATE_HOTRST
));
902 w
= get_conf_word(d
, where
+ PCI_CXL_DEV_STATUS2
);
903 printf("\t\tCXLSta2:\tResetComplete%c ResetError%c PMComplete%c\n",
904 FLAG(w
, PCI_CXL_DEV_STATUS_RC
), FLAG(w
,PCI_CXL_DEV_STATUS_RE
), FLAG(w
, PCI_CXL_DEV_STATUS_PMC
));
906 w
= get_conf_word(d
, where
+ PCI_CXL_DEV_CAP2
);
907 printf("\t\tCXLCap2:\t");
908 cache_unit_size
= BITS(w
, 0, 4);
909 cache_size
= BITS(w
, 8, 8);
910 switch (cache_unit_size
)
912 case PCI_CXL_DEV_CAP2_CACHE_1M
:
913 printf("Cache Size: %08x\n", cache_size
* (1<<20));
915 case PCI_CXL_DEV_CAP2_CACHE_64K
:
916 printf("Cache Size: %08x\n", cache_size
* (64<<10));
918 case PCI_CXL_DEV_CAP2_CACHE_UNK
:
919 printf("Cache Size Not Reported\n");
922 printf("Cache Size: %d of unknown unit size (%d)\n", cache_size
, cache_unit_size
);
926 range_size
= (u64
) get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE1_SIZE_HI
) << 32;
927 range_size
|= get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE1_SIZE_LO
);
928 range_base
= (u64
) get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE1_BASE_HI
) << 32;
929 range_base
|= get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE1_BASE_LO
);
930 cxl_range(range_base
, range_size
, 1);
932 range_size
= (u64
) get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE2_SIZE_HI
) << 32;
933 range_size
|= get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE2_SIZE_LO
);
934 range_base
= (u64
) get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE2_BASE_HI
) << 32;
935 range_base
|= get_conf_long(d
, where
+ PCI_CXL_DEV_RANGE2_BASE_LO
);
936 cxl_range(range_base
, range_size
, 2);
939 if (rev
>= 2 && len
>= PCI_CXL_DEV_LEN_REV2
)
941 w
= get_conf_word(d
, where
+ PCI_CXL_DEV_CAP3
);
942 printf("\t\tCXLCap3:\tDefaultVolatile HDM State After:\tColdReset%c WarmReset%c HotReset%c HotResetConfigurability%c\n",
943 FLAG(w
, PCI_CXL_DEV_CAP3_HDM_STATE_RST_COLD
),
944 FLAG(w
, PCI_CXL_DEV_CAP3_HDM_STATE_RST_WARM
),
945 FLAG(w
, PCI_CXL_DEV_CAP3_HDM_STATE_RST_HOT
),
946 FLAG(w
, PCI_CXL_DEV_CAP3_HDM_STATE_RST_HOT_CFG
));
950 if (len
> PCI_CXL_DEV_LEN_REV2
)
955 dvsec_cxl_port(struct device
*d
, int where
, int len
)
960 if (len
< PCI_CXL_PORT_EXT_LEN
)
963 w
= get_conf_word(d
, where
+ PCI_CXL_PORT_EXT_STATUS
);
964 printf("\t\tCXLPortSta:\tPMComplete%c\n", FLAG(w
, PCI_CXL_PORT_EXT_STATUS
));
966 w
= get_conf_word(d
, where
+ PCI_CXL_PORT_CTRL
);
967 printf("\t\tCXLPortCtl:\tUnmaskSBR%c UnmaskLinkDisable%c AltMem%c AltBME%c ViralEnable%c\n",
968 FLAG(w
, PCI_CXL_PORT_UNMASK_SBR
), FLAG(w
, PCI_CXL_PORT_UNMASK_LINK
),
969 FLAG(w
, PCI_CXL_PORT_ALT_MEMORY
), FLAG(w
, PCI_CXL_PORT_ALT_BME
),
970 FLAG(w
, PCI_CXL_PORT_VIRAL_EN
));
972 b1
= get_conf_byte(d
, where
+ PCI_CXL_PORT_ALT_BUS_BASE
);
973 b2
= get_conf_byte(d
, where
+ PCI_CXL_PORT_ALT_BUS_LIMIT
);
974 printf("\t\tAlternateBus:\t%02x-%02x\n", b1
, b2
);
975 m1
= get_conf_word(d
, where
+ PCI_CXL_PORT_ALT_MEM_BASE
);
976 m2
= get_conf_word(d
, where
+ PCI_CXL_PORT_ALT_MEM_LIMIT
);
977 printf("\t\tAlternateBus:\t%04x-%04x\n", m1
, m2
);
981 dvsec_cxl_register_locator(struct device
*d
, int where
, int len
)
983 static const char * const id_names
[] = {
985 "component registers",
986 "BAR virtualization",
987 "CXL device registers",
993 int pos
= where
+ PCI_CXL_RL_BLOCK1_LO
+ 8*i
;
994 if (pos
+ 7 >= where
+ len
)
997 u32 lo
= get_conf_long(d
, pos
);
998 u32 hi
= get_conf_long(d
, pos
+ 4);
1000 unsigned int bir
= BITS(lo
, 0, 3);
1001 unsigned int block_id
= BITS(lo
, 8, 8);
1002 u64 base
= (BITS(lo
, 16, 16) << 16) | ((u64
) hi
<< 32);
1007 const char *id_name
;
1008 if (block_id
< sizeof(id_names
) / sizeof(*id_names
))
1009 id_name
= id_names
[block_id
];
1010 else if (block_id
== 0xff)
1011 id_name
= "vendor-specific";
1015 printf("\t\tBlock%d: BIR: bar%d, ID: %s, offset: %016" PCI_U64_FMT_X
"\n", i
+ 1, bir
, id_name
, base
);
1020 dvsec_cxl_gpf_device(struct device
*d
, int where
)
1024 u8 time_base
, time_scale
;
1026 w
= get_conf_word(d
, where
+ PCI_CXL_GPF_DEV_PHASE2_DUR
);
1027 time_base
= BITS(w
, 0, 4);
1028 time_scale
= BITS(w
, 8, 4);
1032 case PCI_CXL_GPF_DEV_100US
:
1033 case PCI_CXL_GPF_DEV_100MS
:
1034 duration
= time_base
* 100;
1036 case PCI_CXL_GPF_DEV_10US
:
1037 case PCI_CXL_GPF_DEV_10MS
:
1038 case PCI_CXL_GPF_DEV_10S
:
1039 duration
= time_base
* 10;
1041 case PCI_CXL_GPF_DEV_1US
:
1042 case PCI_CXL_GPF_DEV_1MS
:
1043 case PCI_CXL_GPF_DEV_1S
:
1044 duration
= time_base
;
1048 printf("\t\tReserved time scale encoding %x\n", time_scale
);
1049 duration
= time_base
;
1052 printf("\t\tGPF Phase 2 Duration: %u%s\n", duration
,
1053 (time_scale
< PCI_CXL_GPF_DEV_1MS
) ? "us":
1054 (time_scale
< PCI_CXL_GPF_DEV_1S
) ? "ms" :
1055 (time_scale
<= PCI_CXL_GPF_DEV_10S
) ? "s" : "<?>");
1057 l
= get_conf_long(d
, where
+ PCI_CXL_GPF_DEV_PHASE2_POW
);
1058 printf("\t\tGPF Phase 2 Power: %umW\n", (unsigned int)l
);
1062 dvsec_cxl_gpf_port(struct device
*d
, int where
)
1065 u8 time_base
, time_scale
;
1067 w
= get_conf_word(d
, where
+ PCI_CXL_GPF_PORT_PHASE1_CTRL
);
1068 time_base
= BITS(w
, 0, 4);
1069 time_scale
= BITS(w
, 8, 4);
1073 case PCI_CXL_GPF_PORT_100US
:
1074 case PCI_CXL_GPF_PORT_100MS
:
1075 timeout
= time_base
* 100;
1077 case PCI_CXL_GPF_PORT_10US
:
1078 case PCI_CXL_GPF_PORT_10MS
:
1079 case PCI_CXL_GPF_PORT_10S
:
1080 timeout
= time_base
* 10;
1082 case PCI_CXL_GPF_PORT_1US
:
1083 case PCI_CXL_GPF_PORT_1MS
:
1084 case PCI_CXL_GPF_PORT_1S
:
1085 timeout
= time_base
;
1089 printf("\t\tReserved time scale encoding %x\n", time_scale
);
1090 timeout
= time_base
;
1093 printf("\t\tGPF Phase 1 Timeout: %d%s\n", timeout
,
1094 (time_scale
< PCI_CXL_GPF_PORT_1MS
) ? "us":
1095 (time_scale
< PCI_CXL_GPF_PORT_1S
) ? "ms" :
1096 (time_scale
<= PCI_CXL_GPF_PORT_10S
) ? "s" : "<?>");
1098 w
= get_conf_word(d
, where
+ PCI_CXL_GPF_PORT_PHASE2_CTRL
);
1099 time_base
= BITS(w
, 0, 4);
1100 time_scale
= BITS(w
, 8, 4);
1104 case PCI_CXL_GPF_PORT_100US
:
1105 case PCI_CXL_GPF_PORT_100MS
:
1106 timeout
= time_base
* 100;
1108 case PCI_CXL_GPF_PORT_10US
:
1109 case PCI_CXL_GPF_PORT_10MS
:
1110 case PCI_CXL_GPF_PORT_10S
:
1111 timeout
= time_base
* 10;
1113 case PCI_CXL_GPF_PORT_1US
:
1114 case PCI_CXL_GPF_PORT_1MS
:
1115 case PCI_CXL_GPF_PORT_1S
:
1116 timeout
= time_base
;
1120 printf("\t\tReserved time scale encoding %x\n", time_scale
);
1121 timeout
= time_base
;
1124 printf("\t\tGPF Phase 2 Timeout: %d%s\n", timeout
,
1125 (time_scale
< PCI_CXL_GPF_PORT_1MS
) ? "us":
1126 (time_scale
< PCI_CXL_GPF_PORT_1S
) ? "ms" :
1127 (time_scale
<= PCI_CXL_GPF_PORT_10S
) ? "s" : "<?>");
1131 dvsec_cxl_flex_bus(struct device
*d
, int where
, int rev
, int len
)
1136 // Sanity check: Does the length correspond to its revision?
1139 if (len
!= PCI_CXL_FB_MOD_TS_DATA
)
1140 printf("\t\t<Wrong length for Revision %d>\n", rev
);
1143 if (len
!= PCI_CXL_FB_PORT_CAP2
)
1144 printf("\t\t<Wrong length for Revision %d>\n", rev
);
1147 if (len
!= PCI_CXL_FB_NEXT_UNSUPPORTED
)
1148 printf("\t\t<Wrong length for Revision %d>\n", rev
);
1155 w
= get_conf_word(d
, where
+ PCI_CXL_FB_PORT_CAP
);
1156 printf("\t\tFBCap:\tCache%c IO%c Mem%c 68BFlit%c MltLogDev%c",
1157 FLAG(w
, PCI_CXL_FB_CAP_CACHE
), FLAG(w
, PCI_CXL_FB_CAP_IO
),
1158 FLAG(w
, PCI_CXL_FB_CAP_MEM
), FLAG(w
, PCI_CXL_FB_CAP_68B_FLIT
),
1159 FLAG(w
, PCI_CXL_FB_CAP_MULT_LOG_DEV
));
1162 printf(" 256BFlit%c PBRFlit%c",
1163 FLAG(w
, PCI_CXL_FB_CAP_256B_FLIT
), FLAG(w
, PCI_CXL_FB_CAP_PBR_FLIT
));
1165 w
= get_conf_word(d
, where
+ PCI_CXL_FB_PORT_CTRL
);
1166 printf("\n\t\tFBCtl:\tCache%c IO%c Mem%c SynHdrByp%c DrftBuf%c 68BFlit%c MltLogDev%c RCD%c Retimer1%c Retimer2%c",
1167 FLAG(w
, PCI_CXL_FB_CTRL_CACHE
), FLAG(w
, PCI_CXL_FB_CTRL_IO
),
1168 FLAG(w
, PCI_CXL_FB_CTRL_MEM
), FLAG(w
, PCI_CXL_FB_CTRL_SYNC_HDR_BYP
),
1169 FLAG(w
, PCI_CXL_FB_CTRL_DRFT_BUF
), FLAG(w
, PCI_CXL_FB_CTRL_68B_FLIT
),
1170 FLAG(w
, PCI_CXL_FB_CTRL_MULT_LOG_DEV
), FLAG(w
, PCI_CXL_FB_CTRL_RCD
),
1171 FLAG(w
, PCI_CXL_FB_CTRL_RETIMER1
), FLAG(w
, PCI_CXL_FB_CTRL_RETIMER2
));
1174 printf(" 256BFlit%c PBRFlit%c",
1175 FLAG(w
, PCI_CXL_FB_CTRL_256B_FLIT
), FLAG(w
, PCI_CXL_FB_CTRL_PBR_FLIT
));
1177 w
= get_conf_word(d
, where
+ PCI_CXL_FB_PORT_STATUS
);
1178 printf("\n\t\tFBSta:\tCache%c IO%c Mem%c SynHdrByp%c DrftBuf%c 68BFlit%c MltLogDev%c",
1179 FLAG(w
, PCI_CXL_FB_STAT_CACHE
), FLAG(w
, PCI_CXL_FB_STAT_IO
),
1180 FLAG(w
, PCI_CXL_FB_STAT_MEM
), FLAG(w
, PCI_CXL_FB_STAT_SYNC_HDR_BYP
),
1181 FLAG(w
, PCI_CXL_FB_STAT_DRFT_BUF
), FLAG(w
, PCI_CXL_FB_STAT_68B_FLIT
),
1182 FLAG(w
, PCI_CXL_FB_STAT_MULT_LOG_DEV
));
1185 printf(" 256BFlit%c PBRFlit%c",
1186 FLAG(w
, PCI_CXL_FB_STAT_256B_FLIT
), FLAG(w
, PCI_CXL_FB_STAT_PBR_FLIT
));
1192 l
= get_conf_long(d
, where
+ PCI_CXL_FB_MOD_TS_DATA
);
1193 data
= BITS(l
, 0, 24);
1194 printf("\t\tFBModTS:\tReceived FB Data: %06x\n", (unsigned int)data
);
1202 l
= get_conf_long(d
, where
+ PCI_CXL_FB_PORT_CAP2
);
1203 printf("\t\tFBCap2:\tNOPHint%c\n", FLAG(l
, PCI_CXL_FB_CAP2_NOP_HINT
));
1205 l
= get_conf_long(d
, where
+ PCI_CXL_FB_PORT_CTRL2
);
1206 printf("\t\tFBCtl2:\tNOPHint%c\n", FLAG(l
, PCI_CXL_FB_CTRL2_NOP_HINT
));
1208 l
= get_conf_long(d
, where
+ PCI_CXL_FB_PORT_STATUS2
);
1209 nop
= BITS(l
, 0, 2);
1210 printf("\t\tFBSta2:\tNOPHintInfo: %x\n", nop
);
1214 if (len
> PCI_CXL_FB_LEN
)
1215 printf("\t\t<?>\n");
1219 dvsec_cxl_mld(struct device
*d
, int where
)
1223 w
= get_conf_word(d
, where
+ PCI_CXL_MLD_NUM_LD
);
1225 /* Encodings greater than 16 are reserved */
1226 if (w
&& w
<= PCI_CXL_MLD_MAX_LD
)
1227 printf("\t\tNumLogDevs: %d\n", w
);
1231 dvsec_cxl_function_map(struct device
*d
, int where
)
1234 printf("\t\tFuncMap 0: %08x\n",
1235 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_0
)));
1237 printf("\t\tFuncMap 1: %08x\n",
1238 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_1
)));
1240 printf("\t\tFuncMap 2: %08x\n",
1241 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_2
)));
1243 printf("\t\tFuncMap 3: %08x\n",
1244 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_3
)));
1246 printf("\t\tFuncMap 4: %08x\n",
1247 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_4
)));
1249 printf("\t\tFuncMap 5: %08x\n",
1250 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_5
)));
1252 printf("\t\tFuncMap 6: %08x\n",
1253 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_6
)));
1255 printf("\t\tFuncMap 7: %08x\n",
1256 (unsigned int)(get_conf_word(d
, where
+ PCI_CXL_FUN_MAP_REG_7
)));
1260 cap_dvsec_cxl(struct device
*d
, int id
, int rev
, int where
, int len
)
1266 if (!config_fetch(d
, where
, len
))
1272 printf("\t\tPCIe DVSEC for CXL Devices\n");
1273 dvsec_cxl_device(d
, rev
, where
, len
);
1276 printf("\t\tNon-CXL Function Map DVSEC\n");
1277 dvsec_cxl_function_map(d
, where
);
1280 printf("\t\tCXL Extensions DVSEC for Ports\n");
1281 dvsec_cxl_port(d
, where
, len
);
1284 printf("\t\tGPF DVSEC for CXL Ports\n");
1285 dvsec_cxl_gpf_port(d
, where
);
1288 printf("\t\tGPF DVSEC for CXL Devices\n");
1289 dvsec_cxl_gpf_device(d
, where
);
1292 printf("\t\tPCIe DVSEC for Flex Bus Port\n");
1293 dvsec_cxl_flex_bus(d
, where
, rev
, len
);
1296 printf("\t\tRegister Locator DVSEC\n");
1297 dvsec_cxl_register_locator(d
, where
, len
);
1300 printf("\t\tMLD DVSEC\n");
1301 dvsec_cxl_mld(d
, where
);
1304 printf("\t\tPCIe DVSEC for Test Capability <?>\n");
1307 printf("\t\tUnknown ID %04x\n", id
);
1312 cap_dvsec(struct device
*d
, int where
)
1314 printf("Designated Vendor-Specific: ");
1315 if (!config_fetch(d
, where
+ PCI_DVSEC_HEADER1
, 8))
1317 printf("<unreadable>\n");
1321 u32 hdr
= get_conf_long(d
, where
+ PCI_DVSEC_HEADER1
);
1322 u16 vendor
= BITS(hdr
, 0, 16);
1323 byte rev
= BITS(hdr
, 16, 4);
1324 u16 len
= BITS(hdr
, 20, 12);
1326 u16 id
= get_conf_long(d
, where
+ PCI_DVSEC_HEADER2
);
1328 printf("Vendor=%04x ID=%04x Rev=%d Len=%d", vendor
, id
, rev
, len
);
1329 if (vendor
== PCI_DVSEC_VENDOR_ID_CXL
&& len
>= 16)
1330 cap_dvsec_cxl(d
, id
, rev
, where
, len
);
1336 cap_evendor(struct device
*d
, int where
)
1340 printf("Vendor Specific Information: ");
1341 if (!config_fetch(d
, where
+ PCI_EVNDR_HEADER
, 4))
1343 printf("<unreadable>\n");
1347 hdr
= get_conf_long(d
, where
+ PCI_EVNDR_HEADER
);
1348 printf("ID=%04x Rev=%d Len=%03x <?>\n",
1354 static int l1pm_calc_pwron(int scale
, int value
)
1369 cap_l1pm(struct device
*d
, int where
)
1371 u32 l1_cap
, val
, scale
;
1374 printf("L1 PM Substates\n");
1379 if (!config_fetch(d
, where
+ PCI_L1PM_SUBSTAT_CAP
, 12))
1381 printf("\t\t<unreadable>\n");
1385 l1_cap
= get_conf_long(d
, where
+ PCI_L1PM_SUBSTAT_CAP
);
1386 printf("\t\tL1SubCap: ");
1387 printf("PCI-PM_L1.2%c PCI-PM_L1.1%c ASPM_L1.2%c ASPM_L1.1%c L1_PM_Substates%c\n",
1388 FLAG(l1_cap
, PCI_L1PM_SUBSTAT_CAP_PM_L12
),
1389 FLAG(l1_cap
, PCI_L1PM_SUBSTAT_CAP_PM_L11
),
1390 FLAG(l1_cap
, PCI_L1PM_SUBSTAT_CAP_ASPM_L12
),
1391 FLAG(l1_cap
, PCI_L1PM_SUBSTAT_CAP_ASPM_L11
),
1392 FLAG(l1_cap
, PCI_L1PM_SUBSTAT_CAP_L1PM_SUPP
));
1394 if (l1_cap
& PCI_L1PM_SUBSTAT_CAP_PM_L12
|| l1_cap
& PCI_L1PM_SUBSTAT_CAP_ASPM_L12
)
1396 printf("\t\t\t PortCommonModeRestoreTime=%dus ", BITS(l1_cap
, 8, 8));
1397 time
= l1pm_calc_pwron(BITS(l1_cap
, 16, 2), BITS(l1_cap
, 19, 5));
1399 printf("PortTPowerOnTime=%dus\n", time
);
1401 printf("PortTPowerOnTime=<error>\n");
1404 val
= get_conf_long(d
, where
+ PCI_L1PM_SUBSTAT_CTL1
);
1405 printf("\t\tL1SubCtl1: PCI-PM_L1.2%c PCI-PM_L1.1%c ASPM_L1.2%c ASPM_L1.1%c\n",
1406 FLAG(val
, PCI_L1PM_SUBSTAT_CTL1_PM_L12
),
1407 FLAG(val
, PCI_L1PM_SUBSTAT_CTL1_PM_L11
),
1408 FLAG(val
, PCI_L1PM_SUBSTAT_CTL1_ASPM_L12
),
1409 FLAG(val
, PCI_L1PM_SUBSTAT_CTL1_ASPM_L11
));
1411 if (l1_cap
& PCI_L1PM_SUBSTAT_CAP_PM_L12
|| l1_cap
& PCI_L1PM_SUBSTAT_CAP_ASPM_L12
)
1413 printf("\t\t\t T_CommonMode=%dus", BITS(val
, 8, 8));
1415 if (l1_cap
& PCI_L1PM_SUBSTAT_CAP_ASPM_L12
)
1417 scale
= BITS(val
, 29, 3);
1419 printf(" LTR1.2_Threshold=<error>");
1421 printf(" LTR1.2_Threshold=%" PCI_U64_FMT_U
"ns", BITS(val
, 16, 10) * (u64
) cap_ltr_scale(scale
));
1426 val
= get_conf_long(d
, where
+ PCI_L1PM_SUBSTAT_CTL2
);
1427 printf("\t\tL1SubCtl2:");
1428 if (l1_cap
& PCI_L1PM_SUBSTAT_CAP_PM_L12
|| l1_cap
& PCI_L1PM_SUBSTAT_CAP_ASPM_L12
)
1430 time
= l1pm_calc_pwron(BITS(val
, 0, 2), BITS(val
, 3, 5));
1432 printf(" T_PwrOn=%dus", time
);
1434 printf(" T_PwrOn=<error>");
1440 cap_ptm(struct device
*d
, int where
)
1445 printf("Precision Time Measurement\n");
1450 if (!config_fetch(d
, where
+ 4, 8))
1452 printf("\t\t<unreadable>\n");
1456 buff
= get_conf_long(d
, where
+ 4);
1457 printf("\t\tPTMCap: ");
1458 printf("Requester%c Responder%c Root%c\n",
1463 clock
= BITS(buff
, 8, 8);
1464 printf("\t\tPTMClockGranularity: ");
1468 printf("Unimplemented\n");
1471 printf("Greater than 254ns\n");
1474 printf("%huns\n", clock
);
1477 buff
= get_conf_long(d
, where
+ 8);
1478 printf("\t\tPTMControl: ");
1479 printf("Enabled%c RootSelected%c\n",
1483 clock
= BITS(buff
, 8, 8);
1484 printf("\t\tPTMEffectiveGranularity: ");
1488 printf("Unknown\n");
1491 printf("Greater than 254ns\n");
1494 printf("%huns\n", clock
);
1499 print_rebar_range_size(int ld2_size
)
1501 // This function prints the input as a power-of-2 size value
1502 // It is biased with 1MB = 0, ...
1503 // Maximum resizable BAR value supported is 2^63 bytes = 43
1504 // for the extended resizable BAR capability definition
1505 // (otherwise it would stop at 2^28)
1507 if (ld2_size
>= 0 && ld2_size
< 10)
1508 printf(" %dMB", (1 << ld2_size
));
1509 else if (ld2_size
>= 10 && ld2_size
< 20)
1510 printf(" %dGB", (1 << (ld2_size
-10)));
1511 else if (ld2_size
>= 20 && ld2_size
< 30)
1512 printf(" %dTB", (1 << (ld2_size
-20)));
1513 else if (ld2_size
>= 30 && ld2_size
< 40)
1514 printf(" %dPB", (1 << (ld2_size
-30)));
1515 else if (ld2_size
>= 40 && ld2_size
< 44)
1516 printf(" %dEB", (1 << (ld2_size
-40)));
1518 printf(" <unknown>");
1522 cap_rebar(struct device
*d
, int where
, int virtual)
1524 u32 sizes_buffer
, control_buffer
, ext_sizes
, current_size
;
1525 u16 bar_index
, barcount
, i
;
1526 // If the structure exists, at least one bar is defined
1529 printf("%s Resizable BAR\n", (virtual) ? "Virtual" : "Physical");
1534 // Go through all defined BAR definitions of the caps, at minimum 1
1535 // (loop also terminates if num_bars read from caps is > 6)
1536 for (barcount
= 0; barcount
< num_bars
; barcount
++)
1540 // Get the next BAR configuration
1541 if (!config_fetch(d
, where
, 8))
1543 printf("\t\t<unreadable>\n");
1547 sizes_buffer
= get_conf_long(d
, where
) >> 4;
1549 control_buffer
= get_conf_long(d
, where
);
1551 bar_index
= BITS(control_buffer
, 0, 3);
1552 current_size
= BITS(control_buffer
, 8, 6);
1553 ext_sizes
= BITS(control_buffer
, 16, 16);
1557 // Only index 0 controlreg has the num_bar count definition
1558 num_bars
= BITS(control_buffer
, 5, 3);
1559 if (num_bars
< 1 || num_bars
> 6)
1561 printf("\t\t<error in resizable BAR: num_bars=%d is out of specification>\n", num_bars
);
1566 // Resizable BAR list entry have an arbitrary index and current size
1567 printf("\t\tBAR %d: current size:", bar_index
);
1568 print_rebar_range_size(current_size
);
1570 if (sizes_buffer
|| ext_sizes
)
1572 printf(", supported:");
1574 for (i
=0; i
<28; i
++)
1575 if (sizes_buffer
& (1U << i
))
1576 print_rebar_range_size(i
);
1578 for (i
=0; i
<16; i
++)
1579 if (ext_sizes
& (1U << i
))
1580 print_rebar_range_size(i
+ 28);
1588 cap_doe(struct device
*d
, int where
)
1592 printf("Data Object Exchange\n");
1597 if (!config_fetch(d
, where
+ PCI_DOE_CAP
, 0x14))
1599 printf("\t\t<unreadable>\n");
1603 l
= get_conf_long(d
, where
+ PCI_DOE_CAP
);
1604 printf("\t\tDOECap: IntSup%c\n",
1605 FLAG(l
, PCI_DOE_CAP_INT_SUPP
));
1606 if (l
& PCI_DOE_CAP_INT_SUPP
)
1607 printf("\t\t\tIntMsgNum %d\n",
1608 PCI_DOE_CAP_INT_MSG(l
));
1610 l
= get_conf_long(d
, where
+ PCI_DOE_CTL
);
1611 printf("\t\tDOECtl: IntEn%c\n",
1612 FLAG(l
, PCI_DOE_CTL_INT
));
1614 l
= get_conf_long(d
, where
+ PCI_DOE_STS
);
1615 printf("\t\tDOESta: Busy%c IntSta%c Error%c ObjectReady%c\n",
1616 FLAG(l
, PCI_DOE_STS_BUSY
),
1617 FLAG(l
, PCI_DOE_STS_INT
),
1618 FLAG(l
, PCI_DOE_STS_ERROR
),
1619 FLAG(l
, PCI_DOE_STS_OBJECT_READY
));
1622 static const char *offstr(char *buf
, u32 off
)
1627 sprintf(buf
, "[%x]", off
);
1631 static const char *ide_alg(char *buf
, size_t len
, u32 l
)
1633 const char *algo
[] = { "AES-GCM-256-96b" }; // AES-GCM 256 key size, 96b MAC
1636 snprintf(buf
, len
, "%s", algo
[l
]);
1638 snprintf(buf
, len
, "%s", "reserved");
1643 cap_ide(struct device
*d
, int where
)
1645 const char * const hdr_enc_mode
[] = { "no", "17:2", "25:2", "33:2", "41:2" };
1646 const char * const stream_state
[] = { "insecure", "reserved", "secure" };
1647 const char * const aggr
[] = { "-", "=2", "=4", "=8" };
1648 u32 l
, l2
, linknum
= 0, selnum
= 0, addrnum
, off
, i
, j
;
1649 char buf1
[16], buf2
[16], offs
[16];
1651 printf("Integrity & Data Encryption\n");
1656 if (!config_fetch(d
, where
+ PCI_IDE_CAP
, 8))
1658 printf("\t\t<unreadable>\n");
1662 l
= get_conf_long(d
, where
+ PCI_IDE_CAP
);
1663 if (l
& PCI_IDE_CAP_LINK_IDE_SUPP
)
1664 linknum
= PCI_IDE_CAP_LINK_TC_NUM(l
) + 1;
1665 if (l
& PCI_IDE_CAP_SELECTIVE_IDE_SUPP
)
1666 selnum
= PCI_IDE_CAP_SELECTIVE_STREAMS_NUM(l
) + 1;
1668 printf("\t\tIDECap: Lnk=%d Sel=%d FlowThru%c PartHdr%c Aggr%c PCPC%c IDE_KM%c Alg='%s' TCs=%d TeeLim%c\n",
1671 FLAG(l
, PCI_IDE_CAP_FLOWTHROUGH_IDE_SUPP
),
1672 FLAG(l
, PCI_IDE_CAP_PARTIAL_HEADER_ENC_SUPP
),
1673 FLAG(l
, PCI_IDE_CAP_AGGREGATION_SUPP
),
1674 FLAG(l
, PCI_IDE_CAP_PCRC_SUPP
),
1675 FLAG(l
, PCI_IDE_CAP_IDE_KM_SUPP
),
1676 ide_alg(buf2
, sizeof(buf2
), PCI_IDE_CAP_ALG(l
)),
1677 PCI_IDE_CAP_LINK_TC_NUM(l
) + 1,
1678 FLAG(l
, PCI_IDE_CAP_TEE_LIMITED_SUPP
)
1681 l
= get_conf_long(d
, where
+ PCI_IDE_CTL
);
1682 printf("\t\tIDECtl: FTEn%c\n",
1683 FLAG(l
, PCI_IDE_CTL_FLOWTHROUGH_IDE
));
1685 // The rest of the capability is variable length arrays
1686 off
= where
+ PCI_IDE_LINK_STREAM
;
1688 // Link IDE Register Block repeated 0 to 8 times
1691 if (!config_fetch(d
, off
, 8 * linknum
))
1693 printf("\t\t<unreadable>\n");
1696 for (i
= 0; i
< linknum
; ++i
)
1698 // Link IDE Stream Control Register
1699 l
= get_conf_long(d
, off
);
1700 printf("\t\t%sLinkIDE#%d Ctl: En%c NPR%s PR%s CPL%s PCRC%c HdrEnc=%s Alg='%s' TC%d ID%d\n",
1703 FLAG(l
, PCI_IDE_LINK_CTL_EN
),
1704 aggr
[PCI_IDE_LINK_CTL_TX_AGGR_NPR(l
)],
1705 aggr
[PCI_IDE_LINK_CTL_TX_AGGR_PR(l
)],
1706 aggr
[PCI_IDE_LINK_CTL_TX_AGGR_CPL(l
)],
1707 FLAG(l
, PCI_IDE_LINK_CTL_EN
),
1708 TABLE(hdr_enc_mode
, PCI_IDE_LINK_CTL_PART_ENC(l
), buf1
),
1709 ide_alg(buf2
, sizeof(buf2
), PCI_IDE_LINK_CTL_ALG(l
)),
1710 PCI_IDE_LINK_CTL_TC(l
),
1711 PCI_IDE_LINK_CTL_ID(l
)
1715 /* Link IDE Stream Status Register */
1716 l
= get_conf_long(d
, off
);
1717 printf("\t\t%sLinkIDE#%d Sta: Status=%s RecvChkFail%c\n",
1720 TABLE(stream_state
, PCI_IDE_LINK_STS_STATUS(l
), buf1
),
1721 FLAG(l
, PCI_IDE_LINK_STS_RECVD_INTEGRITY_CHECK
));
1726 for (i
= 0; i
< selnum
; ++i
)
1728 // Fetching Selective IDE Stream Capability/Control/Status/RID1/RID2
1729 if (!config_fetch(d
, off
, 20))
1731 printf("\t\t<unreadable>\n");
1735 // Selective IDE Stream Capability Register
1736 l
= get_conf_long(d
, off
);
1737 printf("\t\t%sSelectiveIDE#%d Cap: RID#=%d\n",
1740 PCI_IDE_SEL_CAP_BLOCKS_NUM(l
));
1742 addrnum
= PCI_IDE_SEL_CAP_BLOCKS_NUM(l
);
1744 // Selective IDE Stream Control Register
1745 l
= get_conf_long(d
, off
);
1747 printf("\t\t%sSelectiveIDE#%d Ctl: En%c NPR%s PR%s CPL%s PCRC%c CFG%c HdrEnc=%s Alg='%s' TC%d ID%d%s\n",
1750 FLAG(l
, PCI_IDE_SEL_CTL_EN
),
1751 aggr
[PCI_IDE_SEL_CTL_TX_AGGR_NPR(l
)],
1752 aggr
[PCI_IDE_SEL_CTL_TX_AGGR_PR(l
)],
1753 aggr
[PCI_IDE_SEL_CTL_TX_AGGR_CPL(l
)],
1754 FLAG(l
, PCI_IDE_SEL_CTL_PCRC_EN
),
1755 FLAG(l
, PCI_IDE_SEL_CTL_CFG_EN
),
1756 TABLE(hdr_enc_mode
, PCI_IDE_SEL_CTL_PART_ENC(l
), buf1
),
1757 ide_alg(buf2
, sizeof(buf2
), PCI_IDE_SEL_CTL_ALG(l
)),
1758 PCI_IDE_SEL_CTL_TC(l
),
1759 PCI_IDE_SEL_CTL_ID(l
),
1760 (l
& PCI_IDE_SEL_CTL_DEFAULT
) ? " Default" : ""
1764 // Selective IDE Stream Status Register
1765 l
= get_conf_long(d
, off
);
1766 printf("\t\t%sSelectiveIDE#%d Sta: %s RecvChkFail%c\n",
1769 TABLE(stream_state
, PCI_IDE_SEL_STS_STATUS(l
), buf1
),
1770 FLAG(l
, PCI_IDE_SEL_STS_RECVD_INTEGRITY_CHECK
));
1773 // IDE RID Association Registers
1774 l
= get_conf_long(d
, off
);
1775 l2
= get_conf_long(d
, off
+ 4);
1777 printf("\t\t%sSelectiveIDE#%d RID: Valid%c Base=%x Limit=%x SegBase=%x\n",
1780 FLAG(l2
, PCI_IDE_SEL_RID_2_VALID
),
1781 PCI_IDE_SEL_RID_2_BASE(l2
),
1782 PCI_IDE_SEL_RID_1_LIMIT(l
),
1783 PCI_IDE_SEL_RID_2_SEG_BASE(l2
));
1786 if (!config_fetch(d
, off
, addrnum
* 12))
1788 printf("\t\t<unreadable>\n");
1792 // IDE Address Association Registers
1793 for (j
= 0; j
< addrnum
; ++j
)
1797 l
= get_conf_long(d
, off
);
1798 limit
= get_conf_long(d
, off
+ 4);
1800 limit
|= (PCI_IDE_SEL_ADDR_1_LIMIT_LOW(l
) << 20) | 0xFFFFF;
1801 base
= get_conf_long(d
, off
+ 8);
1803 base
|= PCI_IDE_SEL_ADDR_1_BASE_LOW(l
) << 20;
1804 printf("\t\t%sSelectiveIDE#%d RID#%d: Valid%c Base=%" PCI_U64_FMT_X
" Limit=%" PCI_U64_FMT_X
"\n",
1808 FLAG(l
, PCI_IDE_SEL_ADDR_1_VALID
),
1816 static const char *l0p_exit_latency(int value
)
1818 static const char * const latencies
[] = {
1820 "1us to less than 2us",
1821 "2us to less than 4us",
1822 "4us to less than 8us",
1823 "8us to less than 16us",
1824 "16us to less than 32us",
1829 if (value
>= 0 && value
<= 7)
1830 return latencies
[value
];
1834 static const char *link_width_str(char *buf
, size_t buflen
, int width
)
1851 snprintf(buf
, buflen
, "Unknown (%d)", width
);
1857 cap_dev3(struct device
*d
, int where
)
1860 u16 devctl3
, devsta3
;
1863 printf("Device 3\n");
1868 if (!config_fetch(d
, where
+ PCI_DEV3_DEVCAP3
, 4))
1870 devcap3
= get_conf_long(d
, where
+ PCI_DEV3_DEVCAP3
);
1872 printf("\t\tDevCap3: DMWr Request Routing%c, 14-Bit Tag Completer%c, 14-Bit Tag Requester%c\n"
1874 FLAG(devcap3
, PCI_DEV3_DEVCAP3_DMWR_REQ
),
1875 FLAG(devcap3
, PCI_DEV3_DEVCAP3_14BIT_TAG_COMP
),
1876 FLAG(devcap3
, PCI_DEV3_DEVCAP3_14BIT_TAG_REQ
),
1877 FLAG(devcap3
, PCI_DEV3_DEVCAP3_L0P_SUPP
));
1879 if (devcap3
& PCI_DEV3_DEVCAP3_L0P_SUPP
)
1880 printf(", Port L0p Exit Latency: %s, Retimer L0p Exit Latency: %s",
1881 l0p_exit_latency(PCI_DEV3_DEVCAP3_PORT_L0P_EXIT(devcap3
)),
1882 l0p_exit_latency(PCI_DEV3_DEVCAP3_RETIMER_L0P_EXIT(devcap3
)));
1884 printf("\n\t\t\t UIO Mem RdWr Completer%c, UIO Mem RdWr Requester%c\n",
1885 FLAG(devcap3
, PCI_DEV3_DEVCAP3_UIO_MEM_RDWR_COMP
),
1886 FLAG(devcap3
, PCI_DEV3_DEVCAP3_UIO_MEM_RDWR_REQ
));
1888 if (!config_fetch(d
, where
+ PCI_DEV3_DEVCTL3
, 2))
1890 devctl3
= get_conf_word(d
, where
+ PCI_DEV3_DEVCTL3
);
1892 printf("\t\tDevCtl3: DMWr Requester%c, DMWr Egress Blocking%c, 14-Bit Tag Requester%c\n"
1893 "\t\t\t L0p%c, Target Link Width: %s\n"
1894 "\t\t\t UIO Mem RdWr Requester%c, UIO Request 256B Boundary%c\n",
1895 FLAG(devctl3
, PCI_DEV3_DEVCTL3_DMWR_REQ_EN
),
1896 FLAG(devctl3
, PCI_DEV3_DEVCTL3_DMWR_EGRESS_BLK
),
1897 FLAG(devctl3
, PCI_DEV3_DEVCTL3_14BIT_TAG_REQ_EN
),
1898 FLAG(devctl3
, PCI_DEV3_DEVCTL3_L0P_EN
),
1899 link_width_str(buf
, sizeof(buf
), PCI_DEV3_DEVCTL3_TARGET_LINK_WIDTH(devctl3
)),
1900 FLAG(devctl3
, PCI_DEV3_DEVCTL3_UIO_MEM_RDWR_REQ_EN
),
1901 FLAG(~devctl3
, PCI_DEV3_DEVCTL3_UIO_REQ_256B_DIS
));
1903 if (!config_fetch(d
, where
+ PCI_DEV3_DEVSTA3
, 2))
1905 devsta3
= get_conf_word(d
, where
+ PCI_DEV3_DEVSTA3
);
1907 printf("\t\tDevSta3: Initial Link Width: %s, Segment Captured%c, Remote L0p%c\n",
1908 link_width_str(buf
, sizeof(buf
), PCI_DEV3_DEVSTA3_INIT_LINK_WIDTH(devsta3
)),
1909 FLAG(devsta3
, PCI_DEV3_DEVSTA3_SEGMENT_CAPTURED
),
1910 FLAG(devsta3
, PCI_DEV3_DEVSTA3_REMOTE_L0P_SUPP
));
1914 show_ext_caps(struct device
*d
, int type
)
1917 char been_there
[0x1000];
1918 memset(been_there
, 0, 0x1000);
1924 if (!config_fetch(d
, where
, 4))
1926 header
= get_conf_long(d
, where
);
1927 if (!header
|| header
== 0xffffffff)
1929 id
= header
& 0xffff;
1930 version
= (header
>> 16) & 0xf;
1931 printf("\tCapabilities: [%03x", where
);
1933 printf(" v%d", version
);
1935 if (been_there
[where
]++)
1937 printf("<chain looped>\n");
1942 case PCI_EXT_CAP_ID_NULL
:
1945 case PCI_EXT_CAP_ID_AER
:
1946 cap_aer(d
, where
, type
);
1948 case PCI_EXT_CAP_ID_DPC
:
1951 case PCI_EXT_CAP_ID_VC
:
1952 case PCI_EXT_CAP_ID_VC2
:
1955 case PCI_EXT_CAP_ID_DSN
:
1958 case PCI_EXT_CAP_ID_PB
:
1959 printf("Power Budgeting <?>\n");
1961 case PCI_EXT_CAP_ID_RCLINK
:
1962 cap_rclink(d
, where
);
1964 case PCI_EXT_CAP_ID_RCILINK
:
1965 printf("Root Complex Internal Link <?>\n");
1967 case PCI_EXT_CAP_ID_RCEC
:
1970 case PCI_EXT_CAP_ID_MFVC
:
1971 printf("Multi-Function Virtual Channel <?>\n");
1973 case PCI_EXT_CAP_ID_RCRB
:
1974 printf("Root Complex Register Block <?>\n");
1976 case PCI_EXT_CAP_ID_VNDR
:
1977 cap_evendor(d
, where
);
1979 case PCI_EXT_CAP_ID_ACS
:
1982 case PCI_EXT_CAP_ID_ARI
:
1985 case PCI_EXT_CAP_ID_ATS
:
1988 case PCI_EXT_CAP_ID_SRIOV
:
1989 cap_sriov(d
, where
);
1991 case PCI_EXT_CAP_ID_MRIOV
:
1992 printf("Multi-Root I/O Virtualization <?>\n");
1994 case PCI_EXT_CAP_ID_MCAST
:
1995 cap_multicast(d
, where
, type
);
1997 case PCI_EXT_CAP_ID_PRI
:
2000 case PCI_EXT_CAP_ID_REBAR
:
2001 cap_rebar(d
, where
, 0);
2003 case PCI_EXT_CAP_ID_DPA
:
2004 printf("Dynamic Power Allocation <?>\n");
2006 case PCI_EXT_CAP_ID_TPH
:
2009 case PCI_EXT_CAP_ID_LTR
:
2012 case PCI_EXT_CAP_ID_SECPCI
:
2015 case PCI_EXT_CAP_ID_PMUX
:
2016 printf("Protocol Multiplexing <?>\n");
2018 case PCI_EXT_CAP_ID_PASID
:
2019 cap_pasid(d
, where
);
2021 case PCI_EXT_CAP_ID_LNR
:
2022 printf("LN Requester <?>\n");
2024 case PCI_EXT_CAP_ID_L1PM
:
2027 case PCI_EXT_CAP_ID_PTM
:
2030 case PCI_EXT_CAP_ID_M_PCIE
:
2031 printf("PCI Express over M_PHY <?>\n");
2033 case PCI_EXT_CAP_ID_FRS
:
2034 printf("FRS Queueing <?>\n");
2036 case PCI_EXT_CAP_ID_RTR
:
2037 printf("Readiness Time Reporting <?>\n");
2039 case PCI_EXT_CAP_ID_DVSEC
:
2040 cap_dvsec(d
, where
);
2042 case PCI_EXT_CAP_ID_VF_REBAR
:
2043 cap_rebar(d
, where
, 1);
2045 case PCI_EXT_CAP_ID_DLNK
:
2046 printf("Data Link Feature <?>\n");
2048 case PCI_EXT_CAP_ID_16GT
:
2049 cap_phy_16gt(d
, where
);
2051 case PCI_EXT_CAP_ID_LMR
:
2054 case PCI_EXT_CAP_ID_HIER_ID
:
2055 printf("Hierarchy ID <?>\n");
2057 case PCI_EXT_CAP_ID_NPEM
:
2058 printf("Native PCIe Enclosure Management <?>\n");
2060 case PCI_EXT_CAP_ID_32GT
:
2061 cap_phy_32gt(d
, where
);
2063 case PCI_EXT_CAP_ID_DOE
:
2066 case PCI_EXT_CAP_ID_IDE
:
2069 case PCI_EXT_CAP_ID_64GT
:
2070 cap_phy_64gt(d
, where
);
2072 case PCI_EXT_CAP_ID_DEV3
:
2076 printf("Extended Capability ID %#02x\n", id
);
2079 where
= (header
>> 20) & ~3;