]> git.ipfire.org Git - thirdparty/pciutils.git/blame_incremental - ls-ecaps.c
header.h: Fix type 1 header comment
[thirdparty/pciutils.git] / ls-ecaps.c
... / ...
CommitLineData
1/*
2 * The PCI Utilities -- Show Extended Capabilities
3 *
4 * Copyright (c) 1997--2022 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL v2+.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include <stdio.h>
12#include <string.h>
13
14#include "lspci.h"
15
16static void
17cap_tph(struct device *d, int where)
18{
19 u32 tph_cap;
20 printf("Transaction Processing Hints\n");
21 if (verbose < 2)
22 return;
23
24 if (!config_fetch(d, where + PCI_TPH_CAPABILITIES, 4))
25 return;
26
27 tph_cap = get_conf_long(d, where + PCI_TPH_CAPABILITIES);
28
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");
35
36 switch (tph_cap & PCI_TPH_ST_LOC_MASK) {
37 case PCI_TPH_ST_NONE:
38 printf("\t\tNo steering table available\n");
39 break;
40 case PCI_TPH_ST_CAP:
41 printf("\t\tSteering table in TPH capability structure\n");
42 break;
43 case PCI_TPH_ST_MSIX:
44 printf("\t\tSteering table in MSI-X table\n");
45 break;
46 default:
47 printf("\t\tReserved steering table location\n");
48 break;
49 }
50}
51
52static u32
53cap_ltr_scale(u8 scale)
54{
55 return 1 << (scale * 5);
56}
57
58static void
59cap_ltr(struct device *d, int where)
60{
61 u32 scale;
62 u16 snoop, nosnoop;
63 printf("Latency Tolerance Reporting\n");
64 if (verbose < 2)
65 return;
66
67 if (!config_fetch(d, where + PCI_LTR_MAX_SNOOP, 4))
68 return;
69
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);
74
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);
79}
80
81static void
82cap_sec(struct device *d, int where)
83{
84 u32 ctrl3, lane_err_stat;
85 u8 lane;
86 printf("Secondary PCI Express\n");
87 if (verbose < 2)
88 return;
89
90 if (!config_fetch(d, where + PCI_SEC_LNKCTL3, 12))
91 return;
92
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));
97
98 lane_err_stat = get_conf_word(d, where + PCI_SEC_LANE_ERR);
99 printf("\t\tLaneErrStat: ");
100 if (lane_err_stat)
101 {
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))
105 printf(" %u", lane);
106 }
107 else
108 printf("0");
109 printf("\n");
110}
111
112static void
113cap_dsn(struct device *d, int where)
114{
115 u32 t1, t2;
116 if (!config_fetch(d, where + 4, 8))
117 return;
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);
123}
124
125static void
126cap_aer(struct device *d, int where, int type)
127{
128 u32 l, l0, l1, l2, l3;
129 u16 w;
130
131 printf("Advanced Error Reporting\n");
132 if (verbose < 2)
133 return;
134
135 if (!config_fetch(d, where + PCI_ERR_UNCOR_STATUS, 40))
136 return;
137
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));
196
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);
202
203 if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ROOT_EC)
204 {
205 if (!config_fetch(d, where + PCI_ERR_ROOT_COMMAND, 12))
206 return;
207
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));
213
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),
224 PCI_ERR_MSG_NUM(l));
225
226 w = get_conf_word(d, where + PCI_ERR_ROOT_COR_SRC);
227 printf("\t\tErrorSrc: ERR_COR: %04x ", w);
228
229 w = get_conf_word(d, where + PCI_ERR_ROOT_SRC);
230 printf("ERR_FATAL/NONFATAL: %04x\n", w);
231 }
232}
233
234static void cap_dpc(struct device *d, int where)
235{
236 u16 l;
237
238 printf("Downstream Port Containment\n");
239 if (verbose < 2)
240 return;
241
242 if (!config_fetch(d, where + PCI_DPC_CAP, 8))
243 return;
244
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));
249
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));
255
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));
260
261 l = get_conf_word(d, where + PCI_DPC_SOURCE);
262 printf("\t\tSource:\t%04x\n", l);
263}
264
265static void
266cap_acs(struct device *d, int where)
267{
268 u16 w;
269
270 printf("Access Control Services\n");
271 if (verbose < 2)
272 return;
273
274 if (!config_fetch(d, where + PCI_ACS_CAP, 4))
275 return;
276
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 "
279 "DirectTrans%c\n",
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 "
285 "DirectTrans%c\n",
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));
289}
290
291static void
292cap_ari(struct device *d, int where)
293{
294 u16 w;
295
296 printf("Alternative Routing-ID Interpretation (ARI)\n");
297 if (verbose < 2)
298 return;
299
300 if (!config_fetch(d, where + PCI_ARI_CAP, 4))
301 return;
302
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),
306 PCI_ARI_CAP_NFN(w));
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),
310 PCI_ARI_CTRL_FG(w));
311}
312
313static void
314cap_ats(struct device *d, int where)
315{
316 u16 w;
317
318 printf("Address Translation Service (ATS)\n");
319 if (verbose < 2)
320 return;
321
322 if (!config_fetch(d, where + PCI_ATS_CAP, 4))
323 return;
324
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));
330}
331
332static void
333cap_pri(struct device *d, int where)
334{
335 u16 w;
336 u32 l;
337
338 printf("Page Request Interface (PRI)\n");
339 if (verbose < 2)
340 return;
341
342 if (!config_fetch(d, where + PCI_PRI_CTRL, 0xc))
343 return;
344
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);
356}
357
358static void
359cap_pasid(struct device *d, int where)
360{
361 u16 w;
362
363 printf("Process Address Space ID (PASID)\n");
364 if (verbose < 2)
365 return;
366
367 if (!config_fetch(d, where + PCI_PASID_CAP, 4))
368 return;
369
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));
378}
379
380static void
381cap_sriov(struct device *d, int where)
382{
383 u16 b;
384 u16 w;
385 u32 l;
386 int i;
387
388 printf("Single Root I/O Virtualization (SR-IOV)\n");
389 if (verbose < 2)
390 return;
391
392 if (!config_fetch(d, where + PCI_IOV_CAP, 0x3c))
393 return;
394
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);
423
424 for (i=0; i < PCI_IOV_NUM_BAR; i++)
425 {
426 u32 addr;
427 int type;
428 u32 h;
429 l = get_conf_long(d, where + PCI_IOV_BAR_BASE + 4*i);
430 if (l == 0xffffffff)
431 l = 0;
432 if (!l)
433 continue;
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)
438 {
439 i++;
440 h = get_conf_long(d, where + PCI_IOV_BAR_BASE + (i*4));
441 printf("%08x", h);
442 }
443 printf("%08x (%s-bit, %sprefetchable)\n",
444 addr,
445 (type == PCI_BASE_ADDRESS_MEM_TYPE_32) ? "32" : "64",
446 (l & PCI_BASE_ADDRESS_MEM_PREFETCH) ? "" : "non-");
447 }
448
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),
451 PCI_IOV_MSA_BIR(l));
452}
453
454static void
455cap_multicast(struct device *d, int where, int type)
456{
457 u16 w;
458 u32 l;
459 u64 bar, rcv, block;
460
461 printf("Multicast\n");
462 if (verbose < 2)
463 return;
464
465 if (!config_fetch(d, where + PCI_MCAST_CAP, 0x30))
466 return;
467
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);
496
497 if (type == PCI_EXP_TYPE_ENDPOINT || type == PCI_EXP_TYPE_ROOT_INT_EP)
498 return;
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));
505 else
506 printf("(disabled)");
507 printf(", BaseAddr %016" PCI_U64_FMT_X "\n", bar & PCI_MCAST_OVL_MASK);
508}
509
510static void
511cap_vc(struct device *d, int where)
512{
513 u32 cr1, cr2;
514 u16 ctrl, status;
515 int evc_cnt;
516 int arb_table_pos;
517 int i, j;
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" };
521 char buf[8];
522
523 printf("Virtual Channel\n");
524 if (verbose < 2)
525 return;
526
527 if (!config_fetch(d, where + 4, 0x1c - 4))
528 return;
529
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);
534
535 evc_cnt = BITS(cr1, 0, 3);
536 printf("\t\tCaps:\tLPEVC=%d RefClk=%s PATEntryBits=%d\n",
537 BITS(cr1, 4, 3),
538 TABLE(ref_clocks, BITS(cr1, 8, 2), buf),
539 1 << BITS(cr1, 10, 2));
540
541 printf("\t\tArb:");
542 for (i=0; i<8; i++)
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);
546
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));
549
550 if (arb_table_pos)
551 {
552 arb_table_pos = where + 16*arb_table_pos;
553 printf("\t\tPort Arbitration Table [%x] <?>\n", arb_table_pos);
554 }
555
556 for (i=0; i<=evc_cnt; i++)
557 {
558 int pos = where + PCI_VC_RES_CAP + 12*i;
559 u32 rcap, rctrl;
560 u16 rstatus;
561 int pat_pos;
562
563 printf("\t\tVC%d:\t", i);
564 if (!config_fetch(d, pos, 12))
565 {
566 printf("<unreadable>\n");
567 continue;
568 }
569 rcap = get_conf_long(d, pos);
570 rctrl = get_conf_long(d, pos+4);
571 rstatus = get_conf_word(d, pos+10);
572
573 pat_pos = BITS(rcap, 24, 8);
574 printf("Caps:\tPATOffset=%02x MaxTimeSlots=%d RejSnoopTrans%c\n",
575 pat_pos,
576 BITS(rcap, 16, 7) + 1,
577 FLAG(rcap, 1 << 15));
578
579 printf("\t\t\tArb:");
580 for (j=0; j<8; j++)
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));
583
584 printf("\n\t\t\tCtrl:\tEnable%c ID=%d ArbSelect=%s TC/VC=%02x\n",
585 FLAG(rctrl, 1 << 31),
586 BITS(rctrl, 24, 3),
587 TABLE(vc_arb_selects, BITS(rctrl, 17, 3), buf),
588 BITS(rctrl, 0, 8));
589
590 printf("\t\t\tStatus:\tNegoPending%c InProgress%c\n",
591 FLAG(rstatus, 2),
592 FLAG(rstatus, 1));
593
594 if (pat_pos)
595 printf("\t\t\tPort Arbitration Table <?>\n");
596 }
597}
598
599static void
600cap_rclink(struct device *d, int where)
601{
602 u32 esd;
603 int num_links;
604 int i;
605 static const char elt_types[][9] = { "Config", "Egress", "Internal" };
606 char buf[8];
607
608 printf("Root Complex Link\n");
609 if (verbose < 2)
610 return;
611
612 if (!config_fetch(d, where + 4, PCI_RCLINK_LINK1 - 4))
613 return;
614
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",
618 BITS(esd, 24, 8),
619 BITS(esd, 16, 8),
620 TABLE(elt_types, BITS(esd, 0, 8), buf));
621
622 for (i=0; i<num_links; i++)
623 {
624 int pos = where + PCI_RCLINK_LINK1 + i*PCI_RCLINK_LINK_SIZE;
625 u32 desc;
626 u32 addr_lo, addr_hi;
627
628 printf("\t\tLink%d:\t", i);
629 if (!config_fetch(d, pos, PCI_RCLINK_LINK_SIZE))
630 {
631 printf("<unreadable>\n");
632 return;
633 }
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);
637
638 printf("Desc:\tTargetPort=%02x TargetComponent=%02x AssocRCRB%c LinkType=%s LinkValid%c\n",
639 BITS(desc, 24, 8),
640 BITS(desc, 16, 8),
641 FLAG(desc, 4),
642 ((desc & 2) ? "Config" : "MemMapped"),
643 FLAG(desc, 1));
644
645 if (desc & 2)
646 {
647 int n = addr_lo & 7;
648 if (!n)
649 n = 8;
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),
654 addr_hi, addr_lo);
655 }
656 else
657 printf("\t\t\tAddr:\t%08x%08x\n", addr_hi, addr_lo);
658 }
659}
660
661static void
662cap_rcec(struct device *d, int where)
663{
664 printf("Root Complex Event Collector Endpoint Association\n");
665 if (verbose < 2)
666 return;
667
668 if (!config_fetch(d, where, 12))
669 return;
670
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: ");
675 if (bmap)
676 {
677 int prevmatched=0;
678 int adjcount=0;
679 int prevdev=0;
680 printf("RCiEP at Device(s):");
681 for (int dev=0; dev < 32; dev++)
682 {
683 if (BITS(bmap, dev, 1))
684 {
685 if (!adjcount)
686 printf("%s %u", (prevmatched) ? "," : "", dev);
687 adjcount++;
688 prevdev=dev;
689 prevmatched=1;
690 }
691 else
692 {
693 if (adjcount > 1)
694 printf("-%u", prevdev);
695 adjcount=0;
696 }
697 }
698 }
699 else
700 printf("%s", (verbose > 2) ? "00000000 [none]" : "[none]");
701 printf("\n");
702
703 if (cap_ver < PCI_RCEC_BUSN_REG_VER)
704 return;
705
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);
709
710 if ((lastbusn == 0x00) && (nextbusn == 0xff))
711 printf("\t\tAssociatedBusNumbers: %s\n", (verbose > 2) ? "ff-00 [none]" : "[none]");
712 else
713 printf("\t\tAssociatedBusNumbers: %02x-%02x\n", nextbusn, lastbusn );
714}
715
716static void
717cap_lmr(struct device *d, int where)
718{
719 printf("Lane Margining at the Receiver\n");
720
721 if (verbose < 2)
722 return;
723
724 if (!config_fetch(d, where, 8))
725 return;
726
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);
729
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));
734}
735
736static void
737cap_phy_16gt(struct device *d, int where)
738{
739 printf("Physical Layer 16.0 GT/s\n");
740
741 if (verbose < 2)
742 return;
743
744 if (!config_fetch(d, where + PCI_16GT_CAP, 0x18)) {
745 printf("\t\t<unreadable>\n");
746 return;
747 }
748
749 u32 status = get_conf_long(d, where + PCI_16GT_STATUS);
750
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));
757}
758
759static void
760cap_phy_32gt(struct device *d, int where)
761{
762 static const char * const mod_ts_modes[] = {
763 "PCI Express",
764 "Training Set Messages",
765 "Alternate Protocol Negotiation"
766 };
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"
772 };
773 char buf[48];
774
775 printf("Physical Layer 32.0 GT/s\n");
776
777 if (verbose < 2)
778 return;
779
780 if (!config_fetch(d, where + PCI_32GT_CAP, 0x1C)) {
781 printf("\t\t<unreadable>\n");
782 return;
783 }
784
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);
788
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));
796
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));
802
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));
816}
817
818static void
819cap_phy_64gt(struct device *d, int where)
820{
821 printf("Physical Layer 64.0 GT/s\n");
822
823 if (verbose < 2)
824 return;
825
826 if (!config_fetch(d, where + PCI_64GT_CAP, 0x0C)) {
827 printf("\t\t<unreadable>\n");
828 return;
829 }
830
831 u32 status = get_conf_long(d, where + PCI_64GT_STATUS);
832
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));
843}
844
845static void
846cxl_range(u64 base, u64 size, int n)
847{
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" };
851 u16 w;
852
853 w = (u16) size;
854
855 size &= ~0x0fffffffULL;
856
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));
863}
864
865static void
866dvsec_cxl_device(struct device *d, int rev, int where, int len)
867{
868 u32 cache_size, cache_unit_size;
869 u64 range_base, range_size;
870 u16 w;
871
872 /* Legacy 1.1 revs aren't handled */
873 if (rev == 0)
874 return;
875
876 if (rev >= 1 && len >= PCI_CXL_DEV_LEN)
877 {
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));
882
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));
888
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));
891
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));
898 if (rev >= 2)
899 printf(" DesiredVolatileHDMStateAfterHotReset%c", FLAG(w, PCI_CXL_DEV_CTRL2_INIT_CXL_HDM_STATE_HOTRST));
900 printf("\n");
901
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));
905
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)
911 {
912 case PCI_CXL_DEV_CAP2_CACHE_1M:
913 printf("Cache Size: %08x\n", cache_size * (1<<20));
914 break;
915 case PCI_CXL_DEV_CAP2_CACHE_64K:
916 printf("Cache Size: %08x\n", cache_size * (64<<10));
917 break;
918 case PCI_CXL_DEV_CAP2_CACHE_UNK:
919 printf("Cache Size Not Reported\n");
920 break;
921 default:
922 printf("Cache Size: %d of unknown unit size (%d)\n", cache_size, cache_unit_size);
923 break;
924 }
925
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);
931
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);
937 }
938
939 if (rev >= 2 && len >= PCI_CXL_DEV_LEN_REV2)
940 {
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));
947 }
948
949 // Unparsed data
950 if (len > PCI_CXL_DEV_LEN_REV2)
951 printf("\t\t<?>\n");
952}
953
954static void
955dvsec_cxl_port(struct device *d, int where, int len)
956{
957 u16 w, m1, m2;
958 u8 b1, b2;
959
960 if (len < PCI_CXL_PORT_EXT_LEN)
961 return;
962
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));
965
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));
971
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);
978}
979
980static void
981dvsec_cxl_register_locator(struct device *d, int where, int len)
982{
983 static const char * const id_names[] = {
984 "empty",
985 "component registers",
986 "BAR virtualization",
987 "CXL device registers",
988 "CPMU registers",
989 };
990
991 for (int i=0; ; i++)
992 {
993 int pos = where + PCI_CXL_RL_BLOCK1_LO + 8*i;
994 if (pos + 7 >= where + len)
995 break;
996
997 u32 lo = get_conf_long(d, pos);
998 u32 hi = get_conf_long(d, pos + 4);
999
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);
1003
1004 if (!block_id)
1005 continue;
1006
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";
1012 else
1013 id_name = "<?>";
1014
1015 printf("\t\tBlock%d: BIR: bar%d, ID: %s, offset: %016" PCI_U64_FMT_X "\n", i + 1, bir, id_name, base);
1016 }
1017}
1018
1019static void
1020dvsec_cxl_gpf_device(struct device *d, int where)
1021{
1022 u32 l;
1023 u16 w, duration;
1024 u8 time_base, time_scale;
1025
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);
1029
1030 switch (time_scale)
1031 {
1032 case PCI_CXL_GPF_DEV_100US:
1033 case PCI_CXL_GPF_DEV_100MS:
1034 duration = time_base * 100;
1035 break;
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;
1040 break;
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;
1045 break;
1046 default:
1047 /* Reserved */
1048 printf("\t\tReserved time scale encoding %x\n", time_scale);
1049 duration = time_base;
1050 }
1051
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" : "<?>");
1056
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);
1059}
1060
1061static void
1062dvsec_cxl_gpf_port(struct device *d, int where)
1063{
1064 u16 w, timeout;
1065 u8 time_base, time_scale;
1066
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);
1070
1071 switch (time_scale)
1072 {
1073 case PCI_CXL_GPF_PORT_100US:
1074 case PCI_CXL_GPF_PORT_100MS:
1075 timeout = time_base * 100;
1076 break;
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;
1081 break;
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;
1086 break;
1087 default:
1088 /* Reserved */
1089 printf("\t\tReserved time scale encoding %x\n", time_scale);
1090 timeout = time_base;
1091 }
1092
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" : "<?>");
1097
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);
1101
1102 switch (time_scale)
1103 {
1104 case PCI_CXL_GPF_PORT_100US:
1105 case PCI_CXL_GPF_PORT_100MS:
1106 timeout = time_base * 100;
1107 break;
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;
1112 break;
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;
1117 break;
1118 default:
1119 /* Reserved */
1120 printf("\t\tReserved time scale encoding %x\n", time_scale);
1121 timeout = time_base;
1122 }
1123
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" : "<?>");
1128}
1129
1130static void
1131dvsec_cxl_flex_bus(struct device *d, int where, int rev, int len)
1132{
1133 u16 w;
1134 u32 l, data;
1135
1136 // Sanity check: Does the length correspond to its revision?
1137 switch (rev) {
1138 case 0:
1139 if (len != PCI_CXL_FB_MOD_TS_DATA)
1140 printf("\t\t<Wrong length for Revision %d>\n", rev);
1141 break;
1142 case 1:
1143 if (len != PCI_CXL_FB_PORT_CAP2)
1144 printf("\t\t<Wrong length for Revision %d>\n", rev);
1145 break;
1146 case 2:
1147 if (len != PCI_CXL_FB_NEXT_UNSUPPORTED)
1148 printf("\t\t<Wrong length for Revision %d>\n", rev);
1149 break;
1150 default:
1151 break;
1152 }
1153
1154 // From Rev 0
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));
1160
1161 if (rev > 1)
1162 printf(" 256BFlit%c PBRFlit%c",
1163 FLAG(w, PCI_CXL_FB_CAP_256B_FLIT), FLAG(w, PCI_CXL_FB_CAP_PBR_FLIT));
1164
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));
1172
1173 if (rev > 1)
1174 printf(" 256BFlit%c PBRFlit%c",
1175 FLAG(w, PCI_CXL_FB_CTRL_256B_FLIT), FLAG(w, PCI_CXL_FB_CTRL_PBR_FLIT));
1176
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));
1183
1184 if (rev > 1)
1185 printf(" 256BFlit%c PBRFlit%c",
1186 FLAG(w, PCI_CXL_FB_STAT_256B_FLIT), FLAG(w, PCI_CXL_FB_STAT_PBR_FLIT));
1187 printf("\n");
1188
1189 // From Rev 1
1190 if (rev >= 1)
1191 {
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);
1195 }
1196
1197 // From Rev 2
1198 if (rev >= 2)
1199 {
1200 u8 nop;
1201
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));
1204
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));
1207
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);
1211 }
1212
1213 // Unparsed data
1214 if (len > PCI_CXL_FB_LEN)
1215 printf("\t\t<?>\n");
1216}
1217
1218static void
1219dvsec_cxl_mld(struct device *d, int where)
1220{
1221 u16 w;
1222
1223 w = get_conf_word(d, where + PCI_CXL_MLD_NUM_LD);
1224
1225 /* Encodings greater than 16 are reserved */
1226 if (w && w <= PCI_CXL_MLD_MAX_LD)
1227 printf("\t\tNumLogDevs: %d\n", w);
1228}
1229
1230static void
1231dvsec_cxl_function_map(struct device *d, int where)
1232{
1233
1234 printf("\t\tFuncMap 0: %08x\n",
1235 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_0)));
1236
1237 printf("\t\tFuncMap 1: %08x\n",
1238 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_1)));
1239
1240 printf("\t\tFuncMap 2: %08x\n",
1241 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_2)));
1242
1243 printf("\t\tFuncMap 3: %08x\n",
1244 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_3)));
1245
1246 printf("\t\tFuncMap 4: %08x\n",
1247 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_4)));
1248
1249 printf("\t\tFuncMap 5: %08x\n",
1250 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_5)));
1251
1252 printf("\t\tFuncMap 6: %08x\n",
1253 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_6)));
1254
1255 printf("\t\tFuncMap 7: %08x\n",
1256 (unsigned int)(get_conf_word(d, where + PCI_CXL_FUN_MAP_REG_7)));
1257}
1258
1259static void
1260cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len)
1261{
1262 printf(": CXL\n");
1263 if (verbose < 2)
1264 return;
1265
1266 if (!config_fetch(d, where, len))
1267 return;
1268
1269 switch (id)
1270 {
1271 case 0:
1272 printf("\t\tPCIe DVSEC for CXL Devices\n");
1273 dvsec_cxl_device(d, rev, where, len);
1274 break;
1275 case 2:
1276 printf("\t\tNon-CXL Function Map DVSEC\n");
1277 dvsec_cxl_function_map(d, where);
1278 break;
1279 case 3:
1280 printf("\t\tCXL Extensions DVSEC for Ports\n");
1281 dvsec_cxl_port(d, where, len);
1282 break;
1283 case 4:
1284 printf("\t\tGPF DVSEC for CXL Ports\n");
1285 dvsec_cxl_gpf_port(d, where);
1286 break;
1287 case 5:
1288 printf("\t\tGPF DVSEC for CXL Devices\n");
1289 dvsec_cxl_gpf_device(d, where);
1290 break;
1291 case 7:
1292 printf("\t\tPCIe DVSEC for Flex Bus Port\n");
1293 dvsec_cxl_flex_bus(d, where, rev, len);
1294 break;
1295 case 8:
1296 printf("\t\tRegister Locator DVSEC\n");
1297 dvsec_cxl_register_locator(d, where, len);
1298 break;
1299 case 9:
1300 printf("\t\tMLD DVSEC\n");
1301 dvsec_cxl_mld(d, where);
1302 break;
1303 case 0xa:
1304 printf("\t\tPCIe DVSEC for Test Capability <?>\n");
1305 break;
1306 default:
1307 printf("\t\tUnknown ID %04x\n", id);
1308 }
1309}
1310
1311static void
1312cap_dvsec(struct device *d, int where)
1313{
1314 printf("Designated Vendor-Specific: ");
1315 if (!config_fetch(d, where + PCI_DVSEC_HEADER1, 8))
1316 {
1317 printf("<unreadable>\n");
1318 return;
1319 }
1320
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);
1325
1326 u16 id = get_conf_long(d, where + PCI_DVSEC_HEADER2);
1327
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);
1331 else
1332 printf(" <?>\n");
1333}
1334
1335static void
1336cap_evendor(struct device *d, int where)
1337{
1338 u32 hdr;
1339
1340 printf("Vendor Specific Information: ");
1341 if (!config_fetch(d, where + PCI_EVNDR_HEADER, 4))
1342 {
1343 printf("<unreadable>\n");
1344 return;
1345 }
1346
1347 hdr = get_conf_long(d, where + PCI_EVNDR_HEADER);
1348 printf("ID=%04x Rev=%d Len=%03x <?>\n",
1349 BITS(hdr, 0, 16),
1350 BITS(hdr, 16, 4),
1351 BITS(hdr, 20, 12));
1352}
1353
1354static int l1pm_calc_pwron(int scale, int value)
1355{
1356 switch (scale)
1357 {
1358 case 0:
1359 return 2 * value;
1360 case 1:
1361 return 10 * value;
1362 case 2:
1363 return 100 * value;
1364 }
1365 return -1;
1366}
1367
1368static void
1369cap_l1pm(struct device *d, int where)
1370{
1371 u32 l1_cap, val, scale;
1372 int time;
1373
1374 printf("L1 PM Substates\n");
1375
1376 if (verbose < 2)
1377 return;
1378
1379 if (!config_fetch(d, where + PCI_L1PM_SUBSTAT_CAP, 12))
1380 {
1381 printf("\t\t<unreadable>\n");
1382 return;
1383 }
1384
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));
1393
1394 if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
1395 {
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));
1398 if (time != -1)
1399 printf("PortTPowerOnTime=%dus\n", time);
1400 else
1401 printf("PortTPowerOnTime=<error>\n");
1402 }
1403
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));
1410
1411 if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
1412 {
1413 printf("\t\t\t T_CommonMode=%dus", BITS(val, 8, 8));
1414
1415 if (l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
1416 {
1417 scale = BITS(val, 29, 3);
1418 if (scale > 5)
1419 printf(" LTR1.2_Threshold=<error>");
1420 else
1421 printf(" LTR1.2_Threshold=%" PCI_U64_FMT_U "ns", BITS(val, 16, 10) * (u64) cap_ltr_scale(scale));
1422 }
1423 printf("\n");
1424 }
1425
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)
1429 {
1430 time = l1pm_calc_pwron(BITS(val, 0, 2), BITS(val, 3, 5));
1431 if (time != -1)
1432 printf(" T_PwrOn=%dus", time);
1433 else
1434 printf(" T_PwrOn=<error>");
1435 }
1436 printf("\n");
1437}
1438
1439static void
1440cap_ptm(struct device *d, int where)
1441{
1442 u32 buff;
1443 u16 clock;
1444
1445 printf("Precision Time Measurement\n");
1446
1447 if (verbose < 2)
1448 return;
1449
1450 if (!config_fetch(d, where + 4, 8))
1451 {
1452 printf("\t\t<unreadable>\n");
1453 return;
1454 }
1455
1456 buff = get_conf_long(d, where + 4);
1457 printf("\t\tPTMCap: ");
1458 printf("Requester%c Responder%c Root%c\n",
1459 FLAG(buff, 0x1),
1460 FLAG(buff, 0x2),
1461 FLAG(buff, 0x4));
1462
1463 clock = BITS(buff, 8, 8);
1464 printf("\t\tPTMClockGranularity: ");
1465 switch (clock)
1466 {
1467 case 0x00:
1468 printf("Unimplemented\n");
1469 break;
1470 case 0xff:
1471 printf("Greater than 254ns\n");
1472 break;
1473 default:
1474 printf("%huns\n", clock);
1475 }
1476
1477 buff = get_conf_long(d, where + 8);
1478 printf("\t\tPTMControl: ");
1479 printf("Enabled%c RootSelected%c\n",
1480 FLAG(buff, 0x1),
1481 FLAG(buff, 0x2));
1482
1483 clock = BITS(buff, 8, 8);
1484 printf("\t\tPTMEffectiveGranularity: ");
1485 switch (clock)
1486 {
1487 case 0x00:
1488 printf("Unknown\n");
1489 break;
1490 case 0xff:
1491 printf("Greater than 254ns\n");
1492 break;
1493 default:
1494 printf("%huns\n", clock);
1495 }
1496}
1497
1498static void
1499print_rebar_range_size(int ld2_size)
1500{
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)
1506
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)));
1517 else
1518 printf(" <unknown>");
1519}
1520
1521static void
1522cap_rebar(struct device *d, int where, int virtual)
1523{
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
1527 u16 num_bars = 1;
1528
1529 printf("%s Resizable BAR\n", (virtual) ? "Virtual" : "Physical");
1530
1531 if (verbose < 2)
1532 return;
1533
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++)
1537 {
1538 where += 4;
1539
1540 // Get the next BAR configuration
1541 if (!config_fetch(d, where, 8))
1542 {
1543 printf("\t\t<unreadable>\n");
1544 return;
1545 }
1546
1547 sizes_buffer = get_conf_long(d, where) >> 4;
1548 where += 4;
1549 control_buffer = get_conf_long(d, where);
1550
1551 bar_index = BITS(control_buffer, 0, 3);
1552 current_size = BITS(control_buffer, 8, 6);
1553 ext_sizes = BITS(control_buffer, 16, 16);
1554
1555 if (barcount == 0)
1556 {
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)
1560 {
1561 printf("\t\t<error in resizable BAR: num_bars=%d is out of specification>\n", num_bars);
1562 break;
1563 }
1564 }
1565
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);
1569
1570 if (sizes_buffer || ext_sizes)
1571 {
1572 printf(", supported:");
1573
1574 for (i=0; i<28; i++)
1575 if (sizes_buffer & (1U << i))
1576 print_rebar_range_size(i);
1577
1578 for (i=0; i<16; i++)
1579 if (ext_sizes & (1U << i))
1580 print_rebar_range_size(i + 28);
1581 }
1582
1583 printf("\n");
1584 }
1585}
1586
1587static void
1588cap_doe(struct device *d, int where)
1589{
1590 u32 l;
1591
1592 printf("Data Object Exchange\n");
1593
1594 if (verbose < 2)
1595 return;
1596
1597 if (!config_fetch(d, where + PCI_DOE_CAP, 0x14))
1598 {
1599 printf("\t\t<unreadable>\n");
1600 return;
1601 }
1602
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));
1609
1610 l = get_conf_long(d, where + PCI_DOE_CTL);
1611 printf("\t\tDOECtl: IntEn%c\n",
1612 FLAG(l, PCI_DOE_CTL_INT));
1613
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));
1620}
1621
1622static const char *offstr(char *buf, u32 off)
1623{
1624 if (verbose < 3)
1625 return "";
1626
1627 sprintf(buf, "[%x]", off);
1628 return buf;
1629}
1630
1631static const char *ide_alg(char *buf, size_t len, u32 l)
1632{
1633 const char *algo[] = { "AES-GCM-256-96b" }; // AES-GCM 256 key size, 96b MAC
1634
1635 if (l == 0)
1636 snprintf(buf, len, "%s", algo[l]);
1637 else
1638 snprintf(buf, len, "%s", "reserved");
1639 return buf;
1640}
1641
1642static void
1643cap_ide(struct device *d, int where)
1644{
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];
1650
1651 printf("Integrity & Data Encryption\n");
1652
1653 if (verbose < 2)
1654 return;
1655
1656 if (!config_fetch(d, where + PCI_IDE_CAP, 8))
1657 {
1658 printf("\t\t<unreadable>\n");
1659 return;
1660 }
1661
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;
1667
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",
1669 linknum,
1670 selnum,
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)
1679 );
1680
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));
1684
1685 // The rest of the capability is variable length arrays
1686 off = where + PCI_IDE_LINK_STREAM;
1687
1688 // Link IDE Register Block repeated 0 to 8 times
1689 if (linknum)
1690 {
1691 if (!config_fetch(d, off, 8 * linknum))
1692 {
1693 printf("\t\t<unreadable>\n");
1694 return;
1695 }
1696 for (i = 0; i < linknum; ++i)
1697 {
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",
1701 offstr(offs, off),
1702 i,
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)
1712 );
1713 off += 4;
1714
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",
1718 offstr(offs, off),
1719 i,
1720 TABLE(stream_state, PCI_IDE_LINK_STS_STATUS(l), buf1),
1721 FLAG(l, PCI_IDE_LINK_STS_RECVD_INTEGRITY_CHECK));
1722 off += 4;
1723 }
1724 }
1725
1726 for (i = 0; i < selnum; ++i)
1727 {
1728 // Fetching Selective IDE Stream Capability/Control/Status/RID1/RID2
1729 if (!config_fetch(d, off, 20))
1730 {
1731 printf("\t\t<unreadable>\n");
1732 return;
1733 }
1734
1735 // Selective IDE Stream Capability Register
1736 l = get_conf_long(d, off);
1737 printf("\t\t%sSelectiveIDE#%d Cap: RID#=%d\n",
1738 offstr(offs, off),
1739 i,
1740 PCI_IDE_SEL_CAP_BLOCKS_NUM(l));
1741 off += 4;
1742 addrnum = PCI_IDE_SEL_CAP_BLOCKS_NUM(l);
1743
1744 // Selective IDE Stream Control Register
1745 l = get_conf_long(d, off);
1746
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",
1748 offstr(offs, off),
1749 i,
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" : ""
1761 );
1762 off += 4;
1763
1764 // Selective IDE Stream Status Register
1765 l = get_conf_long(d, off);
1766 printf("\t\t%sSelectiveIDE#%d Sta: %s RecvChkFail%c\n",
1767 offstr(offs, off),
1768 i ,
1769 TABLE(stream_state, PCI_IDE_SEL_STS_STATUS(l), buf1),
1770 FLAG(l, PCI_IDE_SEL_STS_RECVD_INTEGRITY_CHECK));
1771 off += 4;
1772
1773 // IDE RID Association Registers
1774 l = get_conf_long(d, off);
1775 l2 = get_conf_long(d, off + 4);
1776
1777 printf("\t\t%sSelectiveIDE#%d RID: Valid%c Base=%x Limit=%x SegBase=%x\n",
1778 offstr(offs, off),
1779 i,
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));
1784 off += 8;
1785
1786 if (!config_fetch(d, off, addrnum * 12))
1787 {
1788 printf("\t\t<unreadable>\n");
1789 return;
1790 }
1791
1792 // IDE Address Association Registers
1793 for (j = 0; j < addrnum; ++j)
1794 {
1795 u64 limit, base;
1796
1797 l = get_conf_long(d, off);
1798 limit = get_conf_long(d, off + 4);
1799 limit <<= 32;
1800 limit |= (PCI_IDE_SEL_ADDR_1_LIMIT_LOW(l) << 20) | 0xFFFFF;
1801 base = get_conf_long(d, off + 8);
1802 base <<= 32;
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",
1805 offstr(offs, off),
1806 i,
1807 j,
1808 FLAG(l, PCI_IDE_SEL_ADDR_1_VALID),
1809 base,
1810 limit);
1811 off += 12;
1812 }
1813 }
1814}
1815
1816static const char *l0p_exit_latency(int value)
1817{
1818 static const char * const latencies[] = {
1819 "Less than 1us",
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",
1825 "32us-64us",
1826 "More than 64us"
1827 };
1828
1829 if (value >= 0 && value <= 7)
1830 return latencies[value];
1831 return "Unknown";
1832}
1833
1834static const char *link_width_str(char *buf, size_t buflen, int width)
1835{
1836 switch (width)
1837 {
1838 case 0:
1839 return "x1";
1840 case 1:
1841 return "x2";
1842 case 2:
1843 return "x4";
1844 case 3:
1845 return "x8";
1846 case 4:
1847 return "x16";
1848 case 7:
1849 return "Dynamic";
1850 default:
1851 snprintf(buf, buflen, "Unknown (%d)", width);
1852 return buf;
1853 }
1854}
1855
1856static void
1857cap_dev3(struct device *d, int where)
1858{
1859 u32 devcap3;
1860 u16 devctl3, devsta3;
1861 char buf[16];
1862
1863 printf("Device 3\n");
1864
1865 if (verbose < 2)
1866 return;
1867
1868 if (!config_fetch(d, where + PCI_DEV3_DEVCAP3, 4))
1869 return;
1870 devcap3 = get_conf_long(d, where + PCI_DEV3_DEVCAP3);
1871
1872 printf("\t\tDevCap3: DMWr Request Routing%c, 14-Bit Tag Completer%c, 14-Bit Tag Requester%c\n"
1873 "\t\t\t L0p%c",
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));
1878
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)));
1883
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));
1887
1888 if (!config_fetch(d, where + PCI_DEV3_DEVCTL3, 2))
1889 return;
1890 devctl3 = get_conf_word(d, where + PCI_DEV3_DEVCTL3);
1891
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));
1902
1903 if (!config_fetch(d, where + PCI_DEV3_DEVSTA3, 2))
1904 return;
1905 devsta3 = get_conf_word(d, where + PCI_DEV3_DEVSTA3);
1906
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));
1911}
1912
1913void
1914show_ext_caps(struct device *d, int type)
1915{
1916 int where = 0x100;
1917 char been_there[0x1000];
1918 memset(been_there, 0, 0x1000);
1919 do
1920 {
1921 u32 header;
1922 int id, version;
1923
1924 if (!config_fetch(d, where, 4))
1925 break;
1926 header = get_conf_long(d, where);
1927 if (!header || header == 0xffffffff)
1928 break;
1929 id = header & 0xffff;
1930 version = (header >> 16) & 0xf;
1931 printf("\tCapabilities: [%03x", where);
1932 if (verbose > 1)
1933 printf(" v%d", version);
1934 printf("] ");
1935 if (been_there[where]++)
1936 {
1937 printf("<chain looped>\n");
1938 break;
1939 }
1940 switch (id)
1941 {
1942 case PCI_EXT_CAP_ID_NULL:
1943 printf("Null\n");
1944 break;
1945 case PCI_EXT_CAP_ID_AER:
1946 cap_aer(d, where, type);
1947 break;
1948 case PCI_EXT_CAP_ID_DPC:
1949 cap_dpc(d, where);
1950 break;
1951 case PCI_EXT_CAP_ID_VC:
1952 case PCI_EXT_CAP_ID_VC2:
1953 cap_vc(d, where);
1954 break;
1955 case PCI_EXT_CAP_ID_DSN:
1956 cap_dsn(d, where);
1957 break;
1958 case PCI_EXT_CAP_ID_PB:
1959 printf("Power Budgeting <?>\n");
1960 break;
1961 case PCI_EXT_CAP_ID_RCLINK:
1962 cap_rclink(d, where);
1963 break;
1964 case PCI_EXT_CAP_ID_RCILINK:
1965 printf("Root Complex Internal Link <?>\n");
1966 break;
1967 case PCI_EXT_CAP_ID_RCEC:
1968 cap_rcec(d, where);
1969 break;
1970 case PCI_EXT_CAP_ID_MFVC:
1971 printf("Multi-Function Virtual Channel <?>\n");
1972 break;
1973 case PCI_EXT_CAP_ID_RCRB:
1974 printf("Root Complex Register Block <?>\n");
1975 break;
1976 case PCI_EXT_CAP_ID_VNDR:
1977 cap_evendor(d, where);
1978 break;
1979 case PCI_EXT_CAP_ID_ACS:
1980 cap_acs(d, where);
1981 break;
1982 case PCI_EXT_CAP_ID_ARI:
1983 cap_ari(d, where);
1984 break;
1985 case PCI_EXT_CAP_ID_ATS:
1986 cap_ats(d, where);
1987 break;
1988 case PCI_EXT_CAP_ID_SRIOV:
1989 cap_sriov(d, where);
1990 break;
1991 case PCI_EXT_CAP_ID_MRIOV:
1992 printf("Multi-Root I/O Virtualization <?>\n");
1993 break;
1994 case PCI_EXT_CAP_ID_MCAST:
1995 cap_multicast(d, where, type);
1996 break;
1997 case PCI_EXT_CAP_ID_PRI:
1998 cap_pri(d, where);
1999 break;
2000 case PCI_EXT_CAP_ID_REBAR:
2001 cap_rebar(d, where, 0);
2002 break;
2003 case PCI_EXT_CAP_ID_DPA:
2004 printf("Dynamic Power Allocation <?>\n");
2005 break;
2006 case PCI_EXT_CAP_ID_TPH:
2007 cap_tph(d, where);
2008 break;
2009 case PCI_EXT_CAP_ID_LTR:
2010 cap_ltr(d, where);
2011 break;
2012 case PCI_EXT_CAP_ID_SECPCI:
2013 cap_sec(d, where);
2014 break;
2015 case PCI_EXT_CAP_ID_PMUX:
2016 printf("Protocol Multiplexing <?>\n");
2017 break;
2018 case PCI_EXT_CAP_ID_PASID:
2019 cap_pasid(d, where);
2020 break;
2021 case PCI_EXT_CAP_ID_LNR:
2022 printf("LN Requester <?>\n");
2023 break;
2024 case PCI_EXT_CAP_ID_L1PM:
2025 cap_l1pm(d, where);
2026 break;
2027 case PCI_EXT_CAP_ID_PTM:
2028 cap_ptm(d, where);
2029 break;
2030 case PCI_EXT_CAP_ID_M_PCIE:
2031 printf("PCI Express over M_PHY <?>\n");
2032 break;
2033 case PCI_EXT_CAP_ID_FRS:
2034 printf("FRS Queueing <?>\n");
2035 break;
2036 case PCI_EXT_CAP_ID_RTR:
2037 printf("Readiness Time Reporting <?>\n");
2038 break;
2039 case PCI_EXT_CAP_ID_DVSEC:
2040 cap_dvsec(d, where);
2041 break;
2042 case PCI_EXT_CAP_ID_VF_REBAR:
2043 cap_rebar(d, where, 1);
2044 break;
2045 case PCI_EXT_CAP_ID_DLNK:
2046 printf("Data Link Feature <?>\n");
2047 break;
2048 case PCI_EXT_CAP_ID_16GT:
2049 cap_phy_16gt(d, where);
2050 break;
2051 case PCI_EXT_CAP_ID_LMR:
2052 cap_lmr(d, where);
2053 break;
2054 case PCI_EXT_CAP_ID_HIER_ID:
2055 printf("Hierarchy ID <?>\n");
2056 break;
2057 case PCI_EXT_CAP_ID_NPEM:
2058 printf("Native PCIe Enclosure Management <?>\n");
2059 break;
2060 case PCI_EXT_CAP_ID_32GT:
2061 cap_phy_32gt(d, where);
2062 break;
2063 case PCI_EXT_CAP_ID_DOE:
2064 cap_doe(d, where);
2065 break;
2066 case PCI_EXT_CAP_ID_IDE:
2067 cap_ide(d, where);
2068 break;
2069 case PCI_EXT_CAP_ID_64GT:
2070 cap_phy_64gt(d, where);
2071 break;
2072 case PCI_EXT_CAP_ID_DEV3:
2073 cap_dev3(d, where);
2074 break;
2075 default:
2076 printf("Extended Capability ID %#02x\n", id);
2077 break;
2078 }
2079 where = (header >> 20) & ~3;
2080 } while (where);
2081}