Annotation of embedaddon/pciutils/ls-caps.c, revision 1.1.1.1
1.1 misho 1: /*
2: * The PCI Utilities -- Show Capabilities
3: *
4: * Copyright (c) 1997--2010 Martin Mares <mj@ucw.cz>
5: *
6: * Can be freely distributed and used under the terms of the GNU GPL.
7: */
8:
9: #include <stdio.h>
10: #include <string.h>
11:
12: #include "lspci.h"
13:
14: static void
15: cap_pm(struct device *d, int where, int cap)
16: {
17: int t, b;
18: static int pm_aux_current[8] = { 0, 55, 100, 160, 220, 270, 320, 375 };
19:
20: printf("Power Management version %d\n", cap & PCI_PM_CAP_VER_MASK);
21: if (verbose < 2)
22: return;
23: printf("\t\tFlags: PMEClk%c DSI%c D1%c D2%c AuxCurrent=%dmA PME(D0%c,D1%c,D2%c,D3hot%c,D3cold%c)\n",
24: FLAG(cap, PCI_PM_CAP_PME_CLOCK),
25: FLAG(cap, PCI_PM_CAP_DSI),
26: FLAG(cap, PCI_PM_CAP_D1),
27: FLAG(cap, PCI_PM_CAP_D2),
28: pm_aux_current[(cap >> 6) & 7],
29: FLAG(cap, PCI_PM_CAP_PME_D0),
30: FLAG(cap, PCI_PM_CAP_PME_D1),
31: FLAG(cap, PCI_PM_CAP_PME_D2),
32: FLAG(cap, PCI_PM_CAP_PME_D3_HOT),
33: FLAG(cap, PCI_PM_CAP_PME_D3_COLD));
34: if (!config_fetch(d, where + PCI_PM_CTRL, PCI_PM_SIZEOF - PCI_PM_CTRL))
35: return;
36: t = get_conf_word(d, where + PCI_PM_CTRL);
37: printf("\t\tStatus: D%d NoSoftRst%c PME-Enable%c DSel=%d DScale=%d PME%c\n",
38: t & PCI_PM_CTRL_STATE_MASK,
39: FLAG(t, PCI_PM_CTRL_NO_SOFT_RST),
40: FLAG(t, PCI_PM_CTRL_PME_ENABLE),
41: (t & PCI_PM_CTRL_DATA_SEL_MASK) >> 9,
42: (t & PCI_PM_CTRL_DATA_SCALE_MASK) >> 13,
43: FLAG(t, PCI_PM_CTRL_PME_STATUS));
44: b = get_conf_byte(d, where + PCI_PM_PPB_EXTENSIONS);
45: if (b)
46: printf("\t\tBridge: PM%c B3%c\n",
47: FLAG(t, PCI_PM_BPCC_ENABLE),
48: FLAG(~t, PCI_PM_PPB_B2_B3));
49: }
50:
51: static void
52: format_agp_rate(int rate, char *buf, int agp3)
53: {
54: char *c = buf;
55: int i;
56:
57: for (i=0; i<=2; i++)
58: if (rate & (1 << i))
59: {
60: if (c != buf)
61: *c++ = ',';
62: c += sprintf(c, "x%d", 1 << (i + 2*agp3));
63: }
64: if (c != buf)
65: *c = 0;
66: else
67: strcpy(buf, "<none>");
68: }
69:
70: static void
71: cap_agp(struct device *d, int where, int cap)
72: {
73: u32 t;
74: char rate[16];
75: int ver, rev;
76: int agp3 = 0;
77:
78: ver = (cap >> 4) & 0x0f;
79: rev = cap & 0x0f;
80: printf("AGP version %x.%x\n", ver, rev);
81: if (verbose < 2)
82: return;
83: if (!config_fetch(d, where + PCI_AGP_STATUS, PCI_AGP_SIZEOF - PCI_AGP_STATUS))
84: return;
85: t = get_conf_long(d, where + PCI_AGP_STATUS);
86: if (ver >= 3 && (t & PCI_AGP_STATUS_AGP3))
87: agp3 = 1;
88: format_agp_rate(t & 7, rate, agp3);
89: printf("\t\tStatus: RQ=%d Iso%c ArqSz=%d Cal=%d SBA%c ITACoh%c GART64%c HTrans%c 64bit%c FW%c AGP3%c Rate=%s\n",
90: ((t & PCI_AGP_STATUS_RQ_MASK) >> 24U) + 1,
91: FLAG(t, PCI_AGP_STATUS_ISOCH),
92: ((t & PCI_AGP_STATUS_ARQSZ_MASK) >> 13),
93: ((t & PCI_AGP_STATUS_CAL_MASK) >> 10),
94: FLAG(t, PCI_AGP_STATUS_SBA),
95: FLAG(t, PCI_AGP_STATUS_ITA_COH),
96: FLAG(t, PCI_AGP_STATUS_GART64),
97: FLAG(t, PCI_AGP_STATUS_HTRANS),
98: FLAG(t, PCI_AGP_STATUS_64BIT),
99: FLAG(t, PCI_AGP_STATUS_FW),
100: FLAG(t, PCI_AGP_STATUS_AGP3),
101: rate);
102: t = get_conf_long(d, where + PCI_AGP_COMMAND);
103: format_agp_rate(t & 7, rate, agp3);
104: printf("\t\tCommand: RQ=%d ArqSz=%d Cal=%d SBA%c AGP%c GART64%c 64bit%c FW%c Rate=%s\n",
105: ((t & PCI_AGP_COMMAND_RQ_MASK) >> 24U) + 1,
106: ((t & PCI_AGP_COMMAND_ARQSZ_MASK) >> 13),
107: ((t & PCI_AGP_COMMAND_CAL_MASK) >> 10),
108: FLAG(t, PCI_AGP_COMMAND_SBA),
109: FLAG(t, PCI_AGP_COMMAND_AGP),
110: FLAG(t, PCI_AGP_COMMAND_GART64),
111: FLAG(t, PCI_AGP_COMMAND_64BIT),
112: FLAG(t, PCI_AGP_COMMAND_FW),
113: rate);
114: }
115:
116: static void
117: cap_pcix_nobridge(struct device *d, int where)
118: {
119: u16 command;
120: u32 status;
121: static const byte max_outstanding[8] = { 1, 2, 3, 4, 8, 12, 16, 32 };
122:
123: printf("PCI-X non-bridge device\n");
124:
125: if (verbose < 2)
126: return;
127:
128: if (!config_fetch(d, where + PCI_PCIX_STATUS, 4))
129: return;
130:
131: command = get_conf_word(d, where + PCI_PCIX_COMMAND);
132: status = get_conf_long(d, where + PCI_PCIX_STATUS);
133: printf("\t\tCommand: DPERE%c ERO%c RBC=%d OST=%d\n",
134: FLAG(command, PCI_PCIX_COMMAND_DPERE),
135: FLAG(command, PCI_PCIX_COMMAND_ERO),
136: 1 << (9 + ((command & PCI_PCIX_COMMAND_MAX_MEM_READ_BYTE_COUNT) >> 2U)),
137: max_outstanding[(command & PCI_PCIX_COMMAND_MAX_OUTSTANDING_SPLIT_TRANS) >> 4U]);
138: printf("\t\tStatus: Dev=%02x:%02x.%d 64bit%c 133MHz%c SCD%c USC%c DC=%s DMMRBC=%u DMOST=%u DMCRS=%u RSCEM%c 266MHz%c 533MHz%c\n",
139: ((status >> 8) & 0xff),
140: ((status >> 3) & 0x1f),
141: (status & PCI_PCIX_STATUS_FUNCTION),
142: FLAG(status, PCI_PCIX_STATUS_64BIT),
143: FLAG(status, PCI_PCIX_STATUS_133MHZ),
144: FLAG(status, PCI_PCIX_STATUS_SC_DISCARDED),
145: FLAG(status, PCI_PCIX_STATUS_UNEXPECTED_SC),
146: ((status & PCI_PCIX_STATUS_DEVICE_COMPLEXITY) ? "bridge" : "simple"),
147: 1 << (9 + ((status >> 21) & 3U)),
148: max_outstanding[(status >> 23) & 7U],
149: 1 << (3 + ((status >> 26) & 7U)),
150: FLAG(status, PCI_PCIX_STATUS_RCVD_SC_ERR_MESS),
151: FLAG(status, PCI_PCIX_STATUS_266MHZ),
152: FLAG(status, PCI_PCIX_STATUS_533MHZ));
153: }
154:
155: static void
156: cap_pcix_bridge(struct device *d, int where)
157: {
158: static const char * const sec_clock_freq[8] = { "conv", "66MHz", "100MHz", "133MHz", "?4", "?5", "?6", "?7" };
159: u16 secstatus;
160: u32 status, upstcr, downstcr;
161:
162: printf("PCI-X bridge device\n");
163:
164: if (verbose < 2)
165: return;
166:
167: if (!config_fetch(d, where + PCI_PCIX_BRIDGE_STATUS, 12))
168: return;
169:
170: secstatus = get_conf_word(d, where + PCI_PCIX_BRIDGE_SEC_STATUS);
171: printf("\t\tSecondary Status: 64bit%c 133MHz%c SCD%c USC%c SCO%c SRD%c Freq=%s\n",
172: FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_64BIT),
173: FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_133MHZ),
174: FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_DISCARDED),
175: FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_UNEXPECTED_SC),
176: FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_OVERRUN),
177: FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SPLIT_REQUEST_DELAYED),
178: sec_clock_freq[(secstatus >> 6) & 7]);
179: status = get_conf_long(d, where + PCI_PCIX_BRIDGE_STATUS);
180: printf("\t\tStatus: Dev=%02x:%02x.%d 64bit%c 133MHz%c SCD%c USC%c SCO%c SRD%c\n",
181: ((status >> 8) & 0xff),
182: ((status >> 3) & 0x1f),
183: (status & PCI_PCIX_BRIDGE_STATUS_FUNCTION),
184: FLAG(status, PCI_PCIX_BRIDGE_STATUS_64BIT),
185: FLAG(status, PCI_PCIX_BRIDGE_STATUS_133MHZ),
186: FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_DISCARDED),
187: FLAG(status, PCI_PCIX_BRIDGE_STATUS_UNEXPECTED_SC),
188: FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_OVERRUN),
189: FLAG(status, PCI_PCIX_BRIDGE_STATUS_SPLIT_REQUEST_DELAYED));
190: upstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_UPSTREAM_SPLIT_TRANS_CTRL);
191: printf("\t\tUpstream: Capacity=%u CommitmentLimit=%u\n",
192: (upstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
193: (upstcr >> 16) & 0xffff);
194: downstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_DOWNSTREAM_SPLIT_TRANS_CTRL);
195: printf("\t\tDownstream: Capacity=%u CommitmentLimit=%u\n",
196: (downstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
197: (downstcr >> 16) & 0xffff);
198: }
199:
200: static void
201: cap_pcix(struct device *d, int where)
202: {
203: switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f)
204: {
205: case PCI_HEADER_TYPE_NORMAL:
206: cap_pcix_nobridge(d, where);
207: break;
208: case PCI_HEADER_TYPE_BRIDGE:
209: cap_pcix_bridge(d, where);
210: break;
211: }
212: }
213:
214: static inline char *
215: ht_link_width(unsigned width)
216: {
217: static char * const widths[8] = { "8bit", "16bit", "[2]", "32bit", "2bit", "4bit", "[6]", "N/C" };
218: return widths[width];
219: }
220:
221: static inline char *
222: ht_link_freq(unsigned freq)
223: {
224: static char * const freqs[16] = { "200MHz", "300MHz", "400MHz", "500MHz", "600MHz", "800MHz", "1.0GHz", "1.2GHz",
225: "1.4GHz", "1.6GHz", "[a]", "[b]", "[c]", "[d]", "[e]", "Vend" };
226: return freqs[freq];
227: }
228:
229: static void
230: cap_ht_pri(struct device *d, int where, int cmd)
231: {
232: u16 lctr0, lcnf0, lctr1, lcnf1, eh;
233: u8 rid, lfrer0, lfcap0, ftr, lfrer1, lfcap1, mbu, mlu, bn;
234: char *fmt;
235:
236: printf("HyperTransport: Slave or Primary Interface\n");
237: if (verbose < 2)
238: return;
239:
240: if (!config_fetch(d, where + PCI_HT_PRI_LCTR0, PCI_HT_PRI_SIZEOF - PCI_HT_PRI_LCTR0))
241: return;
242: rid = get_conf_byte(d, where + PCI_HT_PRI_RID);
243: if (rid < 0x22 && rid > 0x11)
244: printf("\t\t!!! Possibly incomplete decoding\n");
245:
246: if (rid >= 0x22)
247: fmt = "\t\tCommand: BaseUnitID=%u UnitCnt=%u MastHost%c DefDir%c DUL%c\n";
248: else
249: fmt = "\t\tCommand: BaseUnitID=%u UnitCnt=%u MastHost%c DefDir%c\n";
250: printf(fmt,
251: (cmd & PCI_HT_PRI_CMD_BUID),
252: (cmd & PCI_HT_PRI_CMD_UC) >> 5,
253: FLAG(cmd, PCI_HT_PRI_CMD_MH),
254: FLAG(cmd, PCI_HT_PRI_CMD_DD),
255: FLAG(cmd, PCI_HT_PRI_CMD_DUL));
256: lctr0 = get_conf_word(d, where + PCI_HT_PRI_LCTR0);
257: if (rid >= 0x22)
258: fmt = "\t\tLink Control 0: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
259: else
260: fmt = "\t\tLink Control 0: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
261: printf(fmt,
262: FLAG(lctr0, PCI_HT_LCTR_CFLE),
263: FLAG(lctr0, PCI_HT_LCTR_CST),
264: FLAG(lctr0, PCI_HT_LCTR_CFE),
265: FLAG(lctr0, PCI_HT_LCTR_LKFAIL),
266: FLAG(lctr0, PCI_HT_LCTR_INIT),
267: FLAG(lctr0, PCI_HT_LCTR_EOC),
268: FLAG(lctr0, PCI_HT_LCTR_TXO),
269: (lctr0 & PCI_HT_LCTR_CRCERR) >> 8,
270: FLAG(lctr0, PCI_HT_LCTR_ISOCEN),
271: FLAG(lctr0, PCI_HT_LCTR_LSEN),
272: FLAG(lctr0, PCI_HT_LCTR_EXTCTL),
273: FLAG(lctr0, PCI_HT_LCTR_64B));
274: lcnf0 = get_conf_word(d, where + PCI_HT_PRI_LCNF0);
275: if (rid >= 0x22)
276: fmt = "\t\tLink Config 0: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
277: else
278: fmt = "\t\tLink Config 0: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
279: printf(fmt,
280: ht_link_width(lcnf0 & PCI_HT_LCNF_MLWI),
281: ht_link_width((lcnf0 & PCI_HT_LCNF_MLWO) >> 4),
282: ht_link_width((lcnf0 & PCI_HT_LCNF_LWI) >> 8),
283: ht_link_width((lcnf0 & PCI_HT_LCNF_LWO) >> 12),
284: FLAG(lcnf0, PCI_HT_LCNF_DFI),
285: FLAG(lcnf0, PCI_HT_LCNF_DFO),
286: FLAG(lcnf0, PCI_HT_LCNF_DFIE),
287: FLAG(lcnf0, PCI_HT_LCNF_DFOE));
288: lctr1 = get_conf_word(d, where + PCI_HT_PRI_LCTR1);
289: if (rid >= 0x22)
290: fmt = "\t\tLink Control 1: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
291: else
292: fmt = "\t\tLink Control 1: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
293: printf(fmt,
294: FLAG(lctr1, PCI_HT_LCTR_CFLE),
295: FLAG(lctr1, PCI_HT_LCTR_CST),
296: FLAG(lctr1, PCI_HT_LCTR_CFE),
297: FLAG(lctr1, PCI_HT_LCTR_LKFAIL),
298: FLAG(lctr1, PCI_HT_LCTR_INIT),
299: FLAG(lctr1, PCI_HT_LCTR_EOC),
300: FLAG(lctr1, PCI_HT_LCTR_TXO),
301: (lctr1 & PCI_HT_LCTR_CRCERR) >> 8,
302: FLAG(lctr1, PCI_HT_LCTR_ISOCEN),
303: FLAG(lctr1, PCI_HT_LCTR_LSEN),
304: FLAG(lctr1, PCI_HT_LCTR_EXTCTL),
305: FLAG(lctr1, PCI_HT_LCTR_64B));
306: lcnf1 = get_conf_word(d, where + PCI_HT_PRI_LCNF1);
307: if (rid >= 0x22)
308: fmt = "\t\tLink Config 1: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
309: else
310: fmt = "\t\tLink Config 1: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
311: printf(fmt,
312: ht_link_width(lcnf1 & PCI_HT_LCNF_MLWI),
313: ht_link_width((lcnf1 & PCI_HT_LCNF_MLWO) >> 4),
314: ht_link_width((lcnf1 & PCI_HT_LCNF_LWI) >> 8),
315: ht_link_width((lcnf1 & PCI_HT_LCNF_LWO) >> 12),
316: FLAG(lcnf1, PCI_HT_LCNF_DFI),
317: FLAG(lcnf1, PCI_HT_LCNF_DFO),
318: FLAG(lcnf1, PCI_HT_LCNF_DFIE),
319: FLAG(lcnf1, PCI_HT_LCNF_DFOE));
320: printf("\t\tRevision ID: %u.%02u\n",
321: (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN));
322: if (rid < 0x22)
323: return;
324: lfrer0 = get_conf_byte(d, where + PCI_HT_PRI_LFRER0);
325: printf("\t\tLink Frequency 0: %s\n", ht_link_freq(lfrer0 & PCI_HT_LFRER_FREQ));
326: printf("\t\tLink Error 0: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
327: FLAG(lfrer0, PCI_HT_LFRER_PROT),
328: FLAG(lfrer0, PCI_HT_LFRER_OV),
329: FLAG(lfrer0, PCI_HT_LFRER_EOC),
330: FLAG(lfrer0, PCI_HT_LFRER_CTLT));
331: lfcap0 = get_conf_byte(d, where + PCI_HT_PRI_LFCAP0);
332: printf("\t\tLink Frequency Capability 0: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
333: FLAG(lfcap0, PCI_HT_LFCAP_200),
334: FLAG(lfcap0, PCI_HT_LFCAP_300),
335: FLAG(lfcap0, PCI_HT_LFCAP_400),
336: FLAG(lfcap0, PCI_HT_LFCAP_500),
337: FLAG(lfcap0, PCI_HT_LFCAP_600),
338: FLAG(lfcap0, PCI_HT_LFCAP_800),
339: FLAG(lfcap0, PCI_HT_LFCAP_1000),
340: FLAG(lfcap0, PCI_HT_LFCAP_1200),
341: FLAG(lfcap0, PCI_HT_LFCAP_1400),
342: FLAG(lfcap0, PCI_HT_LFCAP_1600),
343: FLAG(lfcap0, PCI_HT_LFCAP_VEND));
344: ftr = get_conf_byte(d, where + PCI_HT_PRI_FTR);
345: printf("\t\tFeature Capability: IsocFC%c LDTSTOP%c CRCTM%c ECTLT%c 64bA%c UIDRD%c\n",
346: FLAG(ftr, PCI_HT_FTR_ISOCFC),
347: FLAG(ftr, PCI_HT_FTR_LDTSTOP),
348: FLAG(ftr, PCI_HT_FTR_CRCTM),
349: FLAG(ftr, PCI_HT_FTR_ECTLT),
350: FLAG(ftr, PCI_HT_FTR_64BA),
351: FLAG(ftr, PCI_HT_FTR_UIDRD));
352: lfrer1 = get_conf_byte(d, where + PCI_HT_PRI_LFRER1);
353: printf("\t\tLink Frequency 1: %s\n", ht_link_freq(lfrer1 & PCI_HT_LFRER_FREQ));
354: printf("\t\tLink Error 1: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
355: FLAG(lfrer1, PCI_HT_LFRER_PROT),
356: FLAG(lfrer1, PCI_HT_LFRER_OV),
357: FLAG(lfrer1, PCI_HT_LFRER_EOC),
358: FLAG(lfrer1, PCI_HT_LFRER_CTLT));
359: lfcap1 = get_conf_byte(d, where + PCI_HT_PRI_LFCAP1);
360: printf("\t\tLink Frequency Capability 1: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
361: FLAG(lfcap1, PCI_HT_LFCAP_200),
362: FLAG(lfcap1, PCI_HT_LFCAP_300),
363: FLAG(lfcap1, PCI_HT_LFCAP_400),
364: FLAG(lfcap1, PCI_HT_LFCAP_500),
365: FLAG(lfcap1, PCI_HT_LFCAP_600),
366: FLAG(lfcap1, PCI_HT_LFCAP_800),
367: FLAG(lfcap1, PCI_HT_LFCAP_1000),
368: FLAG(lfcap1, PCI_HT_LFCAP_1200),
369: FLAG(lfcap1, PCI_HT_LFCAP_1400),
370: FLAG(lfcap1, PCI_HT_LFCAP_1600),
371: FLAG(lfcap1, PCI_HT_LFCAP_VEND));
372: eh = get_conf_word(d, where + PCI_HT_PRI_EH);
373: printf("\t\tError Handling: PFlE%c OFlE%c PFE%c OFE%c EOCFE%c RFE%c CRCFE%c SERRFE%c CF%c RE%c PNFE%c ONFE%c EOCNFE%c RNFE%c CRCNFE%c SERRNFE%c\n",
374: FLAG(eh, PCI_HT_EH_PFLE),
375: FLAG(eh, PCI_HT_EH_OFLE),
376: FLAG(eh, PCI_HT_EH_PFE),
377: FLAG(eh, PCI_HT_EH_OFE),
378: FLAG(eh, PCI_HT_EH_EOCFE),
379: FLAG(eh, PCI_HT_EH_RFE),
380: FLAG(eh, PCI_HT_EH_CRCFE),
381: FLAG(eh, PCI_HT_EH_SERRFE),
382: FLAG(eh, PCI_HT_EH_CF),
383: FLAG(eh, PCI_HT_EH_RE),
384: FLAG(eh, PCI_HT_EH_PNFE),
385: FLAG(eh, PCI_HT_EH_ONFE),
386: FLAG(eh, PCI_HT_EH_EOCNFE),
387: FLAG(eh, PCI_HT_EH_RNFE),
388: FLAG(eh, PCI_HT_EH_CRCNFE),
389: FLAG(eh, PCI_HT_EH_SERRNFE));
390: mbu = get_conf_byte(d, where + PCI_HT_PRI_MBU);
391: mlu = get_conf_byte(d, where + PCI_HT_PRI_MLU);
392: printf("\t\tPrefetchable memory behind bridge Upper: %02x-%02x\n", mbu, mlu);
393: bn = get_conf_byte(d, where + PCI_HT_PRI_BN);
394: printf("\t\tBus Number: %02x\n", bn);
395: }
396:
397: static void
398: cap_ht_sec(struct device *d, int where, int cmd)
399: {
400: u16 lctr, lcnf, ftr, eh;
401: u8 rid, lfrer, lfcap, mbu, mlu;
402: char *fmt;
403:
404: printf("HyperTransport: Host or Secondary Interface\n");
405: if (verbose < 2)
406: return;
407:
408: if (!config_fetch(d, where + PCI_HT_SEC_LCTR, PCI_HT_SEC_SIZEOF - PCI_HT_SEC_LCTR))
409: return;
410: rid = get_conf_byte(d, where + PCI_HT_SEC_RID);
411: if (rid < 0x22 && rid > 0x11)
412: printf("\t\t!!! Possibly incomplete decoding\n");
413:
414: if (rid >= 0x22)
415: fmt = "\t\tCommand: WarmRst%c DblEnd%c DevNum=%u ChainSide%c HostHide%c Slave%c <EOCErr%c DUL%c\n";
416: else
417: fmt = "\t\tCommand: WarmRst%c DblEnd%c\n";
418: printf(fmt,
419: FLAG(cmd, PCI_HT_SEC_CMD_WR),
420: FLAG(cmd, PCI_HT_SEC_CMD_DE),
421: (cmd & PCI_HT_SEC_CMD_DN) >> 2,
422: FLAG(cmd, PCI_HT_SEC_CMD_CS),
423: FLAG(cmd, PCI_HT_SEC_CMD_HH),
424: FLAG(cmd, PCI_HT_SEC_CMD_AS),
425: FLAG(cmd, PCI_HT_SEC_CMD_HIECE),
426: FLAG(cmd, PCI_HT_SEC_CMD_DUL));
427: lctr = get_conf_word(d, where + PCI_HT_SEC_LCTR);
428: if (rid >= 0x22)
429: fmt = "\t\tLink Control: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x IsocEn%c LSEn%c ExtCTL%c 64b%c\n";
430: else
431: fmt = "\t\tLink Control: CFlE%c CST%c CFE%c <LkFail%c Init%c EOC%c TXO%c <CRCErr=%x\n";
432: printf(fmt,
433: FLAG(lctr, PCI_HT_LCTR_CFLE),
434: FLAG(lctr, PCI_HT_LCTR_CST),
435: FLAG(lctr, PCI_HT_LCTR_CFE),
436: FLAG(lctr, PCI_HT_LCTR_LKFAIL),
437: FLAG(lctr, PCI_HT_LCTR_INIT),
438: FLAG(lctr, PCI_HT_LCTR_EOC),
439: FLAG(lctr, PCI_HT_LCTR_TXO),
440: (lctr & PCI_HT_LCTR_CRCERR) >> 8,
441: FLAG(lctr, PCI_HT_LCTR_ISOCEN),
442: FLAG(lctr, PCI_HT_LCTR_LSEN),
443: FLAG(lctr, PCI_HT_LCTR_EXTCTL),
444: FLAG(lctr, PCI_HT_LCTR_64B));
445: lcnf = get_conf_word(d, where + PCI_HT_SEC_LCNF);
446: if (rid >= 0x22)
447: fmt = "\t\tLink Config: MLWI=%1$s DwFcIn%5$c MLWO=%2$s DwFcOut%6$c LWI=%3$s DwFcInEn%7$c LWO=%4$s DwFcOutEn%8$c\n";
448: else
449: fmt = "\t\tLink Config: MLWI=%s MLWO=%s LWI=%s LWO=%s\n";
450: printf(fmt,
451: ht_link_width(lcnf & PCI_HT_LCNF_MLWI),
452: ht_link_width((lcnf & PCI_HT_LCNF_MLWO) >> 4),
453: ht_link_width((lcnf & PCI_HT_LCNF_LWI) >> 8),
454: ht_link_width((lcnf & PCI_HT_LCNF_LWO) >> 12),
455: FLAG(lcnf, PCI_HT_LCNF_DFI),
456: FLAG(lcnf, PCI_HT_LCNF_DFO),
457: FLAG(lcnf, PCI_HT_LCNF_DFIE),
458: FLAG(lcnf, PCI_HT_LCNF_DFOE));
459: printf("\t\tRevision ID: %u.%02u\n",
460: (rid & PCI_HT_RID_MAJ) >> 5, (rid & PCI_HT_RID_MIN));
461: if (rid < 0x22)
462: return;
463: lfrer = get_conf_byte(d, where + PCI_HT_SEC_LFRER);
464: printf("\t\tLink Frequency: %s\n", ht_link_freq(lfrer & PCI_HT_LFRER_FREQ));
465: printf("\t\tLink Error: <Prot%c <Ovfl%c <EOC%c CTLTm%c\n",
466: FLAG(lfrer, PCI_HT_LFRER_PROT),
467: FLAG(lfrer, PCI_HT_LFRER_OV),
468: FLAG(lfrer, PCI_HT_LFRER_EOC),
469: FLAG(lfrer, PCI_HT_LFRER_CTLT));
470: lfcap = get_conf_byte(d, where + PCI_HT_SEC_LFCAP);
471: printf("\t\tLink Frequency Capability: 200MHz%c 300MHz%c 400MHz%c 500MHz%c 600MHz%c 800MHz%c 1.0GHz%c 1.2GHz%c 1.4GHz%c 1.6GHz%c Vend%c\n",
472: FLAG(lfcap, PCI_HT_LFCAP_200),
473: FLAG(lfcap, PCI_HT_LFCAP_300),
474: FLAG(lfcap, PCI_HT_LFCAP_400),
475: FLAG(lfcap, PCI_HT_LFCAP_500),
476: FLAG(lfcap, PCI_HT_LFCAP_600),
477: FLAG(lfcap, PCI_HT_LFCAP_800),
478: FLAG(lfcap, PCI_HT_LFCAP_1000),
479: FLAG(lfcap, PCI_HT_LFCAP_1200),
480: FLAG(lfcap, PCI_HT_LFCAP_1400),
481: FLAG(lfcap, PCI_HT_LFCAP_1600),
482: FLAG(lfcap, PCI_HT_LFCAP_VEND));
483: ftr = get_conf_word(d, where + PCI_HT_SEC_FTR);
484: printf("\t\tFeature Capability: IsocFC%c LDTSTOP%c CRCTM%c ECTLT%c 64bA%c UIDRD%c ExtRS%c UCnfE%c\n",
485: FLAG(ftr, PCI_HT_FTR_ISOCFC),
486: FLAG(ftr, PCI_HT_FTR_LDTSTOP),
487: FLAG(ftr, PCI_HT_FTR_CRCTM),
488: FLAG(ftr, PCI_HT_FTR_ECTLT),
489: FLAG(ftr, PCI_HT_FTR_64BA),
490: FLAG(ftr, PCI_HT_FTR_UIDRD),
491: FLAG(ftr, PCI_HT_SEC_FTR_EXTRS),
492: FLAG(ftr, PCI_HT_SEC_FTR_UCNFE));
493: if (ftr & PCI_HT_SEC_FTR_EXTRS)
494: {
495: eh = get_conf_word(d, where + PCI_HT_SEC_EH);
496: printf("\t\tError Handling: PFlE%c OFlE%c PFE%c OFE%c EOCFE%c RFE%c CRCFE%c SERRFE%c CF%c RE%c PNFE%c ONFE%c EOCNFE%c RNFE%c CRCNFE%c SERRNFE%c\n",
497: FLAG(eh, PCI_HT_EH_PFLE),
498: FLAG(eh, PCI_HT_EH_OFLE),
499: FLAG(eh, PCI_HT_EH_PFE),
500: FLAG(eh, PCI_HT_EH_OFE),
501: FLAG(eh, PCI_HT_EH_EOCFE),
502: FLAG(eh, PCI_HT_EH_RFE),
503: FLAG(eh, PCI_HT_EH_CRCFE),
504: FLAG(eh, PCI_HT_EH_SERRFE),
505: FLAG(eh, PCI_HT_EH_CF),
506: FLAG(eh, PCI_HT_EH_RE),
507: FLAG(eh, PCI_HT_EH_PNFE),
508: FLAG(eh, PCI_HT_EH_ONFE),
509: FLAG(eh, PCI_HT_EH_EOCNFE),
510: FLAG(eh, PCI_HT_EH_RNFE),
511: FLAG(eh, PCI_HT_EH_CRCNFE),
512: FLAG(eh, PCI_HT_EH_SERRNFE));
513: mbu = get_conf_byte(d, where + PCI_HT_SEC_MBU);
514: mlu = get_conf_byte(d, where + PCI_HT_SEC_MLU);
515: printf("\t\tPrefetchable memory behind bridge Upper: %02x-%02x\n", mbu, mlu);
516: }
517: }
518:
519: static void
520: cap_ht(struct device *d, int where, int cmd)
521: {
522: int type;
523:
524: switch (cmd & PCI_HT_CMD_TYP_HI)
525: {
526: case PCI_HT_CMD_TYP_HI_PRI:
527: cap_ht_pri(d, where, cmd);
528: return;
529: case PCI_HT_CMD_TYP_HI_SEC:
530: cap_ht_sec(d, where, cmd);
531: return;
532: }
533:
534: type = cmd & PCI_HT_CMD_TYP;
535: switch (type)
536: {
537: case PCI_HT_CMD_TYP_SW:
538: printf("HyperTransport: Switch\n");
539: break;
540: case PCI_HT_CMD_TYP_IDC:
541: printf("HyperTransport: Interrupt Discovery and Configuration\n");
542: break;
543: case PCI_HT_CMD_TYP_RID:
544: printf("HyperTransport: Revision ID: %u.%02u\n",
545: (cmd & PCI_HT_RID_MAJ) >> 5, (cmd & PCI_HT_RID_MIN));
546: break;
547: case PCI_HT_CMD_TYP_UIDC:
548: printf("HyperTransport: UnitID Clumping\n");
549: break;
550: case PCI_HT_CMD_TYP_ECSA:
551: printf("HyperTransport: Extended Configuration Space Access\n");
552: break;
553: case PCI_HT_CMD_TYP_AM:
554: printf("HyperTransport: Address Mapping\n");
555: break;
556: case PCI_HT_CMD_TYP_MSIM:
557: printf("HyperTransport: MSI Mapping Enable%c Fixed%c\n",
558: FLAG(cmd, PCI_HT_MSIM_CMD_EN),
559: FLAG(cmd, PCI_HT_MSIM_CMD_FIXD));
560: if (verbose >= 2 && !(cmd & PCI_HT_MSIM_CMD_FIXD))
561: {
562: u32 offl, offh;
563: if (!config_fetch(d, where + PCI_HT_MSIM_ADDR_LO, 8))
564: break;
565: offl = get_conf_long(d, where + PCI_HT_MSIM_ADDR_LO);
566: offh = get_conf_long(d, where + PCI_HT_MSIM_ADDR_HI);
567: printf("\t\tMapping Address Base: %016llx\n", ((unsigned long long)offh << 32) | (offl & ~0xfffff));
568: }
569: break;
570: case PCI_HT_CMD_TYP_DR:
571: printf("HyperTransport: DirectRoute\n");
572: break;
573: case PCI_HT_CMD_TYP_VCS:
574: printf("HyperTransport: VCSet\n");
575: break;
576: case PCI_HT_CMD_TYP_RM:
577: printf("HyperTransport: Retry Mode\n");
578: break;
579: case PCI_HT_CMD_TYP_X86:
580: printf("HyperTransport: X86 (reserved)\n");
581: break;
582: default:
583: printf("HyperTransport: #%02x\n", type >> 11);
584: }
585: }
586:
587: static void
588: cap_msi(struct device *d, int where, int cap)
589: {
590: int is64;
591: u32 t;
592: u16 w;
593:
594: printf("MSI: Enable%c Count=%d/%d Maskable%c 64bit%c\n",
595: FLAG(cap, PCI_MSI_FLAGS_ENABLE),
596: 1 << ((cap & PCI_MSI_FLAGS_QSIZE) >> 4),
597: 1 << ((cap & PCI_MSI_FLAGS_QMASK) >> 1),
598: FLAG(cap, PCI_MSI_FLAGS_MASK_BIT),
599: FLAG(cap, PCI_MSI_FLAGS_64BIT));
600: if (verbose < 2)
601: return;
602: is64 = cap & PCI_MSI_FLAGS_64BIT;
603: if (!config_fetch(d, where + PCI_MSI_ADDRESS_LO, (is64 ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32) + 2 - PCI_MSI_ADDRESS_LO))
604: return;
605: printf("\t\tAddress: ");
606: if (is64)
607: {
608: t = get_conf_long(d, where + PCI_MSI_ADDRESS_HI);
609: w = get_conf_word(d, where + PCI_MSI_DATA_64);
610: printf("%08x", t);
611: }
612: else
613: w = get_conf_word(d, where + PCI_MSI_DATA_32);
614: t = get_conf_long(d, where + PCI_MSI_ADDRESS_LO);
615: printf("%08x Data: %04x\n", t, w);
616: if (cap & PCI_MSI_FLAGS_MASK_BIT)
617: {
618: u32 mask, pending;
619:
620: if (is64)
621: {
622: if (!config_fetch(d, where + PCI_MSI_MASK_BIT_64, 8))
623: return;
624: mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_64);
625: pending = get_conf_long(d, where + PCI_MSI_PENDING_64);
626: }
627: else
628: {
629: if (!config_fetch(d, where + PCI_MSI_MASK_BIT_32, 8))
630: return;
631: mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_32);
632: pending = get_conf_long(d, where + PCI_MSI_PENDING_32);
633: }
634: printf("\t\tMasking: %08x Pending: %08x\n", mask, pending);
635: }
636: }
637:
638: static float power_limit(int value, int scale)
639: {
640: static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 };
641: return value * scales[scale];
642: }
643:
644: static const char *latency_l0s(int value)
645: {
646: static const char *latencies[] = { "<64ns", "<128ns", "<256ns", "<512ns", "<1us", "<2us", "<4us", "unlimited" };
647: return latencies[value];
648: }
649:
650: static const char *latency_l1(int value)
651: {
652: static const char *latencies[] = { "<1us", "<2us", "<4us", "<8us", "<16us", "<32us", "<64us", "unlimited" };
653: return latencies[value];
654: }
655:
656: static void cap_express_dev(struct device *d, int where, int type)
657: {
658: u32 t;
659: u16 w;
660:
661: t = get_conf_long(d, where + PCI_EXP_DEVCAP);
662: printf("\t\tDevCap:\tMaxPayload %d bytes, PhantFunc %d, Latency L0s %s, L1 %s\n",
663: 128 << (t & PCI_EXP_DEVCAP_PAYLOAD),
664: (1 << ((t & PCI_EXP_DEVCAP_PHANTOM) >> 3)) - 1,
665: latency_l0s((t & PCI_EXP_DEVCAP_L0S) >> 6),
666: latency_l1((t & PCI_EXP_DEVCAP_L1) >> 9));
667: printf("\t\t\tExtTag%c", FLAG(t, PCI_EXP_DEVCAP_EXT_TAG));
668: if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_LEG_END) ||
669: (type == PCI_EXP_TYPE_UPSTREAM) || (type == PCI_EXP_TYPE_PCI_BRIDGE))
670: printf(" AttnBtn%c AttnInd%c PwrInd%c",
671: FLAG(t, PCI_EXP_DEVCAP_ATN_BUT),
672: FLAG(t, PCI_EXP_DEVCAP_ATN_IND), FLAG(t, PCI_EXP_DEVCAP_PWR_IND));
673: printf(" RBE%c FLReset%c",
674: FLAG(t, PCI_EXP_DEVCAP_RBE),
675: FLAG(t, PCI_EXP_DEVCAP_FLRESET));
676: if (type == PCI_EXP_TYPE_UPSTREAM)
677: printf("SlotPowerLimit %.3fW",
678: power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18,
679: (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26));
680: printf("\n");
681:
682: w = get_conf_word(d, where + PCI_EXP_DEVCTL);
683: printf("\t\tDevCtl:\tReport errors: Correctable%c Non-Fatal%c Fatal%c Unsupported%c\n",
684: FLAG(w, PCI_EXP_DEVCTL_CERE),
685: FLAG(w, PCI_EXP_DEVCTL_NFERE),
686: FLAG(w, PCI_EXP_DEVCTL_FERE),
687: FLAG(w, PCI_EXP_DEVCTL_URRE));
688: printf("\t\t\tRlxdOrd%c ExtTag%c PhantFunc%c AuxPwr%c NoSnoop%c",
689: FLAG(w, PCI_EXP_DEVCTL_RELAXED),
690: FLAG(w, PCI_EXP_DEVCTL_EXT_TAG),
691: FLAG(w, PCI_EXP_DEVCTL_PHANTOM),
692: FLAG(w, PCI_EXP_DEVCTL_AUX_PME),
693: FLAG(w, PCI_EXP_DEVCTL_NOSNOOP));
694: if (type == PCI_EXP_TYPE_PCI_BRIDGE || type == PCI_EXP_TYPE_PCIE_BRIDGE)
695: printf(" BrConfRtry%c", FLAG(w, PCI_EXP_DEVCTL_BCRE));
696: if (type == PCI_EXP_TYPE_ENDPOINT && (t & PCI_EXP_DEVCAP_FLRESET))
697: printf(" FLReset%c", FLAG(w, PCI_EXP_DEVCTL_FLRESET));
698: printf("\n\t\t\tMaxPayload %d bytes, MaxReadReq %d bytes\n",
699: 128 << ((w & PCI_EXP_DEVCTL_PAYLOAD) >> 5),
700: 128 << ((w & PCI_EXP_DEVCTL_READRQ) >> 12));
701:
702: w = get_conf_word(d, where + PCI_EXP_DEVSTA);
703: printf("\t\tDevSta:\tCorrErr%c UncorrErr%c FatalErr%c UnsuppReq%c AuxPwr%c TransPend%c\n",
704: FLAG(w, PCI_EXP_DEVSTA_CED),
705: FLAG(w, PCI_EXP_DEVSTA_NFED),
706: FLAG(w, PCI_EXP_DEVSTA_FED),
707: FLAG(w, PCI_EXP_DEVSTA_URD),
708: FLAG(w, PCI_EXP_DEVSTA_AUXPD),
709: FLAG(w, PCI_EXP_DEVSTA_TRPND));
710: }
711:
712: static char *link_speed(int speed)
713: {
714: switch (speed)
715: {
716: case 1:
717: return "2.5GT/s";
718: case 2:
719: return "5GT/s";
720: case 3:
721: return "8GT/s";
722: default:
723: return "unknown";
724: }
725: }
726:
727: static char *aspm_support(int code)
728: {
729: switch (code)
730: {
731: case 1:
732: return "L0s";
733: case 2:
734: return "L1";
735: case 3:
736: return "L0s L1";
737: default:
738: return "unknown";
739: }
740: }
741:
742: static const char *aspm_enabled(int code)
743: {
744: static const char *desc[] = { "Disabled", "L0s Enabled", "L1 Enabled", "L0s L1 Enabled" };
745: return desc[code];
746: }
747:
748: static void cap_express_link(struct device *d, int where, int type)
749: {
750: u32 t;
751: u16 w;
752:
753: t = get_conf_long(d, where + PCI_EXP_LNKCAP);
754: printf("\t\tLnkCap:\tPort #%d, Speed %s, Width x%d, ASPM %s, Latency L0 %s, L1 %s\n",
755: t >> 24,
756: link_speed(t & PCI_EXP_LNKCAP_SPEED), (t & PCI_EXP_LNKCAP_WIDTH) >> 4,
757: aspm_support((t & PCI_EXP_LNKCAP_ASPM) >> 10),
758: latency_l0s((t & PCI_EXP_LNKCAP_L0S) >> 12),
759: latency_l1((t & PCI_EXP_LNKCAP_L1) >> 15));
760: printf("\t\t\tClockPM%c Surprise%c LLActRep%c BwNot%c\n",
761: FLAG(t, PCI_EXP_LNKCAP_CLOCKPM),
762: FLAG(t, PCI_EXP_LNKCAP_SURPRISE),
763: FLAG(t, PCI_EXP_LNKCAP_DLLA),
764: FLAG(t, PCI_EXP_LNKCAP_LBNC));
765:
766: w = get_conf_word(d, where + PCI_EXP_LNKCTL);
767: printf("\t\tLnkCtl:\tASPM %s;", aspm_enabled(w & PCI_EXP_LNKCTL_ASPM));
768: if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_ENDPOINT) ||
769: (type == PCI_EXP_TYPE_LEG_END))
770: printf(" RCB %d bytes", w & PCI_EXP_LNKCTL_RCB ? 128 : 64);
771: printf(" Disabled%c Retrain%c CommClk%c\n\t\t\tExtSynch%c ClockPM%c AutWidDis%c BWInt%c AutBWInt%c\n",
772: FLAG(w, PCI_EXP_LNKCTL_DISABLE),
773: FLAG(w, PCI_EXP_LNKCTL_RETRAIN),
774: FLAG(w, PCI_EXP_LNKCTL_CLOCK),
775: FLAG(w, PCI_EXP_LNKCTL_XSYNCH),
776: FLAG(w, PCI_EXP_LNKCTL_CLOCKPM),
777: FLAG(w, PCI_EXP_LNKCTL_HWAUTWD),
778: FLAG(w, PCI_EXP_LNKCTL_BWMIE),
779: FLAG(w, PCI_EXP_LNKCTL_AUTBWIE));
780:
781: w = get_conf_word(d, where + PCI_EXP_LNKSTA);
782: printf("\t\tLnkSta:\tSpeed %s, Width x%d, TrErr%c Train%c SlotClk%c DLActive%c BWMgmt%c ABWMgmt%c\n",
783: link_speed(w & PCI_EXP_LNKSTA_SPEED),
784: (w & PCI_EXP_LNKSTA_WIDTH) >> 4,
785: FLAG(w, PCI_EXP_LNKSTA_TR_ERR),
786: FLAG(w, PCI_EXP_LNKSTA_TRAIN),
787: FLAG(w, PCI_EXP_LNKSTA_SL_CLK),
788: FLAG(w, PCI_EXP_LNKSTA_DL_ACT),
789: FLAG(w, PCI_EXP_LNKSTA_BWMGMT),
790: FLAG(w, PCI_EXP_LNKSTA_AUTBW));
791: }
792:
793: static const char *indicator(int code)
794: {
795: static const char *names[] = { "Unknown", "On", "Blink", "Off" };
796: return names[code];
797: }
798:
799: static void cap_express_slot(struct device *d, int where)
800: {
801: u32 t;
802: u16 w;
803:
804: t = get_conf_long(d, where + PCI_EXP_SLTCAP);
805: printf("\t\tSltCap:\tAttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c HotPlug%c Surprise%c\n",
806: FLAG(t, PCI_EXP_SLTCAP_ATNB),
807: FLAG(t, PCI_EXP_SLTCAP_PWRC),
808: FLAG(t, PCI_EXP_SLTCAP_MRL),
809: FLAG(t, PCI_EXP_SLTCAP_ATNI),
810: FLAG(t, PCI_EXP_SLTCAP_PWRI),
811: FLAG(t, PCI_EXP_SLTCAP_HPC),
812: FLAG(t, PCI_EXP_SLTCAP_HPS));
813: printf("\t\t\tSlot #%d, PowerLimit %.3fW; Interlock%c NoCompl%c\n",
814: t >> 19,
815: power_limit((t & PCI_EXP_SLTCAP_PWR_VAL) >> 7, (t & PCI_EXP_SLTCAP_PWR_SCL) >> 15),
816: FLAG(t, PCI_EXP_SLTCAP_INTERLOCK),
817: FLAG(t, PCI_EXP_SLTCAP_NOCMDCOMP));
818:
819: w = get_conf_word(d, where + PCI_EXP_SLTCTL);
820: printf("\t\tSltCtl:\tEnable: AttnBtn%c PwrFlt%c MRL%c PresDet%c CmdCplt%c HPIrq%c LinkChg%c\n",
821: FLAG(w, PCI_EXP_SLTCTL_ATNB),
822: FLAG(w, PCI_EXP_SLTCTL_PWRF),
823: FLAG(w, PCI_EXP_SLTCTL_MRLS),
824: FLAG(w, PCI_EXP_SLTCTL_PRSD),
825: FLAG(w, PCI_EXP_SLTCTL_CMDC),
826: FLAG(w, PCI_EXP_SLTCTL_HPIE),
827: FLAG(w, PCI_EXP_SLTCTL_LLCHG));
828: printf("\t\t\tControl: AttnInd %s, PwrInd %s, Power%c Interlock%c\n",
829: indicator((w & PCI_EXP_SLTCTL_ATNI) >> 6),
830: indicator((w & PCI_EXP_SLTCTL_PWRI) >> 8),
831: FLAG(w, PCI_EXP_SLTCTL_PWRC),
832: FLAG(w, PCI_EXP_SLTCTL_INTERLOCK));
833:
834: w = get_conf_word(d, where + PCI_EXP_SLTSTA);
835: printf("\t\tSltSta:\tStatus: AttnBtn%c PowerFlt%c MRL%c CmdCplt%c PresDet%c Interlock%c\n",
836: FLAG(w, PCI_EXP_SLTSTA_ATNB),
837: FLAG(w, PCI_EXP_SLTSTA_PWRF),
838: FLAG(w, PCI_EXP_SLTSTA_MRL_ST),
839: FLAG(w, PCI_EXP_SLTSTA_CMDC),
840: FLAG(w, PCI_EXP_SLTSTA_PRES),
841: FLAG(w, PCI_EXP_SLTSTA_INTERLOCK));
842: printf("\t\t\tChanged: MRL%c PresDet%c LinkState%c\n",
843: FLAG(w, PCI_EXP_SLTSTA_MRLS),
844: FLAG(w, PCI_EXP_SLTSTA_PRSD),
845: FLAG(w, PCI_EXP_SLTSTA_LLCHG));
846: }
847:
848: static void cap_express_root(struct device *d, int where)
849: {
850: u32 w = get_conf_word(d, where + PCI_EXP_RTCTL);
851: printf("\t\tRootCtl: ErrCorrectable%c ErrNon-Fatal%c ErrFatal%c PMEIntEna%c CRSVisible%c\n",
852: FLAG(w, PCI_EXP_RTCTL_SECEE),
853: FLAG(w, PCI_EXP_RTCTL_SENFEE),
854: FLAG(w, PCI_EXP_RTCTL_SEFEE),
855: FLAG(w, PCI_EXP_RTCTL_PMEIE),
856: FLAG(w, PCI_EXP_RTCTL_CRSVIS));
857:
858: w = get_conf_word(d, where + PCI_EXP_RTCAP);
859: printf("\t\tRootCap: CRSVisible%c\n",
860: FLAG(w, PCI_EXP_RTCAP_CRSVIS));
861:
862: w = get_conf_word(d, where + PCI_EXP_RTSTA);
863: printf("\t\tRootSta: PME ReqID %04x, PMEStatus%c PMEPending%c\n",
864: w & PCI_EXP_RTSTA_PME_REQID,
865: FLAG(w, PCI_EXP_RTSTA_PME_STATUS),
866: FLAG(w, PCI_EXP_RTSTA_PME_PENDING));
867: }
868:
869: static const char *cap_express_dev2_timeout_range(int type)
870: {
871: /* Decode Completion Timeout Ranges. */
872: switch (type)
873: {
874: case 0:
875: return "Not Supported";
876: case 1:
877: return "Range A";
878: case 2:
879: return "Range B";
880: case 3:
881: return "Range AB";
882: case 6:
883: return "Range BC";
884: case 7:
885: return "Range ABC";
886: case 14:
887: return "Range BCD";
888: case 15:
889: return "Range ABCD";
890: default:
891: return "Unknown";
892: }
893: }
894:
895: static const char *cap_express_dev2_timeout_value(int type)
896: {
897: /* Decode Completion Timeout Value. */
898: switch (type)
899: {
900: case 0:
901: return "50us to 50ms";
902: case 1:
903: return "50us to 100us";
904: case 2:
905: return "1ms to 10ms";
906: case 5:
907: return "16ms to 55ms";
908: case 6:
909: return "65ms to 210ms";
910: case 9:
911: return "260ms to 900ms";
912: case 10:
913: return "1s to 3.5s";
914: case 13:
915: return "4s to 13s";
916: case 14:
917: return "17s to 64s";
918: default:
919: return "Unknown";
920: }
921: }
922:
923: static void cap_express_dev2(struct device *d, int where, int type)
924: {
925: u32 l;
926: u16 w;
927:
928: l = get_conf_long(d, where + PCI_EXP_DEVCAP2);
929: printf("\t\tDevCap2: Completion Timeout: %s, TimeoutDis%c",
930: cap_express_dev2_timeout_range(PCI_EXP_DEV2_TIMEOUT_RANGE(l)),
931: FLAG(l, PCI_EXP_DEV2_TIMEOUT_DIS));
932: if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
933: printf(" ARIFwd%c\n", FLAG(l, PCI_EXP_DEV2_ARI));
934: else
935: printf("\n");
936:
937: w = get_conf_word(d, where + PCI_EXP_DEVCTL2);
938: printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c",
939: cap_express_dev2_timeout_value(PCI_EXP_DEV2_TIMEOUT_VALUE(w)),
940: FLAG(w, PCI_EXP_DEV2_TIMEOUT_DIS));
941: if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)
942: printf(" ARIFwd%c\n", FLAG(w, PCI_EXP_DEV2_ARI));
943: else
944: printf("\n");
945: }
946:
947: static const char *cap_express_link2_speed(int type)
948: {
949: switch (type)
950: {
951: case 0: /* hardwire to 0 means only the 2.5GT/s is supported */
952: case 1:
953: return "2.5GT/s";
954: case 2:
955: return "5GT/s";
956: case 3:
957: return "8GT/s";
958: default:
959: return "Unknown";
960: }
961: }
962:
963: static const char *cap_express_link2_deemphasis(int type)
964: {
965: switch (type)
966: {
967: case 0:
968: return "-6dB";
969: case 1:
970: return "-3.5dB";
971: default:
972: return "Unknown";
973: }
974: }
975:
976: static const char *cap_express_link2_transmargin(int type)
977: {
978: switch (type)
979: {
980: case 0:
981: return "Normal Operating Range";
982: case 1:
983: return "800-1200mV(full-swing)/400-700mV(half-swing)";
984: case 2:
985: case 3:
986: case 4:
987: case 5:
988: return "200-400mV(full-swing)/100-200mV(half-swing)";
989: default:
990: return "Unknown";
991: }
992: }
993:
994: static void cap_express_link2(struct device *d, int where, int type UNUSED)
995: {
996: u16 w;
997:
998: w = get_conf_word(d, where + PCI_EXP_LNKCTL2);
999: printf("\t\tLnkCtl2: Target Link Speed: %s, EnterCompliance%c SpeedDis%c, Selectable De-emphasis: %s\n"
1000: "\t\t\t Transmit Margin: %s, EnterModifiedCompliance%c ComplianceSOS%c\n"
1001: "\t\t\t Compliance De-emphasis: %s\n",
1002: cap_express_link2_speed(PCI_EXP_LNKCTL2_SPEED(w)),
1003: FLAG(w, PCI_EXP_LNKCTL2_CMPLNC),
1004: FLAG(w, PCI_EXP_LNKCTL2_SPEED_DIS),
1005: cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_DEEMPHASIS(w)),
1006: cap_express_link2_transmargin(PCI_EXP_LNKCTL2_MARGIN(w)),
1007: FLAG(w, PCI_EXP_LNKCTL2_MOD_CMPLNC),
1008: FLAG(w, PCI_EXP_LNKCTL2_CMPLNC_SOS),
1009: cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_COM_DEEMPHASIS(w)));
1010:
1011: w = get_conf_word(d, where + PCI_EXP_LNKSTA2);
1012: printf("\t\tLnkSta2: Current De-emphasis Level: %s, EqualizationComplete%c, EqualizationPhase1%c\n"
1013: "\t\t\t EqualizationPhase2%c, EqualizationPhase3%c, LinkEqualizationRequest%c\n",
1014: cap_express_link2_deemphasis(PCI_EXP_LINKSTA2_DEEMPHASIS(w)),
1015: FLAG(w, PCI_EXP_LINKSTA2_EQU_COMP),
1016: FLAG(w, PCI_EXP_LINKSTA2_EQU_PHASE1),
1017: FLAG(w, PCI_EXP_LINKSTA2_EQU_PHASE2),
1018: FLAG(w, PCI_EXP_LINKSTA2_EQU_PHASE3),
1019: FLAG(w, PCI_EXP_LINKSTA2_EQU_REQ));
1020: }
1021:
1022: static void cap_express_slot2(struct device *d UNUSED, int where UNUSED)
1023: {
1024: /* No capabilities that require this field in PCIe rev2.0 spec. */
1025: }
1026:
1027: static void
1028: cap_express(struct device *d, int where, int cap)
1029: {
1030: int type = (cap & PCI_EXP_FLAGS_TYPE) >> 4;
1031: int size;
1032: int slot = 0;
1033:
1034: printf("Express ");
1035: if (verbose >= 2)
1036: printf("(v%d) ", cap & PCI_EXP_FLAGS_VERS);
1037: switch (type)
1038: {
1039: case PCI_EXP_TYPE_ENDPOINT:
1040: printf("Endpoint");
1041: break;
1042: case PCI_EXP_TYPE_LEG_END:
1043: printf("Legacy Endpoint");
1044: break;
1045: case PCI_EXP_TYPE_ROOT_PORT:
1046: slot = cap & PCI_EXP_FLAGS_SLOT;
1047: printf("Root Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
1048: break;
1049: case PCI_EXP_TYPE_UPSTREAM:
1050: printf("Upstream Port");
1051: break;
1052: case PCI_EXP_TYPE_DOWNSTREAM:
1053: slot = cap & PCI_EXP_FLAGS_SLOT;
1054: printf("Downstream Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
1055: break;
1056: case PCI_EXP_TYPE_PCI_BRIDGE:
1057: printf("PCI/PCI-X Bridge");
1058: break;
1059: case PCI_EXP_TYPE_PCIE_BRIDGE:
1060: printf("PCI/PCI-X to PCI-Express Bridge");
1061: break;
1062: case PCI_EXP_TYPE_ROOT_INT_EP:
1063: printf("Root Complex Integrated Endpoint");
1064: break;
1065: case PCI_EXP_TYPE_ROOT_EC:
1066: printf("Root Complex Event Collector");
1067: break;
1068: default:
1069: printf("Unknown type %d", type);
1070: }
1071: printf(", MSI %02x\n", (cap & PCI_EXP_FLAGS_IRQ) >> 9);
1072: if (verbose < 2)
1073: return;
1074:
1075: size = 16;
1076: if (slot)
1077: size = 24;
1078: if (type == PCI_EXP_TYPE_ROOT_PORT)
1079: size = 32;
1080: if (!config_fetch(d, where + PCI_EXP_DEVCAP, size))
1081: return;
1082:
1083: cap_express_dev(d, where, type);
1084: cap_express_link(d, where, type);
1085: if (slot)
1086: cap_express_slot(d, where);
1087: if (type == PCI_EXP_TYPE_ROOT_PORT)
1088: cap_express_root(d, where);
1089:
1090: if ((cap & PCI_EXP_FLAGS_VERS) < 2)
1091: return;
1092:
1093: size = 16;
1094: if (slot)
1095: size = 24;
1096: if (!config_fetch(d, where + PCI_EXP_DEVCAP2, size))
1097: return;
1098:
1099: cap_express_dev2(d, where, type);
1100: cap_express_link2(d, where, type);
1101: if (slot)
1102: cap_express_slot2(d, where);
1103: }
1104:
1105: static void
1106: cap_msix(struct device *d, int where, int cap)
1107: {
1108: u32 off;
1109:
1110: printf("MSI-X: Enable%c Count=%d Masked%c\n",
1111: FLAG(cap, PCI_MSIX_ENABLE),
1112: (cap & PCI_MSIX_TABSIZE) + 1,
1113: FLAG(cap, PCI_MSIX_MASK));
1114: if (verbose < 2 || !config_fetch(d, where + PCI_MSIX_TABLE, 8))
1115: return;
1116:
1117: off = get_conf_long(d, where + PCI_MSIX_TABLE);
1118: printf("\t\tVector table: BAR=%d offset=%08x\n",
1119: off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR);
1120: off = get_conf_long(d, where + PCI_MSIX_PBA);
1121: printf("\t\tPBA: BAR=%d offset=%08x\n",
1122: off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR);
1123: }
1124:
1125: static void
1126: cap_slotid(int cap)
1127: {
1128: int esr = cap & 0xff;
1129: int chs = cap >> 8;
1130:
1131: printf("Slot ID: %d slots, First%c, chassis %02x\n",
1132: esr & PCI_SID_ESR_NSLOTS,
1133: FLAG(esr, PCI_SID_ESR_FIC),
1134: chs);
1135: }
1136:
1137: static void
1138: cap_ssvid(struct device *d, int where)
1139: {
1140: u16 subsys_v, subsys_d;
1141: char ssnamebuf[256];
1142:
1143: if (!config_fetch(d, where, 8))
1144: return;
1145: subsys_v = get_conf_word(d, where + PCI_SSVID_VENDOR);
1146: subsys_d = get_conf_word(d, where + PCI_SSVID_DEVICE);
1147: printf("Subsystem: %s\n",
1148: pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf),
1149: PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
1150: d->dev->vendor_id, d->dev->device_id, subsys_v, subsys_d));
1151: }
1152:
1153: static void
1154: cap_debug_port(int cap)
1155: {
1156: int bar = cap >> 13;
1157: int pos = cap & 0x1fff;
1158: printf("Debug port: BAR=%d offset=%04x\n", bar, pos);
1159: }
1160:
1161: static void
1162: cap_af(struct device *d, int where)
1163: {
1164: u8 reg;
1165:
1166: printf("PCI Advanced Features\n");
1167: if (verbose < 2 || !config_fetch(d, where + PCI_AF_CAP, 3))
1168: return;
1169:
1170: reg = get_conf_byte(d, where + PCI_AF_CAP);
1171: printf("\t\tAFCap: TP%c FLR%c\n", FLAG(reg, PCI_AF_CAP_TP),
1172: FLAG(reg, PCI_AF_CAP_FLR));
1173: reg = get_conf_byte(d, where + PCI_AF_CTRL);
1174: printf("\t\tAFCtrl: FLR%c\n", FLAG(reg, PCI_AF_CTRL_FLR));
1175: reg = get_conf_byte(d, where + PCI_AF_STATUS);
1176: printf("\t\tAFStatus: TP%c\n", FLAG(reg, PCI_AF_STATUS_TP));
1177: }
1178:
1179: static void
1180: cap_sata_hba(struct device *d, int where, int cap)
1181: {
1182: u32 bars;
1183: int bar;
1184:
1185: printf("SATA HBA v%d.%d", BITS(cap, 4, 4), BITS(cap, 0, 4));
1186: if (verbose < 2 || !config_fetch(d, where + PCI_SATA_HBA_BARS, 4))
1187: {
1188: printf("\n");
1189: return;
1190: }
1191:
1192: bars = get_conf_long(d, where + PCI_SATA_HBA_BARS);
1193: bar = BITS(bars, 0, 4);
1194: if (bar >= 4 && bar <= 9)
1195: printf(" BAR%d Offset=%08x\n", bar - 4, BITS(bars, 4, 20));
1196: else if (bar == 15)
1197: printf(" InCfgSpace\n");
1198: else
1199: printf(" BAR??%d\n", bar);
1200: }
1201:
1202: void
1203: show_caps(struct device *d)
1204: {
1205: int can_have_ext_caps = 0;
1206:
1207: if (get_conf_word(d, PCI_STATUS) & PCI_STATUS_CAP_LIST)
1208: {
1209: int where = get_conf_byte(d, PCI_CAPABILITY_LIST) & ~3;
1210: byte been_there[256];
1211: memset(been_there, 0, 256);
1212: while (where)
1213: {
1214: int id, next, cap;
1215: printf("\tCapabilities: ");
1216: if (!config_fetch(d, where, 4))
1217: {
1218: puts("<access denied>");
1219: break;
1220: }
1221: id = get_conf_byte(d, where + PCI_CAP_LIST_ID);
1222: next = get_conf_byte(d, where + PCI_CAP_LIST_NEXT) & ~3;
1223: cap = get_conf_word(d, where + PCI_CAP_FLAGS);
1224: printf("[%02x] ", where);
1225: if (been_there[where]++)
1226: {
1227: printf("<chain looped>\n");
1228: break;
1229: }
1230: if (id == 0xff)
1231: {
1232: printf("<chain broken>\n");
1233: break;
1234: }
1235: switch (id)
1236: {
1237: case PCI_CAP_ID_PM:
1238: cap_pm(d, where, cap);
1239: break;
1240: case PCI_CAP_ID_AGP:
1241: cap_agp(d, where, cap);
1242: break;
1243: case PCI_CAP_ID_VPD:
1244: cap_vpd(d);
1245: break;
1246: case PCI_CAP_ID_SLOTID:
1247: cap_slotid(cap);
1248: break;
1249: case PCI_CAP_ID_MSI:
1250: cap_msi(d, where, cap);
1251: break;
1252: case PCI_CAP_ID_CHSWP:
1253: printf("CompactPCI hot-swap <?>\n");
1254: break;
1255: case PCI_CAP_ID_PCIX:
1256: cap_pcix(d, where);
1257: can_have_ext_caps = 1;
1258: break;
1259: case PCI_CAP_ID_HT:
1260: cap_ht(d, where, cap);
1261: break;
1262: case PCI_CAP_ID_VNDR:
1263: printf("Vendor Specific Information: Len=%02x <?>\n", BITS(cap, 0, 8));
1264: break;
1265: case PCI_CAP_ID_DBG:
1266: cap_debug_port(cap);
1267: break;
1268: case PCI_CAP_ID_CCRC:
1269: printf("CompactPCI central resource control <?>\n");
1270: break;
1271: case PCI_CAP_ID_HOTPLUG:
1272: printf("Hot-plug capable\n");
1273: break;
1274: case PCI_CAP_ID_SSVID:
1275: cap_ssvid(d, where);
1276: break;
1277: case PCI_CAP_ID_AGP3:
1278: printf("AGP3 <?>\n");
1279: break;
1280: case PCI_CAP_ID_SECURE:
1281: printf("Secure device <?>\n");
1282: break;
1283: case PCI_CAP_ID_EXP:
1284: cap_express(d, where, cap);
1285: can_have_ext_caps = 1;
1286: break;
1287: case PCI_CAP_ID_MSIX:
1288: cap_msix(d, where, cap);
1289: break;
1290: case PCI_CAP_ID_SATA:
1291: cap_sata_hba(d, where, cap);
1292: break;
1293: case PCI_CAP_ID_AF:
1294: cap_af(d, where);
1295: break;
1296: default:
1297: printf("#%02x [%04x]\n", id, cap);
1298: }
1299: where = next;
1300: }
1301: }
1302: if (can_have_ext_caps)
1303: show_ext_caps(d);
1304: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>