1*7687d0d8SRobert Mustacchi /*
2*7687d0d8SRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*7687d0d8SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*7687d0d8SRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*7687d0d8SRobert Mustacchi  * 1.0 of the CDDL.
6*7687d0d8SRobert Mustacchi  *
7*7687d0d8SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*7687d0d8SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*7687d0d8SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*7687d0d8SRobert Mustacchi  */
11*7687d0d8SRobert Mustacchi 
12*7687d0d8SRobert Mustacchi /*
13*7687d0d8SRobert Mustacchi  * Copyright 2021 Oxide Computer Company
14*7687d0d8SRobert Mustacchi  */
15*7687d0d8SRobert Mustacchi 
16*7687d0d8SRobert Mustacchi /*
17*7687d0d8SRobert Mustacchi  * This file contains logic to walk and print a large chunk of configuration
18*7687d0d8SRobert Mustacchi  * space and many of the capabilities. There are multiple sub-commands that
19*7687d0d8SRobert Mustacchi  * vector into the same logic (e.g. 'save-cfgspace' and 'show-cfgspace'). In
20*7687d0d8SRobert Mustacchi  * general, there are a few major goals with this bit of code:
21*7687d0d8SRobert Mustacchi  *
22*7687d0d8SRobert Mustacchi  *  o Every field should strive to be parsable and therefore selectable for
23*7687d0d8SRobert Mustacchi  *    output. This drove the idea that every field has both a short name and a
24*7687d0d8SRobert Mustacchi  *    human name. The short name is a dot-delineated name. When in parsable
25*7687d0d8SRobert Mustacchi  *    mode, the name will always refer to a single field. However, for
26*7687d0d8SRobert Mustacchi  *    convenience for humans, when not trying to be parsable, we show the
27*7687d0d8SRobert Mustacchi  *    parents in the tree. That is if you specify something like
28*7687d0d8SRobert Mustacchi  *    'pcie.linkcap.maxspeed', in parsable mode you'll only get that; however,
29*7687d0d8SRobert Mustacchi  *    in non-parsable mode, you'll get an indication of the capability and
30*7687d0d8SRobert Mustacchi  *    register that field was in.
31*7687d0d8SRobert Mustacchi  *
32*7687d0d8SRobert Mustacchi  *  o Related to the above, parsable mode always outputs a raw, uninterpreted
33*7687d0d8SRobert Mustacchi  *    value. This was done on purpose. Some fields require interpreting multiple
34*7687d0d8SRobert Mustacchi  *    registers to have meaning and long strings aren't always the most useful.
35*7687d0d8SRobert Mustacchi  *
36*7687d0d8SRobert Mustacchi  *  o Every field isn't always pretty printed. This was generally just a
37*7687d0d8SRobert Mustacchi  *    decision based upon the field itself and how much work it'd be to fit it
38*7687d0d8SRobert Mustacchi  *    into the framework we have. In general, the ones we're mostly guilty of
39*7687d0d8SRobert Mustacchi  *    doing this with are related to cases where there's a scaling value in a
40*7687d0d8SRobert Mustacchi  *    subsequent register. If you find yourself wanting this, feel free to add
41*7687d0d8SRobert Mustacchi  *    it.
42*7687d0d8SRobert Mustacchi  *
43*7687d0d8SRobert Mustacchi  *  o Currently designated vendor-specific capabilities aren't included here (or
44*7687d0d8SRobert Mustacchi  *    any specific vendor-specific capabilities for that matter). If they are
45*7687d0d8SRobert Mustacchi  *    added, they should follow the same angle of using a name to represent a
46*7687d0d8SRobert Mustacchi  *    sub-capability as we did with HyperTransport.
47*7687d0d8SRobert Mustacchi  */
48*7687d0d8SRobert Mustacchi 
49*7687d0d8SRobert Mustacchi #include <err.h>
50*7687d0d8SRobert Mustacchi #include <strings.h>
51*7687d0d8SRobert Mustacchi #include <sys/sysmacros.h>
52*7687d0d8SRobert Mustacchi #include <sys/pci.h>
53*7687d0d8SRobert Mustacchi #include <sys/pcie.h>
54*7687d0d8SRobert Mustacchi #include <sys/debug.h>
55*7687d0d8SRobert Mustacchi #include <ofmt.h>
56*7687d0d8SRobert Mustacchi #include <sys/types.h>
57*7687d0d8SRobert Mustacchi #include <sys/stat.h>
58*7687d0d8SRobert Mustacchi #include <fcntl.h>
59*7687d0d8SRobert Mustacchi #include <unistd.h>
60*7687d0d8SRobert Mustacchi 
61*7687d0d8SRobert Mustacchi #include "pcieadm.h"
62*7687d0d8SRobert Mustacchi 
63*7687d0d8SRobert Mustacchi typedef enum pcieadm_cfgspace_op {
64*7687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OP_PRINT,
65*7687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OP_WRITE
66*7687d0d8SRobert Mustacchi } pcieadm_cfgspace_op_t;
67*7687d0d8SRobert Mustacchi 
68*7687d0d8SRobert Mustacchi typedef enum piceadm_cfgspace_flag {
69*7687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_F_PARSE	= 1 << 0,
70*7687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_F_SHORT	= 1 << 1,
71*7687d0d8SRobert Mustacchi } pcieadm_cfgspace_flags_t;
72*7687d0d8SRobert Mustacchi 
73*7687d0d8SRobert Mustacchi typedef enum pcieadm_cfgspace_otype {
74*7687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_SHORT,
75*7687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_HUMAN,
76*7687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_VALUE
77*7687d0d8SRobert Mustacchi } pcieadm_cfgsapce_otype_t;
78*7687d0d8SRobert Mustacchi 
79*7687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_ofmt {
80*7687d0d8SRobert Mustacchi 	const char *pco_base;
81*7687d0d8SRobert Mustacchi 	const char *pco_short;
82*7687d0d8SRobert Mustacchi 	const char *pco_human;
83*7687d0d8SRobert Mustacchi 	uint64_t pco_value;
84*7687d0d8SRobert Mustacchi 	const char *pco_strval;
85*7687d0d8SRobert Mustacchi } pcieadm_cfgspace_ofmt_t;
86*7687d0d8SRobert Mustacchi 
87*7687d0d8SRobert Mustacchi typedef enum pcieadm_regdef_val {
88*7687d0d8SRobert Mustacchi 	PRDV_STRVAL,
89*7687d0d8SRobert Mustacchi 	PRDV_BITFIELD,
90*7687d0d8SRobert Mustacchi 	PRDV_HEX
91*7687d0d8SRobert Mustacchi } pcieadm_regdef_val_t;
92*7687d0d8SRobert Mustacchi 
93*7687d0d8SRobert Mustacchi typedef struct pcieadm_regdef_addend {
94*7687d0d8SRobert Mustacchi 	uint8_t pra_shift;
95*7687d0d8SRobert Mustacchi 	int64_t pra_addend;
96*7687d0d8SRobert Mustacchi } pcieadm_regdef_addend_t;
97*7687d0d8SRobert Mustacchi 
98*7687d0d8SRobert Mustacchi typedef struct pcieadm_regdef {
99*7687d0d8SRobert Mustacchi 	uint8_t prd_lowbit;
100*7687d0d8SRobert Mustacchi 	uint8_t prd_hibit;
101*7687d0d8SRobert Mustacchi 	const char *prd_short;
102*7687d0d8SRobert Mustacchi 	const char *prd_human;
103*7687d0d8SRobert Mustacchi 	pcieadm_regdef_val_t prd_valtype;
104*7687d0d8SRobert Mustacchi 	union {
105*7687d0d8SRobert Mustacchi 		/*
106*7687d0d8SRobert Mustacchi 		 * Enough space for up to an 8-bit fields worth of values
107*7687d0d8SRobert Mustacchi 		 * (though we expect most to be sparse).
108*7687d0d8SRobert Mustacchi 		 */
109*7687d0d8SRobert Mustacchi 		const char *prdv_strval[128];
110*7687d0d8SRobert Mustacchi 		pcieadm_regdef_addend_t prdv_hex;
111*7687d0d8SRobert Mustacchi 	} prd_val;
112*7687d0d8SRobert Mustacchi } pcieadm_regdef_t;
113*7687d0d8SRobert Mustacchi 
114*7687d0d8SRobert Mustacchi typedef struct pcieadm_unitdef {
115*7687d0d8SRobert Mustacchi 	const char *pcd_unit;
116*7687d0d8SRobert Mustacchi 	uint32_t pcd_mult;
117*7687d0d8SRobert Mustacchi } pcieadm_unitdef_t;
118*7687d0d8SRobert Mustacchi 
119*7687d0d8SRobert Mustacchi typedef struct pcieadm_strmap {
120*7687d0d8SRobert Mustacchi 	const char *psr_str;
121*7687d0d8SRobert Mustacchi 	uint64_t psr_val;
122*7687d0d8SRobert Mustacchi } pcieadm_strmap_t;
123*7687d0d8SRobert Mustacchi 
124*7687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_filter {
125*7687d0d8SRobert Mustacchi 	const char *pcf_string;
126*7687d0d8SRobert Mustacchi 	size_t pcf_len;
127*7687d0d8SRobert Mustacchi 	boolean_t pcf_used;
128*7687d0d8SRobert Mustacchi } pcieadm_cfgspace_filter_t;
129*7687d0d8SRobert Mustacchi 
130*7687d0d8SRobert Mustacchi typedef struct pcieadm_strfilt {
131*7687d0d8SRobert Mustacchi 	struct pcieadm_strfilt *pstr_next;
132*7687d0d8SRobert Mustacchi 	const char *pstr_str;
133*7687d0d8SRobert Mustacchi 	char pstr_curgen[256];
134*7687d0d8SRobert Mustacchi } pcieadm_strfilt_t;
135*7687d0d8SRobert Mustacchi 
136*7687d0d8SRobert Mustacchi /*
137*7687d0d8SRobert Mustacchi  * Data is sized to be large enough that we can hold all of PCIe extended
138*7687d0d8SRobert Mustacchi  * configuration space.
139*7687d0d8SRobert Mustacchi  */
140*7687d0d8SRobert Mustacchi typedef union pcieadm_cfgspace_data {
141*7687d0d8SRobert Mustacchi 	uint8_t pcb_u8[PCIE_CONF_HDR_SIZE];
142*7687d0d8SRobert Mustacchi 	uint32_t pcb_u32[PCIE_CONF_HDR_SIZE / 4];
143*7687d0d8SRobert Mustacchi } pcieadm_cfgspace_data_t;
144*7687d0d8SRobert Mustacchi 
145*7687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_walk {
146*7687d0d8SRobert Mustacchi 	pcieadm_t *pcw_pcieadm;
147*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_op_t pcw_op;
148*7687d0d8SRobert Mustacchi 	uint32_t pcw_valid;
149*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_data_t *pcw_data;
150*7687d0d8SRobert Mustacchi 	uint16_t pcw_capoff;
151*7687d0d8SRobert Mustacchi 	uint32_t pcw_caplen;
152*7687d0d8SRobert Mustacchi 	int pcw_outfd;
153*7687d0d8SRobert Mustacchi 	uint_t pcw_dtype;
154*7687d0d8SRobert Mustacchi 	uint_t pcw_nlanes;
155*7687d0d8SRobert Mustacchi 	uint_t pcw_pcietype;
156*7687d0d8SRobert Mustacchi 	uint_t pcw_nfilters;
157*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_filter_t *pcw_filters;
158*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_flags_t pcw_flags;
159*7687d0d8SRobert Mustacchi 	ofmt_handle_t pcw_ofmt;
160*7687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *pcw_filt;
161*7687d0d8SRobert Mustacchi } pcieadm_cfgspace_walk_t;
162*7687d0d8SRobert Mustacchi 
163*7687d0d8SRobert Mustacchi void
164*7687d0d8SRobert Mustacchi pcieadm_strfilt_pop(pcieadm_cfgspace_walk_t *walkp)
165*7687d0d8SRobert Mustacchi {
166*7687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *filt;
167*7687d0d8SRobert Mustacchi 
168*7687d0d8SRobert Mustacchi 	VERIFY3P(walkp->pcw_filt, !=, NULL);
169*7687d0d8SRobert Mustacchi 	filt = walkp->pcw_filt;
170*7687d0d8SRobert Mustacchi 	walkp->pcw_filt = filt->pstr_next;
171*7687d0d8SRobert Mustacchi 	free(filt);
172*7687d0d8SRobert Mustacchi }
173*7687d0d8SRobert Mustacchi 
174*7687d0d8SRobert Mustacchi void
175*7687d0d8SRobert Mustacchi pcieadm_strfilt_push(pcieadm_cfgspace_walk_t *walkp, const char *str)
176*7687d0d8SRobert Mustacchi {
177*7687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *filt;
178*7687d0d8SRobert Mustacchi 	size_t len;
179*7687d0d8SRobert Mustacchi 
180*7687d0d8SRobert Mustacchi 	filt = calloc(1, sizeof (*filt));
181*7687d0d8SRobert Mustacchi 	if (filt == NULL) {
182*7687d0d8SRobert Mustacchi 		errx(EXIT_FAILURE, "failed to allocate memory for string "
183*7687d0d8SRobert Mustacchi 		    "filter");
184*7687d0d8SRobert Mustacchi 	}
185*7687d0d8SRobert Mustacchi 
186*7687d0d8SRobert Mustacchi 	filt->pstr_str = str;
187*7687d0d8SRobert Mustacchi 	if (walkp->pcw_filt == NULL) {
188*7687d0d8SRobert Mustacchi 		len = strlcat(filt->pstr_curgen, str,
189*7687d0d8SRobert Mustacchi 		    sizeof (filt->pstr_curgen));
190*7687d0d8SRobert Mustacchi 	} else {
191*7687d0d8SRobert Mustacchi 		len = snprintf(filt->pstr_curgen, sizeof (filt->pstr_curgen),
192*7687d0d8SRobert Mustacchi 		    "%s.%s", walkp->pcw_filt->pstr_curgen, str);
193*7687d0d8SRobert Mustacchi 		filt->pstr_next = walkp->pcw_filt;
194*7687d0d8SRobert Mustacchi 	}
195*7687d0d8SRobert Mustacchi 
196*7687d0d8SRobert Mustacchi 	if (len >= sizeof (filt->pstr_curgen)) {
197*7687d0d8SRobert Mustacchi 		errx(EXIT_FAILURE, "overflowed internal string buffer "
198*7687d0d8SRobert Mustacchi 		    "appending %s", str);
199*7687d0d8SRobert Mustacchi 	}
200*7687d0d8SRobert Mustacchi 
201*7687d0d8SRobert Mustacchi 	walkp->pcw_filt = filt;
202*7687d0d8SRobert Mustacchi }
203*7687d0d8SRobert Mustacchi 
204*7687d0d8SRobert Mustacchi static boolean_t
205*7687d0d8SRobert Mustacchi pcieadm_cfgspace_filter(pcieadm_cfgspace_walk_t *walkp, const char *str)
206*7687d0d8SRobert Mustacchi {
207*7687d0d8SRobert Mustacchi 	char buf[1024];
208*7687d0d8SRobert Mustacchi 	size_t len;
209*7687d0d8SRobert Mustacchi 
210*7687d0d8SRobert Mustacchi 	if (walkp->pcw_nfilters == 0) {
211*7687d0d8SRobert Mustacchi 		return (B_TRUE);
212*7687d0d8SRobert Mustacchi 	}
213*7687d0d8SRobert Mustacchi 
214*7687d0d8SRobert Mustacchi 	if (str == NULL) {
215*7687d0d8SRobert Mustacchi 		return (B_FALSE);
216*7687d0d8SRobert Mustacchi 	}
217*7687d0d8SRobert Mustacchi 
218*7687d0d8SRobert Mustacchi 	if (walkp->pcw_filt != NULL) {
219*7687d0d8SRobert Mustacchi 		len = snprintf(buf, sizeof (buf), "%s.%s",
220*7687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, str);
221*7687d0d8SRobert Mustacchi 	} else {
222*7687d0d8SRobert Mustacchi 		len = snprintf(buf, sizeof (buf), "%s", str);
223*7687d0d8SRobert Mustacchi 	}
224*7687d0d8SRobert Mustacchi 
225*7687d0d8SRobert Mustacchi 	if (len >= sizeof (buf)) {
226*7687d0d8SRobert Mustacchi 		abort();
227*7687d0d8SRobert Mustacchi 	}
228*7687d0d8SRobert Mustacchi 
229*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nfilters; i++) {
230*7687d0d8SRobert Mustacchi 		if (strcmp(buf, walkp->pcw_filters[i].pcf_string) == 0) {
231*7687d0d8SRobert Mustacchi 			walkp->pcw_filters[i].pcf_used = B_TRUE;
232*7687d0d8SRobert Mustacchi 			return (B_TRUE);
233*7687d0d8SRobert Mustacchi 		}
234*7687d0d8SRobert Mustacchi 
235*7687d0d8SRobert Mustacchi 		/*
236*7687d0d8SRobert Mustacchi 		 * If we're in non-parsable mode, we want to do a little bit
237*7687d0d8SRobert Mustacchi 		 * more in a few cases. We want to make sure that we print the
238*7687d0d8SRobert Mustacchi 		 * parents of more-specific entries. That is, if someone
239*7687d0d8SRobert Mustacchi 		 * specified 'header.command.serr', then we want to print
240*7687d0d8SRobert Mustacchi 		 * 'header', and 'header.command'. Similarly, if someone
241*7687d0d8SRobert Mustacchi 		 * specifies an individual field, we want to print all of its
242*7687d0d8SRobert Mustacchi 		 * subfields, that is asking for 'header.command', really gets
243*7687d0d8SRobert Mustacchi 		 * that and all of 'header.command.*'.
244*7687d0d8SRobert Mustacchi 		 */
245*7687d0d8SRobert Mustacchi 		if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_PARSE) != 0) {
246*7687d0d8SRobert Mustacchi 			continue;
247*7687d0d8SRobert Mustacchi 		}
248*7687d0d8SRobert Mustacchi 
249*7687d0d8SRobert Mustacchi 		if (len >= walkp->pcw_filters[i].pcf_len) {
250*7687d0d8SRobert Mustacchi 			if (strncmp(buf, walkp->pcw_filters[i].pcf_string,
251*7687d0d8SRobert Mustacchi 			    walkp->pcw_filters[i].pcf_len) == 0 &&
252*7687d0d8SRobert Mustacchi 			    buf[walkp->pcw_filters[i].pcf_len] == '.') {
253*7687d0d8SRobert Mustacchi 				return (B_TRUE);
254*7687d0d8SRobert Mustacchi 			}
255*7687d0d8SRobert Mustacchi 		} else {
256*7687d0d8SRobert Mustacchi 			if (strncmp(buf, walkp->pcw_filters[i].pcf_string,
257*7687d0d8SRobert Mustacchi 			    len) == 0 &&
258*7687d0d8SRobert Mustacchi 			    walkp->pcw_filters[i].pcf_string[len] == '.') {
259*7687d0d8SRobert Mustacchi 				return (B_TRUE);
260*7687d0d8SRobert Mustacchi 			}
261*7687d0d8SRobert Mustacchi 		}
262*7687d0d8SRobert Mustacchi 	}
263*7687d0d8SRobert Mustacchi 
264*7687d0d8SRobert Mustacchi 	return (B_FALSE);
265*7687d0d8SRobert Mustacchi }
266*7687d0d8SRobert Mustacchi 
267*7687d0d8SRobert Mustacchi static boolean_t
268*7687d0d8SRobert Mustacchi pcieadm_cfgspace_ofmt_cb(ofmt_arg_t *ofarg, char *buf, uint_t buflen)
269*7687d0d8SRobert Mustacchi {
270*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_ofmt_t *pco = ofarg->ofmt_cbarg;
271*7687d0d8SRobert Mustacchi 
272*7687d0d8SRobert Mustacchi 	switch (ofarg->ofmt_id) {
273*7687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_SHORT:
274*7687d0d8SRobert Mustacchi 		if (snprintf(buf, buflen, "%s.%s", pco->pco_base,
275*7687d0d8SRobert Mustacchi 		    pco->pco_short) >= buflen) {
276*7687d0d8SRobert Mustacchi 			return (B_FALSE);
277*7687d0d8SRobert Mustacchi 		}
278*7687d0d8SRobert Mustacchi 		break;
279*7687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_HUMAN:
280*7687d0d8SRobert Mustacchi 		if (strlcpy(buf, pco->pco_human, buflen) >= buflen) {
281*7687d0d8SRobert Mustacchi 			return (B_FALSE);
282*7687d0d8SRobert Mustacchi 		}
283*7687d0d8SRobert Mustacchi 		break;
284*7687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_VALUE:
285*7687d0d8SRobert Mustacchi 		if (pco->pco_strval != NULL) {
286*7687d0d8SRobert Mustacchi 			if (strlcpy(buf, pco->pco_strval, buflen) >= buflen) {
287*7687d0d8SRobert Mustacchi 				return (B_FALSE);
288*7687d0d8SRobert Mustacchi 			}
289*7687d0d8SRobert Mustacchi 		} else {
290*7687d0d8SRobert Mustacchi 			if (snprintf(buf, buflen, "0x%" PRIx64,
291*7687d0d8SRobert Mustacchi 			    pco->pco_value) >= buflen) {
292*7687d0d8SRobert Mustacchi 				return (B_FALSE);
293*7687d0d8SRobert Mustacchi 			}
294*7687d0d8SRobert Mustacchi 		}
295*7687d0d8SRobert Mustacchi 		break;
296*7687d0d8SRobert Mustacchi 	default:
297*7687d0d8SRobert Mustacchi 		abort();
298*7687d0d8SRobert Mustacchi 	}
299*7687d0d8SRobert Mustacchi 
300*7687d0d8SRobert Mustacchi 	return (B_TRUE);
301*7687d0d8SRobert Mustacchi }
302*7687d0d8SRobert Mustacchi 
303*7687d0d8SRobert Mustacchi 
304*7687d0d8SRobert Mustacchi static const ofmt_field_t pcieadm_cfgspace_ofmt[] = {
305*7687d0d8SRobert Mustacchi 	{ "SHORT", 30, PCIEADM_CFGSPACE_OT_SHORT, pcieadm_cfgspace_ofmt_cb },
306*7687d0d8SRobert Mustacchi 	{ "HUMAN", 30, PCIEADM_CFGSPACE_OT_HUMAN, pcieadm_cfgspace_ofmt_cb },
307*7687d0d8SRobert Mustacchi 	{ "VALUE", 20, PCIEADM_CFGSPACE_OT_VALUE, pcieadm_cfgspace_ofmt_cb },
308*7687d0d8SRobert Mustacchi 	{ NULL, 0, 0, NULL }
309*7687d0d8SRobert Mustacchi };
310*7687d0d8SRobert Mustacchi 
311*7687d0d8SRobert Mustacchi static void
312*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_parse(pcieadm_cfgspace_walk_t *walkp,
313*7687d0d8SRobert Mustacchi     const char *sname, const char *human, uint64_t value)
314*7687d0d8SRobert Mustacchi {
315*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_ofmt_t pco;
316*7687d0d8SRobert Mustacchi 
317*7687d0d8SRobert Mustacchi 	VERIFY3P(walkp->pcw_filt, !=, NULL);
318*7687d0d8SRobert Mustacchi 	pco.pco_base = walkp->pcw_filt->pstr_curgen;
319*7687d0d8SRobert Mustacchi 	pco.pco_short = sname;
320*7687d0d8SRobert Mustacchi 	pco.pco_human = human;
321*7687d0d8SRobert Mustacchi 	pco.pco_value = value;
322*7687d0d8SRobert Mustacchi 	pco.pco_strval = NULL;
323*7687d0d8SRobert Mustacchi 	ofmt_print(walkp->pcw_ofmt, &pco);
324*7687d0d8SRobert Mustacchi }
325*7687d0d8SRobert Mustacchi 
326*7687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_print pcieadm_cfgspace_print_t;
327*7687d0d8SRobert Mustacchi typedef void (*pcieadm_cfgspace_print_f)(pcieadm_cfgspace_walk_t *,
328*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *, void *);
329*7687d0d8SRobert Mustacchi 
330*7687d0d8SRobert Mustacchi struct pcieadm_cfgspace_print {
331*7687d0d8SRobert Mustacchi 	uint8_t pcp_off;
332*7687d0d8SRobert Mustacchi 	uint8_t pcp_len;
333*7687d0d8SRobert Mustacchi 	const char *pcp_short;
334*7687d0d8SRobert Mustacchi 	const char *pcp_human;
335*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_f pcp_print;
336*7687d0d8SRobert Mustacchi 	void *pcp_arg;
337*7687d0d8SRobert Mustacchi };
338*7687d0d8SRobert Mustacchi 
339*7687d0d8SRobert Mustacchi static void
340*7687d0d8SRobert Mustacchi pcieadm_field_printf(pcieadm_cfgspace_walk_t *walkp, const char *shortf,
341*7687d0d8SRobert Mustacchi     const char *humanf, uint64_t val, const char *fmt, ...)
342*7687d0d8SRobert Mustacchi {
343*7687d0d8SRobert Mustacchi 	va_list ap;
344*7687d0d8SRobert Mustacchi 
345*7687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, shortf))
346*7687d0d8SRobert Mustacchi 		return;
347*7687d0d8SRobert Mustacchi 
348*7687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
349*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_parse(walkp, shortf, humanf, val);
350*7687d0d8SRobert Mustacchi 		return;
351*7687d0d8SRobert Mustacchi 	}
352*7687d0d8SRobert Mustacchi 
353*7687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
354*7687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
355*7687d0d8SRobert Mustacchi 	}
356*7687d0d8SRobert Mustacchi 
357*7687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
358*7687d0d8SRobert Mustacchi 		(void) printf("|--> %s (%s.%s): ", humanf,
359*7687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, shortf);
360*7687d0d8SRobert Mustacchi 	} else {
361*7687d0d8SRobert Mustacchi 		(void) printf("|--> %s: ", humanf);
362*7687d0d8SRobert Mustacchi 	}
363*7687d0d8SRobert Mustacchi 
364*7687d0d8SRobert Mustacchi 	va_start(ap, fmt);
365*7687d0d8SRobert Mustacchi 	(void) vprintf(fmt, ap);
366*7687d0d8SRobert Mustacchi 	va_end(ap);
367*7687d0d8SRobert Mustacchi 
368*7687d0d8SRobert Mustacchi }
369*7687d0d8SRobert Mustacchi 
370*7687d0d8SRobert Mustacchi static void
371*7687d0d8SRobert Mustacchi pcieadm_cfgspace_printf(pcieadm_cfgspace_walk_t *walkp,
372*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, uint64_t val, const char *fmt, ...)
373*7687d0d8SRobert Mustacchi {
374*7687d0d8SRobert Mustacchi 	va_list ap;
375*7687d0d8SRobert Mustacchi 
376*7687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, print->pcp_short))
377*7687d0d8SRobert Mustacchi 		return;
378*7687d0d8SRobert Mustacchi 
379*7687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
380*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_parse(walkp, print->pcp_short,
381*7687d0d8SRobert Mustacchi 		    print->pcp_human, val);
382*7687d0d8SRobert Mustacchi 		return;
383*7687d0d8SRobert Mustacchi 	}
384*7687d0d8SRobert Mustacchi 
385*7687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
386*7687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
387*7687d0d8SRobert Mustacchi 	}
388*7687d0d8SRobert Mustacchi 
389*7687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
390*7687d0d8SRobert Mustacchi 		(void) printf("%s (%s.%s): ", print->pcp_human,
391*7687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, print->pcp_short);
392*7687d0d8SRobert Mustacchi 	} else {
393*7687d0d8SRobert Mustacchi 		(void) printf("%s: ", print->pcp_human);
394*7687d0d8SRobert Mustacchi 	}
395*7687d0d8SRobert Mustacchi 
396*7687d0d8SRobert Mustacchi 	va_start(ap, fmt);
397*7687d0d8SRobert Mustacchi 	(void) vprintf(fmt, ap);
398*7687d0d8SRobert Mustacchi 	va_end(ap);
399*7687d0d8SRobert Mustacchi }
400*7687d0d8SRobert Mustacchi 
401*7687d0d8SRobert Mustacchi static void
402*7687d0d8SRobert Mustacchi pcieadm_cfgspace_puts(pcieadm_cfgspace_walk_t *walkp,
403*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, const char *str)
404*7687d0d8SRobert Mustacchi {
405*7687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, print->pcp_short))
406*7687d0d8SRobert Mustacchi 		return;
407*7687d0d8SRobert Mustacchi 
408*7687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
409*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_ofmt_t pco;
410*7687d0d8SRobert Mustacchi 
411*7687d0d8SRobert Mustacchi 		VERIFY3P(walkp->pcw_filt, !=, NULL);
412*7687d0d8SRobert Mustacchi 		pco.pco_base = walkp->pcw_filt->pstr_curgen;
413*7687d0d8SRobert Mustacchi 		pco.pco_short = print->pcp_short;
414*7687d0d8SRobert Mustacchi 		pco.pco_human = print->pcp_human;
415*7687d0d8SRobert Mustacchi 		pco.pco_strval = str;
416*7687d0d8SRobert Mustacchi 		ofmt_print(walkp->pcw_ofmt, &pco);
417*7687d0d8SRobert Mustacchi 		return;
418*7687d0d8SRobert Mustacchi 	}
419*7687d0d8SRobert Mustacchi 
420*7687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
421*7687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
422*7687d0d8SRobert Mustacchi 	}
423*7687d0d8SRobert Mustacchi 
424*7687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
425*7687d0d8SRobert Mustacchi 		(void) printf("%s (%s.%s): %s\n", print->pcp_human,
426*7687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, print->pcp_short, str);
427*7687d0d8SRobert Mustacchi 	} else {
428*7687d0d8SRobert Mustacchi 		(void) printf("%s: %s\n", print->pcp_human, str);
429*7687d0d8SRobert Mustacchi 	}
430*7687d0d8SRobert Mustacchi }
431*7687d0d8SRobert Mustacchi 
432*7687d0d8SRobert Mustacchi static uint64_t
433*7687d0d8SRobert Mustacchi pcieadm_cfgspace_extract(pcieadm_cfgspace_walk_t *walkp,
434*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print)
435*7687d0d8SRobert Mustacchi {
436*7687d0d8SRobert Mustacchi 	uint32_t val = 0;
437*7687d0d8SRobert Mustacchi 
438*7687d0d8SRobert Mustacchi 	VERIFY3U(print->pcp_len, <=, 8);
439*7687d0d8SRobert Mustacchi 	VERIFY3U(print->pcp_off + print->pcp_len + walkp->pcw_capoff, <=,
440*7687d0d8SRobert Mustacchi 	    walkp->pcw_valid);
441*7687d0d8SRobert Mustacchi 	for (uint8_t i = print->pcp_len; i > 0; i--) {
442*7687d0d8SRobert Mustacchi 		val <<= 8;
443*7687d0d8SRobert Mustacchi 		val |= walkp->pcw_data->pcb_u8[walkp->pcw_capoff +
444*7687d0d8SRobert Mustacchi 		    print->pcp_off + i - 1];
445*7687d0d8SRobert Mustacchi 	}
446*7687d0d8SRobert Mustacchi 
447*7687d0d8SRobert Mustacchi 	return (val);
448*7687d0d8SRobert Mustacchi }
449*7687d0d8SRobert Mustacchi 
450*7687d0d8SRobert Mustacchi static uint16_t
451*7687d0d8SRobert Mustacchi pcieadm_cfgspace_extract_u16(pcieadm_cfgspace_walk_t *walkp,
452*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print)
453*7687d0d8SRobert Mustacchi {
454*7687d0d8SRobert Mustacchi 	VERIFY(print->pcp_len == 2);
455*7687d0d8SRobert Mustacchi 	return ((uint16_t)pcieadm_cfgspace_extract(walkp, print));
456*7687d0d8SRobert Mustacchi }
457*7687d0d8SRobert Mustacchi 
458*7687d0d8SRobert Mustacchi static void
459*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_unit(pcieadm_cfgspace_walk_t *walkp,
460*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
461*7687d0d8SRobert Mustacchi {
462*7687d0d8SRobert Mustacchi 	pcieadm_unitdef_t *unit = arg;
463*7687d0d8SRobert Mustacchi 	uint64_t rawval = pcieadm_cfgspace_extract(walkp, print);
464*7687d0d8SRobert Mustacchi 	uint64_t val = rawval;
465*7687d0d8SRobert Mustacchi 
466*7687d0d8SRobert Mustacchi 	if (unit->pcd_mult > 1) {
467*7687d0d8SRobert Mustacchi 		val *= unit->pcd_mult;
468*7687d0d8SRobert Mustacchi 	}
469*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, rawval, "0x%" PRIx64 " %s%s\n",
470*7687d0d8SRobert Mustacchi 	    val, unit->pcd_unit, val != 1 ? "s" : "");
471*7687d0d8SRobert Mustacchi }
472*7687d0d8SRobert Mustacchi 
473*7687d0d8SRobert Mustacchi static void
474*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_regdef(pcieadm_cfgspace_walk_t *walkp,
475*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
476*7687d0d8SRobert Mustacchi {
477*7687d0d8SRobert Mustacchi 	pcieadm_regdef_t *regdef = arg;
478*7687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
479*7687d0d8SRobert Mustacchi 
480*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val);
481*7687d0d8SRobert Mustacchi 
482*7687d0d8SRobert Mustacchi 	pcieadm_indent();
483*7687d0d8SRobert Mustacchi 	pcieadm_strfilt_push(walkp, print->pcp_short);
484*7687d0d8SRobert Mustacchi 
485*7687d0d8SRobert Mustacchi 	for (regdef = arg; regdef->prd_short != NULL; regdef++) {
486*7687d0d8SRobert Mustacchi 		uint32_t nbits = regdef->prd_hibit - regdef->prd_lowbit + 1UL;
487*7687d0d8SRobert Mustacchi 		uint32_t bitmask = (1UL << nbits) - 1UL;
488*7687d0d8SRobert Mustacchi 		uint64_t regval = (val >> regdef->prd_lowbit) & bitmask;
489*7687d0d8SRobert Mustacchi 		const char *strval;
490*7687d0d8SRobert Mustacchi 		uint64_t actval;
491*7687d0d8SRobert Mustacchi 
492*7687d0d8SRobert Mustacchi 		if (!pcieadm_cfgspace_filter(walkp, regdef->prd_short)) {
493*7687d0d8SRobert Mustacchi 			continue;
494*7687d0d8SRobert Mustacchi 		}
495*7687d0d8SRobert Mustacchi 
496*7687d0d8SRobert Mustacchi 		switch (regdef->prd_valtype) {
497*7687d0d8SRobert Mustacchi 		case PRDV_STRVAL:
498*7687d0d8SRobert Mustacchi 			strval = regdef->prd_val.prdv_strval[regval];
499*7687d0d8SRobert Mustacchi 			if (strval == NULL) {
500*7687d0d8SRobert Mustacchi 				strval = "reserved";
501*7687d0d8SRobert Mustacchi 			}
502*7687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
503*7687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "%s (0x%" PRIx64 ")\n",
504*7687d0d8SRobert Mustacchi 			    strval, regval << regdef->prd_lowbit);
505*7687d0d8SRobert Mustacchi 			break;
506*7687d0d8SRobert Mustacchi 		case PRDV_HEX:
507*7687d0d8SRobert Mustacchi 			actval = regval;
508*7687d0d8SRobert Mustacchi 			if (regdef->prd_val.prdv_hex.pra_shift > 0) {
509*7687d0d8SRobert Mustacchi 				actval <<= regdef->prd_val.prdv_hex.pra_shift;
510*7687d0d8SRobert Mustacchi 			}
511*7687d0d8SRobert Mustacchi 			actval += regdef->prd_val.prdv_hex.pra_addend;
512*7687d0d8SRobert Mustacchi 
513*7687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
514*7687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "0x% " PRIx64 "\n",
515*7687d0d8SRobert Mustacchi 			    actval);
516*7687d0d8SRobert Mustacchi 			break;
517*7687d0d8SRobert Mustacchi 		case PRDV_BITFIELD:
518*7687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
519*7687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "0x%" PRIx64 "\n",
520*7687d0d8SRobert Mustacchi 			    regval << regdef->prd_lowbit);
521*7687d0d8SRobert Mustacchi 
522*7687d0d8SRobert Mustacchi 			if (walkp->pcw_ofmt == NULL) {
523*7687d0d8SRobert Mustacchi 				pcieadm_indent();
524*7687d0d8SRobert Mustacchi 				for (uint32_t i = 0; i < nbits; i++) {
525*7687d0d8SRobert Mustacchi 					if (((1 << i) & regval) == 0)
526*7687d0d8SRobert Mustacchi 						continue;
527*7687d0d8SRobert Mustacchi 					pcieadm_print("|--> %s (0x%x)\n",
528*7687d0d8SRobert Mustacchi 					    regdef->prd_val.prdv_strval[i],
529*7687d0d8SRobert Mustacchi 					    1UL << (i + regdef->prd_lowbit));
530*7687d0d8SRobert Mustacchi 				}
531*7687d0d8SRobert Mustacchi 				pcieadm_deindent();
532*7687d0d8SRobert Mustacchi 			}
533*7687d0d8SRobert Mustacchi 			break;
534*7687d0d8SRobert Mustacchi 		}
535*7687d0d8SRobert Mustacchi 	}
536*7687d0d8SRobert Mustacchi 
537*7687d0d8SRobert Mustacchi 	pcieadm_strfilt_pop(walkp);
538*7687d0d8SRobert Mustacchi 	pcieadm_deindent();
539*7687d0d8SRobert Mustacchi }
540*7687d0d8SRobert Mustacchi 
541*7687d0d8SRobert Mustacchi static void
542*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_strmap(pcieadm_cfgspace_walk_t *walkp,
543*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
544*7687d0d8SRobert Mustacchi {
545*7687d0d8SRobert Mustacchi 	pcieadm_strmap_t *strmap = arg;
546*7687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
547*7687d0d8SRobert Mustacchi 	const char *str = "reserved";
548*7687d0d8SRobert Mustacchi 
549*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; strmap[i].psr_str != NULL; i++) {
550*7687d0d8SRobert Mustacchi 		if (strmap[i].psr_val == val) {
551*7687d0d8SRobert Mustacchi 			str = strmap[i].psr_str;
552*7687d0d8SRobert Mustacchi 			break;
553*7687d0d8SRobert Mustacchi 		}
554*7687d0d8SRobert Mustacchi 	}
555*7687d0d8SRobert Mustacchi 
556*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%x -- %s\n", val, str);
557*7687d0d8SRobert Mustacchi }
558*7687d0d8SRobert Mustacchi 
559*7687d0d8SRobert Mustacchi static void
560*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_hex(pcieadm_cfgspace_walk_t *walkp,
561*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
562*7687d0d8SRobert Mustacchi {
563*7687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
564*7687d0d8SRobert Mustacchi 
565*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val);
566*7687d0d8SRobert Mustacchi }
567*7687d0d8SRobert Mustacchi 
568*7687d0d8SRobert Mustacchi static void
569*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_vendor(pcieadm_cfgspace_walk_t *walkp,
570*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
571*7687d0d8SRobert Mustacchi {
572*7687d0d8SRobert Mustacchi 	pcidb_vendor_t *vend;
573*7687d0d8SRobert Mustacchi 	uint16_t vid = pcieadm_cfgspace_extract_u16(walkp, print);
574*7687d0d8SRobert Mustacchi 
575*7687d0d8SRobert Mustacchi 	vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb, vid);
576*7687d0d8SRobert Mustacchi 	if (vend != NULL) {
577*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, vid, "0x%x -- %s\n", vid,
578*7687d0d8SRobert Mustacchi 		    pcidb_vendor_name(vend));
579*7687d0d8SRobert Mustacchi 	} else {
580*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, vid, "0x%x\n", vid);
581*7687d0d8SRobert Mustacchi 	}
582*7687d0d8SRobert Mustacchi }
583*7687d0d8SRobert Mustacchi 
584*7687d0d8SRobert Mustacchi static void
585*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_device(pcieadm_cfgspace_walk_t *walkp,
586*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
587*7687d0d8SRobert Mustacchi {
588*7687d0d8SRobert Mustacchi 	pcidb_device_t *dev;
589*7687d0d8SRobert Mustacchi 	uint16_t did = pcieadm_cfgspace_extract_u16(walkp, print);
590*7687d0d8SRobert Mustacchi 	uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] +
591*7687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8);
592*7687d0d8SRobert Mustacchi 
593*7687d0d8SRobert Mustacchi 	dev = pcidb_lookup_device(walkp->pcw_pcieadm->pia_pcidb, vid, did);
594*7687d0d8SRobert Mustacchi 	if (dev != NULL) {
595*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, did, "0x%x -- %s\n", did,
596*7687d0d8SRobert Mustacchi 		    pcidb_device_name(dev));
597*7687d0d8SRobert Mustacchi 	} else {
598*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, did, "0x%x\n", did);
599*7687d0d8SRobert Mustacchi 	}
600*7687d0d8SRobert Mustacchi }
601*7687d0d8SRobert Mustacchi 
602*7687d0d8SRobert Mustacchi /*
603*7687d0d8SRobert Mustacchi  * To print out detailed information about a subsystem vendor or device, we need
604*7687d0d8SRobert Mustacchi  * all of the information about the vendor and device due to the organization of
605*7687d0d8SRobert Mustacchi  * the PCI IDs db.
606*7687d0d8SRobert Mustacchi  */
607*7687d0d8SRobert Mustacchi static void
608*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_subid(pcieadm_cfgspace_walk_t *walkp,
609*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
610*7687d0d8SRobert Mustacchi {
611*7687d0d8SRobert Mustacchi 	uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] +
612*7687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8);
613*7687d0d8SRobert Mustacchi 	uint16_t did = walkp->pcw_data->pcb_u8[PCI_CONF_DEVID] +
614*7687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_DEVID + 1] << 8);
615*7687d0d8SRobert Mustacchi 	uint16_t svid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID] +
616*7687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID + 1] << 8);
617*7687d0d8SRobert Mustacchi 	uint16_t sdid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID] +
618*7687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID + 1] << 8);
619*7687d0d8SRobert Mustacchi 	uint16_t val = pcieadm_cfgspace_extract_u16(walkp, print);
620*7687d0d8SRobert Mustacchi 	boolean_t isvendor = print->pcp_off == PCI_CONF_SUBVENID;
621*7687d0d8SRobert Mustacchi 
622*7687d0d8SRobert Mustacchi 	if (isvendor) {
623*7687d0d8SRobert Mustacchi 		pcidb_vendor_t *vend;
624*7687d0d8SRobert Mustacchi 		vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb,
625*7687d0d8SRobert Mustacchi 		    svid);
626*7687d0d8SRobert Mustacchi 		if (vend != NULL) {
627*7687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
628*7687d0d8SRobert Mustacchi 			    "0x%x -- %s\n", val, pcidb_vendor_name(vend));
629*7687d0d8SRobert Mustacchi 		} else {
630*7687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
631*7687d0d8SRobert Mustacchi 			    "0x%x\n", val);
632*7687d0d8SRobert Mustacchi 		}
633*7687d0d8SRobert Mustacchi 	} else {
634*7687d0d8SRobert Mustacchi 		pcidb_subvd_t *subvd;
635*7687d0d8SRobert Mustacchi 		subvd = pcidb_lookup_subvd(walkp->pcw_pcieadm->pia_pcidb, vid,
636*7687d0d8SRobert Mustacchi 		    did, svid, sdid);
637*7687d0d8SRobert Mustacchi 		if (subvd != NULL) {
638*7687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
639*7687d0d8SRobert Mustacchi 			    "0x%x -- %s\n", val, pcidb_subvd_name(subvd));
640*7687d0d8SRobert Mustacchi 		} else {
641*7687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val, "0x%x\n",
642*7687d0d8SRobert Mustacchi 			    val);
643*7687d0d8SRobert Mustacchi 		}
644*7687d0d8SRobert Mustacchi 	}
645*7687d0d8SRobert Mustacchi }
646*7687d0d8SRobert Mustacchi 
647*7687d0d8SRobert Mustacchi /*
648*7687d0d8SRobert Mustacchi  * The variable natures of BARs is a pain. This makes printing this out and the
649*7687d0d8SRobert Mustacchi  * fields all a bit gross.
650*7687d0d8SRobert Mustacchi  */
651*7687d0d8SRobert Mustacchi static void
652*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_bars(pcieadm_cfgspace_walk_t *walkp,
653*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
654*7687d0d8SRobert Mustacchi {
655*7687d0d8SRobert Mustacchi 	uint32_t *barp = &walkp->pcw_data->pcb_u32[(walkp->pcw_capoff +
656*7687d0d8SRobert Mustacchi 	    print->pcp_off) / 4];
657*7687d0d8SRobert Mustacchi 	char barname[32];
658*7687d0d8SRobert Mustacchi 	const char *typestrs[2] = { "Memory Space", "I/O Space" };
659*7687d0d8SRobert Mustacchi 
660*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < print->pcp_len / 4; i++) {
661*7687d0d8SRobert Mustacchi 		uint_t type;
662*7687d0d8SRobert Mustacchi 		(void) snprintf(barname, sizeof (barname), "%s%u",
663*7687d0d8SRobert Mustacchi 		    print->pcp_short, i);
664*7687d0d8SRobert Mustacchi 
665*7687d0d8SRobert Mustacchi 		type = barp[i] & PCI_BASE_SPACE_M;
666*7687d0d8SRobert Mustacchi 
667*7687d0d8SRobert Mustacchi 		if (pcieadm_cfgspace_filter(walkp, barname) &&
668*7687d0d8SRobert Mustacchi 		    walkp->pcw_ofmt == NULL) {
669*7687d0d8SRobert Mustacchi 			if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) !=
670*7687d0d8SRobert Mustacchi 			    0) {
671*7687d0d8SRobert Mustacchi 				pcieadm_print("%s %u (%s.%s)\n",
672*7687d0d8SRobert Mustacchi 				    print->pcp_human, i,
673*7687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, barname);
674*7687d0d8SRobert Mustacchi 			} else {
675*7687d0d8SRobert Mustacchi 				pcieadm_print("%s %u\n", print->pcp_human, i);
676*7687d0d8SRobert Mustacchi 			}
677*7687d0d8SRobert Mustacchi 		}
678*7687d0d8SRobert Mustacchi 
679*7687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(walkp, barname);
680*7687d0d8SRobert Mustacchi 		pcieadm_indent();
681*7687d0d8SRobert Mustacchi 
682*7687d0d8SRobert Mustacchi 		pcieadm_field_printf(walkp, "space", "Space", type,
683*7687d0d8SRobert Mustacchi 		    "%s (0x%x)\n", typestrs[type], type);
684*7687d0d8SRobert Mustacchi 
685*7687d0d8SRobert Mustacchi 		if (type == PCI_BASE_SPACE_IO) {
686*7687d0d8SRobert Mustacchi 			uint32_t addr = barp[i] & PCI_BASE_IO_ADDR_M;
687*7687d0d8SRobert Mustacchi 
688*7687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
689*7687d0d8SRobert Mustacchi 			    "0x%" PRIx32 "\n", addr);
690*7687d0d8SRobert Mustacchi 		} else {
691*7687d0d8SRobert Mustacchi 			uint8_t type, pre;
692*7687d0d8SRobert Mustacchi 			uint64_t addr;
693*7687d0d8SRobert Mustacchi 			const char *locstr;
694*7687d0d8SRobert Mustacchi 
695*7687d0d8SRobert Mustacchi 			type = barp[i] & PCI_BASE_TYPE_M;
696*7687d0d8SRobert Mustacchi 			pre = barp[i] & PCI_BASE_PREF_M;
697*7687d0d8SRobert Mustacchi 			addr = barp[i] & PCI_BASE_M_ADDR_M;
698*7687d0d8SRobert Mustacchi 
699*7687d0d8SRobert Mustacchi 			if (type == PCI_BASE_TYPE_ALL) {
700*7687d0d8SRobert Mustacchi 				addr += (uint64_t)barp[i+1] << 32;
701*7687d0d8SRobert Mustacchi 				i++;
702*7687d0d8SRobert Mustacchi 			}
703*7687d0d8SRobert Mustacchi 
704*7687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
705*7687d0d8SRobert Mustacchi 			    "0x%" PRIx64 "\n", addr);
706*7687d0d8SRobert Mustacchi 
707*7687d0d8SRobert Mustacchi 			switch (type) {
708*7687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_MEM:
709*7687d0d8SRobert Mustacchi 				locstr = "32-bit";
710*7687d0d8SRobert Mustacchi 				break;
711*7687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_LOW:
712*7687d0d8SRobert Mustacchi 				locstr = "Sub-1 MiB";
713*7687d0d8SRobert Mustacchi 				break;
714*7687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_ALL:
715*7687d0d8SRobert Mustacchi 				locstr = "64-bit";
716*7687d0d8SRobert Mustacchi 				break;
717*7687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_RES:
718*7687d0d8SRobert Mustacchi 			default:
719*7687d0d8SRobert Mustacchi 				locstr = "Reserved";
720*7687d0d8SRobert Mustacchi 				break;
721*7687d0d8SRobert Mustacchi 			}
722*7687d0d8SRobert Mustacchi 
723*7687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
724*7687d0d8SRobert Mustacchi 			    "%s (0x%x)\n", locstr, type >> 1);
725*7687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "prefetch", "Prefetchable",
726*7687d0d8SRobert Mustacchi 			    pre != 0, "%s (0x%x)\n", pre != 0 ? "yes" : "no",
727*7687d0d8SRobert Mustacchi 			    pre != 0);
728*7687d0d8SRobert Mustacchi 		}
729*7687d0d8SRobert Mustacchi 
730*7687d0d8SRobert Mustacchi 		pcieadm_deindent();
731*7687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(walkp);
732*7687d0d8SRobert Mustacchi 	}
733*7687d0d8SRobert Mustacchi }
734*7687d0d8SRobert Mustacchi 
735*7687d0d8SRobert Mustacchi static void
736*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_ecv(pcieadm_cfgspace_walk_t *walkp,
737*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
738*7687d0d8SRobert Mustacchi {
739*7687d0d8SRobert Mustacchi 	uint16_t bitlen, nwords;
740*7687d0d8SRobert Mustacchi 
741*7687d0d8SRobert Mustacchi 	if (BITX(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 5, 5) == 0) {
742*7687d0d8SRobert Mustacchi 		return;
743*7687d0d8SRobert Mustacchi 	}
744*7687d0d8SRobert Mustacchi 
745*7687d0d8SRobert Mustacchi 	bitlen = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 5];
746*7687d0d8SRobert Mustacchi 	if (bitlen == 0) {
747*7687d0d8SRobert Mustacchi 		bitlen = 256;
748*7687d0d8SRobert Mustacchi 	}
749*7687d0d8SRobert Mustacchi 
750*7687d0d8SRobert Mustacchi 	nwords = bitlen / 32;
751*7687d0d8SRobert Mustacchi 	if ((bitlen % 8) != 0) {
752*7687d0d8SRobert Mustacchi 		nwords++;
753*7687d0d8SRobert Mustacchi 	}
754*7687d0d8SRobert Mustacchi 
755*7687d0d8SRobert Mustacchi 	for (uint16_t i = 0; i < nwords; i++) {
756*7687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
757*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
758*7687d0d8SRobert Mustacchi 
759*7687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "ecv%u", i);
760*7687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "Egress Control "
761*7687d0d8SRobert Mustacchi 		    "Vector %u", i);
762*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
763*7687d0d8SRobert Mustacchi 		p.pcp_len = 4;
764*7687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
765*7687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
766*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
767*7687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
768*7687d0d8SRobert Mustacchi 
769*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
770*7687d0d8SRobert Mustacchi 	}
771*7687d0d8SRobert Mustacchi }
772*7687d0d8SRobert Mustacchi 
773*7687d0d8SRobert Mustacchi static void
774*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpa_paa(pcieadm_cfgspace_walk_t *walkp,
775*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
776*7687d0d8SRobert Mustacchi {
777*7687d0d8SRobert Mustacchi 	uint8_t nents;
778*7687d0d8SRobert Mustacchi 
779*7687d0d8SRobert Mustacchi 	nents = BITX(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 4, 0) + 1;
780*7687d0d8SRobert Mustacchi 	if (nents == 0) {
781*7687d0d8SRobert Mustacchi 		return;
782*7687d0d8SRobert Mustacchi 	}
783*7687d0d8SRobert Mustacchi 
784*7687d0d8SRobert Mustacchi 	for (uint8_t i = 0; i < nents; i++) {
785*7687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
786*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
787*7687d0d8SRobert Mustacchi 
788*7687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "%s%u",
789*7687d0d8SRobert Mustacchi 		    print->pcp_short, i);
790*7687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "%s %u",
791*7687d0d8SRobert Mustacchi 		    print->pcp_human, i);
792*7687d0d8SRobert Mustacchi 
793*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i;
794*7687d0d8SRobert Mustacchi 		p.pcp_len = 1;
795*7687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
796*7687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
797*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
798*7687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
799*7687d0d8SRobert Mustacchi 
800*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
801*7687d0d8SRobert Mustacchi 	}
802*7687d0d8SRobert Mustacchi }
803*7687d0d8SRobert Mustacchi 
804*7687d0d8SRobert Mustacchi /*
805*7687d0d8SRobert Mustacchi  * Config Space Header Table Definitions
806*7687d0d8SRobert Mustacchi  */
807*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_command[] = {
808*7687d0d8SRobert Mustacchi 	{ 0, 0, "io", "I/O Space", PRDV_STRVAL,
809*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
810*7687d0d8SRobert Mustacchi 	{ 1, 1, "mem", "Memory Space", PRDV_STRVAL,
811*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
812*7687d0d8SRobert Mustacchi 	{ 2, 2, "bus", "Bus Master", PRDV_STRVAL,
813*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
814*7687d0d8SRobert Mustacchi 	{ 3, 3, "spec", "Special Cycle", PRDV_STRVAL,
815*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
816*7687d0d8SRobert Mustacchi 	{ 4, 4, "mwi", "Memory Write and Invalidate", PRDV_STRVAL,
817*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
818*7687d0d8SRobert Mustacchi 	{ 5, 5, "vga", "VGA Palette Snoop", PRDV_STRVAL,
819*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
820*7687d0d8SRobert Mustacchi 	{ 6, 6, "per", "Parity Error Response", PRDV_STRVAL,
821*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
822*7687d0d8SRobert Mustacchi 	{ 7, 7, "idsel", "IDSEL Stepping/Wait Cycle Control", PRDV_STRVAL,
823*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
824*7687d0d8SRobert Mustacchi 	{ 8, 8, "serr", "SERR# Enable", PRDV_STRVAL,
825*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } }, },
826*7687d0d8SRobert Mustacchi 	{ 9, 9, "fbtx", "Fast Back-to-Back Transactions", PRDV_STRVAL,
827*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } }, },
828*7687d0d8SRobert Mustacchi 	{ 10, 10, "intx", "Interrupt X", PRDV_STRVAL,
829*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
830*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
831*7687d0d8SRobert Mustacchi };
832*7687d0d8SRobert Mustacchi 
833*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_status[] = {
834*7687d0d8SRobert Mustacchi 	{ 0, 0, "imm", "Immediate Readiness", PRDV_STRVAL,
835*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
836*7687d0d8SRobert Mustacchi 	{ 3, 3, "istat", "Interrupt Status", PRDV_STRVAL,
837*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not pending", "pending" } }, },
838*7687d0d8SRobert Mustacchi 	{ 4, 4, "capsup", "Capabilities List", PRDV_STRVAL,
839*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
840*7687d0d8SRobert Mustacchi 	{ 5, 5, "66mhz", "66 MHz Capable", PRDV_STRVAL,
841*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
842*7687d0d8SRobert Mustacchi 	{ 7, 7, "fbtxcap", "Fast Back-to-Back Capable", PRDV_STRVAL,
843*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
844*7687d0d8SRobert Mustacchi 	{ 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL,
845*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } }, },
846*7687d0d8SRobert Mustacchi 	{ 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL,
847*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "fast", "medium", "slow",
848*7687d0d8SRobert Mustacchi 	    "reserved" } } },
849*7687d0d8SRobert Mustacchi 	{ 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL,
850*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
851*7687d0d8SRobert Mustacchi 	{ 12, 12, "rta", "Received Target Abort", PRDV_STRVAL,
852*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
853*7687d0d8SRobert Mustacchi 	{ 13, 13, "rma", "Received Master Abort", PRDV_STRVAL,
854*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
855*7687d0d8SRobert Mustacchi 	{ 14, 14, "sse", "Signaled System Error", PRDV_STRVAL,
856*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
857*7687d0d8SRobert Mustacchi 	{ 15, 15, "dpe", "Detected Parity Error", PRDV_STRVAL,
858*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
859*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
860*7687d0d8SRobert Mustacchi };
861*7687d0d8SRobert Mustacchi 
862*7687d0d8SRobert Mustacchi /*
863*7687d0d8SRobert Mustacchi  * It might be interesting to translate these into numbers at a future point.
864*7687d0d8SRobert Mustacchi  */
865*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_class[] = {
866*7687d0d8SRobert Mustacchi 	{ 16, 23, "class", "Class Code", PRDV_HEX },
867*7687d0d8SRobert Mustacchi 	{ 7, 15, "sclass", "Sub-Class Code", PRDV_HEX },
868*7687d0d8SRobert Mustacchi 	{ 0, 7, "pi", "Programming Interface", PRDV_HEX },
869*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
870*7687d0d8SRobert Mustacchi };
871*7687d0d8SRobert Mustacchi 
872*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_iobase[] = {
873*7687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
874*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } },
875*7687d0d8SRobert Mustacchi 	{ 4, 7, "base", "Base", PRDV_HEX,
876*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12 } } },
877*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
878*7687d0d8SRobert Mustacchi };
879*7687d0d8SRobert Mustacchi 
880*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_iolim[] = {
881*7687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
882*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } },
883*7687d0d8SRobert Mustacchi 	{ 4, 7, "limit", "Limit", PRDV_HEX,
884*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12, 0xfff } } },
885*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
886*7687d0d8SRobert Mustacchi };
887*7687d0d8SRobert Mustacchi 
888*7687d0d8SRobert Mustacchi 
889*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridgests[] = {
890*7687d0d8SRobert Mustacchi 	{ 5, 5, "66mhz", "66 MHz", PRDV_STRVAL,
891*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
892*7687d0d8SRobert Mustacchi 	{ 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL,
893*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
894*7687d0d8SRobert Mustacchi 	{ 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL,
895*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } } },
896*7687d0d8SRobert Mustacchi 	{ 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL,
897*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "fast", "medium", "slow" } } },
898*7687d0d8SRobert Mustacchi 	{ 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL,
899*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
900*7687d0d8SRobert Mustacchi 	{ 12, 12, "rta", "Received Target Abort", PRDV_STRVAL,
901*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
902*7687d0d8SRobert Mustacchi 	{ 13, 13, "rma", "Received Master Abort", PRDV_STRVAL,
903*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
904*7687d0d8SRobert Mustacchi 	{ 14, 14, "rsyserr", "Received System Error", PRDV_STRVAL,
905*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error received" } } },
906*7687d0d8SRobert Mustacchi 	{ 15, 15, "dperr", "Detected Parity Error", PRDV_STRVAL,
907*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } } },
908*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
909*7687d0d8SRobert Mustacchi };
910*7687d0d8SRobert Mustacchi 
911*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_membase[] = {
912*7687d0d8SRobert Mustacchi 	{ 4, 16, "base", "Base", PRDV_HEX,
913*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20 } } },
914*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
915*7687d0d8SRobert Mustacchi };
916*7687d0d8SRobert Mustacchi 
917*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_memlim[] = {
918*7687d0d8SRobert Mustacchi 	{ 4, 16, "limit", "Limit", PRDV_HEX,
919*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20, 0xfffff } } },
920*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
921*7687d0d8SRobert Mustacchi };
922*7687d0d8SRobert Mustacchi 
923*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_pfbase[] = {
924*7687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
925*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } },
926*7687d0d8SRobert Mustacchi 	{ 4, 16, "base", "Base", PRDV_HEX,
927*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20 } } },
928*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
929*7687d0d8SRobert Mustacchi };
930*7687d0d8SRobert Mustacchi 
931*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_pflim[] = {
932*7687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
933*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } },
934*7687d0d8SRobert Mustacchi 	{ 4, 16, "limit", "Limit", PRDV_HEX,
935*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20, 0xfffff } } },
936*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
937*7687d0d8SRobert Mustacchi };
938*7687d0d8SRobert Mustacchi 
939*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_ctl[] = {
940*7687d0d8SRobert Mustacchi 	{ 0, 0, "perrresp", "Parity Error Response", PRDV_STRVAL,
941*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
942*7687d0d8SRobert Mustacchi 	{ 1, 1, "serr", "SERR#", PRDV_STRVAL,
943*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
944*7687d0d8SRobert Mustacchi 	{ 2, 2, "isa", "ISA", PRDV_STRVAL,
945*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
946*7687d0d8SRobert Mustacchi 	{ 3, 3, "vga", "VGA", PRDV_STRVAL,
947*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
948*7687d0d8SRobert Mustacchi 	{ 4, 4, "vgadec", "VGA 16-bit Decode", PRDV_STRVAL,
949*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "10-bit", "16-bit" } } },
950*7687d0d8SRobert Mustacchi 	{ 5, 5, "mabort", "Master Abort", PRDV_STRVAL,
951*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
952*7687d0d8SRobert Mustacchi 	{ 6, 6, "secrst", "Secondary Bus Reset", PRDV_HEX },
953*7687d0d8SRobert Mustacchi 	{ 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL,
954*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
955*7687d0d8SRobert Mustacchi 	{ 8, 8, "pridisc", "Primary Discard Timer", PRDV_STRVAL,
956*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } },
957*7687d0d8SRobert Mustacchi 	{ 9, 9, "secdisc", "Secondary Discard Timer", PRDV_STRVAL,
958*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } },
959*7687d0d8SRobert Mustacchi 	{ 10, 10, "disctimer", "Discard Timer Error", PRDV_STRVAL,
960*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
961*7687d0d8SRobert Mustacchi 	{ 11, 11, "discserr", "Discard Timer SERR#", PRDV_STRVAL,
962*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
963*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
964*7687d0d8SRobert Mustacchi };
965*7687d0d8SRobert Mustacchi 
966*7687d0d8SRobert Mustacchi static pcieadm_unitdef_t pcieadm_unitdef_cache = {
967*7687d0d8SRobert Mustacchi 	"byte", 4
968*7687d0d8SRobert Mustacchi };
969*7687d0d8SRobert Mustacchi 
970*7687d0d8SRobert Mustacchi static pcieadm_unitdef_t pcieadm_unitdef_latreg = { "cycle" };
971*7687d0d8SRobert Mustacchi 
972*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_header[] = {
973*7687d0d8SRobert Mustacchi 	{ 0, 6, "layout", "Header Layout", PRDV_STRVAL,
974*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Device", "Bridge", "PC Card" } } },
975*7687d0d8SRobert Mustacchi 	{ 7, 7, "mfd", "Multi-Function Device", PRDV_STRVAL,
976*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
977*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
978*7687d0d8SRobert Mustacchi };
979*7687d0d8SRobert Mustacchi 
980*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bist[] = {
981*7687d0d8SRobert Mustacchi 	{ 0, 3, "code", "Completion Code", PRDV_HEX },
982*7687d0d8SRobert Mustacchi 	{ 6, 6, "start", "Start BIST", PRDV_HEX },
983*7687d0d8SRobert Mustacchi 	{ 7, 7, "cap", "BIST Capable", PRDV_STRVAL,
984*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
985*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
986*7687d0d8SRobert Mustacchi };
987*7687d0d8SRobert Mustacchi 
988*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_exprom[] = {
989*7687d0d8SRobert Mustacchi 	{ 0, 0, "enable", "Enable", PRDV_STRVAL,
990*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
991*7687d0d8SRobert Mustacchi 	{ 11, 31, "addr", "Base Address", PRDV_HEX,
992*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 21 } } },
993*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
994*7687d0d8SRobert Mustacchi };
995*7687d0d8SRobert Mustacchi 
996*7687d0d8SRobert Mustacchi static pcieadm_strmap_t pcieadm_strmap_ipin[] = {
997*7687d0d8SRobert Mustacchi 	{ "none", 0 },
998*7687d0d8SRobert Mustacchi 	{ "INTA", PCI_INTA },
999*7687d0d8SRobert Mustacchi 	{ "INTB", PCI_INTB },
1000*7687d0d8SRobert Mustacchi 	{ "INTC", PCI_INTC },
1001*7687d0d8SRobert Mustacchi 	{ "INTD", PCI_INTD },
1002*7687d0d8SRobert Mustacchi 	{ NULL }
1003*7687d0d8SRobert Mustacchi };
1004*7687d0d8SRobert Mustacchi 
1005*7687d0d8SRobert Mustacchi 
1006*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cfgspace_type0[] = {
1007*7687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
1008*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
1009*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef,
1010*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_command },
1011*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef,
1012*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_status },
1013*7687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
1014*7687d0d8SRobert Mustacchi 	{ 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef,
1015*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_class },
1016*7687d0d8SRobert Mustacchi 	{ 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit,
1017*7687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_cache },
1018*7687d0d8SRobert Mustacchi 	{ 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit,
1019*7687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_latreg },
1020*7687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
1021*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
1022*7687d0d8SRobert Mustacchi 	{ 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef,
1023*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_bist },
1024*7687d0d8SRobert Mustacchi 	{ 0x10, 24, "bar", "Base Address Register",
1025*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
1026*7687d0d8SRobert Mustacchi 	{ 0x28, 4, "cis", "Cardbus CIS Pointer", pcieadm_cfgspace_print_hex },
1027*7687d0d8SRobert Mustacchi 	{ 0x2c, 2, "subvid", "Subsystem Vendor ID",
1028*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_subid },
1029*7687d0d8SRobert Mustacchi 	{ 0x2e, 2, "subdev", "Subsystem Device ID",
1030*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_subid },
1031*7687d0d8SRobert Mustacchi 	{ 0x30, 4, "rom", "Expansion ROM", pcieadm_cfgspace_print_regdef,
1032*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_exprom },
1033*7687d0d8SRobert Mustacchi 	{ 0x34, 1, "cap", "Capabilities Pointer", pcieadm_cfgspace_print_hex },
1034*7687d0d8SRobert Mustacchi 	{ 0x3c, 1, "iline", "Interrupt Line", pcieadm_cfgspace_print_hex },
1035*7687d0d8SRobert Mustacchi 	{ 0x3d, 1, "ipin", "Interrupt Pin", pcieadm_cfgspace_print_strmap,
1036*7687d0d8SRobert Mustacchi 	    pcieadm_strmap_ipin },
1037*7687d0d8SRobert Mustacchi 	{ 0x3e, 1, "gnt", "Min_Gnt", pcieadm_cfgspace_print_hex },
1038*7687d0d8SRobert Mustacchi 	{ 0x3f, 1, "lat", "Min_Lat", pcieadm_cfgspace_print_hex },
1039*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1040*7687d0d8SRobert Mustacchi };
1041*7687d0d8SRobert Mustacchi 
1042*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cfgspace_type1[] = {
1043*7687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
1044*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
1045*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef,
1046*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_command },
1047*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef,
1048*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_status },
1049*7687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
1050*7687d0d8SRobert Mustacchi 	{ 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef,
1051*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_class },
1052*7687d0d8SRobert Mustacchi 	{ 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit,
1053*7687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_cache },
1054*7687d0d8SRobert Mustacchi 	{ 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit,
1055*7687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_latreg },
1056*7687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
1057*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
1058*7687d0d8SRobert Mustacchi 	{ 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef,
1059*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_bist },
1060*7687d0d8SRobert Mustacchi 	{ 0x10, 8, "bar", "Base Address Register",
1061*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
1062*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_PRIBUS, 1, "pribus", "Primary Bus Number",
1063*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1064*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_SECBUS, 1, "secbus", "Secondary Bus Number",
1065*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1066*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_SUBBUS, 1, "subbus", "Subordinate Bus Number",
1067*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1068*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_LATENCY_TIMER, 1, "latency2", "Secondary Latency timer",
1069*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_unit, &pcieadm_unitdef_latreg },
1070*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_BASE_LOW, 1, "iobase", "I/O Base Low",
1071*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iobase },
1072*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_LIMIT_LOW, 1, "iolimit", "I/O Limit Low",
1073*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iolim },
1074*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_SEC_STATUS, 2, "status2", "Secondary Status",
1075*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridgests },
1076*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_MEM_BASE, 2, "membase", "Memory Base",
1077*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_membase },
1078*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_MEM_LIMIT, 2, "memlimit", "Memory Limit",
1079*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_memlim },
1080*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_BASE_LOW, 2, "pfbase", "Prefetchable Memory Base",
1081*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pfbase },
1082*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_LIMIT_LOW, 2, "pflimit", "Prefetchable Memory Limit",
1083*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pflim },
1084*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_BASE_HIGH, 4, "pfbasehi",
1085*7687d0d8SRobert Mustacchi 	    "Prefetchable Base Upper 32 bits",
1086*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1087*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_LIMIT_HIGH, 4, "pflimihi",
1088*7687d0d8SRobert Mustacchi 	    "Prefetchable Limit Upper 32 bits",
1089*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1090*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_BASE_HI, 2, "iobasehi", "I/O Base Upper 16 bits",
1091*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1092*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_LIMIT_HI, 2, "iobasehi", "I/O Limit Upper 16 bits",
1093*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1094*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_CAP_PTR, 1, "cap", "Capabilities Pointer",
1095*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1096*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_ROM, 4, "rom", "Expansion ROM",
1097*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_exprom },
1098*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_ILINE, 1, "iline", "Interrupt Line",
1099*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1100*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_IPIN, 1, "ipin", "Interrupt Pin",
1101*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_strmap, pcieadm_strmap_ipin },
1102*7687d0d8SRobert Mustacchi 	{ PCI_BCNF_BCNTRL, 2, "bctl", "Bridge Control",
1103*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_ctl },
1104*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1105*7687d0d8SRobert Mustacchi };
1106*7687d0d8SRobert Mustacchi 
1107*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cfgspace_unknown[] = {
1108*7687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
1109*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
1110*7687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
1111*7687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
1112*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
1113*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1114*7687d0d8SRobert Mustacchi };
1115*7687d0d8SRobert Mustacchi 
1116*7687d0d8SRobert Mustacchi /*
1117*7687d0d8SRobert Mustacchi  * Power Management Capability Version 3. Note versions two and three seem to be
1118*7687d0d8SRobert Mustacchi  * the same, but are used to indicate compliance to different revisions of the
1119*7687d0d8SRobert Mustacchi  * PCI power management specification.
1120*7687d0d8SRobert Mustacchi  */
1121*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pmcap[] = {
1122*7687d0d8SRobert Mustacchi 	{ 0, 2, "vers", "Version", PRDV_HEX },
1123*7687d0d8SRobert Mustacchi 	{ 3, 3, "clock", "PME Clock", PRDV_STRVAL,
1124*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
1125*7687d0d8SRobert Mustacchi 	{ 4, 4, "irrd0", "Immediate Readiness on Return to D0", PRDV_STRVAL,
1126*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1127*7687d0d8SRobert Mustacchi 	{ 5, 5, "dsi", "Device Specific Initialization", PRDV_STRVAL,
1128*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1129*7687d0d8SRobert Mustacchi 	{ 6, 8, "auxcur", "Auxiliary Current", PRDV_STRVAL,
1130*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "0", "55 mA", "100 mA", "160 mA",
1131*7687d0d8SRobert Mustacchi 	    "220 mA", "270 mA", "320 mA", "375 mA" } } },
1132*7687d0d8SRobert Mustacchi 	{ 9, 9, "d1", "D1", PRDV_STRVAL,
1133*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1134*7687d0d8SRobert Mustacchi 	{ 10, 10, "d2", "D2", PRDV_STRVAL,
1135*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1136*7687d0d8SRobert Mustacchi 	{ 11, 15, "pme", "PME Support", PRDV_BITFIELD,
1137*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "D0", "D1", "D2", "D3hot",
1138*7687d0d8SRobert Mustacchi 	    "D3cold" } } },
1139*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1140*7687d0d8SRobert Mustacchi };
1141*7687d0d8SRobert Mustacchi 
1142*7687d0d8SRobert Mustacchi 
1143*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcipm_v3[] = {
1144*7687d0d8SRobert Mustacchi 	{ PCI_PMCAP, 2, "pmcap", "Power Management Capabilities",
1145*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pmcap },
1146*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1147*7687d0d8SRobert Mustacchi };
1148*7687d0d8SRobert Mustacchi 
1149*7687d0d8SRobert Mustacchi /*
1150*7687d0d8SRobert Mustacchi  * PCI Bridge Subsystem Capability
1151*7687d0d8SRobert Mustacchi  */
1152*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_bridge_subsys[] = {
1153*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "subvid", "Subsystem Vendor ID", pcieadm_cfgspace_print_hex },
1154*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "subdev", "Subsystem Device ID", pcieadm_cfgspace_print_hex },
1155*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1156*7687d0d8SRobert Mustacchi };
1157*7687d0d8SRobert Mustacchi 
1158*7687d0d8SRobert Mustacchi /*
1159*7687d0d8SRobert Mustacchi  * MSI Capability
1160*7687d0d8SRobert Mustacchi  */
1161*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msictrl[] = {
1162*7687d0d8SRobert Mustacchi 	{ 0, 0, "enable", "MSI Enable", PRDV_STRVAL,
1163*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1164*7687d0d8SRobert Mustacchi 	{ 1, 3, "mmsgcap", "Multiple Message Capable", PRDV_STRVAL,
1165*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 vector", "2 vectors",
1166*7687d0d8SRobert Mustacchi 	    "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } },
1167*7687d0d8SRobert Mustacchi 	{ 4, 6, "mmsgen", "Multiple Message Enabled", PRDV_STRVAL,
1168*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 vector", "2 vectors",
1169*7687d0d8SRobert Mustacchi 	    "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } },
1170*7687d0d8SRobert Mustacchi 	{ 7, 7, "addr64", "64-bit Address Capable", PRDV_STRVAL,
1171*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1172*7687d0d8SRobert Mustacchi 	{ 8, 8, "pvm", "Per-Vector Masking Capable", PRDV_STRVAL,
1173*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1174*7687d0d8SRobert Mustacchi 	{ 9, 9, "extmdcap", "Extended Message Data Capable",
1175*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1176*7687d0d8SRobert Mustacchi 	{ 10, 10, "extmden", "extended Message Data Enable",
1177*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1178*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1179*7687d0d8SRobert Mustacchi };
1180*7687d0d8SRobert Mustacchi 
1181*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_32[] = {
1182*7687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
1183*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
1184*7687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
1185*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1186*7687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
1187*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1188*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1189*7687d0d8SRobert Mustacchi };
1190*7687d0d8SRobert Mustacchi 
1191*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_32ext[] = {
1192*7687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
1193*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
1194*7687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
1195*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1196*7687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
1197*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1198*7687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data",
1199*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1200*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1201*7687d0d8SRobert Mustacchi };
1202*7687d0d8SRobert Mustacchi 
1203*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_32pvm[] = {
1204*7687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
1205*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
1206*7687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
1207*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1208*7687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
1209*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1210*7687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data",
1211*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1212*7687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_MASK, 4, "mask", "Mask Bits",
1213*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1214*7687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_PENDING, 4, "pend", "Pending Bits",
1215*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1216*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1217*7687d0d8SRobert Mustacchi };
1218*7687d0d8SRobert Mustacchi 
1219*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_64[] = {
1220*7687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
1221*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
1222*7687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
1223*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1224*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
1225*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1226*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
1227*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1228*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1229*7687d0d8SRobert Mustacchi };
1230*7687d0d8SRobert Mustacchi 
1231*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_64ext[] = {
1232*7687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
1233*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
1234*7687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
1235*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1236*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
1237*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1238*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
1239*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1240*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data",
1241*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1242*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1243*7687d0d8SRobert Mustacchi };
1244*7687d0d8SRobert Mustacchi 
1245*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_64pvm[] = {
1246*7687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
1247*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
1248*7687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
1249*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1250*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
1251*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1252*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
1253*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1254*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data",
1255*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1256*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_MASKBITS, 4, "mask", "Mask Bits",
1257*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1258*7687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_PENDING, 4, "pend", "Pending Bits",
1259*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
1260*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1261*7687d0d8SRobert Mustacchi };
1262*7687d0d8SRobert Mustacchi 
1263*7687d0d8SRobert Mustacchi /*
1264*7687d0d8SRobert Mustacchi  * MSI-X Capability
1265*7687d0d8SRobert Mustacchi  */
1266*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msixctrl[] = {
1267*7687d0d8SRobert Mustacchi 	{ 0, 10, "size", "Table Size", PRDV_HEX,
1268*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
1269*7687d0d8SRobert Mustacchi 	{ 14, 14, "mask", "Function Mask", PRDV_STRVAL,
1270*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unmasked", "masked" } } },
1271*7687d0d8SRobert Mustacchi 	{ 15, 15, "enable", "MSI-X Enable", PRDV_STRVAL,
1272*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1273*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1274*7687d0d8SRobert Mustacchi };
1275*7687d0d8SRobert Mustacchi 
1276*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msixtable[] = {
1277*7687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "Table BIR", PRDV_STRVAL,
1278*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
1279*7687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
1280*7687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "Table Offset", PRDV_HEX,
1281*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
1282*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1283*7687d0d8SRobert Mustacchi };
1284*7687d0d8SRobert Mustacchi 
1285*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msixpba[] = {
1286*7687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "PBA BIR", PRDV_STRVAL,
1287*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
1288*7687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
1289*7687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "PBA Offset", PRDV_HEX,
1290*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
1291*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1292*7687d0d8SRobert Mustacchi };
1293*7687d0d8SRobert Mustacchi 
1294*7687d0d8SRobert Mustacchi 
1295*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msix[] = {
1296*7687d0d8SRobert Mustacchi 	{ PCI_MSIX_CTRL, 2, "ctrl", "Control Register",
1297*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixctrl },
1298*7687d0d8SRobert Mustacchi 	{ PCI_MSIX_TBL_OFFSET, 4, "table", "Table Offset",
1299*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixtable },
1300*7687d0d8SRobert Mustacchi 	{ PCI_MSIX_PBA_OFFSET, 4, "pba", "PBA Offset",
1301*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixpba },
1302*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1303*7687d0d8SRobert Mustacchi };
1304*7687d0d8SRobert Mustacchi 
1305*7687d0d8SRobert Mustacchi /*
1306*7687d0d8SRobert Mustacchi  * PCI Express Capability
1307*7687d0d8SRobert Mustacchi  */
1308*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_cap[] = {
1309*7687d0d8SRobert Mustacchi 	{ 0, 3, "vers", "Version", PRDV_HEX },
1310*7687d0d8SRobert Mustacchi 	{ 4, 7, "type", "Device/Port Type", PRDV_STRVAL,
1311*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PCIe Endpoint",
1312*7687d0d8SRobert Mustacchi 	    "Legacy PCIe Endpoint", NULL, NULL,
1313*7687d0d8SRobert Mustacchi 	    "Root Port of PCIe Root Complex",
1314*7687d0d8SRobert Mustacchi 	    "Upstream Port of PCIe Switch",
1315*7687d0d8SRobert Mustacchi 	    "Downstream Port of PCIe Switch",
1316*7687d0d8SRobert Mustacchi 	    "PCIe to PCI/PCI-X Bridge",
1317*7687d0d8SRobert Mustacchi 	    "PCI/PCI-x to PCIe Bridge",
1318*7687d0d8SRobert Mustacchi 	    "RCiEP",
1319*7687d0d8SRobert Mustacchi 	    "Root Complex Event Collector" } } },
1320*7687d0d8SRobert Mustacchi 	{ 8, 8, "slot", "Slot Implemented", PRDV_STRVAL,
1321*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No", "Yes" } } },
1322*7687d0d8SRobert Mustacchi 	{ 9, 13, "intno", "Interrupt Message Number", PRDV_HEX },
1323*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1324*7687d0d8SRobert Mustacchi };
1325*7687d0d8SRobert Mustacchi 
1326*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devcap[] = {
1327*7687d0d8SRobert Mustacchi 	{ 0, 2, "mps", "Max Payload Size Supported", PRDV_STRVAL,
1328*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
1329*7687d0d8SRobert Mustacchi 	    "512 bytes", "1024 byes", "2048 bytes", "4096 bytes" } } },
1330*7687d0d8SRobert Mustacchi 	{ 3, 4, "pfunc", "Phantom Functions Supported", PRDV_STRVAL,
1331*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No", "1-bit", "2-bits",
1332*7687d0d8SRobert Mustacchi 	    "3-bits" } } },
1333*7687d0d8SRobert Mustacchi 	{ 5, 5, "exttag", "Extended Tag Field", PRDV_STRVAL,
1334*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "5-bit", "8-bit" } } },
1335*7687d0d8SRobert Mustacchi 	{ 6, 8, "l0slat", "L0s Acceptable Latency", PRDV_STRVAL,
1336*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "64 ns", "128 ns", "256 ns",
1337*7687d0d8SRobert Mustacchi 	    "512 ns", "1 us", "2 us", "4 us", "No limit" } } },
1338*7687d0d8SRobert Mustacchi 	{ 9, 11, "l1lat", "L1 Acceptable Latency", PRDV_STRVAL,
1339*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 us", "2 us", "4 us", "8 us",
1340*7687d0d8SRobert Mustacchi 	    "16 us", "32 us", "64 us", "No limit" } } },
1341*7687d0d8SRobert Mustacchi 	{ 15, 15, "rber", "Role Based Error Reporting", PRDV_STRVAL,
1342*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1343*7687d0d8SRobert Mustacchi 	{ 16, 16, "errcor", "ERR_COR Subclass", PRDV_STRVAL,
1344*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1345*7687d0d8SRobert Mustacchi 	{ 18, 25, "csplv", "Captured Slot Power Limit", PRDV_HEX },
1346*7687d0d8SRobert Mustacchi 	{ 26, 27, "cspls", "Captured Slot Power Limit Scale", PRDV_STRVAL,
1347*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1.0x", "0.1x", "0.01x",
1348*7687d0d8SRobert Mustacchi 	    "0.001x" } } },
1349*7687d0d8SRobert Mustacchi 	{ 28, 28, "flr", "Function Level Reset", PRDV_STRVAL,
1350*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1351*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1352*7687d0d8SRobert Mustacchi };
1353*7687d0d8SRobert Mustacchi 
1354*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devctl[] = {
1355*7687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL,
1356*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1357*7687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL,
1358*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1359*7687d0d8SRobert Mustacchi 	{ 2, 2, "ferr", "Fatal Error Reporting", PRDV_STRVAL,
1360*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1361*7687d0d8SRobert Mustacchi 	{ 3, 3, "unsupreq", "Unsupported Request Reporting", PRDV_STRVAL,
1362*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1363*7687d0d8SRobert Mustacchi 	{ 4, 4, "relord", "Relaxed Ordering", PRDV_STRVAL,
1364*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1365*7687d0d8SRobert Mustacchi 	{ 5, 7, "mps", "Max Payload Size", PRDV_STRVAL,
1366*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
1367*7687d0d8SRobert Mustacchi 	    "512 bytes", "1024 byes", "2048 bytes", "4096 bytes" } } },
1368*7687d0d8SRobert Mustacchi 	{ 8, 8, "exttag", "Extended Tag Field", PRDV_STRVAL,
1369*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1370*7687d0d8SRobert Mustacchi 	{ 9, 9, "pfunc", "Phantom Functions", PRDV_STRVAL,
1371*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1372*7687d0d8SRobert Mustacchi 	{ 9, 9, "auxpm", "Aux Power PM", PRDV_STRVAL,
1373*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1374*7687d0d8SRobert Mustacchi 	{ 11, 11, "nosnoop", "No Snoop", PRDV_STRVAL,
1375*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1376*7687d0d8SRobert Mustacchi 	{ 12, 14, "mrrs", "Max Read Request Size", PRDV_STRVAL,
1377*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
1378*7687d0d8SRobert Mustacchi 	    "512 bytes", "1024 byes", "2048 bytes", "4096 bytes" } } },
1379*7687d0d8SRobert Mustacchi 	{ 15, 15, "bcrflr", "Bridge Configuration Retry / Function Level Reset",
1380*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
1381*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1382*7687d0d8SRobert Mustacchi };
1383*7687d0d8SRobert Mustacchi 
1384*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devsts[] = {
1385*7687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Detected", PRDV_STRVAL,
1386*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1387*7687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Detected", PRDV_STRVAL,
1388*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1389*7687d0d8SRobert Mustacchi 	{ 2, 2, "ferr", "Fatal Error Detected", PRDV_STRVAL,
1390*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1391*7687d0d8SRobert Mustacchi 	{ 3, 3, "unsupreq", "Unsupported Request Detected", PRDV_STRVAL,
1392*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1393*7687d0d8SRobert Mustacchi 	{ 4, 4, "auxpm", "AUX Power Detected", PRDV_STRVAL,
1394*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1395*7687d0d8SRobert Mustacchi 	{ 5, 5, "txpend", "Transactions Pending", PRDV_STRVAL,
1396*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1397*7687d0d8SRobert Mustacchi 	{ 6, 6, "eprd", "Emergency Power Reduction Detected", PRDV_STRVAL,
1398*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1399*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1400*7687d0d8SRobert Mustacchi };
1401*7687d0d8SRobert Mustacchi 
1402*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkcap[] = {
1403*7687d0d8SRobert Mustacchi 	{ 0, 3, "maxspeed", "Maximum Link Speed", PRDV_STRVAL,
1404*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
1405*7687d0d8SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s" } } },
1406*7687d0d8SRobert Mustacchi 	{ 4, 9, "maxwidth", "Maximum Link Width", PRDV_HEX },
1407*7687d0d8SRobert Mustacchi 	{ 10, 11, "aspm", "ASPM Support", PRDV_STRVAL,
1408*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } },
1409*7687d0d8SRobert Mustacchi 	{ 12, 14, "l0slat", "L0s Exit Latency", PRDV_STRVAL,
1410*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "<64ns", "64-128ns", "128-256ns",
1411*7687d0d8SRobert Mustacchi 	    "256-512ns", "512ns-1us", "1-2us", "2-4us", ">4us" } } },
1412*7687d0d8SRobert Mustacchi 	{ 15, 17, "l1lat", "L1 Exit Latency", PRDV_STRVAL,
1413*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "<1us", "1-2us", "2-4us", "4-8us",
1414*7687d0d8SRobert Mustacchi 	    "8-16us", "16-32us" "32-64us", ">64us" } } },
1415*7687d0d8SRobert Mustacchi 	{ 18, 18, "clockpm", "Clock Power Management", PRDV_STRVAL,
1416*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1417*7687d0d8SRobert Mustacchi 	{ 19, 19, "supdown", "Surprise Down Error Reporting", PRDV_STRVAL,
1418*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1419*7687d0d8SRobert Mustacchi 	{ 20, 20, "dlact", "Data Link Layer Active Reporting", PRDV_STRVAL,
1420*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1421*7687d0d8SRobert Mustacchi 	{ 21, 21, "linkbw", "Link Bandwidth Notification Capability",
1422*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
1423*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1424*7687d0d8SRobert Mustacchi 	{ 22, 22, "aspmcomp", "ASPM Optionality Compliance", PRDV_STRVAL,
1425*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not compliant", "compliant" } } },
1426*7687d0d8SRobert Mustacchi 	{ 24, 31, "portno", "Port Number", PRDV_HEX },
1427*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1428*7687d0d8SRobert Mustacchi };
1429*7687d0d8SRobert Mustacchi 
1430*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkctl[] = {
1431*7687d0d8SRobert Mustacchi 	{ 0, 1, "aspmctl", "ASPM Control", PRDV_STRVAL,
1432*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } },
1433*7687d0d8SRobert Mustacchi 	{ 3, 3, "rcb", "Read Completion Boundary", PRDV_STRVAL,
1434*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "64 byte", "128 byte" } } },
1435*7687d0d8SRobert Mustacchi 	{ 4, 4, "disable", "Link Disable", PRDV_STRVAL,
1436*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not force disabled",
1437*7687d0d8SRobert Mustacchi 	    "force disabled" } } },
1438*7687d0d8SRobert Mustacchi 	{ 5, 5, "retrain", "Retrain Link", PRDV_HEX },
1439*7687d0d8SRobert Mustacchi 	{ 6, 6, "ccc", "Common Clock Configuration", PRDV_STRVAL,
1440*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "asynchronous", "common" } } },
1441*7687d0d8SRobert Mustacchi 	{ 7, 7, "extsync", "Extended Sync", PRDV_HEX,
1442*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1443*7687d0d8SRobert Mustacchi 	{ 8, 8, "clkpm", "Clock Power Management", PRDV_HEX,
1444*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1445*7687d0d8SRobert Mustacchi 	{ 9, 9, "hwawd", "Hardware Autonomous Width", PRDV_HEX,
1446*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
1447*7687d0d8SRobert Mustacchi 	{ 10, 10, "linkbwint", "Link Bandwidth Management Interrupt", PRDV_HEX,
1448*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1449*7687d0d8SRobert Mustacchi 	{ 11, 11, "linkabwint", "Link Autonomous Bandwidth Interrupt", PRDV_HEX,
1450*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1451*7687d0d8SRobert Mustacchi 	{ 14, 15, "drs", "DRS Signaling Control", PRDV_HEX,
1452*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not reported", "Interrupt enabled",
1453*7687d0d8SRobert Mustacchi 	    "DRS->FRS enabled" } } },
1454*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1455*7687d0d8SRobert Mustacchi };
1456*7687d0d8SRobert Mustacchi 
1457*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linksts[] = {
1458*7687d0d8SRobert Mustacchi 	{ 0, 3, "speed", "Link Speed", PRDV_STRVAL,
1459*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
1460*7687d0d8SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s" } } },
1461*7687d0d8SRobert Mustacchi 	{ 4, 9, "width", "Link Width", PRDV_HEX },
1462*7687d0d8SRobert Mustacchi 	{ 11, 11, "training", "Link Training", PRDV_STRVAL,
1463*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1464*7687d0d8SRobert Mustacchi 	{ 12, 12, "slotclk", "Slot Clock Configuration", PRDV_STRVAL,
1465*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "asynchronous", "common" } } },
1466*7687d0d8SRobert Mustacchi 	{ 13, 13, "dllact", "Data Link Layer Link Active", PRDV_STRVAL,
1467*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1468*7687d0d8SRobert Mustacchi 	{ 14, 14, "linkbw", "Link Bandwidth Management Status", PRDV_STRVAL,
1469*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no change", "change occurred" } } },
1470*7687d0d8SRobert Mustacchi 	{ 15, 15, "linkabw", "Link Autonomous Bandwidth Status", PRDV_STRVAL,
1471*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no change", "change occurred" } } },
1472*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1473*7687d0d8SRobert Mustacchi };
1474*7687d0d8SRobert Mustacchi 
1475*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotcap[] = {
1476*7687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Present", PRDV_STRVAL,
1477*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1478*7687d0d8SRobert Mustacchi 	{ 1, 1, "pwrctrl", "Power Controller Present", PRDV_STRVAL,
1479*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1480*7687d0d8SRobert Mustacchi 	{ 2, 2, "mrlsen", "MRL Sensor Present", PRDV_STRVAL,
1481*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1482*7687d0d8SRobert Mustacchi 	{ 3, 3, "attnind", "Attention Indicator Present", PRDV_STRVAL,
1483*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1484*7687d0d8SRobert Mustacchi 	{ 4, 4, "powind", "Power Indicator Present", PRDV_STRVAL,
1485*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1486*7687d0d8SRobert Mustacchi 	{ 5, 5, "hpsup", "Hot-Plug Surprise", PRDV_STRVAL,
1487*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1488*7687d0d8SRobert Mustacchi 	{ 6, 6, "hpcap", "Hot-Plug Capable ", PRDV_STRVAL,
1489*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1490*7687d0d8SRobert Mustacchi 	{ 7, 14, "slotplv", "Slot Power Limit Value", PRDV_HEX },
1491*7687d0d8SRobert Mustacchi 	{ 15, 16, "slotpls", "Slot Power Limit Scale", PRDV_HEX },
1492*7687d0d8SRobert Mustacchi 	{ 17, 17, "emi", "Electromechanical Interlock Present",
1493*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1494*7687d0d8SRobert Mustacchi 	{ 18, 18, "ncc", "No Command Completed", PRDV_HEX,
1495*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1496*7687d0d8SRobert Mustacchi 	{ 19, 31, "slotno", "Physical Slot Number", PRDV_HEX },
1497*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1498*7687d0d8SRobert Mustacchi };
1499*7687d0d8SRobert Mustacchi 
1500*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotctl[] = {
1501*7687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Pressed", PRDV_STRVAL,
1502*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1503*7687d0d8SRobert Mustacchi 	{ 1, 1, "powflt", "Power Fault Detected", PRDV_STRVAL,
1504*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1505*7687d0d8SRobert Mustacchi 	{ 2, 2, "mrlsen", "MRL Sensor Changed", PRDV_STRVAL,
1506*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1507*7687d0d8SRobert Mustacchi 	{ 3, 3, "presdet", "Presence Detect Changed", PRDV_STRVAL,
1508*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1509*7687d0d8SRobert Mustacchi 	{ 4, 4, "ccmpltint", "Command Complete Interrupt", PRDV_STRVAL,
1510*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "Enabled" } } },
1511*7687d0d8SRobert Mustacchi 	{ 5, 5, "hpi", "Hot Plug Interrupt Enable", PRDV_STRVAL,
1512*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1513*7687d0d8SRobert Mustacchi 	{ 6, 7, "attnind", "Attention Indicator Control", PRDV_STRVAL,
1514*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } },
1515*7687d0d8SRobert Mustacchi 	{ 8, 9, "powin", "Power Indicator Control", PRDV_STRVAL,
1516*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } },
1517*7687d0d8SRobert Mustacchi 	{ 10, 10, "pwrctrl", "Power Controller Control", PRDV_STRVAL,
1518*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "power on", "power off" } } },
1519*7687d0d8SRobert Mustacchi 	{ 11, 11, "emi", "Electromechanical Interlock Control", PRDV_HEX },
1520*7687d0d8SRobert Mustacchi 	{ 12, 12, "dll", "Data Link Layer State Changed", PRDV_STRVAL,
1521*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1522*7687d0d8SRobert Mustacchi 	{ 13, 13, "autopowdis", "Auto Slot Power Limit", PRDV_STRVAL,
1523*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
1524*7687d0d8SRobert Mustacchi 	{ 14, 14, "ibpddis", "In-Band PD", PRDV_STRVAL,
1525*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
1526*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1527*7687d0d8SRobert Mustacchi };
1528*7687d0d8SRobert Mustacchi 
1529*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotsts[] = {
1530*7687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Pressed", PRDV_STRVAL,
1531*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1532*7687d0d8SRobert Mustacchi 	{ 1, 1, "powflt", "Power Fault Detected", PRDV_STRVAL,
1533*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1534*7687d0d8SRobert Mustacchi 	{ 2, 2, "mrlsen", "MRL Sensor Changed", PRDV_STRVAL,
1535*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1536*7687d0d8SRobert Mustacchi 	{ 3, 3, "presdet", "Presence Detect Changed", PRDV_STRVAL,
1537*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1538*7687d0d8SRobert Mustacchi 	{ 4, 4, "ccmplt", "Command Complete", PRDV_STRVAL,
1539*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1540*7687d0d8SRobert Mustacchi 	{ 5, 5, "mrlsen", "MRL Sensor State", PRDV_STRVAL,
1541*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "closed", "open" } } },
1542*7687d0d8SRobert Mustacchi 	{ 6, 6, "presdet", "Presence Detect State", PRDV_STRVAL,
1543*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not present", "present" } } },
1544*7687d0d8SRobert Mustacchi 	{ 7, 7, "emi", "Electromechanical Interlock", PRDV_STRVAL,
1545*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disengaged", "engaged" } } },
1546*7687d0d8SRobert Mustacchi 	{ 8, 8, "dll", "Data Link Layer State Changed", PRDV_STRVAL,
1547*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1548*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1549*7687d0d8SRobert Mustacchi };
1550*7687d0d8SRobert Mustacchi 
1551*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_rootcap[] = {
1552*7687d0d8SRobert Mustacchi 	{ 0, 0, "syscorerr", "System Error on Correctable Error", PRDV_STRVAL,
1553*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1554*7687d0d8SRobert Mustacchi 	{ 1, 1, "sysnonftl", "System Error on Non-Fatal Error", PRDV_STRVAL,
1555*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1556*7687d0d8SRobert Mustacchi 	{ 2, 2, "sysfatal", "System Error on Fatal Error", PRDV_STRVAL,
1557*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1558*7687d0d8SRobert Mustacchi 	{ 3, 3, "pmeie", "PME Interrupt", PRDV_STRVAL,
1559*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1560*7687d0d8SRobert Mustacchi 	{ 4, 4,  "crssw", "CRS Software Visibility", PRDV_STRVAL,
1561*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1562*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1563*7687d0d8SRobert Mustacchi };
1564*7687d0d8SRobert Mustacchi 
1565*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_rootctl[] = {
1566*7687d0d8SRobert Mustacchi 	{ 0, 0, "crssw", "CRS Software Visibility", PRDV_STRVAL,
1567*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1568*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1569*7687d0d8SRobert Mustacchi };
1570*7687d0d8SRobert Mustacchi 
1571*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_rootsts[] = {
1572*7687d0d8SRobert Mustacchi 	{ 0, 15, "pmereqid", "PME Requester ID", PRDV_HEX },
1573*7687d0d8SRobert Mustacchi 	{ 16, 16, "pmests", "PME Status", PRDV_STRVAL,
1574*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "deasserted", "asserted" } } },
1575*7687d0d8SRobert Mustacchi 	{ 17, 17, "pmepend", "PME Pending", PRDV_STRVAL,
1576*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1577*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1578*7687d0d8SRobert Mustacchi };
1579*7687d0d8SRobert Mustacchi 
1580*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devcap2[] = {
1581*7687d0d8SRobert Mustacchi 	{ 0, 3, "cmpto", "Completion Timeout Ranges Supported", PRDV_BITFIELD,
1582*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "50us-10ms", "10ms-250ms",
1583*7687d0d8SRobert Mustacchi 	    "250ms-4s", "4s-64s" } } },
1584*7687d0d8SRobert Mustacchi 	{ 4, 4, "cmptodis", "Completion Timeout Disable", PRDV_STRVAL,
1585*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1586*7687d0d8SRobert Mustacchi 	{ 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL,
1587*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1588*7687d0d8SRobert Mustacchi 	{ 6, 6, "atomroute", "AtomicOp Routing", PRDV_STRVAL,
1589*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1590*7687d0d8SRobert Mustacchi 	{ 7, 7, "atom32", "32-bit AtomicOp Completer", PRDV_STRVAL,
1591*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1592*7687d0d8SRobert Mustacchi 	{ 8, 8, "atom64", "64-bit AtomicOp Completer", PRDV_STRVAL,
1593*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1594*7687d0d8SRobert Mustacchi 	{ 9, 9, "cas128", "128-bit CAS Completer", PRDV_STRVAL,
1595*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1596*7687d0d8SRobert Mustacchi 	{ 10, 10, "norelord", "No Ro-enabld PR-PR Passing", PRDV_STRVAL,
1597*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1598*7687d0d8SRobert Mustacchi 	{ 11, 11, "ltr", "LTR Mechanism", PRDV_STRVAL,
1599*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1600*7687d0d8SRobert Mustacchi 	{ 12, 13, "tph", "TPH Completer", PRDV_STRVAL,
1601*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "TPH supported",
1602*7687d0d8SRobert Mustacchi 	    NULL, "TPH and Extended TPH supported" } } },
1603*7687d0d8SRobert Mustacchi 	{ 14, 15, "lncls", "LN System CLS", PRDV_STRVAL,
1604*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported",
1605*7687d0d8SRobert Mustacchi 	    "LN with 64-byte cachelines", "LN with 128-byte cachelines" } } },
1606*7687d0d8SRobert Mustacchi 	{ 16, 16, "tag10comp", "10-bit Tag Completer", PRDV_STRVAL,
1607*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1608*7687d0d8SRobert Mustacchi 	{ 17, 17, "tag10req", "10-bit Tag Requester", PRDV_STRVAL,
1609*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1610*7687d0d8SRobert Mustacchi 	{ 18, 19, "obff", "OBFF", PRDV_STRVAL,
1611*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "Message Signaling",
1612*7687d0d8SRobert Mustacchi 	    "WAKE# Signaling", "WAKE# and Message Signaling" } } },
1613*7687d0d8SRobert Mustacchi 	{ 20, 20, "extfmt", "Extended Fmt Field Supported", PRDV_STRVAL,
1614*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1615*7687d0d8SRobert Mustacchi 	{ 21, 21, "eetlp", "End-End TLP Prefix Supported", PRDV_STRVAL,
1616*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1617*7687d0d8SRobert Mustacchi 	{ 22, 23, "maxeetlp", "Max End-End TLP Prefixes", PRDV_STRVAL,
1618*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4", "1", "2", "3" } } },
1619*7687d0d8SRobert Mustacchi 	{ 24, 25, "empr", "Emergency Power Reduction", PRDV_STRVAL,
1620*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported",
1621*7687d0d8SRobert Mustacchi 	    "supported, device-specific",
1622*7687d0d8SRobert Mustacchi 	    "supported, from factor or device-specific" } } },
1623*7687d0d8SRobert Mustacchi 	{ 21, 21, "emprinit",
1624*7687d0d8SRobert Mustacchi 	    "Emergency Power Reduction Initialization Required", PRDV_STRVAL,
1625*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1626*7687d0d8SRobert Mustacchi 	{ 31, 31, "frs", "Function Readiness Status", PRDV_STRVAL,
1627*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1628*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1629*7687d0d8SRobert Mustacchi };
1630*7687d0d8SRobert Mustacchi 
1631*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devctl2[] = {
1632*7687d0d8SRobert Mustacchi 	{ 0, 3, "cmpto", "Completion Timeout", PRDV_STRVAL,
1633*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "50us-50ms", "50us-100us",
1634*7687d0d8SRobert Mustacchi 	    "1ms-10ms", NULL, NULL, "16ms-55ms", "65ms-210ms", NULL, NULL,
1635*7687d0d8SRobert Mustacchi 	    "260ms-900ms", "1s-3.5s", NULL, NULL, "4s-13s", "17s-64s" } } },
1636*7687d0d8SRobert Mustacchi 	{ 4, 4, "cmptodis", "Completion Timeout Disabled", PRDV_STRVAL,
1637*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not disabled", "disabled" } } },
1638*7687d0d8SRobert Mustacchi 	{ 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL,
1639*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1640*7687d0d8SRobert Mustacchi 	{ 6, 6, "atomreq", "AtomicOp Requester", PRDV_STRVAL,
1641*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1642*7687d0d8SRobert Mustacchi 	{ 7, 7, "atomblock", "AtomicOp Egress Blocking", PRDV_STRVAL,
1643*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unblocked", "blocked" } } },
1644*7687d0d8SRobert Mustacchi 	{ 8, 8, "idoreq", "ID-Based Ordering Request", PRDV_STRVAL,
1645*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1646*7687d0d8SRobert Mustacchi 	{ 9, 9, "idocomp", "ID-Based Ordering Completion", PRDV_STRVAL,
1647*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1648*7687d0d8SRobert Mustacchi 	{ 10, 10, "ltr", "LTR Mechanism", PRDV_STRVAL,
1649*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1650*7687d0d8SRobert Mustacchi 	{ 11, 11, "empowred", "Emergency Power Reduction", PRDV_STRVAL,
1651*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not requested", "requested" } } },
1652*7687d0d8SRobert Mustacchi 	{ 12, 12, "tag10req", "10-bit Tag Requester", PRDV_STRVAL,
1653*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1654*7687d0d8SRobert Mustacchi 	{ 13, 14, "obff", "OBFF", PRDV_STRVAL,
1655*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "message signaling - A",
1656*7687d0d8SRobert Mustacchi 	    "message signaling - B", "WAKE# signaling" } } },
1657*7687d0d8SRobert Mustacchi 	{ 15, 15, "eetlpblk", "End-End TLP Prefix Blocking", PRDV_STRVAL,
1658*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unblocked", "blocked" } } },
1659*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1660*7687d0d8SRobert Mustacchi };
1661*7687d0d8SRobert Mustacchi 
1662*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devsts2[] = {
1663*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1664*7687d0d8SRobert Mustacchi };
1665*7687d0d8SRobert Mustacchi 
1666*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkcap2[] = {
1667*7687d0d8SRobert Mustacchi 	{ 1, 7, "supspeeds", "Supported Link Speeds", PRDV_BITFIELD,
1668*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
1669*7687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
1670*7687d0d8SRobert Mustacchi 	{ 8, 8, "crosslink", "Crosslink", PRDV_STRVAL,
1671*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1672*7687d0d8SRobert Mustacchi 	{ 9, 15, "skposgen", "Lower SKP OS Generation Supported Speeds Vector",
1673*7687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
1674*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
1675*7687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
1676*7687d0d8SRobert Mustacchi 	{ 16, 22, "skposrecv", "Lower SKP OS Reception Supported Speeds Vector",
1677*7687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
1678*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
1679*7687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
1680*7687d0d8SRobert Mustacchi 	{ 23, 23, "retimedet", "Retimer Presence Detect Supported", PRDV_STRVAL,
1681*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1682*7687d0d8SRobert Mustacchi 	{ 24, 24, "retime2det", "Two Retimers Presence Detect Supported",
1683*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
1684*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1685*7687d0d8SRobert Mustacchi 	{ 31, 31, "drs", "Device Readiness Status", PRDV_STRVAL,
1686*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1687*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1688*7687d0d8SRobert Mustacchi };
1689*7687d0d8SRobert Mustacchi 
1690*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkctl2[] = {
1691*7687d0d8SRobert Mustacchi 	{ 0, 3, "targspeed", "Target Link Speed", PRDV_STRVAL,
1692*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
1693*7687d0d8SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s" } } },
1694*7687d0d8SRobert Mustacchi 	{ 4, 4, "comp", "Enter Compliance", PRDV_STRVAL,
1695*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1696*7687d0d8SRobert Mustacchi 	{ 5, 5, "hwautosp", "Hardware Autonomous Speed Disable", PRDV_STRVAL,
1697*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not disabled", "disabled" } } },
1698*7687d0d8SRobert Mustacchi 	{ 6, 6, "seldeemph", "Selectable De-emphasis", PRDV_STRVAL,
1699*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } },
1700*7687d0d8SRobert Mustacchi 	{ 7, 9, "txmarg", "TX Margin", PRDV_HEX },
1701*7687d0d8SRobert Mustacchi 	{ 10, 10, "modcomp", "Enter Modified Compliance", PRDV_STRVAL,
1702*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1703*7687d0d8SRobert Mustacchi 	{ 11, 11, "compsos", "Compliance SOS",
1704*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1705*7687d0d8SRobert Mustacchi 	{ 12, 15, "compemph", "Compliance Preset/De-emphasis", PRDV_HEX },
1706*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1707*7687d0d8SRobert Mustacchi };
1708*7687d0d8SRobert Mustacchi 
1709*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linksts2[] = {
1710*7687d0d8SRobert Mustacchi 	{ 0, 0, "curdeemph", "Current De-emphasis Level", PRDV_STRVAL,
1711*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } },
1712*7687d0d8SRobert Mustacchi 	{ 1, 1, "eq8comp", "Equalization 8.0 GT/s Complete", PRDV_STRVAL,
1713*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1714*7687d0d8SRobert Mustacchi 	{ 2, 2, "eq8p1comp", "Equalization 8.0 GT/s Phase 1", PRDV_STRVAL,
1715*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
1716*7687d0d8SRobert Mustacchi 	{ 3, 3, "eq8p2comp", "Equalization 8.0 GT/s Phase 2", PRDV_STRVAL,
1717*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
1718*7687d0d8SRobert Mustacchi 	{ 4, 4, "eq8p3comp", "Equalization 8.0 GT/s Phase 3", PRDV_STRVAL,
1719*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
1720*7687d0d8SRobert Mustacchi 	{ 5, 5, "linkeq8req", "Link Equalization Request 8.0 GT/s", PRDV_STRVAL,
1721*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not requested", "requested" } } },
1722*7687d0d8SRobert Mustacchi 	{ 6, 6, "retimedet", "Retimer Presence Detected", PRDV_STRVAL,
1723*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1724*7687d0d8SRobert Mustacchi 	{ 7, 7, "retime2det", "Two Retimers Presence Detected", PRDV_STRVAL,
1725*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1726*7687d0d8SRobert Mustacchi 	{ 8, 9, "crosslink", "Crosslink Resolution", PRDV_STRVAL,
1727*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "upstream port",
1728*7687d0d8SRobert Mustacchi 	    "downstream port", "incomplete" } } },
1729*7687d0d8SRobert Mustacchi 	{ 12, 14, "dscomppres", "Downstream Component Presence", PRDV_STRVAL,
1730*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "link down - undetermined",
1731*7687d0d8SRobert Mustacchi 	    "link down - not present", "link down - present", NULL,
1732*7687d0d8SRobert Mustacchi 	    "link up - present", "link up - present and DRS" } } },
1733*7687d0d8SRobert Mustacchi 	{ 15, 15, "drsrx", "DRS Message Received", PRDV_STRVAL,
1734*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1735*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1736*7687d0d8SRobert Mustacchi };
1737*7687d0d8SRobert Mustacchi 
1738*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotcap2[] = {
1739*7687d0d8SRobert Mustacchi 	{ 0, 0, "ibpddis", "In-Band PD Disable", PRDV_STRVAL,
1740*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1741*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1742*7687d0d8SRobert Mustacchi };
1743*7687d0d8SRobert Mustacchi 
1744*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotctl2[] = {
1745*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1746*7687d0d8SRobert Mustacchi };
1747*7687d0d8SRobert Mustacchi 
1748*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotsts2[] = {
1749*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1750*7687d0d8SRobert Mustacchi };
1751*7687d0d8SRobert Mustacchi 
1752*7687d0d8SRobert Mustacchi 
1753*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1[] = {
1754*7687d0d8SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1755*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1756*7687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1757*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1758*7687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1759*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1760*7687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
1761*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
1762*7687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
1763*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
1764*7687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
1765*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
1766*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
1767*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
1768*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
1769*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
1770*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
1771*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
1772*7687d0d8SRobert Mustacchi 	{ PCIE_ROOTCTL, 2, "rootctl", "Root control",
1773*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl },
1774*7687d0d8SRobert Mustacchi 	{ PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities",
1775*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap },
1776*7687d0d8SRobert Mustacchi 	{ PCIE_ROOTSTS, 4, "rootsts", "Root Status",
1777*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts },
1778*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1779*7687d0d8SRobert Mustacchi };
1780*7687d0d8SRobert Mustacchi 
1781*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie_v2[] = {
1782*7687d0d8SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1783*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1784*7687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1785*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1786*7687d0d8SRobert Mustacchi 	{ PCIE_DEVCTL, 2, "devctl", "Device Control",
1787*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl },
1788*7687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1789*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1790*7687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
1791*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
1792*7687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
1793*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
1794*7687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
1795*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
1796*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
1797*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
1798*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
1799*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
1800*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
1801*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
1802*7687d0d8SRobert Mustacchi 	{ PCIE_ROOTCTL, 2, "rootctl", "Root Control",
1803*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl },
1804*7687d0d8SRobert Mustacchi 	{ PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities",
1805*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap },
1806*7687d0d8SRobert Mustacchi 	{ PCIE_ROOTSTS, 4, "rootsts", "Root Status",
1807*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts },
1808*7687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP2, 4, "devcap2", "Device Capabilities 2",
1809*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap2 },
1810*7687d0d8SRobert Mustacchi 	{ PCIE_DEVCTL2, 2, "devctl2", "Device Control 2",
1811*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl2 },
1812*7687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS2, 2, "devsts2", "Device Status 2",
1813*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts2 },
1814*7687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP2, 4, "linkcap2", "Link Capabilities 2",
1815*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap2 },
1816*7687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL2, 2, "linkctl2", "Link Control 2",
1817*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl2 },
1818*7687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS2, 2, "linksts2", "Link Status 2",
1819*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts2 },
1820*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP2, 4, "slotcap2", "Slot Capabilities 2",
1821*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap2 },
1822*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL2, 2, "slotctl2", "Slot Control 2",
1823*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl2 },
1824*7687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS2, 2, "slotsts2", "Slot Status 2",
1825*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts2 },
1826*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1827*7687d0d8SRobert Mustacchi };
1828*7687d0d8SRobert Mustacchi 
1829*7687d0d8SRobert Mustacchi /*
1830*7687d0d8SRobert Mustacchi  * PCIe Extended Capability Header
1831*7687d0d8SRobert Mustacchi  */
1832*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_caphdr[] = {
1833*7687d0d8SRobert Mustacchi 	{ 0, 15, "capid", "Capability ID", PRDV_HEX },
1834*7687d0d8SRobert Mustacchi 	{ 16, 19, "version", "Capability Version", PRDV_HEX },
1835*7687d0d8SRobert Mustacchi 	{ 20, 32, "offset", "Next Capability Offset", PRDV_HEX },
1836*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1837*7687d0d8SRobert Mustacchi };
1838*7687d0d8SRobert Mustacchi 
1839*7687d0d8SRobert Mustacchi /*
1840*7687d0d8SRobert Mustacchi  * VPD Capability
1841*7687d0d8SRobert Mustacchi  */
1842*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vpd_addr[] = {
1843*7687d0d8SRobert Mustacchi 	{ 0, 14, "addr", "VPD Address", PRDV_HEX },
1844*7687d0d8SRobert Mustacchi 	{ 15, 15, "flag", "Flag", PRDV_HEX },
1845*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1846*7687d0d8SRobert Mustacchi };
1847*7687d0d8SRobert Mustacchi 
1848*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vpd[] = {
1849*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "addr", "VPD Address Register",
1850*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vpd_addr },
1851*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "data", "VPD Data", pcieadm_cfgspace_print_hex },
1852*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1853*7687d0d8SRobert Mustacchi };
1854*7687d0d8SRobert Mustacchi 
1855*7687d0d8SRobert Mustacchi /*
1856*7687d0d8SRobert Mustacchi  * SATA Capability per AHCI 1.3.1
1857*7687d0d8SRobert Mustacchi  */
1858*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sata_cr0[] = {
1859*7687d0d8SRobert Mustacchi 	{ 0, 3, "minrev", "Minor Revision", PRDV_HEX },
1860*7687d0d8SRobert Mustacchi 	{ 4, 7, "majrev", "Major Revision", PRDV_HEX },
1861*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1862*7687d0d8SRobert Mustacchi };
1863*7687d0d8SRobert Mustacchi 
1864*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sata_cr1[] = {
1865*7687d0d8SRobert Mustacchi 	{ 0, 3, "bar", "BAR Location", PRDV_HEX,
1866*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 2 } } },
1867*7687d0d8SRobert Mustacchi 	{ 4, 23, "offset", "BAR Offset", PRDV_HEX,
1868*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 2 } } },
1869*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1870*7687d0d8SRobert Mustacchi };
1871*7687d0d8SRobert Mustacchi 
1872*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_sata[] = {
1873*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "satacr0", "SATA Capability Register 0",
1874*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr0 },
1875*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "satacr1", "SATA Capability Register 1",
1876*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr1 },
1877*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1878*7687d0d8SRobert Mustacchi };
1879*7687d0d8SRobert Mustacchi 
1880*7687d0d8SRobert Mustacchi /*
1881*7687d0d8SRobert Mustacchi  * Debug Capability per EHCI
1882*7687d0d8SRobert Mustacchi  */
1883*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_debug[] = {
1884*7687d0d8SRobert Mustacchi 	{ 0, 12, "offset", "BAR Offset", PRDV_HEX },
1885*7687d0d8SRobert Mustacchi 	{ 13, 15, "bar", "BAR Location ", PRDV_STRVAL,
1886*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "BAR 0", "BAR 1", "BAR 2",
1887*7687d0d8SRobert Mustacchi 	    "BAR 3", "BAR 4", "BAR 5" } } },
1888*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1889*7687d0d8SRobert Mustacchi };
1890*7687d0d8SRobert Mustacchi 
1891*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_debug[] = {
1892*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "port", "Debug Port",
1893*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_debug },
1894*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1895*7687d0d8SRobert Mustacchi };
1896*7687d0d8SRobert Mustacchi 
1897*7687d0d8SRobert Mustacchi /*
1898*7687d0d8SRobert Mustacchi  * AER Capability
1899*7687d0d8SRobert Mustacchi  */
1900*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_ue[] = {
1901*7687d0d8SRobert Mustacchi 	{ 4, 4, "dlp", "Data Link Protocol Error", PRDV_HEX },
1902*7687d0d8SRobert Mustacchi 	{ 5, 5, "sde", "Surprise Down Error", PRDV_HEX },
1903*7687d0d8SRobert Mustacchi 	{ 12, 12, "ptlp", "Poisoned TLP Received", PRDV_HEX },
1904*7687d0d8SRobert Mustacchi 	{ 13, 13, "fcp", "Flow Control Protocol Error", PRDV_HEX },
1905*7687d0d8SRobert Mustacchi 	{ 14, 14, "cto", "Completion Timeout", PRDV_HEX },
1906*7687d0d8SRobert Mustacchi 	{ 15, 15, "cab", "Completion Abort", PRDV_HEX },
1907*7687d0d8SRobert Mustacchi 	{ 16, 16, "unco", "Unexpected Completion", PRDV_HEX },
1908*7687d0d8SRobert Mustacchi 	{ 17, 17, "rxov", "Receiver Overflow", PRDV_HEX },
1909*7687d0d8SRobert Mustacchi 	{ 18, 18, "maltlp", "Malformed TLP", PRDV_HEX },
1910*7687d0d8SRobert Mustacchi 	{ 19, 19, "ecrc", "ECRC Error", PRDV_HEX },
1911*7687d0d8SRobert Mustacchi 	{ 20, 20, "usuprx", "Unsupported Request Error", PRDV_HEX },
1912*7687d0d8SRobert Mustacchi 	{ 21, 21, "acs", "ACS Violation", PRDV_HEX },
1913*7687d0d8SRobert Mustacchi 	{ 22, 22, "ueint", "Uncorrectable Internal Error", PRDV_HEX },
1914*7687d0d8SRobert Mustacchi 	{ 23, 23, "mcbtlp", "MC Blocked TLP", PRDV_HEX },
1915*7687d0d8SRobert Mustacchi 	{ 24, 24, "atoomeb", "AtomicOp Egress Blocked", PRDV_HEX },
1916*7687d0d8SRobert Mustacchi 	{ 25, 25, "tlppb", "TLP Prefix Blocked Error", PRDV_HEX },
1917*7687d0d8SRobert Mustacchi 	{ 26, 26, "ptlpeb", "Poisoned TLP Egress Blocked", PRDV_HEX },
1918*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1919*7687d0d8SRobert Mustacchi };
1920*7687d0d8SRobert Mustacchi 
1921*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_ce[] = {
1922*7687d0d8SRobert Mustacchi 	{ 0, 0, "rxerr", "Receiver Error", PRDV_HEX },
1923*7687d0d8SRobert Mustacchi 	{ 6, 6, "badtlp", "Bad TLP", PRDV_HEX },
1924*7687d0d8SRobert Mustacchi 	{ 7, 7, "baddllp", "Bad DLLP", PRDV_HEX },
1925*7687d0d8SRobert Mustacchi 	{ 8, 8, "replayro", "REPLAY_NUM Rollover", PRDV_HEX },
1926*7687d0d8SRobert Mustacchi 	{ 12, 12, "rtto", "Replay timer Timeout", PRDV_HEX },
1927*7687d0d8SRobert Mustacchi 	{ 13, 13, "advnfe", "Advisory Non-Fatal Error", PRDV_HEX },
1928*7687d0d8SRobert Mustacchi 	{ 14, 14, "ceint", "Correctable Internal Error", PRDV_HEX },
1929*7687d0d8SRobert Mustacchi 	{ 15, 15, "headlov", "Header Log Overflow", PRDV_HEX },
1930*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1931*7687d0d8SRobert Mustacchi };
1932*7687d0d8SRobert Mustacchi 
1933*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_ctrl[] = {
1934*7687d0d8SRobert Mustacchi 	{ 0, 4, "feptr", "First Error Pointer", PRDV_HEX },
1935*7687d0d8SRobert Mustacchi 	{ 5, 5, "ecgencap", "ECRC Generation Capable", PRDV_STRVAL,
1936*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1937*7687d0d8SRobert Mustacchi 	{ 6, 6, "ecgenen", "ECRC Generation Enable", PRDV_STRVAL,
1938*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1939*7687d0d8SRobert Mustacchi 	{ 7, 7, "ecchkcap", "ECRC Check Capable", PRDV_STRVAL,
1940*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1941*7687d0d8SRobert Mustacchi 	{ 8, 8, "ecchken", "ECRC Check Enable", PRDV_STRVAL,
1942*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1943*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1944*7687d0d8SRobert Mustacchi };
1945*7687d0d8SRobert Mustacchi 
1946*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_rootcom[] = {
1947*7687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL,
1948*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1949*7687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL,
1950*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1951*7687d0d8SRobert Mustacchi 	{ 2, 2, "faterr", "Fatal Error Reporting", PRDV_STRVAL,
1952*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1953*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1954*7687d0d8SRobert Mustacchi };
1955*7687d0d8SRobert Mustacchi 
1956*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_rootsts[] = {
1957*7687d0d8SRobert Mustacchi 	{ 0, 0, "errcor", "ERR_COR Received", PRDV_HEX },
1958*7687d0d8SRobert Mustacchi 	{ 1, 1, "merrcor", "Multiple ERR_COR Received", PRDV_HEX },
1959*7687d0d8SRobert Mustacchi 	{ 2, 2, "errfnf", "ERR_FATAL/NONFATAL Received", PRDV_HEX },
1960*7687d0d8SRobert Mustacchi 	{ 3, 3, "merrfnf", "Multiple ERR_FATAL/NONFATAL Received", PRDV_HEX },
1961*7687d0d8SRobert Mustacchi 	{ 4, 4, "fuefat", "First Uncorrectable Fatal", PRDV_HEX },
1962*7687d0d8SRobert Mustacchi 	{ 5, 5, "nferrrx", "Non-Fatal Error Messages Received", PRDV_HEX },
1963*7687d0d8SRobert Mustacchi 	{ 6, 6, "faterrx", "Fatal Error Messages Received", PRDV_HEX },
1964*7687d0d8SRobert Mustacchi 	{ 7, 8, "errcorsc", "ERR_COR Subclass", PRDV_STRVAL,
1965*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "ECS Legacy", "ECS SIG_SFW",
1966*7687d0d8SRobert Mustacchi 	    "ECS SIG_OS", "ECS Extended" } } },
1967*7687d0d8SRobert Mustacchi 	{ 27, 31, "inum", "Advanced Error Interrupt Message", PRDV_HEX },
1968*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1969*7687d0d8SRobert Mustacchi };
1970*7687d0d8SRobert Mustacchi 
1971*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_esi[] = {
1972*7687d0d8SRobert Mustacchi 	{ 0, 15, "errcorr", "ERR_COR Source", PRDV_HEX },
1973*7687d0d8SRobert Mustacchi 	{ 16, 31, "errfnf", "ERR_FATAL/NONFATAL Source", PRDV_HEX },
1974*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1975*7687d0d8SRobert Mustacchi };
1976*7687d0d8SRobert Mustacchi 
1977*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_secue[] = {
1978*7687d0d8SRobert Mustacchi 	{ 0, 0, "taosc", "Target-Abort on Split Completion", PRDV_HEX },
1979*7687d0d8SRobert Mustacchi 	{ 1, 1, "maosc", "Master-Abort on Split Completion", PRDV_HEX },
1980*7687d0d8SRobert Mustacchi 	{ 2, 2, "rxta", "Received Target-Abort", PRDV_HEX },
1981*7687d0d8SRobert Mustacchi 	{ 3, 3, "rxma", "Received Master-Abort", PRDV_HEX },
1982*7687d0d8SRobert Mustacchi 	{ 5, 5, "unsce", "Unexpected Split Completion Error", PRDV_HEX },
1983*7687d0d8SRobert Mustacchi 	{ 6, 6, "uescmd", "Uncorrectable Split Completion Message Data Error",
1984*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
1985*7687d0d8SRobert Mustacchi 	{ 7, 7, "uede", "Uncorrectable Data Error", PRDV_HEX },
1986*7687d0d8SRobert Mustacchi 	{ 8, 8, "ueattre", "Uncorrectable Attribute Error", PRDV_HEX },
1987*7687d0d8SRobert Mustacchi 	{ 9, 9, "ueaddre", "Uncorrectable Address Error", PRDV_HEX },
1988*7687d0d8SRobert Mustacchi 	{ 10, 10, "dtdte", "Delayed Transaction Discard Timer Expired",
1989*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
1990*7687d0d8SRobert Mustacchi 	{ 11, 11, "perr", "PERR# Assertion", PRDV_HEX },
1991*7687d0d8SRobert Mustacchi 	{ 12, 12, "serr", "SERR# Assertion", PRDV_HEX },
1992*7687d0d8SRobert Mustacchi 	{ 13, 13, "internal", "Internal Bridge Error", PRDV_HEX },
1993*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
1994*7687d0d8SRobert Mustacchi };
1995*7687d0d8SRobert Mustacchi 
1996*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_secctl[] = {
1997*7687d0d8SRobert Mustacchi 	{ 0, 4, "feptr", "Secondary Uncorrectable First Error Pointer",
1998*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
1999*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2000*7687d0d8SRobert Mustacchi };
2001*7687d0d8SRobert Mustacchi 
2002*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_aer_v1[] = {
2003*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
2004*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2005*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
2006*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2007*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
2008*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2009*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
2010*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2011*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
2012*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
2013*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
2014*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
2015*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
2016*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
2017*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
2018*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2019*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
2020*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2021*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
2022*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2023*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
2024*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2025*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "rootcmd", "Root Error Command",
2026*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
2027*7687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
2028*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
2029*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_SRC_ID, 4, "esi", "Error Source Identification",
2030*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_esi },
2031*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2032*7687d0d8SRobert Mustacchi };
2033*7687d0d8SRobert Mustacchi 
2034*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_aer_v2[] = {
2035*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
2036*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2037*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
2038*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2039*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
2040*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2041*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
2042*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2043*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
2044*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
2045*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
2046*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
2047*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
2048*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
2049*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
2050*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2051*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
2052*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2053*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
2054*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2055*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
2056*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2057*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "rootcmd", "Root Error Command",
2058*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
2059*7687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
2060*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
2061*7687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG, 4, "tlplog0", "TLP Prefix Log 0",
2062*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2063*7687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 4, 4, "tlplog1", "TLP Prefix Log 1",
2064*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2065*7687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 8, 4, "tlplog2", "TLP Prefix Log 2",
2066*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2067*7687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 12, 4, "tlplog3", "TLP Prefix Log 3",
2068*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2069*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2070*7687d0d8SRobert Mustacchi };
2071*7687d0d8SRobert Mustacchi 
2072*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_aer_bridge[] = {
2073*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
2074*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2075*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
2076*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2077*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
2078*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2079*7687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
2080*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
2081*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
2082*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
2083*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
2084*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
2085*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
2086*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
2087*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
2088*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2089*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
2090*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2091*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
2092*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2093*7687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
2094*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2095*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "rootcmd", "Root Error Command",
2096*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
2097*7687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
2098*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
2099*7687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_SRC_ID, 4, "esi", "Error Source Identification",
2100*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_esi },
2101*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_STS, 4, "secuests",
2102*7687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Status",
2103*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
2104*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_MASK, 4, "secuests",
2105*7687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Mask",
2106*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
2107*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_SERV, 4, "secuests",
2108*7687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Severity",
2109*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
2110*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SCTL, 4, "secctrl",
2111*7687d0d8SRobert Mustacchi 	    "Secondary Error Capabilityes and Control",
2112*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secctl },
2113*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG, 4, "shl0", "Secondary Header Log 0",
2114*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2115*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 4, 4, "shl1", "Secondary Header Log 1",
2116*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2117*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 8, 4, "shl1", "Secondary Header Log 2",
2118*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2119*7687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 12, 4, "shl1", "Secondary Header Log 3",
2120*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2121*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2122*7687d0d8SRobert Mustacchi };
2123*7687d0d8SRobert Mustacchi 
2124*7687d0d8SRobert Mustacchi /*
2125*7687d0d8SRobert Mustacchi  * Secondary PCI Express Extended Capability
2126*7687d0d8SRobert Mustacchi  */
2127*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie2_linkctl3[] = {
2128*7687d0d8SRobert Mustacchi 	{ 0, 0, "peq", "Perform Equalization", PRDV_HEX },
2129*7687d0d8SRobert Mustacchi 	{ 1, 1, "leqrie", "Link Equalization Request Interrupt Enable",
2130*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
2131*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2132*7687d0d8SRobert Mustacchi 	{ 9, 15, "elskpos", "Enable Lower SKP OS Generation Vector",
2133*7687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
2134*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
2135*7687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
2136*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2137*7687d0d8SRobert Mustacchi };
2138*7687d0d8SRobert Mustacchi 
2139*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie2_linkeq[] = {
2140*7687d0d8SRobert Mustacchi 	{ 0, 3, "dstxpre", "Downstream Port 8.0 GT/s Transmitter Preset",
2141*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
2142*7687d0d8SRobert Mustacchi 	{ 4, 6, "dstxhint", "Downstream Port 8.0 GT/s Receiver Hint",
2143*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
2144*7687d0d8SRobert Mustacchi 	{ 8, 11, "ustxpre", "Upstream Port 8.0 GT/s Transmitter Preset",
2145*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
2146*7687d0d8SRobert Mustacchi 	{ 12, 14, "ustxhint", "Upstream Port 8.0 GT/s Receiver Hint",
2147*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
2148*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2149*7687d0d8SRobert Mustacchi };
2150*7687d0d8SRobert Mustacchi 
2151*7687d0d8SRobert Mustacchi static void
2152*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_laneq(pcieadm_cfgspace_walk_t *walkp,
2153*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
2154*7687d0d8SRobert Mustacchi {
2155*7687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
2156*7687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
2157*7687d0d8SRobert Mustacchi 		    "secondary PCIe cap");
2158*7687d0d8SRobert Mustacchi 		return;
2159*7687d0d8SRobert Mustacchi 	}
2160*7687d0d8SRobert Mustacchi 
2161*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
2162*7687d0d8SRobert Mustacchi 		char eqshort[32], eqhuman[128];
2163*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
2164*7687d0d8SRobert Mustacchi 
2165*7687d0d8SRobert Mustacchi 		(void) snprintf(eqshort, sizeof (eqshort), "lane%u", i);
2166*7687d0d8SRobert Mustacchi 		(void) snprintf(eqhuman, sizeof (eqhuman), "Lane %u EQ Control",
2167*7687d0d8SRobert Mustacchi 		    i);
2168*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 2;
2169*7687d0d8SRobert Mustacchi 		p.pcp_len = 2;
2170*7687d0d8SRobert Mustacchi 		p.pcp_short = eqshort;
2171*7687d0d8SRobert Mustacchi 		p.pcp_human = eqhuman;
2172*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
2173*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_pcie2_linkeq;
2174*7687d0d8SRobert Mustacchi 
2175*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
2176*7687d0d8SRobert Mustacchi 	}
2177*7687d0d8SRobert Mustacchi }
2178*7687d0d8SRobert Mustacchi 
2179*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie2[] = {
2180*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2181*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2182*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "linkctl3", "Link Control 3",
2183*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie2_linkctl3 },
2184*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "laneerr", "Lane Error Status", pcieadm_cfgspace_print_hex },
2185*7687d0d8SRobert Mustacchi 	{ 0xc, 2, "eqctl", "Lane Equalization Control",
2186*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_laneq },
2187*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2188*7687d0d8SRobert Mustacchi };
2189*7687d0d8SRobert Mustacchi 
2190*7687d0d8SRobert Mustacchi /*
2191*7687d0d8SRobert Mustacchi  * Access Control Services
2192*7687d0d8SRobert Mustacchi  */
2193*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_acs_cap[] = {
2194*7687d0d8SRobert Mustacchi 	{ 0, 0, "srcvd", "ACS Source Validation", PRDV_STRVAL,
2195*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2196*7687d0d8SRobert Mustacchi 	{ 1, 1, "tranblk", "ACS Transaction Blocking", PRDV_STRVAL,
2197*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2198*7687d0d8SRobert Mustacchi 	{ 2, 2, "p2prr", "ACS P2P Request Redirect", PRDV_STRVAL,
2199*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2200*7687d0d8SRobert Mustacchi 	{ 3, 3, "p2pcr", "ACS P2P Completion Redirect", PRDV_STRVAL,
2201*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2202*7687d0d8SRobert Mustacchi 	{ 4, 4, "upfwd", "ACS Upstream Forwarding", PRDV_STRVAL,
2203*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2204*7687d0d8SRobert Mustacchi 	{ 5, 5, "p2pegctl", "ACS P2P Egress Control", PRDV_STRVAL,
2205*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2206*7687d0d8SRobert Mustacchi 	{ 6, 6, "dtp2p", "ACS Direct Translated P2P", PRDV_STRVAL,
2207*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2208*7687d0d8SRobert Mustacchi 	{ 7, 7, "enhcap", "ACS Enhanced Capability", PRDV_STRVAL,
2209*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2210*7687d0d8SRobert Mustacchi 	{ 8, 15, "ecvsz", "Egress Control Vector Size", PRDV_HEX },
2211*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2212*7687d0d8SRobert Mustacchi };
2213*7687d0d8SRobert Mustacchi 
2214*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_acs_ctl[] = {
2215*7687d0d8SRobert Mustacchi 	{ 0, 0, "srcvd", "ACS Source Validation", PRDV_STRVAL,
2216*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2217*7687d0d8SRobert Mustacchi 	{ 1, 1, "tranblk", "ACS Transaction Blocking", PRDV_STRVAL,
2218*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2219*7687d0d8SRobert Mustacchi 	{ 2, 2, "p2prr", "ACS P2P Request Redirect", PRDV_STRVAL,
2220*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2221*7687d0d8SRobert Mustacchi 	{ 3, 3, "p2pcr", "ACS P2P Completion Redirect", PRDV_STRVAL,
2222*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2223*7687d0d8SRobert Mustacchi 	{ 4, 4, "upfwd", "ACS Upstream Forwarding", PRDV_STRVAL,
2224*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2225*7687d0d8SRobert Mustacchi 	{ 5, 5, "p2pegctl", "ACS P2P Egress Control", PRDV_STRVAL,
2226*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2227*7687d0d8SRobert Mustacchi 	{ 6, 6, "dtp2p", "ACS Direct Translated P2P", PRDV_STRVAL,
2228*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2229*7687d0d8SRobert Mustacchi 	{ 7, 7, "iorb", "ACS I/O Request Blocking", PRDV_STRVAL,
2230*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2231*7687d0d8SRobert Mustacchi 	{ 8, 9, "dspmta", "ACS DSP Memory Target Access Control", PRDV_STRVAL,
2232*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Direct Request access",
2233*7687d0d8SRobert Mustacchi 	    "Request blocking", "Request redirect" } } },
2234*7687d0d8SRobert Mustacchi 	{ 10, 11, "uspmta", "ACS USP Memory Target Access Control", PRDV_STRVAL,
2235*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Direct Request access",
2236*7687d0d8SRobert Mustacchi 	    "Request blocking", "Request redirect" } } },
2237*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2238*7687d0d8SRobert Mustacchi };
2239*7687d0d8SRobert Mustacchi 
2240*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_acs[] = {
2241*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2242*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2243*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ACS Capability",
2244*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_acs_cap },
2245*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "ACS Control",
2246*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_acs_ctl },
2247*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "ecv", "Egress Control Vector", pcieadm_cfgspace_print_ecv },
2248*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2249*7687d0d8SRobert Mustacchi };
2250*7687d0d8SRobert Mustacchi 
2251*7687d0d8SRobert Mustacchi /*
2252*7687d0d8SRobert Mustacchi  * L1 PM Substates
2253*7687d0d8SRobert Mustacchi  */
2254*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_cap[] = {
2255*7687d0d8SRobert Mustacchi 	{ 0, 0, "pcil1.2", "PCI-PM L1.2", PRDV_STRVAL,
2256*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2257*7687d0d8SRobert Mustacchi 	{ 1, 1, "pcil1.1", "PCI-PM L1.1", PRDV_STRVAL,
2258*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2259*7687d0d8SRobert Mustacchi 	{ 2, 2, "aspml1.2", "ASPM L1.2", PRDV_STRVAL,
2260*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2261*7687d0d8SRobert Mustacchi 	{ 3, 3, "aspml1.1", "ASPM L1.1", PRDV_STRVAL,
2262*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2263*7687d0d8SRobert Mustacchi 	{ 4, 4, "l1pmsub", "L1 PM Substates", PRDV_STRVAL,
2264*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2265*7687d0d8SRobert Mustacchi 	{ 5, 5, "linkact", "Link Activation", PRDV_STRVAL,
2266*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2267*7687d0d8SRobert Mustacchi 	{ 8, 15, "pcmrt", "Port Common_Mode_Restore_Time", PRDV_HEX },
2268*7687d0d8SRobert Mustacchi 	{ 16, 17, "poscale", "Port T_POWER_ON Scale", PRDV_STRVAL,
2269*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2 us", "10 us", "100 us" } } },
2270*7687d0d8SRobert Mustacchi 	{ 19, 23, "portpo", "Port T_POWER_ON Value", PRDV_HEX },
2271*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2272*7687d0d8SRobert Mustacchi };
2273*7687d0d8SRobert Mustacchi 
2274*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_ctl1[] = {
2275*7687d0d8SRobert Mustacchi 	{ 0, 0, "pcil1.2", "PCI-PM L1.2", PRDV_STRVAL,
2276*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2277*7687d0d8SRobert Mustacchi 	{ 1, 1, "pcil1.1", "PCI-PM L1.1", PRDV_STRVAL,
2278*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2279*7687d0d8SRobert Mustacchi 	{ 2, 2, "aspml1.2", "ASPM L1.2", PRDV_STRVAL,
2280*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2281*7687d0d8SRobert Mustacchi 	{ 3, 3, "aspml1.1", "ASPM L1.1", PRDV_STRVAL,
2282*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2283*7687d0d8SRobert Mustacchi 	{ 4, 4, "laie", "Link Activation Interrupt Enable", PRDV_STRVAL,
2284*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2285*7687d0d8SRobert Mustacchi 	{ 5, 5, "lactl", "Link Activation Control", PRDV_STRVAL,
2286*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2287*7687d0d8SRobert Mustacchi 	{ 8, 15, "cmrt", "Common_Mode_Restore_Time", PRDV_HEX },
2288*7687d0d8SRobert Mustacchi 	{ 16, 25, "ltrl1.2", "LTR L1.2 Threshold Value", PRDV_HEX },
2289*7687d0d8SRobert Mustacchi 	{ 29, 31, "ltrl1.2s", "LTR L1.2 Threshold Scale", PRDV_STRVAL,
2290*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ns", "32 ns", "1024 ns",
2291*7687d0d8SRobert Mustacchi 	    "32,768 ns", "1,048,576 ns", "33,554,432 ns" } } },
2292*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2293*7687d0d8SRobert Mustacchi };
2294*7687d0d8SRobert Mustacchi 
2295*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_ctl2[] = {
2296*7687d0d8SRobert Mustacchi 	{ 0, 1, "poscale", "T_POWER_ON Scale", PRDV_STRVAL,
2297*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2 us", "10 us", "100 us" } } },
2298*7687d0d8SRobert Mustacchi 	{ 3, 7, "portpo", "T_POWER_ON Value", PRDV_HEX },
2299*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2300*7687d0d8SRobert Mustacchi };
2301*7687d0d8SRobert Mustacchi 
2302*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_sts[] = {
2303*7687d0d8SRobert Mustacchi 	{ 0, 0, "la", "Link Activation", PRDV_HEX },
2304*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2305*7687d0d8SRobert Mustacchi };
2306*7687d0d8SRobert Mustacchi 
2307*7687d0d8SRobert Mustacchi 
2308*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_l1pm_v1[] = {
2309*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2310*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2311*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "caps", "L1 PM Substates Capabilities",
2312*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_cap },
2313*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl1", "L1 PM Substates Control 1",
2314*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl1 },
2315*7687d0d8SRobert Mustacchi 	{ 0xc, 4, "ctl1", "L1 PM Substates Control 2",
2316*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl2 },
2317*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2318*7687d0d8SRobert Mustacchi };
2319*7687d0d8SRobert Mustacchi 
2320*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_l1pm_v2[] = {
2321*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2322*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2323*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "caps", "L1 PM Substates Capabilities",
2324*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_cap },
2325*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl1", "L1 PM Substates Control 1",
2326*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl1 },
2327*7687d0d8SRobert Mustacchi 	{ 0xc, 4, "ctl1", "L1 PM Substates Control 2",
2328*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl2 },
2329*7687d0d8SRobert Mustacchi 	{ 0x10, 4, "sts", "L1 PM Substates Status",
2330*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_sts },
2331*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2332*7687d0d8SRobert Mustacchi };
2333*7687d0d8SRobert Mustacchi 
2334*7687d0d8SRobert Mustacchi /*
2335*7687d0d8SRobert Mustacchi  * Latency Tolerance Reporting (LTR)
2336*7687d0d8SRobert Mustacchi  */
2337*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ltr[] = {
2338*7687d0d8SRobert Mustacchi 	{ 0, 9, "latval", "Latency Value", PRDV_HEX },
2339*7687d0d8SRobert Mustacchi 	{ 10, 12, "latscale", "Latency Scale", PRDV_STRVAL,
2340*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ns", "32 ns", "1024 ns",
2341*7687d0d8SRobert Mustacchi 	    "32,768 ns", "1,048,576 ns", "33,554,432 ns" } } },
2342*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2343*7687d0d8SRobert Mustacchi };
2344*7687d0d8SRobert Mustacchi 
2345*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ltr[] = {
2346*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2347*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2348*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "snoop", "Max Snoop Latency",
2349*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ltr },
2350*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "snoop", "Max No-Snoop Latency",
2351*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ltr },
2352*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2353*7687d0d8SRobert Mustacchi };
2354*7687d0d8SRobert Mustacchi 
2355*7687d0d8SRobert Mustacchi /*
2356*7687d0d8SRobert Mustacchi  * Alternative Routing ID
2357*7687d0d8SRobert Mustacchi  */
2358*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ari_cap[] = {
2359*7687d0d8SRobert Mustacchi 	{ 0, 0, "mfvcfg", "MFVC Function Groups", PRDV_STRVAL,
2360*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2361*7687d0d8SRobert Mustacchi 	{ 1, 1, "acsfg", "ACS Function Groups", PRDV_STRVAL,
2362*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2363*7687d0d8SRobert Mustacchi 	{ 8, 15, "nfunc", "Next Function Number", PRDV_HEX },
2364*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2365*7687d0d8SRobert Mustacchi };
2366*7687d0d8SRobert Mustacchi 
2367*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ari_ctl[] = {
2368*7687d0d8SRobert Mustacchi 	{ 0, 0, "mfvcfg", "MFVC Function Groups", PRDV_STRVAL,
2369*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2370*7687d0d8SRobert Mustacchi 	{ 1, 1, "acsfg", "ACS Function Groups", PRDV_STRVAL,
2371*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2372*7687d0d8SRobert Mustacchi 	{ 4, 6, "fgrp", "Function Group", PRDV_HEX },
2373*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2374*7687d0d8SRobert Mustacchi };
2375*7687d0d8SRobert Mustacchi 
2376*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ari[] = {
2377*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2378*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2379*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ARI Capability",
2380*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ari_cap },
2381*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "ARI Control",
2382*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ari_ctl },
2383*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2384*7687d0d8SRobert Mustacchi };
2385*7687d0d8SRobert Mustacchi 
2386*7687d0d8SRobert Mustacchi /*
2387*7687d0d8SRobert Mustacchi  * PASID
2388*7687d0d8SRobert Mustacchi  */
2389*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pasid_cap[] = {
2390*7687d0d8SRobert Mustacchi 	{ 1, 1, "exec", "Execution Permission", PRDV_STRVAL,
2391*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2392*7687d0d8SRobert Mustacchi 	{ 2, 2, "priv", "Privileged Mode", PRDV_STRVAL,
2393*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2394*7687d0d8SRobert Mustacchi 	{ 8, 12, "width", "Max PASID Width", PRDV_HEX },
2395*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2396*7687d0d8SRobert Mustacchi };
2397*7687d0d8SRobert Mustacchi 
2398*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pasid_ctl[] = {
2399*7687d0d8SRobert Mustacchi 	{ 0, 0, "pasid", "PASID", PRDV_STRVAL,
2400*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2401*7687d0d8SRobert Mustacchi 	{ 1, 1, "exec", "Execution Permission", PRDV_STRVAL,
2402*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2403*7687d0d8SRobert Mustacchi 	{ 2, 2, "priv", "Privileged Mode", PRDV_STRVAL,
2404*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2405*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2406*7687d0d8SRobert Mustacchi };
2407*7687d0d8SRobert Mustacchi 
2408*7687d0d8SRobert Mustacchi 
2409*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pasid[] = {
2410*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2411*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2412*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "PASID Capability",
2413*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pasid_cap },
2414*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "PASID Control",
2415*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pasid_ctl },
2416*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2417*7687d0d8SRobert Mustacchi };
2418*7687d0d8SRobert Mustacchi 
2419*7687d0d8SRobert Mustacchi /*
2420*7687d0d8SRobert Mustacchi  * "Advanced Features"
2421*7687d0d8SRobert Mustacchi  */
2422*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_af_cap[] = {
2423*7687d0d8SRobert Mustacchi 	{ 0, 0, "tp", "Transactions Pending", PRDV_STRVAL,
2424*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2425*7687d0d8SRobert Mustacchi 	{ 1, 1, "flr", "Function Level Reset", PRDV_STRVAL,
2426*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2427*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2428*7687d0d8SRobert Mustacchi };
2429*7687d0d8SRobert Mustacchi 
2430*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_af_ctl[] = {
2431*7687d0d8SRobert Mustacchi 	{ 0, 0, "flr", "Function Level Reset", PRDV_HEX },
2432*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2433*7687d0d8SRobert Mustacchi };
2434*7687d0d8SRobert Mustacchi 
2435*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_af_sts[] = {
2436*7687d0d8SRobert Mustacchi 	{ 0, 0, "tp", "Transactions Pending", PRDV_STRVAL,
2437*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "none pending", "pending" } } },
2438*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2439*7687d0d8SRobert Mustacchi };
2440*7687d0d8SRobert Mustacchi 
2441*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_af[] = {
2442*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "cap", "AF Capabilities",
2443*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_cap },
2444*7687d0d8SRobert Mustacchi 	{ 0x4, 1, "ctl", "AF Control",
2445*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_ctl },
2446*7687d0d8SRobert Mustacchi 	{ 0x5, 1, "sts", "AF Status",
2447*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_sts },
2448*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2449*7687d0d8SRobert Mustacchi };
2450*7687d0d8SRobert Mustacchi 
2451*7687d0d8SRobert Mustacchi /*
2452*7687d0d8SRobert Mustacchi  * Multicast
2453*7687d0d8SRobert Mustacchi  */
2454*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_cap[] = {
2455*7687d0d8SRobert Mustacchi 	{ 0, 5, "maxgrp", "Max Group", PRDV_HEX,
2456*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
2457*7687d0d8SRobert Mustacchi 	{ 8, 13, "winsize", "Window Size (raw)", PRDV_HEX },
2458*7687d0d8SRobert Mustacchi 	{ 15, 15, "ecrc", "ECRC Regeneration", PRDV_STRVAL,
2459*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2460*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2461*7687d0d8SRobert Mustacchi };
2462*7687d0d8SRobert Mustacchi 
2463*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_ctl[] = {
2464*7687d0d8SRobert Mustacchi 	{ 0, 5, "numgrp", "Number of Groups", PRDV_HEX,
2465*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
2466*7687d0d8SRobert Mustacchi 	{ 15, 15, "enable", "Enable", PRDV_STRVAL,
2467*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2468*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2469*7687d0d8SRobert Mustacchi };
2470*7687d0d8SRobert Mustacchi 
2471*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_base[] = {
2472*7687d0d8SRobert Mustacchi 	{ 0, 5, "index", "Multicast Index Position", PRDV_HEX },
2473*7687d0d8SRobert Mustacchi 	{ 12, 63, "addr", "Base Address", PRDV_HEX,
2474*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12 } } },
2475*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2476*7687d0d8SRobert Mustacchi };
2477*7687d0d8SRobert Mustacchi 
2478*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_overlay[] = {
2479*7687d0d8SRobert Mustacchi 	{ 0, 5, "size", "Overlay Size (raw)", PRDV_HEX },
2480*7687d0d8SRobert Mustacchi 	{ 6, 63, "addr", "Overlay Base Address", PRDV_HEX,
2481*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 6 } } },
2482*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2483*7687d0d8SRobert Mustacchi };
2484*7687d0d8SRobert Mustacchi 
2485*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_mcast[] = {
2486*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2487*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2488*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "Multicast Capability",
2489*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_cap },
2490*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "Multicast Control",
2491*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_ctl },
2492*7687d0d8SRobert Mustacchi 	{ 0x8, 8, "base", "Multicast Base Address",
2493*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_base },
2494*7687d0d8SRobert Mustacchi 	{ 0x10, 8, "rx", "Multicast Receive", pcieadm_cfgspace_print_hex },
2495*7687d0d8SRobert Mustacchi 	{ 0x18, 8, "block", "Multicast Block All", pcieadm_cfgspace_print_hex },
2496*7687d0d8SRobert Mustacchi 	{ 0x20, 8, "blockun", "Multicast Block Untranslated",
2497*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2498*7687d0d8SRobert Mustacchi 	{ 0x28, 8, "overlay", "Multicast Overlay BAR",
2499*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_overlay },
2500*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2501*7687d0d8SRobert Mustacchi };
2502*7687d0d8SRobert Mustacchi 
2503*7687d0d8SRobert Mustacchi /*
2504*7687d0d8SRobert Mustacchi  * Various vendor extensions
2505*7687d0d8SRobert Mustacchi  */
2506*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vsec[] = {
2507*7687d0d8SRobert Mustacchi 	{ 0, 15, "id", "ID", PRDV_HEX },
2508*7687d0d8SRobert Mustacchi 	{ 16, 19, "rev", "Revision", PRDV_HEX },
2509*7687d0d8SRobert Mustacchi 	{ 20, 31, "len", "Length", PRDV_HEX },
2510*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2511*7687d0d8SRobert Mustacchi };
2512*7687d0d8SRobert Mustacchi 
2513*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vs[] = {
2514*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "length", "Length", pcieadm_cfgspace_print_hex },
2515*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2516*7687d0d8SRobert Mustacchi };
2517*7687d0d8SRobert Mustacchi 
2518*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vsec[] = {
2519*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2520*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2521*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "header", "Vendor-Specific Header",
2522*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vsec },
2523*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2524*7687d0d8SRobert Mustacchi };
2525*7687d0d8SRobert Mustacchi 
2526*7687d0d8SRobert Mustacchi /*
2527*7687d0d8SRobert Mustacchi  * Data Link Feature
2528*7687d0d8SRobert Mustacchi  */
2529*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dlf_cap[] = {
2530*7687d0d8SRobert Mustacchi 	{ 0, 0, "lsfc", "Local Scaled Flow Control", PRDV_STRVAL,
2531*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2532*7687d0d8SRobert Mustacchi 	{ 31, 31, "dlex", "Data Link Exchange", PRDV_STRVAL,
2533*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2534*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2535*7687d0d8SRobert Mustacchi };
2536*7687d0d8SRobert Mustacchi 
2537*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dlf_sts[] = {
2538*7687d0d8SRobert Mustacchi 	{ 0, 0, "rsfc", "Remote Scaled Flow Control", PRDV_STRVAL,
2539*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2540*7687d0d8SRobert Mustacchi 	{ 31, 31, "valid", "Remote Data Link Feature Valid", PRDV_STRVAL,
2541*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "invalid", "valid" } } },
2542*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2543*7687d0d8SRobert Mustacchi };
2544*7687d0d8SRobert Mustacchi 
2545*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_dlf[] = {
2546*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2547*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2548*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "Data Link Feature Capabilities",
2549*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dlf_cap },
2550*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "sts", "Data Link Feature Status",
2551*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dlf_sts },
2552*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2553*7687d0d8SRobert Mustacchi };
2554*7687d0d8SRobert Mustacchi 
2555*7687d0d8SRobert Mustacchi /*
2556*7687d0d8SRobert Mustacchi  * 16.0 GT/s cap
2557*7687d0d8SRobert Mustacchi  */
2558*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_cap[] = {
2559*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2560*7687d0d8SRobert Mustacchi };
2561*7687d0d8SRobert Mustacchi 
2562*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_ctl[] = {
2563*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2564*7687d0d8SRobert Mustacchi };
2565*7687d0d8SRobert Mustacchi 
2566*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_sts[] = {
2567*7687d0d8SRobert Mustacchi 	{ 0, 0, "eqcomp", "Equalization 16.0 GT/s Complete", PRDV_STRVAL,
2568*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
2569*7687d0d8SRobert Mustacchi 	{ 1, 1, "eqp1", "Equalization 16.0 GT/s Phase 1", PRDV_STRVAL,
2570*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
2571*7687d0d8SRobert Mustacchi 	{ 2, 2, "eqp2", "Equalization 16.0 GT/s Phase 2", PRDV_STRVAL,
2572*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
2573*7687d0d8SRobert Mustacchi 	{ 3, 3, "eqp3", "Equalization 16.0 GT/s Phase 3", PRDV_STRVAL,
2574*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
2575*7687d0d8SRobert Mustacchi 	{ 4, 4, "req", "Link Equalization Request 16.0 GT/s", PRDV_HEX },
2576*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2577*7687d0d8SRobert Mustacchi };
2578*7687d0d8SRobert Mustacchi 
2579*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_eq[] = {
2580*7687d0d8SRobert Mustacchi 	{ 0, 3, "dstxpre", "Downstream Port 16.0 GT/s Transmitter Preset",
2581*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
2582*7687d0d8SRobert Mustacchi 	{ 4, 7, "ustxpre", "Upstream Port 16.0 GT/s Transmitter Preset",
2583*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
2584*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2585*7687d0d8SRobert Mustacchi };
2586*7687d0d8SRobert Mustacchi 
2587*7687d0d8SRobert Mustacchi static void
2588*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_16geq(pcieadm_cfgspace_walk_t *walkp,
2589*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
2590*7687d0d8SRobert Mustacchi {
2591*7687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
2592*7687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
2593*7687d0d8SRobert Mustacchi 		    "secondary PCIe cap");
2594*7687d0d8SRobert Mustacchi 		return;
2595*7687d0d8SRobert Mustacchi 	}
2596*7687d0d8SRobert Mustacchi 
2597*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
2598*7687d0d8SRobert Mustacchi 		char eqshort[32], eqhuman[128];
2599*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
2600*7687d0d8SRobert Mustacchi 
2601*7687d0d8SRobert Mustacchi 		(void) snprintf(eqshort, sizeof (eqshort), "lane%u", i);
2602*7687d0d8SRobert Mustacchi 		(void) snprintf(eqhuman, sizeof (eqhuman), "Lane %u EQ Control",
2603*7687d0d8SRobert Mustacchi 		    i);
2604*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 1;
2605*7687d0d8SRobert Mustacchi 		p.pcp_len = 1;
2606*7687d0d8SRobert Mustacchi 		p.pcp_short = eqshort;
2607*7687d0d8SRobert Mustacchi 		p.pcp_human = eqhuman;
2608*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
2609*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_16g_eq;
2610*7687d0d8SRobert Mustacchi 
2611*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
2612*7687d0d8SRobert Mustacchi 	}
2613*7687d0d8SRobert Mustacchi }
2614*7687d0d8SRobert Mustacchi 
2615*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_16g[] = {
2616*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2617*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2618*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "16.0 GT/s Capabilities",
2619*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_cap },
2620*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl", "16.0 GT/s Control",
2621*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_ctl },
2622*7687d0d8SRobert Mustacchi 	{ 0xc, 4, "sts", "16.0 GT/s Status",
2623*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_sts },
2624*7687d0d8SRobert Mustacchi 	{ 0x10, 4, "ldpmis", "16.0 GT/s Local Data Parity Mismatch",
2625*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2626*7687d0d8SRobert Mustacchi 	{ 0x14, 4, "frpmis", "16.0 GT/s First Retimer Data Parity Mismatch",
2627*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2628*7687d0d8SRobert Mustacchi 	{ 0x18, 4, "srpmis", "16.0 GT/s Second Retimer Data Parity Mismatch",
2629*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2630*7687d0d8SRobert Mustacchi 	{ 0x1c, 4, "rsvd", "16.0 GT/s Second Retimer Data Parity Mismatch",
2631*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2632*7687d0d8SRobert Mustacchi 	{ 0x20, 1, "eqctl", "16.0 GT/s EQ Control",
2633*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_16geq },
2634*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2635*7687d0d8SRobert Mustacchi };
2636*7687d0d8SRobert Mustacchi 
2637*7687d0d8SRobert Mustacchi /*
2638*7687d0d8SRobert Mustacchi  * Receiver Margining
2639*7687d0d8SRobert Mustacchi  */
2640*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_margin_cap[] = {
2641*7687d0d8SRobert Mustacchi 	{ 0, 0, "sw", "Margining uses Driver Software", PRDV_STRVAL,
2642*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2643*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2644*7687d0d8SRobert Mustacchi };
2645*7687d0d8SRobert Mustacchi 
2646*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_margin_sts[] = {
2647*7687d0d8SRobert Mustacchi 	{ 0, 0, "ready", "Margining Ready", PRDV_STRVAL,
2648*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2649*7687d0d8SRobert Mustacchi 	{ 1, 1, "sw", "Margining Software Ready", PRDV_STRVAL,
2650*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2651*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2652*7687d0d8SRobert Mustacchi };
2653*7687d0d8SRobert Mustacchi 
2654*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_margin_lane[] = {
2655*7687d0d8SRobert Mustacchi 	{ 0, 2, "rxno", "Receiver Number", PRDV_HEX },
2656*7687d0d8SRobert Mustacchi 	{ 3, 5, "type", "Margin Type", PRDV_HEX },
2657*7687d0d8SRobert Mustacchi 	{ 6, 6, "model", "Usage Model", PRDV_HEX },
2658*7687d0d8SRobert Mustacchi 	{ 8, 15, "payload", "Margin Payload", PRDV_HEX },
2659*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2660*7687d0d8SRobert Mustacchi };
2661*7687d0d8SRobert Mustacchi 
2662*7687d0d8SRobert Mustacchi static void
2663*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_margin(pcieadm_cfgspace_walk_t *walkp,
2664*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
2665*7687d0d8SRobert Mustacchi {
2666*7687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
2667*7687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
2668*7687d0d8SRobert Mustacchi 		    "lane margining capability");
2669*7687d0d8SRobert Mustacchi 		return;
2670*7687d0d8SRobert Mustacchi 	}
2671*7687d0d8SRobert Mustacchi 
2672*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
2673*7687d0d8SRobert Mustacchi 		char mshort[32], mhuman[128];
2674*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
2675*7687d0d8SRobert Mustacchi 
2676*7687d0d8SRobert Mustacchi 		(void) snprintf(mshort, sizeof (mshort), "lane%uctl", i);
2677*7687d0d8SRobert Mustacchi 		(void) snprintf(mhuman, sizeof (mhuman), "Lane %u Margining "
2678*7687d0d8SRobert Mustacchi 		    "Control", i);
2679*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
2680*7687d0d8SRobert Mustacchi 		p.pcp_len = 2;
2681*7687d0d8SRobert Mustacchi 		p.pcp_short = mshort;
2682*7687d0d8SRobert Mustacchi 		p.pcp_human = mhuman;
2683*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
2684*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_margin_lane;
2685*7687d0d8SRobert Mustacchi 
2686*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
2687*7687d0d8SRobert Mustacchi 
2688*7687d0d8SRobert Mustacchi 		(void) snprintf(mshort, sizeof (mshort), "lane%usts", i);
2689*7687d0d8SRobert Mustacchi 		(void) snprintf(mhuman, sizeof (mhuman), "Lane %u Margining "
2690*7687d0d8SRobert Mustacchi 		    "Status", i);
2691*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + 2 + i * 4;
2692*7687d0d8SRobert Mustacchi 		p.pcp_len = 2;
2693*7687d0d8SRobert Mustacchi 		p.pcp_short = mshort;
2694*7687d0d8SRobert Mustacchi 		p.pcp_human = mhuman;
2695*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
2696*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_margin_lane;
2697*7687d0d8SRobert Mustacchi 
2698*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
2699*7687d0d8SRobert Mustacchi 	}
2700*7687d0d8SRobert Mustacchi }
2701*7687d0d8SRobert Mustacchi 
2702*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_margin[] = {
2703*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2704*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2705*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "Margining Port Capabilities",
2706*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_margin_cap },
2707*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "sts", "Margining Port Status",
2708*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_margin_sts },
2709*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "lane", "Margining Lane", pcieadm_cfgspace_print_margin },
2710*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2711*7687d0d8SRobert Mustacchi };
2712*7687d0d8SRobert Mustacchi 
2713*7687d0d8SRobert Mustacchi /*
2714*7687d0d8SRobert Mustacchi  * Serial Number Capability
2715*7687d0d8SRobert Mustacchi  */
2716*7687d0d8SRobert Mustacchi static void
2717*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_sn(pcieadm_cfgspace_walk_t *walkp,
2718*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
2719*7687d0d8SRobert Mustacchi {
2720*7687d0d8SRobert Mustacchi 	char sn[64];
2721*7687d0d8SRobert Mustacchi 	uint16_t off = walkp->pcw_capoff + print->pcp_off;
2722*7687d0d8SRobert Mustacchi 
2723*7687d0d8SRobert Mustacchi 	(void) snprintf(sn, sizeof (sn),
2724*7687d0d8SRobert Mustacchi 	    "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
2725*7687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 7], walkp->pcw_data->pcb_u8[off + 6],
2726*7687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 5], walkp->pcw_data->pcb_u8[off + 4],
2727*7687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 3], walkp->pcw_data->pcb_u8[off + 2],
2728*7687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 1], walkp->pcw_data->pcb_u8[off]);
2729*7687d0d8SRobert Mustacchi 
2730*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_puts(walkp, print, sn);
2731*7687d0d8SRobert Mustacchi }
2732*7687d0d8SRobert Mustacchi 
2733*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_sn[] = {
2734*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2735*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2736*7687d0d8SRobert Mustacchi 	{ 0x4, 8, "sn", "Serial Number", pcieadm_cfgspace_print_sn },
2737*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2738*7687d0d8SRobert Mustacchi };
2739*7687d0d8SRobert Mustacchi 
2740*7687d0d8SRobert Mustacchi /*
2741*7687d0d8SRobert Mustacchi  * TLP Processing Hints (TPH)
2742*7687d0d8SRobert Mustacchi  */
2743*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_tph_cap[] = {
2744*7687d0d8SRobert Mustacchi 	{ 0, 0, "nost", "No ST Mode", PRDV_STRVAL,
2745*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2746*7687d0d8SRobert Mustacchi 	{ 1, 1, "ivec", "Interrupt Vector Mode", PRDV_STRVAL,
2747*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2748*7687d0d8SRobert Mustacchi 	{ 2, 2, "dev", "Device Specific Mode", PRDV_STRVAL,
2749*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2750*7687d0d8SRobert Mustacchi 	{ 8, 8, "exttph", "Extended TPH Requester", PRDV_STRVAL,
2751*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2752*7687d0d8SRobert Mustacchi 	{ 9, 10, "loc", "ST Table Location", PRDV_STRVAL,
2753*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Not Present",
2754*7687d0d8SRobert Mustacchi 	    "In Capability Structure", "MSI-X" } } },
2755*7687d0d8SRobert Mustacchi 	{ 16, 26, "size", "ST Table Size", PRDV_HEX, { .prdv_hex = { 0, 1 } } },
2756*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2757*7687d0d8SRobert Mustacchi };
2758*7687d0d8SRobert Mustacchi 
2759*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_tph_ctl[] = {
2760*7687d0d8SRobert Mustacchi 	{ 0, 2, "mode", "ST Mode Select", PRDV_STRVAL,
2761*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No ST", "Interrupt Vector",
2762*7687d0d8SRobert Mustacchi 	    "Device Specific" } } },
2763*7687d0d8SRobert Mustacchi 	{ 8, 9, "en", "TPH Requester", PRDV_STRVAL,
2764*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Not Permitted", "TPH", NULL,
2765*7687d0d8SRobert Mustacchi 	    "TPH and Extended TPH" } } },
2766*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2767*7687d0d8SRobert Mustacchi };
2768*7687d0d8SRobert Mustacchi 
2769*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_tph_st[] = {
2770*7687d0d8SRobert Mustacchi 	{ 0, 7, "low", "ST Lower", PRDV_HEX },
2771*7687d0d8SRobert Mustacchi 	{ 8, 15, "up", "ST Upper", PRDV_HEX },
2772*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2773*7687d0d8SRobert Mustacchi };
2774*7687d0d8SRobert Mustacchi 
2775*7687d0d8SRobert Mustacchi /*
2776*7687d0d8SRobert Mustacchi  * The TPH ST table is only conditionally present in the capability. So we need
2777*7687d0d8SRobert Mustacchi  * to read the TPH capability register and then check if the table location and
2778*7687d0d8SRobert Mustacchi  * size are set here.
2779*7687d0d8SRobert Mustacchi  */
2780*7687d0d8SRobert Mustacchi static void
2781*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_tphst(pcieadm_cfgspace_walk_t *walkp,
2782*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
2783*7687d0d8SRobert Mustacchi {
2784*7687d0d8SRobert Mustacchi 	uint_t nents;
2785*7687d0d8SRobert Mustacchi 	uint32_t tphcap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
2786*7687d0d8SRobert Mustacchi 
2787*7687d0d8SRobert Mustacchi 	if (BITX(tphcap, 10, 9) != 1) {
2788*7687d0d8SRobert Mustacchi 		return;
2789*7687d0d8SRobert Mustacchi 	}
2790*7687d0d8SRobert Mustacchi 
2791*7687d0d8SRobert Mustacchi 	nents = BITX(tphcap, 26, 16) + 1;
2792*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < nents; i++) {
2793*7687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
2794*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
2795*7687d0d8SRobert Mustacchi 
2796*7687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "st%u", i);
2797*7687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "ST Table %u",
2798*7687d0d8SRobert Mustacchi 		    i);
2799*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 2;
2800*7687d0d8SRobert Mustacchi 		p.pcp_len = 2;
2801*7687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
2802*7687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
2803*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
2804*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_tph_st;
2805*7687d0d8SRobert Mustacchi 
2806*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
2807*7687d0d8SRobert Mustacchi 	}
2808*7687d0d8SRobert Mustacchi }
2809*7687d0d8SRobert Mustacchi 
2810*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_tph[] = {
2811*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2812*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2813*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "TPH Requester Capability",
2814*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_tph_cap },
2815*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl", "TPH Requester Control",
2816*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_tph_ctl },
2817*7687d0d8SRobert Mustacchi 	{ 0xc, 2, "table", "ST Table", pcieadm_cfgspace_print_tphst },
2818*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2819*7687d0d8SRobert Mustacchi };
2820*7687d0d8SRobert Mustacchi 
2821*7687d0d8SRobert Mustacchi /*
2822*7687d0d8SRobert Mustacchi  * SR-IOV
2823*7687d0d8SRobert Mustacchi  */
2824*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_cap[] = {
2825*7687d0d8SRobert Mustacchi 	{ 0, 0, "migration", "Migration", PRDV_STRVAL,
2826*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
2827*7687d0d8SRobert Mustacchi 	{ 1, 1, "ari", "ARI Capable Hierarchy Preserved", PRDV_STRVAL,
2828*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unpreserved", "preserved" } } },
2829*7687d0d8SRobert Mustacchi 	{ 2, 2, "vf10b", "VF 10-bit Tag Requester", PRDV_STRVAL,
2830*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unpreserved", "preserved" } } },
2831*7687d0d8SRobert Mustacchi 	{ 21, 31, "inum", "VF Migration Interrupt Message Number", PRDV_HEX },
2832*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2833*7687d0d8SRobert Mustacchi };
2834*7687d0d8SRobert Mustacchi 
2835*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_ctl[] = {
2836*7687d0d8SRobert Mustacchi 	{ 0, 0, "vf", "VF", PRDV_STRVAL,
2837*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2838*7687d0d8SRobert Mustacchi 	{ 1, 1, "vfm", "VF Migration", PRDV_STRVAL,
2839*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2840*7687d0d8SRobert Mustacchi 	{ 2, 2, "vfmi", "VF Migration Interrupt", PRDV_STRVAL,
2841*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2842*7687d0d8SRobert Mustacchi 	{ 3, 3, "ari", "ARI Capable Hierarchy", PRDV_STRVAL,
2843*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2844*7687d0d8SRobert Mustacchi 	{ 4, 4, "vf10b", "VF 10-bit Tag Requester", PRDV_STRVAL,
2845*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2846*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2847*7687d0d8SRobert Mustacchi };
2848*7687d0d8SRobert Mustacchi 
2849*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_sts[] = {
2850*7687d0d8SRobert Mustacchi 	{ 0, 0, "vfm", "VF Migration", PRDV_STRVAL,
2851*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "none", "requested" } } },
2852*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2853*7687d0d8SRobert Mustacchi };
2854*7687d0d8SRobert Mustacchi 
2855*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_pgsup[] = {
2856*7687d0d8SRobert Mustacchi 	{ 0, 31, "pgsz", "Supported Page Sizes", PRDV_BITFIELD,
2857*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4 KB", "8 KB", "16 KB", "32 KB",
2858*7687d0d8SRobert Mustacchi 	    "64 KB", "128 KB", "256 KB", "512 KB", "1 MB", "2 MB", "4 MB",
2859*7687d0d8SRobert Mustacchi 	    "8 MB", "16 MB", "32 MB", "64 MB", "128 MB", "256 MB", "512 MB",
2860*7687d0d8SRobert Mustacchi 	    "1 GB", "2 GB", "4 GB", "8 GB", "16 GB", "32 GB", "64 GB",
2861*7687d0d8SRobert Mustacchi 	    "128 GB", "256 GB", "512 GB", "1 TB", "2 TB", "4 TB", "8 TB" } } },
2862*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2863*7687d0d8SRobert Mustacchi };
2864*7687d0d8SRobert Mustacchi 
2865*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_pgen[] = {
2866*7687d0d8SRobert Mustacchi 	{ 0, 31, "pgsz", "System Page Sizes", PRDV_BITFIELD,
2867*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4 KB", "8 KB", "16 KB", "32 KB",
2868*7687d0d8SRobert Mustacchi 	    "64 KB", "128 KB", "256 KB", "512 KB", "1 MB", "2 MB", "4 MB",
2869*7687d0d8SRobert Mustacchi 	    "8 MB", "16 MB", "32 MB", "64 MB", "128 MB", "256 MB", "512 MB",
2870*7687d0d8SRobert Mustacchi 	    "1 GB", "2 GB", "4 GB", "8 GB", "16 GB", "32 GB", "64 GB",
2871*7687d0d8SRobert Mustacchi 	    "128 GB", "256 GB", "512 GB", "1 TB", "2 TB", "4 TB", "8 TB" } } },
2872*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2873*7687d0d8SRobert Mustacchi };
2874*7687d0d8SRobert Mustacchi 
2875*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_mig[] = {
2876*7687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "VF Migration State BIR", PRDV_STRVAL,
2877*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
2878*7687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
2879*7687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "VF Migration State Offset", PRDV_HEX,
2880*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
2881*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2882*7687d0d8SRobert Mustacchi };
2883*7687d0d8SRobert Mustacchi 
2884*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_sriov[] = {
2885*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
2886*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
2887*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "SR-IOV Capabilities",
2888*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_cap },
2889*7687d0d8SRobert Mustacchi 	{ 0x8, 2, "ctl", "SR-IOV Control",
2890*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_ctl },
2891*7687d0d8SRobert Mustacchi 	{ 0xa, 2, "sts", "SR-IOV Status",
2892*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_sts },
2893*7687d0d8SRobert Mustacchi 	{ 0xc, 2, "initvfs", "Initial VFs", pcieadm_cfgspace_print_hex },
2894*7687d0d8SRobert Mustacchi 	{ 0xe, 2, "totvfs", "Total VFs", pcieadm_cfgspace_print_hex },
2895*7687d0d8SRobert Mustacchi 	{ 0x10, 2, "numvfs", "Number VFs", pcieadm_cfgspace_print_hex },
2896*7687d0d8SRobert Mustacchi 	{ 0x12, 1, "dep", "Function Dependency Link",
2897*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
2898*7687d0d8SRobert Mustacchi 	{ 0x14, 2, "offset", "First VF Offset", pcieadm_cfgspace_print_hex },
2899*7687d0d8SRobert Mustacchi 	{ 0x16, 2, "stride", "VF Stride", pcieadm_cfgspace_print_hex },
2900*7687d0d8SRobert Mustacchi 	{ 0x1a, 2, "devid", "VF Device ID", pcieadm_cfgspace_print_hex },
2901*7687d0d8SRobert Mustacchi 	{ 0x1c, 4, "pgsz", "Supported Page Sizes",
2902*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_pgsup },
2903*7687d0d8SRobert Mustacchi 	{ 0x20, 4, "pgsz", "System Page Sizes",
2904*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_pgen },
2905*7687d0d8SRobert Mustacchi 	{ 0x24, 24, "vfbar", "Virtual Base Address Register",
2906*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
2907*7687d0d8SRobert Mustacchi 	{ 0x3c, 4, "migration", "VF Migration State Array",
2908*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_mig },
2909*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2910*7687d0d8SRobert Mustacchi };
2911*7687d0d8SRobert Mustacchi 
2912*7687d0d8SRobert Mustacchi /*
2913*7687d0d8SRobert Mustacchi  * PCI-X
2914*7687d0d8SRobert Mustacchi  */
2915*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_dev_ctl[] = {
2916*7687d0d8SRobert Mustacchi 	{ 0, 0, "dper", "Data Parity Error Recovery", PRDV_STRVAL,
2917*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2918*7687d0d8SRobert Mustacchi 	{ 1, 1, "ro", "Relaxed Ordering", PRDV_STRVAL,
2919*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
2920*7687d0d8SRobert Mustacchi 	{ 2, 3, "maxread", "Maximum Memory Read Byte Count", PRDV_STRVAL,
2921*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "512 bytes", "1024 bytes",
2922*7687d0d8SRobert Mustacchi 	    "2048 byes", "4096 bytes" } } },
2923*7687d0d8SRobert Mustacchi 	{ 4, 6, "maxsplit", "Maximum Outstanding Split Transactions",
2924*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "1", "2", "3", "4", "8",
2925*7687d0d8SRobert Mustacchi 	    "12", "16", "32" } } },
2926*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2927*7687d0d8SRobert Mustacchi };
2928*7687d0d8SRobert Mustacchi 
2929*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_dev_sts[] = {
2930*7687d0d8SRobert Mustacchi 	{ 0, 2, "func", "Function Number", PRDV_HEX },
2931*7687d0d8SRobert Mustacchi 	{ 3, 7, "dev", "Device Number", PRDV_HEX },
2932*7687d0d8SRobert Mustacchi 	{ 8, 15, "bus", "Bus Number", PRDV_HEX },
2933*7687d0d8SRobert Mustacchi 	{ 16, 16, "64bit", "64-bit Device", PRDV_STRVAL,
2934*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
2935*7687d0d8SRobert Mustacchi 	    "supported" } } },
2936*7687d0d8SRobert Mustacchi 	{ 17, 17, "133mhz", "133 MHz Capable", PRDV_STRVAL,
2937*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
2938*7687d0d8SRobert Mustacchi 	    "supported" } } },
2939*7687d0d8SRobert Mustacchi 	{ 18, 18, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
2940*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2941*7687d0d8SRobert Mustacchi 	{ 19, 19, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
2942*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2943*7687d0d8SRobert Mustacchi 	{ 20, 20, "complex", "Device Complexity", PRDV_STRVAL,
2944*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "simple", "bridge" } } },
2945*7687d0d8SRobert Mustacchi 	{ 21, 22, "maxread", "Designed Maximum Memory Read Byte Count",
2946*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "512 bytes",
2947*7687d0d8SRobert Mustacchi 	    "1024 bytes", "2048 byes", "4096 bytes" } } },
2948*7687d0d8SRobert Mustacchi 	{ 23, 25, "maxsplit", "Designed Maximum Outstanding Split Transactions",
2949*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "1", "2", "3", "4", "8",
2950*7687d0d8SRobert Mustacchi 	    "12", "16", "32" } } },
2951*7687d0d8SRobert Mustacchi 	{ 26, 28, "maxcread", "Designed Maximum Cumulative Read Size",
2952*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "8/1KB", "16/2KB",
2953*7687d0d8SRobert Mustacchi 	    "32/4KB", "64/8KB", "128/16KB", "256/32KB", "512/64KB",
2954*7687d0d8SRobert Mustacchi 	    "1024/128KB" } } },
2955*7687d0d8SRobert Mustacchi 	{ 29, 29, "rxspcoer", "Received Split Completion Error Message",
2956*7687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "no", "yes" } } },
2957*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2958*7687d0d8SRobert Mustacchi };
2959*7687d0d8SRobert Mustacchi 
2960*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_sec_sts[] = {
2961*7687d0d8SRobert Mustacchi 	{ 0, 0, "64bit", "64-bit Device", PRDV_STRVAL,
2962*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
2963*7687d0d8SRobert Mustacchi 	    "supported" } } },
2964*7687d0d8SRobert Mustacchi 	{ 1, 1, "133mhz", "133 MHz Capable", PRDV_STRVAL,
2965*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
2966*7687d0d8SRobert Mustacchi 	    "supported" } } },
2967*7687d0d8SRobert Mustacchi 	{ 2, 2, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
2968*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2969*7687d0d8SRobert Mustacchi 	{ 3, 3, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
2970*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2971*7687d0d8SRobert Mustacchi 	{ 4, 4, "spcoor", "Split Completion Overrun", PRDV_STRVAL,
2972*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2973*7687d0d8SRobert Mustacchi 	{ 5, 5, "sprde", "Split Request Delayed", PRDV_STRVAL,
2974*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2975*7687d0d8SRobert Mustacchi 	{ 6, 8, "freq", "Secondary Clock Frequency", PRDV_STRVAL,
2976*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "conventional", "66 MHz", "100 Mhz",
2977*7687d0d8SRobert Mustacchi 	    "133 MHz" } } },
2978*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
2979*7687d0d8SRobert Mustacchi };
2980*7687d0d8SRobert Mustacchi 
2981*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_bridge_sts[] = {
2982*7687d0d8SRobert Mustacchi 	{ 0, 2, "func", "Function Number", PRDV_HEX },
2983*7687d0d8SRobert Mustacchi 	{ 3, 7, "dev", "Device Number", PRDV_HEX },
2984*7687d0d8SRobert Mustacchi 	{ 8, 15, "bus", "Bus Number", PRDV_HEX },
2985*7687d0d8SRobert Mustacchi 	{ 16, 16, "64bit", "64-bit Device", PRDV_STRVAL,
2986*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
2987*7687d0d8SRobert Mustacchi 	    "supported" } } },
2988*7687d0d8SRobert Mustacchi 	{ 17, 17, "133mhz", "133 MHz Capable", PRDV_STRVAL,
2989*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
2990*7687d0d8SRobert Mustacchi 	    "supported" } } },
2991*7687d0d8SRobert Mustacchi 	{ 18, 18, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
2992*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2993*7687d0d8SRobert Mustacchi 	{ 19, 19, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
2994*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2995*7687d0d8SRobert Mustacchi 	{ 20, 20, "spcoor", "Split Completion Overrun", PRDV_STRVAL,
2996*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2997*7687d0d8SRobert Mustacchi 	{ 21, 21, "sprde", "Split Request Delayed", PRDV_STRVAL,
2998*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
2999*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3000*7687d0d8SRobert Mustacchi };
3001*7687d0d8SRobert Mustacchi 
3002*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_bridge_split[] = {
3003*7687d0d8SRobert Mustacchi 	{ 0, 15, "cap", "Split Transaction Capacity", PRDV_HEX },
3004*7687d0d8SRobert Mustacchi 	{ 16, 31, "limit", "Split Transaction Commitment Limit", PRDV_HEX },
3005*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3006*7687d0d8SRobert Mustacchi };
3007*7687d0d8SRobert Mustacchi 
3008*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcix_dev[] = {
3009*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "ctl", "PCI-X Command",
3010*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_dev_ctl },
3011*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "sts", "PCI-X Status",
3012*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_dev_sts },
3013*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3014*7687d0d8SRobert Mustacchi };
3015*7687d0d8SRobert Mustacchi 
3016*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcix_bridge[] = {
3017*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "secsts", "PCI-X Secondary Status",
3018*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_sec_sts },
3019*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "sts", "PCI-X Bridge Status",
3020*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_sts },
3021*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "ussplit", "Upstream Split Transaction",
3022*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_split },
3023*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "dssplit", "Downstream Split Transaction",
3024*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_split },
3025*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3026*7687d0d8SRobert Mustacchi };
3027*7687d0d8SRobert Mustacchi 
3028*7687d0d8SRobert Mustacchi /*
3029*7687d0d8SRobert Mustacchi  * Dynamic Power Allocation
3030*7687d0d8SRobert Mustacchi  */
3031*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpa_cap[] = {
3032*7687d0d8SRobert Mustacchi 	{ 0, 4, "substates", "Substate Max", PRDV_HEX,
3033*7687d0d8SRobert Mustacchi 	    { .prdv_hex = { 0, 1 } } },
3034*7687d0d8SRobert Mustacchi 	{ 8, 9, "tlu", "Transition Latency Unit", PRDV_STRVAL,
3035*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ms", "10 ms", "100 ms" } } },
3036*7687d0d8SRobert Mustacchi 	{ 12, 13, "pas", "Power Allocation Scale", PRDV_STRVAL,
3037*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "10.0x", "1.0x", "0.1x",
3038*7687d0d8SRobert Mustacchi 	    "0.01x" } } },
3039*7687d0d8SRobert Mustacchi 	{ 16, 23, "tlv0", "Transition Latency Value 0", PRDV_HEX },
3040*7687d0d8SRobert Mustacchi 	{ 24, 31, "tlv0", "Transition Latency Value 1", PRDV_HEX },
3041*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3042*7687d0d8SRobert Mustacchi };
3043*7687d0d8SRobert Mustacchi 
3044*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpa_sts[] = {
3045*7687d0d8SRobert Mustacchi 	{ 0, 4, "substate", "Substate Status", PRDV_HEX },
3046*7687d0d8SRobert Mustacchi 	{ 8, 8, "ctlen", "Substate Control Enabled", PRDV_STRVAL,
3047*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3048*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3049*7687d0d8SRobert Mustacchi };
3050*7687d0d8SRobert Mustacchi 
3051*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpa_ctl[] = {
3052*7687d0d8SRobert Mustacchi 	{ 0, 4, "substate", "Substate Control", PRDV_HEX },
3053*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3054*7687d0d8SRobert Mustacchi };
3055*7687d0d8SRobert Mustacchi 
3056*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_dpa[] = {
3057*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3058*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3059*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "DPA Capability",
3060*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_cap },
3061*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "lat", "DPA Latency Indicator", pcieadm_cfgspace_print_hex },
3062*7687d0d8SRobert Mustacchi 	{ 0xc, 2, "sts", "DPA Status",
3063*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_sts },
3064*7687d0d8SRobert Mustacchi 	{ 0xe, 2, "sts", "DPA Control",
3065*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_ctl },
3066*7687d0d8SRobert Mustacchi 	{ 0x10, 1, "paa", "DPA Power Allocation Array",
3067*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpa_paa },
3068*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3069*7687d0d8SRobert Mustacchi };
3070*7687d0d8SRobert Mustacchi 
3071*7687d0d8SRobert Mustacchi /*
3072*7687d0d8SRobert Mustacchi  * Power Budgeting
3073*7687d0d8SRobert Mustacchi  */
3074*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_powbudg_data[] = {
3075*7687d0d8SRobert Mustacchi 	{ 0, 7, "base", "Base Power", PRDV_HEX },
3076*7687d0d8SRobert Mustacchi 	{ 8, 9, "scale", "Data Scale", PRDV_STRVAL,
3077*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1.0x", "0.1x", "0.01x",
3078*7687d0d8SRobert Mustacchi 	    "0.001x" } } },
3079*7687d0d8SRobert Mustacchi 	{ 10, 12, "pmsub", "PM Substate", PRDV_STRVAL,
3080*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Default", "Device Specific",
3081*7687d0d8SRobert Mustacchi 	    "Device Specific", "Device Specific", "Device Specific",
3082*7687d0d8SRobert Mustacchi 	    "Device Specific", "Device Specific", "Device Specific" } } },
3083*7687d0d8SRobert Mustacchi 	{ 13, 14, "pmstate", "PM State", PRDV_STRVAL,
3084*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "D0", "D1", "D2", "D3" } } },
3085*7687d0d8SRobert Mustacchi 	{ 15, 17, "type", "Type", PRDV_STRVAL,
3086*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PME Aux", "Axiliary", "Idle",
3087*7687d0d8SRobert Mustacchi 	    "Sustained", "Sustained - EPRS", "Maximum - EPRS", NULL,
3088*7687d0d8SRobert Mustacchi 	    "Maximum" } } },
3089*7687d0d8SRobert Mustacchi 	{ 18, 20, "rail", "Power Rail", PRDV_STRVAL,
3090*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Power (12V)", "Power (3.3V)",
3091*7687d0d8SRobert Mustacchi 	    "Power (1.5V or 1.8V)", NULL, NULL, NULL, NULL, "Thermal" } } },
3092*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3093*7687d0d8SRobert Mustacchi };
3094*7687d0d8SRobert Mustacchi 
3095*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_powbudg_cap[] = {
3096*7687d0d8SRobert Mustacchi 	{ 0, 0, "sa", "System Allocated", PRDV_STRVAL,
3097*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
3098*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3099*7687d0d8SRobert Mustacchi };
3100*7687d0d8SRobert Mustacchi 
3101*7687d0d8SRobert Mustacchi 
3102*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_powbudg[] = {
3103*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3104*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3105*7687d0d8SRobert Mustacchi 	{ 0x4, 1, "sel", "Data Select", pcieadm_cfgspace_print_hex },
3106*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "data", "Data Regiser", pcieadm_cfgspace_print_regdef,
3107*7687d0d8SRobert Mustacchi 	    pcieadm_regdef_powbudg_data },
3108*7687d0d8SRobert Mustacchi 	{ 0xc, 0x1, "cap", "Power Budget Capability",
3109*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_powbudg_cap },
3110*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3111*7687d0d8SRobert Mustacchi };
3112*7687d0d8SRobert Mustacchi 
3113*7687d0d8SRobert Mustacchi /*
3114*7687d0d8SRobert Mustacchi  * Precision Time Management
3115*7687d0d8SRobert Mustacchi  */
3116*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ptm_cap[] = {
3117*7687d0d8SRobert Mustacchi 	{ 0, 0, "req", "PTM Requester", PRDV_STRVAL,
3118*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3119*7687d0d8SRobert Mustacchi 	{ 1, 1, "resp", "PTM Responder", PRDV_STRVAL,
3120*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3121*7687d0d8SRobert Mustacchi 	{ 2, 2, "root", "PTM Root", PRDV_STRVAL,
3122*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3123*7687d0d8SRobert Mustacchi 	{ 3, 3, "eptm", "ePTM", PRDV_STRVAL,
3124*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3125*7687d0d8SRobert Mustacchi 	{ 8, 15, "gran", "Local Clock Granularity", PRDV_HEX },
3126*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3127*7687d0d8SRobert Mustacchi };
3128*7687d0d8SRobert Mustacchi 
3129*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ptm_ctl[] = {
3130*7687d0d8SRobert Mustacchi 	{ 0, 0, "en", "PTM Enable", PRDV_STRVAL,
3131*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3132*7687d0d8SRobert Mustacchi 	{ 1, 1, "root", "Root Select", PRDV_STRVAL,
3133*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3134*7687d0d8SRobert Mustacchi 	{ 8, 15, "gran", "Effective Granularity", PRDV_HEX },
3135*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3136*7687d0d8SRobert Mustacchi };
3137*7687d0d8SRobert Mustacchi 
3138*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_info_ptm[] = {
3139*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3140*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3141*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "PTM Capability",
3142*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ptm_cap },
3143*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap", "PTM Control",
3144*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ptm_ctl },
3145*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3146*7687d0d8SRobert Mustacchi };
3147*7687d0d8SRobert Mustacchi 
3148*7687d0d8SRobert Mustacchi /*
3149*7687d0d8SRobert Mustacchi  * Address Translation Services (ATS)
3150*7687d0d8SRobert Mustacchi  */
3151*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ats_cap[] = {
3152*7687d0d8SRobert Mustacchi 	{ 0, 4, "invqd", "Invalidate Queue Depth", PRDV_HEX },
3153*7687d0d8SRobert Mustacchi 	{ 5, 5, "pgalign", "Page Aligned Request", PRDV_STRVAL,
3154*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
3155*7687d0d8SRobert Mustacchi 	{ 6, 6, "glbinv", "Global Invalidate", PRDV_STRVAL,
3156*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3157*7687d0d8SRobert Mustacchi 	{ 7, 7, "relo", "Relaxed Ordering", PRDV_STRVAL,
3158*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3159*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3160*7687d0d8SRobert Mustacchi };
3161*7687d0d8SRobert Mustacchi 
3162*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ats_ctl[] = {
3163*7687d0d8SRobert Mustacchi 	{ 0, 4, "stu", "Smallest Translation Unit", PRDV_HEX },
3164*7687d0d8SRobert Mustacchi 	{ 15, 15, "en", "Enable", PRDV_STRVAL,
3165*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3166*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3167*7687d0d8SRobert Mustacchi };
3168*7687d0d8SRobert Mustacchi 
3169*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ats[] = {
3170*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3171*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3172*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ATS Capability",
3173*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ats_cap },
3174*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "cap", "ATS Control",
3175*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ats_ctl },
3176*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3177*7687d0d8SRobert Mustacchi };
3178*7687d0d8SRobert Mustacchi 
3179*7687d0d8SRobert Mustacchi /*
3180*7687d0d8SRobert Mustacchi  * Page Request
3181*7687d0d8SRobert Mustacchi  */
3182*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pgreq_ctl[] = {
3183*7687d0d8SRobert Mustacchi 	{ 0, 0, "en", "Enable", PRDV_STRVAL,
3184*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3185*7687d0d8SRobert Mustacchi 	{ 1, 1, "reset", "Reset", PRDV_HEX },
3186*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3187*7687d0d8SRobert Mustacchi };
3188*7687d0d8SRobert Mustacchi 
3189*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pgreq_sts[] = {
3190*7687d0d8SRobert Mustacchi 	{ 0, 0, "rf", "Response Failure", PRDV_STRVAL,
3191*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
3192*7687d0d8SRobert Mustacchi 	{ 1, 1, "uprgi", "Unexpected Page Request Group Index", PRDV_STRVAL,
3193*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
3194*7687d0d8SRobert Mustacchi 	{ 8, 8, "stopped", "Stopped", PRDV_STRVAL,
3195*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
3196*7687d0d8SRobert Mustacchi 	{ 15, 15, "prgrpreq", "PRG Response PASID", PRDV_STRVAL,
3197*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
3198*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3199*7687d0d8SRobert Mustacchi };
3200*7687d0d8SRobert Mustacchi 
3201*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pgreq[] = {
3202*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3203*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3204*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "ctl", "Page Request Control",
3205*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pgreq_ctl },
3206*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "Page Request Status",
3207*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pgreq_sts },
3208*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap", "Outstanding Page Request Capacity",
3209*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
3210*7687d0d8SRobert Mustacchi 	{ 0xc, 4, "alloc", "Outstanding Page Request Allocation",
3211*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
3212*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3213*7687d0d8SRobert Mustacchi };
3214*7687d0d8SRobert Mustacchi 
3215*7687d0d8SRobert Mustacchi /*
3216*7687d0d8SRobert Mustacchi  * NULL Capability
3217*7687d0d8SRobert Mustacchi  */
3218*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_null[] = {
3219*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3220*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3221*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3222*7687d0d8SRobert Mustacchi };
3223*7687d0d8SRobert Mustacchi 
3224*7687d0d8SRobert Mustacchi /*
3225*7687d0d8SRobert Mustacchi  * Downstream Port Containment
3226*7687d0d8SRobert Mustacchi  */
3227*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_cap[] = {
3228*7687d0d8SRobert Mustacchi 	{ 0, 4, "inum", "DPC Interrupt Message Number", PRDV_HEX },
3229*7687d0d8SRobert Mustacchi 	{ 5, 5, "rpext", "Root Port Extensions", PRDV_STRVAL,
3230*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3231*7687d0d8SRobert Mustacchi 	{ 6, 6, "ptlpeb", "Poisoned TLP Egress Blocking", PRDV_STRVAL,
3232*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3233*7687d0d8SRobert Mustacchi 	{ 7, 7, "swtrig", "Software Triggering", PRDV_STRVAL,
3234*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3235*7687d0d8SRobert Mustacchi 	{ 8, 11, "logsz", "RP PIO Log Size", PRDV_HEX },
3236*7687d0d8SRobert Mustacchi 	{ 12, 12, "errcorr", "DL_Active ERR_COR Signaling", PRDV_STRVAL,
3237*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3238*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3239*7687d0d8SRobert Mustacchi };
3240*7687d0d8SRobert Mustacchi 
3241*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_ctl[] = {
3242*7687d0d8SRobert Mustacchi 	{ 0, 1, "trigger", "DPC Trigger", PRDV_STRVAL,
3243*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled, fatal",
3244*7687d0d8SRobert Mustacchi 	    "enabled, non-fatal" } } },
3245*7687d0d8SRobert Mustacchi 	{ 2, 2, "comp", "Completion Control", PRDV_STRVAL,
3246*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Completer Abort",
3247*7687d0d8SRobert Mustacchi 	    "Unsupported Request" } } },
3248*7687d0d8SRobert Mustacchi 	{ 3, 3, "intr", "Interrupt",
3249*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3250*7687d0d8SRobert Mustacchi 	{ 4, 4, "errcor", "ERR_COR",
3251*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3252*7687d0d8SRobert Mustacchi 	{ 5, 5, "ptlpeb", "Poisoned TLP Egress Blocking", PRDV_STRVAL,
3253*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3254*7687d0d8SRobert Mustacchi 	{ 6, 6, "swtrig", "Software Trigger", PRDV_HEX },
3255*7687d0d8SRobert Mustacchi 	{ 7, 7, "corerr", "DL_Active ERR_COR",
3256*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3257*7687d0d8SRobert Mustacchi 	{ 8, 8, "sigsfw", "SIG_SFW",
3258*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3259*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3260*7687d0d8SRobert Mustacchi };
3261*7687d0d8SRobert Mustacchi 
3262*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_sts[] = {
3263*7687d0d8SRobert Mustacchi 	{ 0, 0, "trigger", "Trigger Status", PRDV_STRVAL,
3264*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not triggered", "triggered" } } },
3265*7687d0d8SRobert Mustacchi 	{ 1, 2, "reason", "Trigger Reason", PRDV_STRVAL,
3266*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unmasked uncorrectable",
3267*7687d0d8SRobert Mustacchi 	    "ERR_NONFATAL received", "ERR_FATAL received",
3268*7687d0d8SRobert Mustacchi 	    "see extension" } } },
3269*7687d0d8SRobert Mustacchi 	{ 3, 3, "istatus", "Interrupt Status", PRDV_HEX },
3270*7687d0d8SRobert Mustacchi 	{ 4, 4, "rpbusy", "RP Busy", PRDV_STRVAL,
3271*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
3272*7687d0d8SRobert Mustacchi 	{ 5, 6, "extreason", "Trigger Reason Extension", PRDV_STRVAL,
3273*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "RP PIO", "Software Trigger" } } },
3274*7687d0d8SRobert Mustacchi 	{ 8, 12, "feptr", "RP PIO, First Error Pointer", PRDV_HEX },
3275*7687d0d8SRobert Mustacchi 	{ 13, 13, "sigsfw", "SIG_SFW Status", PRDV_HEX },
3276*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3277*7687d0d8SRobert Mustacchi };
3278*7687d0d8SRobert Mustacchi 
3279*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_rppio_bits[] = {
3280*7687d0d8SRobert Mustacchi 	{ 0, 0, "cfgur", "Configuration Request UR Completion", PRDV_HEX },
3281*7687d0d8SRobert Mustacchi 	{ 1, 1, "cfgca", "Configuration Request CA Completion", PRDV_HEX },
3282*7687d0d8SRobert Mustacchi 	{ 2, 2, "cfgcto", "Configuration Request Completion Timeout",
3283*7687d0d8SRobert Mustacchi 	    PRDV_HEX },
3284*7687d0d8SRobert Mustacchi 	{ 8, 8, "iour", "I/O UR Completion", PRDV_HEX },
3285*7687d0d8SRobert Mustacchi 	{ 9, 9, "ioca", "I/O CA Completion", PRDV_HEX },
3286*7687d0d8SRobert Mustacchi 	{ 10, 10, "iocto", "I/O Completion Timeout", PRDV_HEX },
3287*7687d0d8SRobert Mustacchi 	{ 8, 8, "memur", "Memory UR Completion", PRDV_HEX },
3288*7687d0d8SRobert Mustacchi 	{ 9, 9, "memca", "Memory CA Completion", PRDV_HEX },
3289*7687d0d8SRobert Mustacchi 	{ 10, 10, "memcto", "Memory Completion Timeout", PRDV_HEX },
3290*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3291*7687d0d8SRobert Mustacchi };
3292*7687d0d8SRobert Mustacchi 
3293*7687d0d8SRobert Mustacchi static void
3294*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_rppio(pcieadm_cfgspace_walk_t *walkp,
3295*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
3296*7687d0d8SRobert Mustacchi {
3297*7687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
3298*7687d0d8SRobert Mustacchi 
3299*7687d0d8SRobert Mustacchi 	if (BITX(cap, 5, 5) == 0) {
3300*7687d0d8SRobert Mustacchi 		return;
3301*7687d0d8SRobert Mustacchi 	}
3302*7687d0d8SRobert Mustacchi 
3303*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_regdef(walkp, print, arg);
3304*7687d0d8SRobert Mustacchi }
3305*7687d0d8SRobert Mustacchi 
3306*7687d0d8SRobert Mustacchi static void
3307*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_piohead(pcieadm_cfgspace_walk_t *walkp,
3308*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
3309*7687d0d8SRobert Mustacchi {
3310*7687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
3311*7687d0d8SRobert Mustacchi 	uint32_t nwords = BITX(cap, 11, 8);
3312*7687d0d8SRobert Mustacchi 
3313*7687d0d8SRobert Mustacchi 	if (BITX(cap, 5, 5) == 0 || nwords < 4) {
3314*7687d0d8SRobert Mustacchi 		return;
3315*7687d0d8SRobert Mustacchi 	}
3316*7687d0d8SRobert Mustacchi 
3317*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, NULL);
3318*7687d0d8SRobert Mustacchi }
3319*7687d0d8SRobert Mustacchi 
3320*7687d0d8SRobert Mustacchi static void
3321*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_impspec(pcieadm_cfgspace_walk_t *walkp,
3322*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
3323*7687d0d8SRobert Mustacchi {
3324*7687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
3325*7687d0d8SRobert Mustacchi 	uint32_t nwords = BITX(cap, 11, 8);
3326*7687d0d8SRobert Mustacchi 
3327*7687d0d8SRobert Mustacchi 	if (BITX(cap, 5, 5) == 0 || nwords < 5) {
3328*7687d0d8SRobert Mustacchi 		return;
3329*7687d0d8SRobert Mustacchi 	}
3330*7687d0d8SRobert Mustacchi 
3331*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, NULL);
3332*7687d0d8SRobert Mustacchi }
3333*7687d0d8SRobert Mustacchi 
3334*7687d0d8SRobert Mustacchi static void
3335*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_tlplog(pcieadm_cfgspace_walk_t *walkp,
3336*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
3337*7687d0d8SRobert Mustacchi {
3338*7687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
3339*7687d0d8SRobert Mustacchi 	int32_t nwords = BITX(cap, 11, 8);
3340*7687d0d8SRobert Mustacchi 
3341*7687d0d8SRobert Mustacchi 	if (nwords == 0 || BITX(cap, 5, 5) == 0) {
3342*7687d0d8SRobert Mustacchi 		return;
3343*7687d0d8SRobert Mustacchi 	}
3344*7687d0d8SRobert Mustacchi 
3345*7687d0d8SRobert Mustacchi 	if (nwords <= 9) {
3346*7687d0d8SRobert Mustacchi 		nwords -= 5;
3347*7687d0d8SRobert Mustacchi 	} else {
3348*7687d0d8SRobert Mustacchi 		nwords -= 4;
3349*7687d0d8SRobert Mustacchi 	}
3350*7687d0d8SRobert Mustacchi 
3351*7687d0d8SRobert Mustacchi 	for (int32_t i = 0; i < nwords; i++) {
3352*7687d0d8SRobert Mustacchi 		char tlpshort[32], tlphuman[128];
3353*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
3354*7687d0d8SRobert Mustacchi 
3355*7687d0d8SRobert Mustacchi 		(void) snprintf(tlpshort, sizeof (tlpshort), "%s%u",
3356*7687d0d8SRobert Mustacchi 		    print->pcp_short, i);
3357*7687d0d8SRobert Mustacchi 		(void) snprintf(tlphuman, sizeof (tlphuman), "%s %u",
3358*7687d0d8SRobert Mustacchi 		    print->pcp_human, i);
3359*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
3360*7687d0d8SRobert Mustacchi 		p.pcp_len = 4;
3361*7687d0d8SRobert Mustacchi 		p.pcp_short = tlpshort;
3362*7687d0d8SRobert Mustacchi 		p.pcp_human = tlphuman;
3363*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
3364*7687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
3365*7687d0d8SRobert Mustacchi 
3366*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
3367*7687d0d8SRobert Mustacchi 	}
3368*7687d0d8SRobert Mustacchi }
3369*7687d0d8SRobert Mustacchi 
3370*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_dpc[] = {
3371*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3372*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3373*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "DPC Capability",
3374*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_cap },
3375*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "DPC Control",
3376*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_ctl },
3377*7687d0d8SRobert Mustacchi 	{ 0x8, 2, "sts", "DPC Status",
3378*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_sts },
3379*7687d0d8SRobert Mustacchi 	{ 0xa, 2, "srcid", "DPC Error Source ID",
3380*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
3381*7687d0d8SRobert Mustacchi 	{ 0x10, 4, "rppiosts", "RP PIO Status",
3382*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
3383*7687d0d8SRobert Mustacchi 	{ 0x14, 4, "rppiomask", "RP PIO Mask ID",
3384*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
3385*7687d0d8SRobert Mustacchi 	{ 0x14, 4, "rppiosev", "RP PIO Severity",
3386*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
3387*7687d0d8SRobert Mustacchi 	{ 0x18, 4, "rppiose", "RP PIO SysError",
3388*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
3389*7687d0d8SRobert Mustacchi 	{ 0x1c, 4, "rppioex", "RP PIO Exception",
3390*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
3391*7687d0d8SRobert Mustacchi 	{ 0x20, 4, "rppiohl0", "RP PIO Header Log 0",
3392*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
3393*7687d0d8SRobert Mustacchi 	{ 0x24, 4, "rppiohl1", "RP PIO Header Log 1",
3394*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
3395*7687d0d8SRobert Mustacchi 	{ 0x28, 4, "rppiohl2", "RP PIO Header Log 2",
3396*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
3397*7687d0d8SRobert Mustacchi 	{ 0x2c, 4, "rppiohl3", "RP PIO Header Log 3",
3398*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
3399*7687d0d8SRobert Mustacchi 	{ 0x30, 4, "impspec", "RP PIO ImpSpec Log",
3400*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_impspec },
3401*7687d0d8SRobert Mustacchi 	{ 0x34, 16, "tlplog", "RP PIO TLP Prefix Log",
3402*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_tlplog },
3403*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3404*7687d0d8SRobert Mustacchi };
3405*7687d0d8SRobert Mustacchi 
3406*7687d0d8SRobert Mustacchi /*
3407*7687d0d8SRobert Mustacchi  * Virtual Channel Capability
3408*7687d0d8SRobert Mustacchi  */
3409*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_cap1[] = {
3410*7687d0d8SRobert Mustacchi 	{ 0, 2, "count", "Extended VC Count", PRDV_HEX },
3411*7687d0d8SRobert Mustacchi 	{ 4, 6, "lpcount", "Low Priority Extended VC Count", PRDV_HEX },
3412*7687d0d8SRobert Mustacchi 	{ 8, 9, "refclk", "Reference Clock", PRDV_STRVAL,
3413*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "100ns" } } },
3414*7687d0d8SRobert Mustacchi 	{ 10, 11, "patsz", "Port Arbitration Table Size", PRDV_STRVAL,
3415*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 bit", "2 bits", "4 bits",
3416*7687d0d8SRobert Mustacchi 	    "8 bits" } } },
3417*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3418*7687d0d8SRobert Mustacchi };
3419*7687d0d8SRobert Mustacchi 
3420*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_cap2[] = {
3421*7687d0d8SRobert Mustacchi 	{ 0, 7, "arbcap", "VC Arbitration Capability", PRDV_BITFIELD,
3422*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
3423*7687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
3424*7687d0d8SRobert Mustacchi 	    "128 phase weighted round robin" } } },
3425*7687d0d8SRobert Mustacchi 	{ 24, 31, "offset", "VC Arbitration Table Offset", PRDV_HEX },
3426*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3427*7687d0d8SRobert Mustacchi };
3428*7687d0d8SRobert Mustacchi 
3429*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_ctl[] = {
3430*7687d0d8SRobert Mustacchi 	{ 0, 0, "loadtbl", "Load VC Arbitration Table", PRDV_HEX },
3431*7687d0d8SRobert Mustacchi 	{ 1, 3, "arbtype", "VC Arbitration Select", PRDV_STRVAL,
3432*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
3433*7687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
3434*7687d0d8SRobert Mustacchi 	    "128 phase weighted round robin" } } },
3435*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3436*7687d0d8SRobert Mustacchi };
3437*7687d0d8SRobert Mustacchi 
3438*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_sts[] = {
3439*7687d0d8SRobert Mustacchi 	{ 0, 0, "table", "VC Arbitration Table Status", PRDV_HEX },
3440*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3441*7687d0d8SRobert Mustacchi };
3442*7687d0d8SRobert Mustacchi 
3443*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_rsrccap[] = {
3444*7687d0d8SRobert Mustacchi 	{ 0, 7, "arbcap", "Port Arbitration Capability", PRDV_BITFIELD,
3445*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
3446*7687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
3447*7687d0d8SRobert Mustacchi 	    "128 phase weighted round robin",
3448*7687d0d8SRobert Mustacchi 	    "128 phase time-based weighted round robin",
3449*7687d0d8SRobert Mustacchi 	    "256 phase weighted round robin" } } },
3450*7687d0d8SRobert Mustacchi 	{ 14, 14, "aps", "Advanced Packet Switching", PRDV_STRVAL,
3451*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3452*7687d0d8SRobert Mustacchi 	{ 15, 15, "rstx", "Reject Snoop Transactions", PRDV_STRVAL,
3453*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3454*7687d0d8SRobert Mustacchi 	{ 16, 22, "nslots", "Maximum Time Slots", PRDV_HEX,
3455*7687d0d8SRobert Mustacchi 	    { .prdv_hex = { 0, 1 } } },
3456*7687d0d8SRobert Mustacchi 	{ 24, 31, "offset", "VC Arbitration Table Offset", PRDV_HEX },
3457*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3458*7687d0d8SRobert Mustacchi };
3459*7687d0d8SRobert Mustacchi 
3460*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_rsrcctl[] = {
3461*7687d0d8SRobert Mustacchi 	{ 0, 7, "tcmap", "TC/VC Map", PRDV_HEX },
3462*7687d0d8SRobert Mustacchi 	{ 16, 16, "loadtbl", "Load VC Arbitration Table", PRDV_HEX },
3463*7687d0d8SRobert Mustacchi 	{ 17, 19, "arbtype", "Port Arbitration Select", PRDV_STRVAL,
3464*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
3465*7687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
3466*7687d0d8SRobert Mustacchi 	    "128 phase weighted round robin",
3467*7687d0d8SRobert Mustacchi 	    "128 phase time-based weighted round robin",
3468*7687d0d8SRobert Mustacchi 	    "256 phase weighted round robin" } } },
3469*7687d0d8SRobert Mustacchi 	{ 24, 26, "vcid", "VC ID", PRDV_HEX },
3470*7687d0d8SRobert Mustacchi 	{ 31, 31, "en", "VC Enable",
3471*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3472*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3473*7687d0d8SRobert Mustacchi };
3474*7687d0d8SRobert Mustacchi 
3475*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_rsrcsts[] = {
3476*7687d0d8SRobert Mustacchi 	{ 0, 0, "table", "Port Arbitration Table Status", PRDV_HEX },
3477*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3478*7687d0d8SRobert Mustacchi };
3479*7687d0d8SRobert Mustacchi 
3480*7687d0d8SRobert Mustacchi static void
3481*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_vc_rsrc(pcieadm_cfgspace_walk_t *walkp,
3482*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
3483*7687d0d8SRobert Mustacchi {
3484*7687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
3485*7687d0d8SRobert Mustacchi 	uint32_t nents = BITX(cap, 2, 0) + 1;
3486*7687d0d8SRobert Mustacchi 
3487*7687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < nents; i++) {
3488*7687d0d8SRobert Mustacchi 		char vcshort[32], vchuman[128];
3489*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
3490*7687d0d8SRobert Mustacchi 
3491*7687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrccap%u", i);
3492*7687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
3493*7687d0d8SRobert Mustacchi 		    "Capability", i);
3494*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10;
3495*7687d0d8SRobert Mustacchi 		p.pcp_len = 4;
3496*7687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
3497*7687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
3498*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
3499*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrccap;
3500*7687d0d8SRobert Mustacchi 
3501*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
3502*7687d0d8SRobert Mustacchi 
3503*7687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrcctl%u", i);
3504*7687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
3505*7687d0d8SRobert Mustacchi 		    "Control", i);
3506*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10 + 4;
3507*7687d0d8SRobert Mustacchi 		p.pcp_len = 4;
3508*7687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
3509*7687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
3510*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
3511*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrcctl;
3512*7687d0d8SRobert Mustacchi 
3513*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
3514*7687d0d8SRobert Mustacchi 
3515*7687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrcsts%u", i);
3516*7687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
3517*7687d0d8SRobert Mustacchi 		    "Status", i);
3518*7687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10 + 0xa;
3519*7687d0d8SRobert Mustacchi 		p.pcp_len = 2;
3520*7687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
3521*7687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
3522*7687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
3523*7687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrcsts;
3524*7687d0d8SRobert Mustacchi 
3525*7687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
3526*7687d0d8SRobert Mustacchi 	}
3527*7687d0d8SRobert Mustacchi }
3528*7687d0d8SRobert Mustacchi 
3529*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vc[] = {
3530*7687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
3531*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
3532*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap1", "Port VC Capability 1",
3533*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_cap1 },
3534*7687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap2", "Port VC Capability 2",
3535*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_cap2 },
3536*7687d0d8SRobert Mustacchi 	{ 0xc, 2, "ctl", "Port VC Control",
3537*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_ctl },
3538*7687d0d8SRobert Mustacchi 	{ 0xe, 2, "sts", "Port VC Status",
3539*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_sts },
3540*7687d0d8SRobert Mustacchi 	{ 0x10, 12, "vcrec", "VC Resource", pcieadm_cfgspace_print_vc_rsrc },
3541*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3542*7687d0d8SRobert Mustacchi };
3543*7687d0d8SRobert Mustacchi 
3544*7687d0d8SRobert Mustacchi /*
3545*7687d0d8SRobert Mustacchi  * HyperTransport
3546*7687d0d8SRobert Mustacchi  */
3547*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_intr[] = {
3548*7687d0d8SRobert Mustacchi 	{ 0x2, 1, "index", "Interrupt Discovery Index",
3549*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
3550*7687d0d8SRobert Mustacchi 	{ 0x4, 4, "dataport", "Interrupt Dataport",
3551*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
3552*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3553*7687d0d8SRobert Mustacchi };
3554*7687d0d8SRobert Mustacchi 
3555*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_command_pri[] = {
3556*7687d0d8SRobert Mustacchi 	{ 0, 4, "unitid", "Base Unit ID", PRDV_HEX },
3557*7687d0d8SRobert Mustacchi 	{ 5, 9, "count", "Unit Count", PRDV_HEX },
3558*7687d0d8SRobert Mustacchi 	{ 10, 10, "host", "Master Host", PRDV_HEX },
3559*7687d0d8SRobert Mustacchi 	{ 11, 11, "dir", "Default Direction", PRDV_STRVAL,
3560*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "towards host",
3561*7687d0d8SRobert Mustacchi 	    "away from host" } } },
3562*7687d0d8SRobert Mustacchi 	{ 12, 12, "drop", "Drop on Uninitialized Link", PRDV_HEX },
3563*7687d0d8SRobert Mustacchi 	{ 13, 15, "cap", "Capability ID", PRDV_HEX },
3564*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3565*7687d0d8SRobert Mustacchi };
3566*7687d0d8SRobert Mustacchi 
3567*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_command_sec[] = {
3568*7687d0d8SRobert Mustacchi 	{ 0, 0, "reset", "Warm Reset", PRDV_HEX },
3569*7687d0d8SRobert Mustacchi 	{ 1, 1, "de", "Double Ended", PRDV_HEX },
3570*7687d0d8SRobert Mustacchi 	{ 2, 6, "devno", "Device Number", PRDV_HEX },
3571*7687d0d8SRobert Mustacchi 	{ 7, 7, "chain", "Chain Side", PRDV_STRVAL,
3572*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "from host", "from chain" } } },
3573*7687d0d8SRobert Mustacchi 	{ 8, 8, "hide", "Host Hide", PRDV_STRVAL,
3574*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "visible", "hidden" } } },
3575*7687d0d8SRobert Mustacchi 	{ 10, 10, "target", "Act as Target", PRDV_HEX },
3576*7687d0d8SRobert Mustacchi 	{ 11, 11, "eocerr", "Host Inbound End of Chain Error", PRDV_HEX },
3577*7687d0d8SRobert Mustacchi 	{ 12, 12, "drop", "Drop on Uninitialized Link", PRDV_HEX },
3578*7687d0d8SRobert Mustacchi 	{ 13, 15, "cap", "Capability ID", PRDV_HEX },
3579*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3580*7687d0d8SRobert Mustacchi };
3581*7687d0d8SRobert Mustacchi 
3582*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkctl[] = {
3583*7687d0d8SRobert Mustacchi 	{ 0, 0, "srcid", "Source ID", PRDV_STRVAL,
3584*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3585*7687d0d8SRobert Mustacchi 	{ 1, 1, "cfl", "CRC Flood", PRDV_STRVAL,
3586*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3587*7687d0d8SRobert Mustacchi 	{ 2, 2, "cst", "CRC Start Test", PRDV_HEX },
3588*7687d0d8SRobert Mustacchi 	{ 3, 3, "cfer", "CRC Force Error", PRDV_STRVAL,
3589*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3590*7687d0d8SRobert Mustacchi 	{ 4, 4, "linkfail", "Link Failure", PRDV_HEX },
3591*7687d0d8SRobert Mustacchi 	{ 5, 5, "initcmp", "Initialization Complete", PRDV_HEX },
3592*7687d0d8SRobert Mustacchi 	{ 6, 6, "eoc", "End of Chain", PRDV_HEX },
3593*7687d0d8SRobert Mustacchi 	{ 7, 7, "txoff", "Transmitter Off", PRDV_STRVAL,
3594*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "transmitter on",
3595*7687d0d8SRobert Mustacchi 	    "transmitter off" } } },
3596*7687d0d8SRobert Mustacchi 	{ 8, 11, "crcerr", "CRC Error", PRDV_HEX },
3597*7687d0d8SRobert Mustacchi 	{ 12, 12, "isoc", "Isochronous Flow Control", PRDV_STRVAL,
3598*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3599*7687d0d8SRobert Mustacchi 	{ 13, 13, "ls", "LDTSTOP# Tristate", PRDV_STRVAL,
3600*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3601*7687d0d8SRobert Mustacchi 	{ 14, 14, "extctl", "Extended CTL Time", PRDV_HEX },
3602*7687d0d8SRobert Mustacchi 	{ 15, 15, "64b", "64-bit Addressing", PRDV_STRVAL,
3603*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3604*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3605*7687d0d8SRobert Mustacchi };
3606*7687d0d8SRobert Mustacchi 
3607*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkcfg[] = {
3608*7687d0d8SRobert Mustacchi 	{ 0, 2, "maxin", "Maximum Link Width In", PRDV_STRVAL,
3609*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
3610*7687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
3611*7687d0d8SRobert Mustacchi 	{ 3, 3, "dwfcinsup", "Doubleword Flow Control In", PRDV_STRVAL,
3612*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3613*7687d0d8SRobert Mustacchi 	{ 4, 6, "maxout", "Maximum Link Width Out", PRDV_STRVAL,
3614*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
3615*7687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
3616*7687d0d8SRobert Mustacchi 	{ 7, 7, "dwfcoutsup", "Doubleword Flow Control Out", PRDV_STRVAL,
3617*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3618*7687d0d8SRobert Mustacchi 	{ 8, 10, "linkin", "Link Width In", PRDV_STRVAL,
3619*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
3620*7687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
3621*7687d0d8SRobert Mustacchi 	{ 11, 11, "dwfcin", "Doubleword Flow Control In", PRDV_STRVAL,
3622*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3623*7687d0d8SRobert Mustacchi 	{ 12, 14, "linkout", "Link Width Out", PRDV_STRVAL,
3624*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
3625*7687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
3626*7687d0d8SRobert Mustacchi 	{ 15, 15, "dwfcout", "Doubleword Flow Control Out", PRDV_STRVAL,
3627*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3628*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3629*7687d0d8SRobert Mustacchi };
3630*7687d0d8SRobert Mustacchi 
3631*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_rev[] = {
3632*7687d0d8SRobert Mustacchi 	{ 0, 4, "minor", "Minor Revision", PRDV_HEX },
3633*7687d0d8SRobert Mustacchi 	{ 5, 7, "major", "Major Revision", PRDV_HEX },
3634*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3635*7687d0d8SRobert Mustacchi };
3636*7687d0d8SRobert Mustacchi 
3637*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkfreq[] = {
3638*7687d0d8SRobert Mustacchi 	{ 0, 4, "freq", "Link Frequency", PRDV_STRVAL,
3639*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "200 MHz", "300 MHz", "400 MHz",
3640*7687d0d8SRobert Mustacchi 	    "500 MHz", "600 MHz", "800 MHz", "1000 MHz", "1200 MHz", "1400 MHz",
3641*7687d0d8SRobert Mustacchi 	    "1600 MHz", "1800 MHz", "2000 MHz", "2200 MHz", "2400 MHz",
3642*7687d0d8SRobert Mustacchi 	    "2600 MHz", "Vendor Specfic" } } },
3643*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3644*7687d0d8SRobert Mustacchi };
3645*7687d0d8SRobert Mustacchi 
3646*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkerr[] = {
3647*7687d0d8SRobert Mustacchi 	{ 4, 4, "prot", "Protocol Error", PRDV_HEX },
3648*7687d0d8SRobert Mustacchi 	{ 5, 5, "over", "Overflow Error", PRDV_HEX },
3649*7687d0d8SRobert Mustacchi 	{ 6, 6, "eoc", "End of Chain Error", PRDV_HEX },
3650*7687d0d8SRobert Mustacchi 	{ 7, 7, "ctl", "CTL Timeout", PRDV_HEX },
3651*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3652*7687d0d8SRobert Mustacchi };
3653*7687d0d8SRobert Mustacchi 
3654*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkcap[] = {
3655*7687d0d8SRobert Mustacchi 	{ 0, 15, "freq", "Link Frequency", PRDV_BITFIELD,
3656*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "200 MHz", "300 MHz", "400 MHz",
3657*7687d0d8SRobert Mustacchi 	    "500 MHz", "600 MHz", "800 MHz", "1000 MHz", "1200 MHz", "1400 MHz",
3658*7687d0d8SRobert Mustacchi 	    "1600 MHz", "1800 MHz", "2000 MHz", "2200 MHz", "2400 MHz",
3659*7687d0d8SRobert Mustacchi 	    "2600 MHz", "Vendor Specfic" } } },
3660*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3661*7687d0d8SRobert Mustacchi };
3662*7687d0d8SRobert Mustacchi 
3663*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_feature[] = {
3664*7687d0d8SRobert Mustacchi 	{ 0, 0, "isofc", "Isochronous Flow Control", PRDV_STRVAL,
3665*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3666*7687d0d8SRobert Mustacchi 	{ 1, 1, "ls", "LDTSTOP#", PRDV_STRVAL,
3667*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3668*7687d0d8SRobert Mustacchi 	{ 2, 2, "crct", "CRC Test Mode", PRDV_STRVAL,
3669*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3670*7687d0d8SRobert Mustacchi 	{ 3, 3, "ectl", "Extended CTL Time", PRDV_STRVAL,
3671*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
3672*7687d0d8SRobert Mustacchi 	{ 4, 4, "64b", "64-bit Addressing", PRDV_STRVAL,
3673*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3674*7687d0d8SRobert Mustacchi 	{ 5, 5, "unitid", "UnitID Reorder", PRDV_STRVAL,
3675*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
3676*7687d0d8SRobert Mustacchi 	{ 6, 6, "srcid", "Source Identification Extension", PRDV_STRVAL,
3677*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
3678*7687d0d8SRobert Mustacchi 	{ 8, 8, "extreg", "Extended Register Set", PRDV_STRVAL,
3679*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
3680*7687d0d8SRobert Mustacchi 	{ 9, 9, "uscfg", "Upstream Configuration", PRDV_STRVAL,
3681*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3682*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3683*7687d0d8SRobert Mustacchi };
3684*7687d0d8SRobert Mustacchi 
3685*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_error[] = {
3686*7687d0d8SRobert Mustacchi 	{ 0, 0, "protfl", "Protocol Error Flood", PRDV_STRVAL,
3687*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3688*7687d0d8SRobert Mustacchi 	{ 1, 1, "ovfl", "Overflow Error Flood", PRDV_STRVAL,
3689*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3690*7687d0d8SRobert Mustacchi 	{ 2, 2, "protf", "Protocol Error Fatal", PRDV_STRVAL,
3691*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3692*7687d0d8SRobert Mustacchi 	{ 3, 3, "ovf", "Overflow Error Fatal", PRDV_STRVAL,
3693*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3694*7687d0d8SRobert Mustacchi 	{ 4, 4, "eocf", "End of Chain Fatal Error", PRDV_STRVAL,
3695*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3696*7687d0d8SRobert Mustacchi 	{ 5, 5, "respf", "Response Error Fatal", PRDV_STRVAL,
3697*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3698*7687d0d8SRobert Mustacchi 	{ 6, 6, "crcf", "CRC Error Fatal", PRDV_STRVAL,
3699*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3700*7687d0d8SRobert Mustacchi 	{ 7, 7, "sysf", "System Error Fatal", PRDV_STRVAL,
3701*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3702*7687d0d8SRobert Mustacchi 	{ 8, 8, "chain", "Chain Fail", PRDV_HEX },
3703*7687d0d8SRobert Mustacchi 	{ 9, 9, "resp", "Response Error", PRDV_HEX },
3704*7687d0d8SRobert Mustacchi 	{ 10, 10, "protnf", "Protocol Error Non-Fatal", PRDV_STRVAL,
3705*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3706*7687d0d8SRobert Mustacchi 	{ 11, 11, "ovfnf", "Overflow Error Non-Fatal", PRDV_STRVAL,
3707*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3708*7687d0d8SRobert Mustacchi 	{ 12, 12, "eocnf", "End of Chain Error Non-Fatal", PRDV_STRVAL,
3709*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3710*7687d0d8SRobert Mustacchi 	{ 13, 13, "respnf", "Response Error Non-Fatal", PRDV_STRVAL,
3711*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3712*7687d0d8SRobert Mustacchi 	{ 14, 14, "crcnf", "CRC Error Non-Fatal", PRDV_STRVAL,
3713*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3714*7687d0d8SRobert Mustacchi 	{ 15, 15, "sysnf", "System Error Non-Fatal", PRDV_STRVAL,
3715*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3716*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3717*7687d0d8SRobert Mustacchi };
3718*7687d0d8SRobert Mustacchi 
3719*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_memory[] = {
3720*7687d0d8SRobert Mustacchi 	{ 0, 8, "base", "Memory Base Upper 8 Bits", PRDV_HEX,
3721*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 32 } } },
3722*7687d0d8SRobert Mustacchi 	{ 9, 15, "limit", "Memory Limit Upper 8 Bits", PRDV_HEX,
3723*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 32 } } },
3724*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3725*7687d0d8SRobert Mustacchi };
3726*7687d0d8SRobert Mustacchi 
3727*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_pri[] = {
3728*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
3729*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_command_pri },
3730*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "linkctl0", "Link Control 0",
3731*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
3732*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "linkcfg0", "Link Configuration 0",
3733*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
3734*7687d0d8SRobert Mustacchi 	{ 0x8, 2, "linkctl1", "Link Control 1",
3735*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
3736*7687d0d8SRobert Mustacchi 	{ 0xa, 2, "linkcfg1", "Link Configuration 1",
3737*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
3738*7687d0d8SRobert Mustacchi 	{ 0xc, 1, "rev", "Revision",
3739*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_rev },
3740*7687d0d8SRobert Mustacchi 	{ 0xd, 1, "linkfreq0", "Link Frequency 0",
3741*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
3742*7687d0d8SRobert Mustacchi 	{ 0xd, 1, "linkerr0", "Link Error 0",
3743*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
3744*7687d0d8SRobert Mustacchi 	{ 0xe, 2, "linkfcap0", "Link Frequency Cap 0",
3745*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
3746*7687d0d8SRobert Mustacchi 	{ 0x10, 1, "feature", "Feature Capability",
3747*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_feature },
3748*7687d0d8SRobert Mustacchi 	{ 0x11, 1, "linkfreq1", "Link Frequency 1",
3749*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
3750*7687d0d8SRobert Mustacchi 	{ 0x11, 1, "linkerr1", "Link Error 1",
3751*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
3752*7687d0d8SRobert Mustacchi 	{ 0x12, 2, "linkfcap1", "Link Frequency Cap 1",
3753*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
3754*7687d0d8SRobert Mustacchi 	{ 0x14, 2, "scratch", "Enumeration Scratchpad",
3755*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
3756*7687d0d8SRobert Mustacchi 	{ 0x16, 2, "error", "Error Handling",
3757*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_error },
3758*7687d0d8SRobert Mustacchi 	{ 0x18, 2, "memory", "Memory",
3759*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_memory },
3760*7687d0d8SRobert Mustacchi 	{ 0x1a, 1, "bus", "Bus Number", pcieadm_cfgspace_print_hex },
3761*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3762*7687d0d8SRobert Mustacchi };
3763*7687d0d8SRobert Mustacchi 
3764*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_sec[] = {
3765*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
3766*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_command_sec },
3767*7687d0d8SRobert Mustacchi 	{ 0x4, 2, "linkctl", "Link Control",
3768*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
3769*7687d0d8SRobert Mustacchi 	{ 0x6, 2, "linkcfg", "Link Configuration",
3770*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
3771*7687d0d8SRobert Mustacchi 	{ 0x8, 1, "rev", "Revision",
3772*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_rev },
3773*7687d0d8SRobert Mustacchi 	{ 0x9, 1, "linkfreq", "Link Frequency 0",
3774*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
3775*7687d0d8SRobert Mustacchi 	{ 0x9, 1, "linkerr", "Link Error 0",
3776*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
3777*7687d0d8SRobert Mustacchi 	{ 0xa, 2, "linkfcap", "Link Frequency Cap 0",
3778*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
3779*7687d0d8SRobert Mustacchi 	{ 0xc, 2, "feature", "Feature Capability",
3780*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_feature },
3781*7687d0d8SRobert Mustacchi 	{ 0x10, 2, "scratch", "Enumeration Scratchpad",
3782*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
3783*7687d0d8SRobert Mustacchi 	{ 0x12, 2, "error", "Error Handling",
3784*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_error },
3785*7687d0d8SRobert Mustacchi 	{ 0x14, 2, "memory", "Memory",
3786*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_memory },
3787*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3788*7687d0d8SRobert Mustacchi };
3789*7687d0d8SRobert Mustacchi 
3790*7687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_msi[] = {
3791*7687d0d8SRobert Mustacchi 	{ 0, 0, "en", "Enable", PRDV_STRVAL,
3792*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3793*7687d0d8SRobert Mustacchi 	{ 1, 1, "fixed", "Fixed", PRDV_STRVAL,
3794*7687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
3795*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3796*7687d0d8SRobert Mustacchi };
3797*7687d0d8SRobert Mustacchi 
3798*7687d0d8SRobert Mustacchi static void
3799*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_ht_msi_addr(pcieadm_cfgspace_walk_t *walkp,
3800*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
3801*7687d0d8SRobert Mustacchi {
3802*7687d0d8SRobert Mustacchi 	uint8_t fixed = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 2];
3803*7687d0d8SRobert Mustacchi 
3804*7687d0d8SRobert Mustacchi 	if (BITX(fixed, 1, 1) != 0)
3805*7687d0d8SRobert Mustacchi 		return;
3806*7687d0d8SRobert Mustacchi 
3807*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, arg);
3808*7687d0d8SRobert Mustacchi }
3809*7687d0d8SRobert Mustacchi 
3810*7687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_msi[] = {
3811*7687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
3812*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_msi },
3813*7687d0d8SRobert Mustacchi 	{ 0x4, 8, "address", "MSI Address",
3814*7687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_ht_msi_addr },
3815*7687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
3816*7687d0d8SRobert Mustacchi };
3817*7687d0d8SRobert Mustacchi 
3818*7687d0d8SRobert Mustacchi /*
3819*7687d0d8SRobert Mustacchi  * Capability related tables
3820*7687d0d8SRobert Mustacchi  */
3821*7687d0d8SRobert Mustacchi typedef struct pcieadm_cap_vers {
3822*7687d0d8SRobert Mustacchi 	uint32_t ppr_vers;
3823*7687d0d8SRobert Mustacchi 	uint32_t ppr_len;
3824*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_t *ppr_print;
3825*7687d0d8SRobert Mustacchi } pcieadm_cap_vers_t;
3826*7687d0d8SRobert Mustacchi 
3827*7687d0d8SRobert Mustacchi typedef struct pcieadm_subcap {
3828*7687d0d8SRobert Mustacchi 	const char *psub_short;
3829*7687d0d8SRobert Mustacchi 	const char *psub_human;
3830*7687d0d8SRobert Mustacchi } pcieadm_subcap_t;
3831*7687d0d8SRobert Mustacchi 
3832*7687d0d8SRobert Mustacchi typedef struct pcieadm_pci_cap pcieadm_pci_cap_t;
3833*7687d0d8SRobert Mustacchi 
3834*7687d0d8SRobert Mustacchi typedef void (*pcieadm_cap_info_f)(pcieadm_cfgspace_walk_t *,
3835*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *, uint32_t, const pcieadm_cap_vers_t **,
3836*7687d0d8SRobert Mustacchi     uint32_t *, const pcieadm_subcap_t **);
3837*7687d0d8SRobert Mustacchi 
3838*7687d0d8SRobert Mustacchi struct pcieadm_pci_cap {
3839*7687d0d8SRobert Mustacchi 	uint32_t ppc_id;
3840*7687d0d8SRobert Mustacchi 	const char *ppc_short;
3841*7687d0d8SRobert Mustacchi 	const char *ppc_human;
3842*7687d0d8SRobert Mustacchi 	pcieadm_cap_info_f ppc_info;
3843*7687d0d8SRobert Mustacchi 	pcieadm_cap_vers_t ppc_vers[4];
3844*7687d0d8SRobert Mustacchi };
3845*7687d0d8SRobert Mustacchi 
3846*7687d0d8SRobert Mustacchi /*
3847*7687d0d8SRobert Mustacchi  * Capability version determinations.
3848*7687d0d8SRobert Mustacchi  */
3849*7687d0d8SRobert Mustacchi 
3850*7687d0d8SRobert Mustacchi static void
3851*7687d0d8SRobert Mustacchi pcieadm_cap_info_fixed(pcieadm_cfgspace_walk_t *walkp,
3852*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
3853*7687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
3854*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
3855*7687d0d8SRobert Mustacchi {
3856*7687d0d8SRobert Mustacchi 	*versp = &cap->ppc_vers[0];
3857*7687d0d8SRobert Mustacchi 	*lenp = cap->ppc_vers[0].ppr_len;
3858*7687d0d8SRobert Mustacchi 	*subcap = NULL;
3859*7687d0d8SRobert Mustacchi }
3860*7687d0d8SRobert Mustacchi 
3861*7687d0d8SRobert Mustacchi static void
3862*7687d0d8SRobert Mustacchi pcieadm_cap_info_vers(pcieadm_cfgspace_walk_t *walkp,
3863*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
3864*7687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
3865*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
3866*7687d0d8SRobert Mustacchi {
3867*7687d0d8SRobert Mustacchi 	uint8_t vers;
3868*7687d0d8SRobert Mustacchi 
3869*7687d0d8SRobert Mustacchi 	*subcap = NULL;
3870*7687d0d8SRobert Mustacchi 	vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
3871*7687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < ARRAY_SIZE(cap->ppc_vers); i++) {
3872*7687d0d8SRobert Mustacchi 		if (vers == cap->ppc_vers[i].ppr_vers &&
3873*7687d0d8SRobert Mustacchi 		    cap->ppc_vers[i].ppr_vers != 0) {
3874*7687d0d8SRobert Mustacchi 			*versp = &cap->ppc_vers[i];
3875*7687d0d8SRobert Mustacchi 			*lenp = cap->ppc_vers[i].ppr_len;
3876*7687d0d8SRobert Mustacchi 			return;
3877*7687d0d8SRobert Mustacchi 		}
3878*7687d0d8SRobert Mustacchi 	}
3879*7687d0d8SRobert Mustacchi 
3880*7687d0d8SRobert Mustacchi 	*versp = NULL;
3881*7687d0d8SRobert Mustacchi 	*lenp = 0;
3882*7687d0d8SRobert Mustacchi }
3883*7687d0d8SRobert Mustacchi 
3884*7687d0d8SRobert Mustacchi /*
3885*7687d0d8SRobert Mustacchi  * The PCI Power Management capability uses a 3-bit version ID as opposed to the
3886*7687d0d8SRobert Mustacchi  * standard 4-bit version.
3887*7687d0d8SRobert Mustacchi  */
3888*7687d0d8SRobert Mustacchi static void
3889*7687d0d8SRobert Mustacchi pcieadm_cap_info_pcipm(pcieadm_cfgspace_walk_t *walkp,
3890*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
3891*7687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
3892*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
3893*7687d0d8SRobert Mustacchi {
3894*7687d0d8SRobert Mustacchi 	uint8_t vers;
3895*7687d0d8SRobert Mustacchi 
3896*7687d0d8SRobert Mustacchi 	*subcap = NULL;
3897*7687d0d8SRobert Mustacchi 	vers = walkp->pcw_data->pcb_u8[off + 2] & 0x7;
3898*7687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < ARRAY_SIZE(cap->ppc_vers); i++) {
3899*7687d0d8SRobert Mustacchi 		if (vers == cap->ppc_vers[i].ppr_vers) {
3900*7687d0d8SRobert Mustacchi 			*versp = &cap->ppc_vers[i];
3901*7687d0d8SRobert Mustacchi 			*lenp = cap->ppc_vers[i].ppr_len;
3902*7687d0d8SRobert Mustacchi 			return;
3903*7687d0d8SRobert Mustacchi 		}
3904*7687d0d8SRobert Mustacchi 	}
3905*7687d0d8SRobert Mustacchi 
3906*7687d0d8SRobert Mustacchi 	*versp = NULL;
3907*7687d0d8SRobert Mustacchi 	*lenp = 0;
3908*7687d0d8SRobert Mustacchi }
3909*7687d0d8SRobert Mustacchi 
3910*7687d0d8SRobert Mustacchi /*
3911*7687d0d8SRobert Mustacchi  * The length of the MSI capability depends on bits in its control field. As
3912*7687d0d8SRobert Mustacchi  * such we use a custom function to extract the length and treat each of these
3913*7687d0d8SRobert Mustacchi  * variants as thought it were a different version.
3914*7687d0d8SRobert Mustacchi  */
3915*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32 = {
3916*7687d0d8SRobert Mustacchi 	0, 0xa, pcieadm_cap_msi_32
3917*7687d0d8SRobert Mustacchi };
3918*7687d0d8SRobert Mustacchi 
3919*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32ext = {
3920*7687d0d8SRobert Mustacchi 	0, 0xc, pcieadm_cap_msi_32ext
3921*7687d0d8SRobert Mustacchi };
3922*7687d0d8SRobert Mustacchi 
3923*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64 = {
3924*7687d0d8SRobert Mustacchi 	0, 0xe, pcieadm_cap_msi_64
3925*7687d0d8SRobert Mustacchi };
3926*7687d0d8SRobert Mustacchi 
3927*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64ext = {
3928*7687d0d8SRobert Mustacchi 	0, 0x10, pcieadm_cap_msi_64ext
3929*7687d0d8SRobert Mustacchi };
3930*7687d0d8SRobert Mustacchi 
3931*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32pvm = {
3932*7687d0d8SRobert Mustacchi 	0, 0x14, pcieadm_cap_msi_32pvm
3933*7687d0d8SRobert Mustacchi };
3934*7687d0d8SRobert Mustacchi 
3935*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64pvm = {
3936*7687d0d8SRobert Mustacchi 	0, 0x18, pcieadm_cap_msi_64pvm
3937*7687d0d8SRobert Mustacchi };
3938*7687d0d8SRobert Mustacchi 
3939*7687d0d8SRobert Mustacchi static void
3940*7687d0d8SRobert Mustacchi pcieadm_cap_info_msi(pcieadm_cfgspace_walk_t *walkp,
3941*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
3942*7687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
3943*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
3944*7687d0d8SRobert Mustacchi {
3945*7687d0d8SRobert Mustacchi 	uint16_t ctrl;
3946*7687d0d8SRobert Mustacchi 	boolean_t addr64, pvm, ext;
3947*7687d0d8SRobert Mustacchi 
3948*7687d0d8SRobert Mustacchi 	*subcap = NULL;
3949*7687d0d8SRobert Mustacchi 	ctrl = walkp->pcw_data->pcb_u8[off + 2] |
3950*7687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[off + 3] << 8);
3951*7687d0d8SRobert Mustacchi 	if (ctrl == PCI_EINVAL16) {
3952*7687d0d8SRobert Mustacchi 		warnx("failed to read MSI Message Control register");
3953*7687d0d8SRobert Mustacchi 		*lenp = 0;
3954*7687d0d8SRobert Mustacchi 		*versp = NULL;
3955*7687d0d8SRobert Mustacchi 		return;
3956*7687d0d8SRobert Mustacchi 	}
3957*7687d0d8SRobert Mustacchi 
3958*7687d0d8SRobert Mustacchi 	/*
3959*7687d0d8SRobert Mustacchi 	 * The MSI capability has three main things that control its size.
3960*7687d0d8SRobert Mustacchi 	 * 64-bit addressing adds 4 bytes. Per-Vector Masking adds 8 bytes and
3961*7687d0d8SRobert Mustacchi 	 * causes the Extended data addressing piece to always be present.
3962*7687d0d8SRobert Mustacchi 	 * Therefore we check first for pvm as it implies evt, effectively.
3963*7687d0d8SRobert Mustacchi 	 */
3964*7687d0d8SRobert Mustacchi 	addr64 = (ctrl & PCI_MSI_64BIT_MASK) != 0;
3965*7687d0d8SRobert Mustacchi 	pvm = (ctrl & PCI_MSI_PVM_MASK) != 0;
3966*7687d0d8SRobert Mustacchi 	ext = (ctrl & PCI_MSI_EMD_MASK) != 0;
3967*7687d0d8SRobert Mustacchi 
3968*7687d0d8SRobert Mustacchi 	if (pvm && addr64) {
3969*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64pvm;
3970*7687d0d8SRobert Mustacchi 	} else if (pvm) {
3971*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32pvm;
3972*7687d0d8SRobert Mustacchi 	} else if (addr64 && ext) {
3973*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64ext;
3974*7687d0d8SRobert Mustacchi 	} else if (addr64) {
3975*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64;
3976*7687d0d8SRobert Mustacchi 	} else if (ext) {
3977*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32ext;
3978*7687d0d8SRobert Mustacchi 	} else {
3979*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32;
3980*7687d0d8SRobert Mustacchi 	}
3981*7687d0d8SRobert Mustacchi 
3982*7687d0d8SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
3983*7687d0d8SRobert Mustacchi }
3984*7687d0d8SRobert Mustacchi 
3985*7687d0d8SRobert Mustacchi /*
3986*7687d0d8SRobert Mustacchi  * The AER Capability is technically different for PCIe-PCI bridges. If we find
3987*7687d0d8SRobert Mustacchi  * that device type here, then we need to use a different version information
3988*7687d0d8SRobert Mustacchi  * rather than the actual set defined with the device (which have changed over
3989*7687d0d8SRobert Mustacchi  * time).
3990*7687d0d8SRobert Mustacchi  */
3991*7687d0d8SRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_aer_bridge = {
3992*7687d0d8SRobert Mustacchi 	1, 0x4c, pcieadm_cap_aer_bridge
3993*7687d0d8SRobert Mustacchi };
3994*7687d0d8SRobert Mustacchi 
3995*7687d0d8SRobert Mustacchi static void
3996*7687d0d8SRobert Mustacchi pcieadm_cap_info_aer(pcieadm_cfgspace_walk_t *walkp,
3997*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
3998*7687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
3999*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
4000*7687d0d8SRobert Mustacchi {
4001*7687d0d8SRobert Mustacchi 	if (walkp->pcw_dtype == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
4002*7687d0d8SRobert Mustacchi 		uint8_t vers;
4003*7687d0d8SRobert Mustacchi 
4004*7687d0d8SRobert Mustacchi 		*subcap = NULL;
4005*7687d0d8SRobert Mustacchi 		vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
4006*7687d0d8SRobert Mustacchi 		if (vers != pcieadm_cap_vers_aer_bridge.ppr_vers) {
4007*7687d0d8SRobert Mustacchi 			warnx("encountered PCIe to PCI bridge with unknown "
4008*7687d0d8SRobert Mustacchi 			    "AER capability version: %u", vers);
4009*7687d0d8SRobert Mustacchi 			*lenp = 0;
4010*7687d0d8SRobert Mustacchi 			*versp = NULL;
4011*7687d0d8SRobert Mustacchi 			return;
4012*7687d0d8SRobert Mustacchi 		}
4013*7687d0d8SRobert Mustacchi 		*lenp = pcieadm_cap_vers_aer_bridge.ppr_len;
4014*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_aer_bridge;
4015*7687d0d8SRobert Mustacchi 	}
4016*7687d0d8SRobert Mustacchi 
4017*7687d0d8SRobert Mustacchi 	return (pcieadm_cap_info_vers(walkp, cap, off, versp, lenp, subcap));
4018*7687d0d8SRobert Mustacchi }
4019*7687d0d8SRobert Mustacchi 
4020*7687d0d8SRobert Mustacchi /*
4021*7687d0d8SRobert Mustacchi  * The PCI-X capability varies depending on the header type of the device.
4022*7687d0d8SRobert Mustacchi  * Therefore we simply use the device type to figure out what to do.
4023*7687d0d8SRobert Mustacchi  */
4024*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcix_dev = {
4025*7687d0d8SRobert Mustacchi 	0, 0x8, pcieadm_cap_pcix_dev
4026*7687d0d8SRobert Mustacchi };
4027*7687d0d8SRobert Mustacchi 
4028*7687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcix_bridge = {
4029*7687d0d8SRobert Mustacchi 	0, 0x10, pcieadm_cap_pcix_bridge
4030*7687d0d8SRobert Mustacchi };
4031*7687d0d8SRobert Mustacchi 
4032*7687d0d8SRobert Mustacchi static void
4033*7687d0d8SRobert Mustacchi pcieadm_cap_info_pcix(pcieadm_cfgspace_walk_t *walkp,
4034*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
4035*7687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
4036*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
4037*7687d0d8SRobert Mustacchi {
4038*7687d0d8SRobert Mustacchi 
4039*7687d0d8SRobert Mustacchi 	*subcap = NULL;
4040*7687d0d8SRobert Mustacchi 	switch (walkp->pcw_dtype) {
4041*7687d0d8SRobert Mustacchi 	case PCI_HEADER_ZERO:
4042*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcix_dev;
4043*7687d0d8SRobert Mustacchi 		break;
4044*7687d0d8SRobert Mustacchi 	case PCI_HEADER_ONE:
4045*7687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcix_bridge;
4046*7687d0d8SRobert Mustacchi 		break;
4047*7687d0d8SRobert Mustacchi 	default:
4048*7687d0d8SRobert Mustacchi 		warnx("encountered PCI-X capability with unsupported device "
4049*7687d0d8SRobert Mustacchi 		    "type: 0x%x\n", walkp->pcw_dtype);
4050*7687d0d8SRobert Mustacchi 		*lenp = 0;
4051*7687d0d8SRobert Mustacchi 		*versp = NULL;
4052*7687d0d8SRobert Mustacchi 		return;
4053*7687d0d8SRobert Mustacchi 	}
4054*7687d0d8SRobert Mustacchi 
4055*7687d0d8SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
4056*7687d0d8SRobert Mustacchi }
4057*7687d0d8SRobert Mustacchi 
4058*7687d0d8SRobert Mustacchi typedef struct pcieadm_cap_ht {
4059*7687d0d8SRobert Mustacchi 	uint32_t pch_capid;
4060*7687d0d8SRobert Mustacchi 	pcieadm_subcap_t pch_subcap;
4061*7687d0d8SRobert Mustacchi 	pcieadm_cap_vers_t pch_vers;
4062*7687d0d8SRobert Mustacchi } pcieadm_cap_ht_t;
4063*7687d0d8SRobert Mustacchi 
4064*7687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_cap_pri = {
4065*7687d0d8SRobert Mustacchi 	0x00, { "pri", "Primary" }, { 0, 0x1c, pcieadm_cap_ht_pri }
4066*7687d0d8SRobert Mustacchi };
4067*7687d0d8SRobert Mustacchi 
4068*7687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_cap_sec = {
4069*7687d0d8SRobert Mustacchi 	0x01, { "sec", "Secondary" }, { 0, 0x18, pcieadm_cap_ht_sec }
4070*7687d0d8SRobert Mustacchi };
4071*7687d0d8SRobert Mustacchi 
4072*7687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_caps[] = {
4073*7687d0d8SRobert Mustacchi 	{ 0x08, { "switch", "Switch" } },
4074*7687d0d8SRobert Mustacchi 	{ 0x10, { "intr", "Interrupt Discovery and Configuration" },
4075*7687d0d8SRobert Mustacchi 	    { 0, 8, pcieadm_cap_ht_intr } },
4076*7687d0d8SRobert Mustacchi 	{ 0x11, { "rev", "Revision ID" } },
4077*7687d0d8SRobert Mustacchi 	{ 0x12, { "unitid", "UnitID Clumping" } },
4078*7687d0d8SRobert Mustacchi 	{ 0x13, { "extcfg", "Extended Configuration Space Access" } },
4079*7687d0d8SRobert Mustacchi 	{ 0x14, { "addrmap", "Address Mapping" } },
4080*7687d0d8SRobert Mustacchi 	{ 0x15, { "msi", "MSI Mapping" },
4081*7687d0d8SRobert Mustacchi 	    { 0, 4, pcieadm_cap_ht_msi } },
4082*7687d0d8SRobert Mustacchi 	{ 0x16, { "dir", "DirectRoute" } },
4083*7687d0d8SRobert Mustacchi 	{ 0x17, { "vcset", "VCSet" } },
4084*7687d0d8SRobert Mustacchi 	{ 0x18, { "retry", "Retry Mode" } },
4085*7687d0d8SRobert Mustacchi 	{ 0x19, { "x86", "X86 Encoding" } },
4086*7687d0d8SRobert Mustacchi 	{ 0x1a, { "gen3", "Gen3" } },
4087*7687d0d8SRobert Mustacchi 	{ 0x1b, { "fle", "Function-Level Extension" } },
4088*7687d0d8SRobert Mustacchi 	{ 0x1c, { "pm", "Power Management" } },
4089*7687d0d8SRobert Mustacchi 	{ UINT32_MAX, NULL },
4090*7687d0d8SRobert Mustacchi };
4091*7687d0d8SRobert Mustacchi 
4092*7687d0d8SRobert Mustacchi static void
4093*7687d0d8SRobert Mustacchi pcieadm_cap_info_ht(pcieadm_cfgspace_walk_t *walkp,
4094*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
4095*7687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
4096*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
4097*7687d0d8SRobert Mustacchi {
4098*7687d0d8SRobert Mustacchi 	uint32_t base = walkp->pcw_data->pcb_u32[off / 4];
4099*7687d0d8SRobert Mustacchi 	uint32_t caplo = BITX(base, 31, 29);
4100*7687d0d8SRobert Mustacchi 	pcieadm_cap_ht_t *htcap = NULL;
4101*7687d0d8SRobert Mustacchi 
4102*7687d0d8SRobert Mustacchi 	*versp = NULL;
4103*7687d0d8SRobert Mustacchi 	*lenp = 0;
4104*7687d0d8SRobert Mustacchi 	*subcap = NULL;
4105*7687d0d8SRobert Mustacchi 
4106*7687d0d8SRobert Mustacchi 	if (caplo > 1) {
4107*7687d0d8SRobert Mustacchi 		uint32_t capid = BITX(base, 31, 27);
4108*7687d0d8SRobert Mustacchi 
4109*7687d0d8SRobert Mustacchi 		for (uint32_t i = 0; pcieadm_ht_caps[i].pch_capid != UINT32_MAX;
4110*7687d0d8SRobert Mustacchi 		    i++) {
4111*7687d0d8SRobert Mustacchi 			if (capid == pcieadm_ht_caps[i].pch_capid) {
4112*7687d0d8SRobert Mustacchi 				htcap = &pcieadm_ht_caps[i];
4113*7687d0d8SRobert Mustacchi 				break;
4114*7687d0d8SRobert Mustacchi 			}
4115*7687d0d8SRobert Mustacchi 		}
4116*7687d0d8SRobert Mustacchi 	} else if (caplo == 0) {
4117*7687d0d8SRobert Mustacchi 		htcap = &pcieadm_ht_cap_pri;
4118*7687d0d8SRobert Mustacchi 	} else if (caplo == 1) {
4119*7687d0d8SRobert Mustacchi 		htcap = &pcieadm_ht_cap_sec;
4120*7687d0d8SRobert Mustacchi 	}
4121*7687d0d8SRobert Mustacchi 
4122*7687d0d8SRobert Mustacchi 	if (htcap == NULL) {
4123*7687d0d8SRobert Mustacchi 		warnx("encountered unknown HyperTransport Capability 0x%x",
4124*7687d0d8SRobert Mustacchi 		    BITX(base, 31, 27));
4125*7687d0d8SRobert Mustacchi 		return;
4126*7687d0d8SRobert Mustacchi 	}
4127*7687d0d8SRobert Mustacchi 
4128*7687d0d8SRobert Mustacchi 	*subcap = &htcap->pch_subcap;
4129*7687d0d8SRobert Mustacchi 	if (htcap->pch_vers.ppr_print != NULL) {
4130*7687d0d8SRobert Mustacchi 		*versp = &htcap->pch_vers;
4131*7687d0d8SRobert Mustacchi 		*lenp = htcap->pch_vers.ppr_len;
4132*7687d0d8SRobert Mustacchi 	}
4133*7687d0d8SRobert Mustacchi }
4134*7687d0d8SRobert Mustacchi 
4135*7687d0d8SRobert Mustacchi pcieadm_pci_cap_t pcieadm_pci_caps[] = {
4136*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PM, "pcipm", "PCI Power Management",
4137*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_pcipm, { { 2, 8, pcieadm_cap_pcipm_v3 },
4138*7687d0d8SRobert Mustacchi 	    { 3, 8, pcieadm_cap_pcipm_v3 } } },
4139*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_AGP, "agp", "Accelerated Graphics Port" },
4140*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_VPD, "vpd", "Vital Product Data", pcieadm_cap_info_fixed,
4141*7687d0d8SRobert Mustacchi 	    { { 0, 8, pcieadm_cap_vpd } } },
4142*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SLOT_ID, "slot", "Slot Identification" },
4143*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_MSI, "msi", "Message Signaled Interrupts",
4144*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_msi },
4145*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_cPCI_HS, "cpci", "CompactPCI Hot Swap" },
4146*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PCIX, "pcix", "PCI-X", pcieadm_cap_info_pcix },
4147*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_HT, "ht", "HyperTransport", pcieadm_cap_info_ht },
4148*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_VS, "vs", "Vendor Specific", pcieadm_cap_info_fixed,
4149*7687d0d8SRobert Mustacchi 	    { { 0, 3, pcieadm_cap_vs } } },
4150*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_DEBUG_PORT, "dbg", "Debug Port", pcieadm_cap_info_fixed,
4151*7687d0d8SRobert Mustacchi 	    { { 0, 4, pcieadm_cap_debug } } },
4152*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_cPCI_CRC, "cpcicrc",
4153*7687d0d8SRobert Mustacchi 	    "CompactPCI Central Resource Control" },
4154*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PCI_HOTPLUG, "pcihp", "PCI Hot-Plug" },
4155*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_P2P_SUBSYS, "bdgsub", "PCI Bridge Subsystem Vendor ID",
4156*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_fixed, { 0, 8, pcieadm_cap_bridge_subsys } },
4157*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_AGP_8X, "agp8x", "AGP 8x" },
4158*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SECURE_DEV, "secdev", "Secure Device" },
4159*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PCI_E, "pcie", "PCI Express", pcieadm_cap_info_vers,
4160*7687d0d8SRobert Mustacchi 	    { { 1, 0x24, pcieadm_cap_pcie_v1 },
4161*7687d0d8SRobert Mustacchi 	    { 2, 0x3c, pcieadm_cap_pcie_v2 } } },
4162*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_MSI_X, "msix", "MSI-X", pcieadm_cap_info_fixed,
4163*7687d0d8SRobert Mustacchi 	    { { 0, 12, pcieadm_cap_msix } } },
4164*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SATA, "sata", "Serial ATA Configuration",
4165*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_fixed, { { 0, 8, pcieadm_cap_sata } } },
4166*7687d0d8SRobert Mustacchi 	/*
4167*7687d0d8SRobert Mustacchi 	 * Note, the AF feature doesn't have a version but encodes a length in
4168*7687d0d8SRobert Mustacchi 	 * the version field, so we cheat and use that.
4169*7687d0d8SRobert Mustacchi 	 */
4170*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_FLR, "af", "Advanced Features", pcieadm_cap_info_vers,
4171*7687d0d8SRobert Mustacchi 	    { { 6, 6, pcieadm_cap_af } } },
4172*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_EA, "ea", "Enhanced Allocation" },
4173*7687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_FPB, "fpb", "Flattening Portal Bridge" }
4174*7687d0d8SRobert Mustacchi };
4175*7687d0d8SRobert Mustacchi 
4176*7687d0d8SRobert Mustacchi pcieadm_pci_cap_t pcieadm_pcie_caps[] = {
4177*7687d0d8SRobert Mustacchi 	{ 0, "null", "NULL Capability", pcieadm_cap_info_fixed,
4178*7687d0d8SRobert Mustacchi 	    { { 0, 0x4, pcieadm_cap_null } } },
4179*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_AER, "aer", "Advanced Error Reporting",
4180*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_aer, { { 1, 0x38, pcieadm_cap_aer_v1 },
4181*7687d0d8SRobert Mustacchi 	    { 2, 0x48, pcieadm_cap_aer_v2 } } },
4182*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VC, "vc", "Virtual Channel", pcieadm_cap_info_vers,
4183*7687d0d8SRobert Mustacchi 	    { { 0x1, 0x1c, pcieadm_cap_vc } } },
4184*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SER, "sn", "Serial Number", pcieadm_cap_info_vers,
4185*7687d0d8SRobert Mustacchi 	    { { 1, 0xc, pcieadm_cap_sn } } },
4186*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PWR_BUDGET, "powbudg", "Power Budgeting",
4187*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_powbudg } } },
4188*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_LINK_DECL, "rcld",
4189*7687d0d8SRobert Mustacchi 	    "Root Complex Link Declaration" },
4190*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_INT_LINKCTRL, "rcilc",
4191*7687d0d8SRobert Mustacchi 	    "Root Complex Internal Link Control" },
4192*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_EVNT_CEA, "rcecea",
4193*7687d0d8SRobert Mustacchi 	    "Root Complex Event Collector Endpoint Aggregation" },
4194*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MFVC, "mfvc", "Multi-Function Virtual Channel" },
4195*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VC_WITH_MFVC, "vcwmfvc", "Virtual Channel with MFVC",
4196*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 0x1, 0x1c, pcieadm_cap_vc } } },
4197*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RCRB, "rcrb", "Root Complex Register Block" },
4198*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VS, "vsec", "Vendor Specific Extended Capability",
4199*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_vsec } } },
4200*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_CAC, "cac", "Configuration Access Correlation" },
4201*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ACS, "acs", "Access Control Services",
4202*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_acs } } },
4203*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ARI, "ari", "Alternative Routing-ID Interpretation",
4204*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ari } } },
4205*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ATS, "ats", "Access Translation Services",
4206*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ats } } },
4207*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SRIOV, "sriov", "Single Root I/O Virtualization",
4208*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x40, pcieadm_cap_sriov } } },
4209*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MRIOV, "mriov", "Multi-Root I/O Virtualization" },
4210*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MULTICAST, "mcast", "Multicast",
4211*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x30, pcieadm_cap_mcast } } },
4212*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PGREQ, "pgreq", "Page Request",
4213*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_pgreq } } },
4214*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_EA, "ea", "Enhanced Allocation" },
4215*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RESIZE_BAR, "rbar", "Resizable Bar" },
4216*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DPA, "dpa", "Dynamic Power Allocation",
4217*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_dpa } } },
4218*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_TPH_REQ, "tph", "TPH Requester",
4219*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_tph } } },
4220*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LTR, "ltr", "Latency Tolerance Reporting",
4221*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ltr } } },
4222*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PCIE2, "pcie2", "Secondary PCI Express",
4223*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_pcie2 } } },
4224*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PASID, "pasid", "Process Address Space ID",
4225*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_pasid } } },
4226*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LNR, "lnr", "LN Requester" },
4227*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DPC, "dpc", "Downstream Port Containment",
4228*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x30, pcieadm_cap_dpc } } },
4229*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_L1PM, "l1pm", "L1 PM Substates",
4230*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_l1pm_v1 },
4231*7687d0d8SRobert Mustacchi 	    { 2, 0x14, pcieadm_cap_l1pm_v2 } } },
4232*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PTM, "ptm", "Precision Time Management",
4233*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_info_ptm } } },
4234*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FRS, "frs", "FRS Queueing" },
4235*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RTR, "trt", "Readiness Time Reporting" },
4236*7687d0d8SRobert Mustacchi 	/*
4237*7687d0d8SRobert Mustacchi 	 * When we encounter a designated vendor specificaiton, in particular,
4238*7687d0d8SRobert Mustacchi 	 * for CXL, we'll want to set ppc_subcap so we can use reasonable
4239*7687d0d8SRobert Mustacchi 	 * filtering.
4240*7687d0d8SRobert Mustacchi 	 */
4241*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DVS, "dvsec",
4242*7687d0d8SRobert Mustacchi 	    "Designated Vendor-Specific Extended Capability" },
4243*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VFRBAR, "vfrbar", "Virtual Function Resizable BAR" },
4244*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DLF, "dlf", "Data Link Feature",
4245*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_dlf } } },
4246*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL16GT, "pl16g", "Physical Layer 16.0 GT/s",
4247*7687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x22, pcieadm_cap_16g } } },
4248*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LANE_MARGIN, "margin",
4249*7687d0d8SRobert Mustacchi 	    "Lane Margining at the Receiver", pcieadm_cap_info_vers,
4250*7687d0d8SRobert Mustacchi 	    { { 1, 0x8, pcieadm_cap_margin } } },
4251*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_HIEARCHY_ID, "hierid", "Hierarchy ID" },
4252*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_NPEM, "npem", "Native PCIe Enclosure Management" },
4253*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL32GT, "pl32g", "Physical Layer 32.0 GT/s" },
4254*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_AP, "ap", "Alternative Protocol" },
4255*7687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SFI, "sfi", "System Firmware Intermediary" }
4256*7687d0d8SRobert Mustacchi };
4257*7687d0d8SRobert Mustacchi 
4258*7687d0d8SRobert Mustacchi static const pcieadm_pci_cap_t *
4259*7687d0d8SRobert Mustacchi pcieadm_cfgspace_match_cap(uint32_t capid, boolean_t pcie)
4260*7687d0d8SRobert Mustacchi {
4261*7687d0d8SRobert Mustacchi 	uint_t ncaps;
4262*7687d0d8SRobert Mustacchi 	pcieadm_pci_cap_t *caps;
4263*7687d0d8SRobert Mustacchi 
4264*7687d0d8SRobert Mustacchi 	if (pcie) {
4265*7687d0d8SRobert Mustacchi 		ncaps = ARRAY_SIZE(pcieadm_pcie_caps);
4266*7687d0d8SRobert Mustacchi 		caps = pcieadm_pcie_caps;
4267*7687d0d8SRobert Mustacchi 	} else {
4268*7687d0d8SRobert Mustacchi 		ncaps = ARRAY_SIZE(pcieadm_pci_caps);
4269*7687d0d8SRobert Mustacchi 		caps = pcieadm_pci_caps;
4270*7687d0d8SRobert Mustacchi 	}
4271*7687d0d8SRobert Mustacchi 
4272*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < ncaps; i++) {
4273*7687d0d8SRobert Mustacchi 		if (caps[i].ppc_id == capid) {
4274*7687d0d8SRobert Mustacchi 			return (&caps[i]);
4275*7687d0d8SRobert Mustacchi 		}
4276*7687d0d8SRobert Mustacchi 	}
4277*7687d0d8SRobert Mustacchi 
4278*7687d0d8SRobert Mustacchi 	return (NULL);
4279*7687d0d8SRobert Mustacchi }
4280*7687d0d8SRobert Mustacchi 
4281*7687d0d8SRobert Mustacchi static void
4282*7687d0d8SRobert Mustacchi pcieadm_cfgspace_print_cap(pcieadm_cfgspace_walk_t *walkp, uint_t capid,
4283*7687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap_info, const pcieadm_cap_vers_t *vers_info,
4284*7687d0d8SRobert Mustacchi     const pcieadm_subcap_t *subcap)
4285*7687d0d8SRobert Mustacchi {
4286*7687d0d8SRobert Mustacchi 	boolean_t filter = B_FALSE;
4287*7687d0d8SRobert Mustacchi 
4288*7687d0d8SRobert Mustacchi 	/*
4289*7687d0d8SRobert Mustacchi 	 * If we don't recognize the capability, print out the ID if we're not
4290*7687d0d8SRobert Mustacchi 	 * filtering and not in parsable mode.
4291*7687d0d8SRobert Mustacchi 	 */
4292*7687d0d8SRobert Mustacchi 	if (cap_info == NULL) {
4293*7687d0d8SRobert Mustacchi 		if (walkp->pcw_ofmt == NULL &&
4294*7687d0d8SRobert Mustacchi 		    pcieadm_cfgspace_filter(walkp, NULL)) {
4295*7687d0d8SRobert Mustacchi 			warnx("encountered unknown capability ID 0x%x "
4296*7687d0d8SRobert Mustacchi 			    "unable to print or list", capid);
4297*7687d0d8SRobert Mustacchi 			pcieadm_print("Unknown Capability (0x%x)\n", capid);
4298*7687d0d8SRobert Mustacchi 		}
4299*7687d0d8SRobert Mustacchi 		return;
4300*7687d0d8SRobert Mustacchi 	}
4301*7687d0d8SRobert Mustacchi 
4302*7687d0d8SRobert Mustacchi 	/*
4303*7687d0d8SRobert Mustacchi 	 * Check to see if we should print this and in particular, if there's
4304*7687d0d8SRobert Mustacchi 	 * both a capability or subcapability, we need to try and match both.
4305*7687d0d8SRobert Mustacchi 	 * The reason that the calls to check the filters are conditioned on
4306*7687d0d8SRobert Mustacchi 	 * pcw_ofmt is that when we're in parsable mode, we cannot match a
4307*7687d0d8SRobert Mustacchi 	 * top-level capability since it's an arbitrary number of fields.
4308*7687d0d8SRobert Mustacchi 	 */
4309*7687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt == NULL) {
4310*7687d0d8SRobert Mustacchi 		filter = pcieadm_cfgspace_filter(walkp, cap_info->ppc_short);
4311*7687d0d8SRobert Mustacchi 	}
4312*7687d0d8SRobert Mustacchi 	pcieadm_strfilt_push(walkp, cap_info->ppc_short);
4313*7687d0d8SRobert Mustacchi 	if (subcap != NULL) {
4314*7687d0d8SRobert Mustacchi 		if (walkp->pcw_ofmt == NULL) {
4315*7687d0d8SRobert Mustacchi 			boolean_t subfilt = pcieadm_cfgspace_filter(walkp,
4316*7687d0d8SRobert Mustacchi 			    subcap->psub_short);
4317*7687d0d8SRobert Mustacchi 			filter = subfilt || filter;
4318*7687d0d8SRobert Mustacchi 		}
4319*7687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(walkp, subcap->psub_short);
4320*7687d0d8SRobert Mustacchi 	}
4321*7687d0d8SRobert Mustacchi 
4322*7687d0d8SRobert Mustacchi 
4323*7687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt == NULL && filter) {
4324*7687d0d8SRobert Mustacchi 		if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
4325*7687d0d8SRobert Mustacchi 			if (subcap != NULL) {
4326*7687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability - %s (%s) "
4327*7687d0d8SRobert Mustacchi 				    "(0x%x)\n", cap_info->ppc_human,
4328*7687d0d8SRobert Mustacchi 				    subcap->psub_human,
4329*7687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, capid);
4330*7687d0d8SRobert Mustacchi 			} else {
4331*7687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability (%s) (0x%x)\n",
4332*7687d0d8SRobert Mustacchi 				    cap_info->ppc_human,
4333*7687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, capid);
4334*7687d0d8SRobert Mustacchi 			}
4335*7687d0d8SRobert Mustacchi 		} else {
4336*7687d0d8SRobert Mustacchi 			if (subcap != NULL) {
4337*7687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability - %s (0x%x)\n",
4338*7687d0d8SRobert Mustacchi 				    cap_info->ppc_human, subcap->psub_human,
4339*7687d0d8SRobert Mustacchi 				    capid);
4340*7687d0d8SRobert Mustacchi 			} else {
4341*7687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability (0x%x)\n",
4342*7687d0d8SRobert Mustacchi 				    cap_info->ppc_human, capid);
4343*7687d0d8SRobert Mustacchi 			}
4344*7687d0d8SRobert Mustacchi 		}
4345*7687d0d8SRobert Mustacchi 	}
4346*7687d0d8SRobert Mustacchi 
4347*7687d0d8SRobert Mustacchi 	if (vers_info != NULL) {
4348*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t *print;
4349*7687d0d8SRobert Mustacchi 
4350*7687d0d8SRobert Mustacchi 		pcieadm_indent();
4351*7687d0d8SRobert Mustacchi 		for (print = vers_info->ppr_print;
4352*7687d0d8SRobert Mustacchi 		    print->pcp_short != NULL; print++) {
4353*7687d0d8SRobert Mustacchi 			VERIFY3P(print->pcp_print, !=, NULL);
4354*7687d0d8SRobert Mustacchi 			print->pcp_print(walkp, print,
4355*7687d0d8SRobert Mustacchi 			    print->pcp_arg);
4356*7687d0d8SRobert Mustacchi 		}
4357*7687d0d8SRobert Mustacchi 		pcieadm_deindent();
4358*7687d0d8SRobert Mustacchi 	} else {
4359*7687d0d8SRobert Mustacchi 		if (subcap != NULL) {
4360*7687d0d8SRobert Mustacchi 			warnx("Unable to print or list %s - %s (no support or "
4361*7687d0d8SRobert Mustacchi 			    "missing version info)", cap_info->ppc_human,
4362*7687d0d8SRobert Mustacchi 			    subcap->psub_human);
4363*7687d0d8SRobert Mustacchi 		} else {
4364*7687d0d8SRobert Mustacchi 			warnx("Unable to print or list %s (no support or "
4365*7687d0d8SRobert Mustacchi 			    "missing version info)", cap_info->ppc_human);
4366*7687d0d8SRobert Mustacchi 		}
4367*7687d0d8SRobert Mustacchi 	}
4368*7687d0d8SRobert Mustacchi 
4369*7687d0d8SRobert Mustacchi 	if (subcap != NULL) {
4370*7687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(walkp);
4371*7687d0d8SRobert Mustacchi 	}
4372*7687d0d8SRobert Mustacchi 	pcieadm_strfilt_pop(walkp);
4373*7687d0d8SRobert Mustacchi }
4374*7687d0d8SRobert Mustacchi 
4375*7687d0d8SRobert Mustacchi static void
4376*7687d0d8SRobert Mustacchi pcieadm_cfgspace_write(int fd, const uint8_t *source, size_t len)
4377*7687d0d8SRobert Mustacchi {
4378*7687d0d8SRobert Mustacchi 	size_t off = 0;
4379*7687d0d8SRobert Mustacchi 
4380*7687d0d8SRobert Mustacchi 	while (len > 0) {
4381*7687d0d8SRobert Mustacchi 		ssize_t ret = write(fd, source + off, len - off);
4382*7687d0d8SRobert Mustacchi 		if (ret < 0) {
4383*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to write config space to "
4384*7687d0d8SRobert Mustacchi 			    "output file");
4385*7687d0d8SRobert Mustacchi 		}
4386*7687d0d8SRobert Mustacchi 
4387*7687d0d8SRobert Mustacchi 		off += ret;
4388*7687d0d8SRobert Mustacchi 		len -= ret;
4389*7687d0d8SRobert Mustacchi 	}
4390*7687d0d8SRobert Mustacchi }
4391*7687d0d8SRobert Mustacchi 
4392*7687d0d8SRobert Mustacchi void
4393*7687d0d8SRobert Mustacchi pcieadm_cfgspace(pcieadm_t *pcip, pcieadm_cfgspace_op_t op,
4394*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_f readf, int fd, void *readarg, uint_t nfilts,
4395*7687d0d8SRobert Mustacchi     pcieadm_cfgspace_filter_t *filters, pcieadm_cfgspace_flags_t flags,
4396*7687d0d8SRobert Mustacchi     ofmt_handle_t ofmt)
4397*7687d0d8SRobert Mustacchi {
4398*7687d0d8SRobert Mustacchi 	uint_t type;
4399*7687d0d8SRobert Mustacchi 	uint16_t cap;
4400*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_data_t data;
4401*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_walk_t walk;
4402*7687d0d8SRobert Mustacchi 	const char *headstr, *headshort;
4403*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_t *header;
4404*7687d0d8SRobert Mustacchi 	boolean_t capsup = B_FALSE, extcfg = B_FALSE;
4405*7687d0d8SRobert Mustacchi 	uint_t ncaps;
4406*7687d0d8SRobert Mustacchi 
4407*7687d0d8SRobert Mustacchi 	walk.pcw_pcieadm = pcip;
4408*7687d0d8SRobert Mustacchi 	walk.pcw_op = op;
4409*7687d0d8SRobert Mustacchi 	walk.pcw_data = &data;
4410*7687d0d8SRobert Mustacchi 	walk.pcw_outfd = fd;
4411*7687d0d8SRobert Mustacchi 	walk.pcw_capoff = 0;
4412*7687d0d8SRobert Mustacchi 	walk.pcw_nlanes = 0;
4413*7687d0d8SRobert Mustacchi 	walk.pcw_nfilters = nfilts;
4414*7687d0d8SRobert Mustacchi 	walk.pcw_filters = filters;
4415*7687d0d8SRobert Mustacchi 	walk.pcw_flags = flags;
4416*7687d0d8SRobert Mustacchi 	walk.pcw_ofmt = ofmt;
4417*7687d0d8SRobert Mustacchi 	walk.pcw_filt = NULL;
4418*7687d0d8SRobert Mustacchi 
4419*7687d0d8SRobert Mustacchi 	/*
4420*7687d0d8SRobert Mustacchi 	 * Start by reading all of the basic 40-byte config space header in one
4421*7687d0d8SRobert Mustacchi 	 * fell swoop.
4422*7687d0d8SRobert Mustacchi 	 */
4423*7687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < PCI_CAP_PTR_OFF / 4; i++) {
4424*7687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
4425*7687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
4426*7687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
4427*7687d0d8SRobert Mustacchi 		}
4428*7687d0d8SRobert Mustacchi 	}
4429*7687d0d8SRobert Mustacchi 	walk.pcw_valid = PCI_CAP_PTR_OFF;
4430*7687d0d8SRobert Mustacchi 	walk.pcw_caplen = PCI_CAP_PTR_OFF;
4431*7687d0d8SRobert Mustacchi 
4432*7687d0d8SRobert Mustacchi 	/*
4433*7687d0d8SRobert Mustacchi 	 * Grab the information from the header that we need to figure out what
4434*7687d0d8SRobert Mustacchi 	 * kind of device this is, how to print it, if there are any
4435*7687d0d8SRobert Mustacchi 	 * capabilities, and go from there.
4436*7687d0d8SRobert Mustacchi 	 */
4437*7687d0d8SRobert Mustacchi 	type = data.pcb_u8[PCI_CONF_HEADER] & PCI_HEADER_TYPE_M;
4438*7687d0d8SRobert Mustacchi 	switch (type) {
4439*7687d0d8SRobert Mustacchi 	case PCI_HEADER_ZERO:
4440*7687d0d8SRobert Mustacchi 		headstr = "Type 0 Header";
4441*7687d0d8SRobert Mustacchi 		headshort = "header0";
4442*7687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_type0;
4443*7687d0d8SRobert Mustacchi 		capsup = (data.pcb_u8[PCI_CONF_STAT] & PCI_STAT_CAP) != 0;
4444*7687d0d8SRobert Mustacchi 		break;
4445*7687d0d8SRobert Mustacchi 	case PCI_HEADER_ONE:
4446*7687d0d8SRobert Mustacchi 		headstr = "Type 1 Header";
4447*7687d0d8SRobert Mustacchi 		headshort = "header1";
4448*7687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_type1;
4449*7687d0d8SRobert Mustacchi 		capsup = (data.pcb_u8[PCI_CONF_STAT] & PCI_STAT_CAP) != 0;
4450*7687d0d8SRobert Mustacchi 		break;
4451*7687d0d8SRobert Mustacchi 	case PCI_HEADER_TWO:
4452*7687d0d8SRobert Mustacchi 	default:
4453*7687d0d8SRobert Mustacchi 		headstr = "Unknown Header";
4454*7687d0d8SRobert Mustacchi 		headshort = "headerX";
4455*7687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_unknown;
4456*7687d0d8SRobert Mustacchi 		warnx("unsupported PCI header type: 0x%x, output limited to "
4457*7687d0d8SRobert Mustacchi 		    "data configuration space");
4458*7687d0d8SRobert Mustacchi 	}
4459*7687d0d8SRobert Mustacchi 
4460*7687d0d8SRobert Mustacchi 	walk.pcw_dtype = type;
4461*7687d0d8SRobert Mustacchi 
4462*7687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
4463*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[0], PCI_CAP_PTR_OFF);
4464*7687d0d8SRobert Mustacchi 	} else if (op == PCIEADM_CFGSPACE_OP_PRINT) {
4465*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t *print;
4466*7687d0d8SRobert Mustacchi 
4467*7687d0d8SRobert Mustacchi 		if (walk.pcw_ofmt == NULL &&
4468*7687d0d8SRobert Mustacchi 		    pcieadm_cfgspace_filter(&walk, headshort)) {
4469*7687d0d8SRobert Mustacchi 			if ((flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
4470*7687d0d8SRobert Mustacchi 				pcieadm_print("Device %s -- %s (%s)\n",
4471*7687d0d8SRobert Mustacchi 				    pcip->pia_devstr, headstr, headshort);
4472*7687d0d8SRobert Mustacchi 			} else {
4473*7687d0d8SRobert Mustacchi 				pcieadm_print("Device %s -- %s\n",
4474*7687d0d8SRobert Mustacchi 				    pcip->pia_devstr, headstr);
4475*7687d0d8SRobert Mustacchi 			}
4476*7687d0d8SRobert Mustacchi 		}
4477*7687d0d8SRobert Mustacchi 
4478*7687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(&walk, headshort);
4479*7687d0d8SRobert Mustacchi 		pcieadm_indent();
4480*7687d0d8SRobert Mustacchi 		for (print = header; print->pcp_short != NULL; print++) {
4481*7687d0d8SRobert Mustacchi 			print->pcp_print(&walk, print, print->pcp_arg);
4482*7687d0d8SRobert Mustacchi 		}
4483*7687d0d8SRobert Mustacchi 		pcieadm_deindent();
4484*7687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(&walk);
4485*7687d0d8SRobert Mustacchi 	}
4486*7687d0d8SRobert Mustacchi 
4487*7687d0d8SRobert Mustacchi 
4488*7687d0d8SRobert Mustacchi 	if (!capsup) {
4489*7687d0d8SRobert Mustacchi 		return;
4490*7687d0d8SRobert Mustacchi 	}
4491*7687d0d8SRobert Mustacchi 
4492*7687d0d8SRobert Mustacchi 	for (uint32_t i = PCI_CAP_PTR_OFF / 4; i < PCI_CONF_HDR_SIZE / 4; i++) {
4493*7687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
4494*7687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
4495*7687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
4496*7687d0d8SRobert Mustacchi 		}
4497*7687d0d8SRobert Mustacchi 	}
4498*7687d0d8SRobert Mustacchi 	walk.pcw_valid = PCIE_EXT_CAP;
4499*7687d0d8SRobert Mustacchi 	VERIFY3P(walk.pcw_filt, ==, NULL);
4500*7687d0d8SRobert Mustacchi 
4501*7687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
4502*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[PCI_CAP_PTR_OFF],
4503*7687d0d8SRobert Mustacchi 		    PCI_CONF_HDR_SIZE - PCI_CAP_PTR_OFF);
4504*7687d0d8SRobert Mustacchi 	}
4505*7687d0d8SRobert Mustacchi 
4506*7687d0d8SRobert Mustacchi 	ncaps = 0;
4507*7687d0d8SRobert Mustacchi 	cap = data.pcb_u8[PCI_CONF_CAP_PTR];
4508*7687d0d8SRobert Mustacchi 	while (cap != 0 && cap != PCI_EINVAL8) {
4509*7687d0d8SRobert Mustacchi 		const pcieadm_pci_cap_t *cap_info;
4510*7687d0d8SRobert Mustacchi 		const pcieadm_cap_vers_t *vers_info = NULL;
4511*7687d0d8SRobert Mustacchi 		const pcieadm_subcap_t *subcap = NULL;
4512*7687d0d8SRobert Mustacchi 		uint8_t cap_id, nextcap;
4513*7687d0d8SRobert Mustacchi 		uint32_t read_len = 0;
4514*7687d0d8SRobert Mustacchi 
4515*7687d0d8SRobert Mustacchi 		/*
4516*7687d0d8SRobert Mustacchi 		 * The PCI specification requires that the caller mask off the
4517*7687d0d8SRobert Mustacchi 		 * bottom two bits. Always check for an invalid value (all 1s)
4518*7687d0d8SRobert Mustacchi 		 * before this.
4519*7687d0d8SRobert Mustacchi 		 */
4520*7687d0d8SRobert Mustacchi 		cap &= PCI_CAP_PTR_MASK;
4521*7687d0d8SRobert Mustacchi 		cap_id = data.pcb_u8[cap + PCI_CAP_ID];
4522*7687d0d8SRobert Mustacchi 		nextcap = data.pcb_u8[cap + PCI_CAP_NEXT_PTR];
4523*7687d0d8SRobert Mustacchi 		cap_info = pcieadm_cfgspace_match_cap(cap_id, B_FALSE);
4524*7687d0d8SRobert Mustacchi 		if (cap_info != NULL && cap_info->ppc_info != NULL) {
4525*7687d0d8SRobert Mustacchi 			cap_info->ppc_info(&walk, cap_info, cap, &vers_info,
4526*7687d0d8SRobert Mustacchi 			    &read_len, &subcap);
4527*7687d0d8SRobert Mustacchi 		}
4528*7687d0d8SRobert Mustacchi 
4529*7687d0d8SRobert Mustacchi 		walk.pcw_caplen = read_len;
4530*7687d0d8SRobert Mustacchi 		walk.pcw_capoff = cap;
4531*7687d0d8SRobert Mustacchi 
4532*7687d0d8SRobert Mustacchi 		if (cap_id == PCI_CAP_ID_PCI_E) {
4533*7687d0d8SRobert Mustacchi 			extcfg = B_TRUE;
4534*7687d0d8SRobert Mustacchi 			if (walk.pcw_valid != 0) {
4535*7687d0d8SRobert Mustacchi 				walk.pcw_pcietype = data.pcb_u8[cap +
4536*7687d0d8SRobert Mustacchi 				    PCIE_PCIECAP] & PCIE_PCIECAP_DEV_TYPE_MASK;
4537*7687d0d8SRobert Mustacchi 				walk.pcw_nlanes = (data.pcb_u8[cap +
4538*7687d0d8SRobert Mustacchi 				    PCIE_LINKCAP] & 0xf0) >> 4;
4539*7687d0d8SRobert Mustacchi 				walk.pcw_nlanes |= (data.pcb_u8[cap +
4540*7687d0d8SRobert Mustacchi 				    PCIE_LINKCAP + 1] & 0x01) << 4;
4541*7687d0d8SRobert Mustacchi 			} else {
4542*7687d0d8SRobert Mustacchi 				walk.pcw_pcietype = UINT_MAX;
4543*7687d0d8SRobert Mustacchi 			}
4544*7687d0d8SRobert Mustacchi 		}
4545*7687d0d8SRobert Mustacchi 
4546*7687d0d8SRobert Mustacchi 		if (op == PCIEADM_CFGSPACE_OP_PRINT) {
4547*7687d0d8SRobert Mustacchi 			pcieadm_cfgspace_print_cap(&walk, cap_id, cap_info,
4548*7687d0d8SRobert Mustacchi 			    vers_info, subcap);
4549*7687d0d8SRobert Mustacchi 		}
4550*7687d0d8SRobert Mustacchi 
4551*7687d0d8SRobert Mustacchi 		cap = nextcap;
4552*7687d0d8SRobert Mustacchi 		ncaps++;
4553*7687d0d8SRobert Mustacchi 		if (ncaps >= PCI_CAP_MAX_PTR) {
4554*7687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "encountered more PCI capabilities "
4555*7687d0d8SRobert Mustacchi 			    "than fit in configuration space");
4556*7687d0d8SRobert Mustacchi 		}
4557*7687d0d8SRobert Mustacchi 	}
4558*7687d0d8SRobert Mustacchi 
4559*7687d0d8SRobert Mustacchi 	if (!extcfg) {
4560*7687d0d8SRobert Mustacchi 		return;
4561*7687d0d8SRobert Mustacchi 	}
4562*7687d0d8SRobert Mustacchi 
4563*7687d0d8SRobert Mustacchi 	for (uint_t i = PCIE_EXT_CAP / 4; i < PCIE_CONF_HDR_SIZE / 4; i++) {
4564*7687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
4565*7687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
4566*7687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
4567*7687d0d8SRobert Mustacchi 		}
4568*7687d0d8SRobert Mustacchi 	}
4569*7687d0d8SRobert Mustacchi 	walk.pcw_valid = PCIE_CONF_HDR_SIZE;
4570*7687d0d8SRobert Mustacchi 
4571*7687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
4572*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[PCIE_EXT_CAP],
4573*7687d0d8SRobert Mustacchi 		    PCIE_CONF_HDR_SIZE - PCIE_EXT_CAP);
4574*7687d0d8SRobert Mustacchi 		return;
4575*7687d0d8SRobert Mustacchi 	}
4576*7687d0d8SRobert Mustacchi 
4577*7687d0d8SRobert Mustacchi 	cap = PCIE_EXT_CAP;
4578*7687d0d8SRobert Mustacchi 	ncaps = 0;
4579*7687d0d8SRobert Mustacchi 	while (cap != 0 && cap != PCI_EINVAL16) {
4580*7687d0d8SRobert Mustacchi 		uint16_t cap_id, nextcap;
4581*7687d0d8SRobert Mustacchi 		const pcieadm_pci_cap_t *cap_info;
4582*7687d0d8SRobert Mustacchi 		const pcieadm_cap_vers_t *vers_info = NULL;
4583*7687d0d8SRobert Mustacchi 		const pcieadm_subcap_t *subcap = NULL;
4584*7687d0d8SRobert Mustacchi 		uint32_t read_len = 0;
4585*7687d0d8SRobert Mustacchi 
4586*7687d0d8SRobert Mustacchi 		/*
4587*7687d0d8SRobert Mustacchi 		 * PCIe has the same masking as PCI. Note, sys/pcie.h currently
4588*7687d0d8SRobert Mustacchi 		 * has PCIE_EXT_CAP_NEXT_PTR_MASK as 0xfff, instead of the
4589*7687d0d8SRobert Mustacchi 		 * below. This should be switched to PCIE_EXT_CAP_NEXT_PTR_MASK
4590*7687d0d8SRobert Mustacchi 		 * when the kernel headers are fixed.
4591*7687d0d8SRobert Mustacchi 		 */
4592*7687d0d8SRobert Mustacchi 		cap &= 0xffc;
4593*7687d0d8SRobert Mustacchi 
4594*7687d0d8SRobert Mustacchi 		/*
4595*7687d0d8SRobert Mustacchi 		 * While this seems duplicative of the loop condition, a device
4596*7687d0d8SRobert Mustacchi 		 * without capabilities indicates it with a zero for the first
4597*7687d0d8SRobert Mustacchi 		 * cap.
4598*7687d0d8SRobert Mustacchi 		 */
4599*7687d0d8SRobert Mustacchi 		if (data.pcb_u32[cap / 4] == 0 ||
4600*7687d0d8SRobert Mustacchi 		    data.pcb_u32[cap / 4] == PCI_EINVAL32)
4601*7687d0d8SRobert Mustacchi 			break;
4602*7687d0d8SRobert Mustacchi 
4603*7687d0d8SRobert Mustacchi 		cap_id = data.pcb_u32[cap / 4] & PCIE_EXT_CAP_ID_MASK;
4604*7687d0d8SRobert Mustacchi 		nextcap = (data.pcb_u32[cap / 4] >>
4605*7687d0d8SRobert Mustacchi 		    PCIE_EXT_CAP_NEXT_PTR_SHIFT) & PCIE_EXT_CAP_NEXT_PTR_MASK;
4606*7687d0d8SRobert Mustacchi 
4607*7687d0d8SRobert Mustacchi 		cap_info = pcieadm_cfgspace_match_cap(cap_id, B_TRUE);
4608*7687d0d8SRobert Mustacchi 		if (cap_info != NULL && cap_info->ppc_info != NULL) {
4609*7687d0d8SRobert Mustacchi 			cap_info->ppc_info(&walk, cap_info, cap, &vers_info,
4610*7687d0d8SRobert Mustacchi 			    &read_len, &subcap);
4611*7687d0d8SRobert Mustacchi 		}
4612*7687d0d8SRobert Mustacchi 
4613*7687d0d8SRobert Mustacchi 		walk.pcw_caplen = read_len;
4614*7687d0d8SRobert Mustacchi 		walk.pcw_capoff = cap;
4615*7687d0d8SRobert Mustacchi 
4616*7687d0d8SRobert Mustacchi 		if (op == PCIEADM_CFGSPACE_OP_PRINT) {
4617*7687d0d8SRobert Mustacchi 			pcieadm_cfgspace_print_cap(&walk, cap_id, cap_info,
4618*7687d0d8SRobert Mustacchi 			    vers_info, subcap);
4619*7687d0d8SRobert Mustacchi 		}
4620*7687d0d8SRobert Mustacchi 
4621*7687d0d8SRobert Mustacchi 		cap = nextcap;
4622*7687d0d8SRobert Mustacchi 		ncaps++;
4623*7687d0d8SRobert Mustacchi 		if (ncaps >= PCIE_EXT_CAP_MAX_PTR) {
4624*7687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "encountered more PCI capabilities "
4625*7687d0d8SRobert Mustacchi 			    "than fit in configuration space");
4626*7687d0d8SRobert Mustacchi 		}
4627*7687d0d8SRobert Mustacchi 	}
4628*7687d0d8SRobert Mustacchi }
4629*7687d0d8SRobert Mustacchi 
4630*7687d0d8SRobert Mustacchi void
4631*7687d0d8SRobert Mustacchi pcieadm_show_cfgspace_usage(FILE *f)
4632*7687d0d8SRobert Mustacchi {
4633*7687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tshow-cfgspace\t[-L] [-n] [-H] -d device | -f file "
4634*7687d0d8SRobert Mustacchi 	    "[filter...]\n");
4635*7687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tshow-cfgspace\t-p -o field[,...] [-H] -d device | "
4636*7687d0d8SRobert Mustacchi 	    "-f file [filter...]\n");
4637*7687d0d8SRobert Mustacchi }
4638*7687d0d8SRobert Mustacchi 
4639*7687d0d8SRobert Mustacchi static void
4640*7687d0d8SRobert Mustacchi pcieadm_show_cfgspace_help(const char *fmt, ...)
4641*7687d0d8SRobert Mustacchi {
4642*7687d0d8SRobert Mustacchi 	if (fmt != NULL) {
4643*7687d0d8SRobert Mustacchi 		va_list ap;
4644*7687d0d8SRobert Mustacchi 
4645*7687d0d8SRobert Mustacchi 		va_start(ap, fmt);
4646*7687d0d8SRobert Mustacchi 		vwarnx(fmt, ap);
4647*7687d0d8SRobert Mustacchi 		va_end(ap);
4648*7687d0d8SRobert Mustacchi 		(void) fprintf(stderr, "\n");
4649*7687d0d8SRobert Mustacchi 	}
4650*7687d0d8SRobert Mustacchi 
4651*7687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "Usage:  %s show-cfgspace [-L] [-n] [-H] -d "
4652*7687d0d8SRobert Mustacchi 	    "device | -f file [filter...]\n", pcieadm_progname);
4653*7687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "        %s show-cfgspace -p -o field[,...] "
4654*7687d0d8SRobert Mustacchi 	    "[-H] -d device | -f file\n\t\t\t      [filter...]\n",
4655*7687d0d8SRobert Mustacchi 	    pcieadm_progname);
4656*7687d0d8SRobert Mustacchi 
4657*7687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "\nPrint and decode PCI configuration space "
4658*7687d0d8SRobert Mustacchi 	    "data from a device or file. Each\n<filter> selects a given "
4659*7687d0d8SRobert Mustacchi 	    "capability, sub-capability, register, or field to print.\n\n"
4660*7687d0d8SRobert Mustacchi 	    "\t-d device\tread data from the specified device (driver instance,"
4661*7687d0d8SRobert Mustacchi 	    "\n\t\t\t/devices path, or b/d/f)\n"
4662*7687d0d8SRobert Mustacchi 	    "\t-f file\t\tread data from the specified file\n"
4663*7687d0d8SRobert Mustacchi 	    "\t-L\t\tlist printable fields\n"
4664*7687d0d8SRobert Mustacchi 	    "\t-n\t\tshow printable short names\n"
4665*7687d0d8SRobert Mustacchi 	    "\t-H\t\tomit the column header (for -L and -p)\n"
4666*7687d0d8SRobert Mustacchi 	    "\t-p\t\tparsable output (requires -o)\n"
4667*7687d0d8SRobert Mustacchi 	    "\t-o field\toutput fields to print (required for -p)\n");
4668*7687d0d8SRobert Mustacchi }
4669*7687d0d8SRobert Mustacchi 
4670*7687d0d8SRobert Mustacchi int
4671*7687d0d8SRobert Mustacchi pcieadm_show_cfgspace(pcieadm_t *pcip, int argc, char *argv[])
4672*7687d0d8SRobert Mustacchi {
4673*7687d0d8SRobert Mustacchi 	int c, ret;
4674*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
4675*7687d0d8SRobert Mustacchi 	void *readarg;
4676*7687d0d8SRobert Mustacchi 	boolean_t list = B_FALSE, parse = B_FALSE;
4677*7687d0d8SRobert Mustacchi 	const char *device = NULL, *file = NULL, *fields = NULL;
4678*7687d0d8SRobert Mustacchi 	uint_t nfilts = 0;
4679*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_filter_t *filts = NULL;
4680*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_flags_t flags = 0;
4681*7687d0d8SRobert Mustacchi 	uint_t oflags = 0;
4682*7687d0d8SRobert Mustacchi 	ofmt_handle_t ofmt = NULL;
4683*7687d0d8SRobert Mustacchi 
4684*7687d0d8SRobert Mustacchi 	while ((c = getopt(argc, argv, ":HLd:f:o:np")) != -1) {
4685*7687d0d8SRobert Mustacchi 		switch (c) {
4686*7687d0d8SRobert Mustacchi 		case 'd':
4687*7687d0d8SRobert Mustacchi 			device = optarg;
4688*7687d0d8SRobert Mustacchi 			break;
4689*7687d0d8SRobert Mustacchi 		case 'L':
4690*7687d0d8SRobert Mustacchi 			list = B_TRUE;
4691*7687d0d8SRobert Mustacchi 			break;
4692*7687d0d8SRobert Mustacchi 		case 'f':
4693*7687d0d8SRobert Mustacchi 			file = optarg;
4694*7687d0d8SRobert Mustacchi 			break;
4695*7687d0d8SRobert Mustacchi 		case 'p':
4696*7687d0d8SRobert Mustacchi 			parse = B_TRUE;
4697*7687d0d8SRobert Mustacchi 			flags |= PCIEADM_CFGSPACE_F_PARSE;
4698*7687d0d8SRobert Mustacchi 			oflags |= OFMT_PARSABLE;
4699*7687d0d8SRobert Mustacchi 			break;
4700*7687d0d8SRobert Mustacchi 		case 'n':
4701*7687d0d8SRobert Mustacchi 			flags |= PCIEADM_CFGSPACE_F_SHORT;
4702*7687d0d8SRobert Mustacchi 			break;
4703*7687d0d8SRobert Mustacchi 		case 'H':
4704*7687d0d8SRobert Mustacchi 			oflags |= OFMT_NOHEADER;
4705*7687d0d8SRobert Mustacchi 			break;
4706*7687d0d8SRobert Mustacchi 		case 'o':
4707*7687d0d8SRobert Mustacchi 			fields = optarg;
4708*7687d0d8SRobert Mustacchi 			break;
4709*7687d0d8SRobert Mustacchi 		case ':':
4710*7687d0d8SRobert Mustacchi 			pcieadm_show_cfgspace_help("Option -%c requires an "
4711*7687d0d8SRobert Mustacchi 			    "argument", optopt);
4712*7687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
4713*7687d0d8SRobert Mustacchi 		case '?':
4714*7687d0d8SRobert Mustacchi 		default:
4715*7687d0d8SRobert Mustacchi 			pcieadm_show_cfgspace_help("unknown option: -%c",
4716*7687d0d8SRobert Mustacchi 			    optopt);
4717*7687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
4718*7687d0d8SRobert Mustacchi 		}
4719*7687d0d8SRobert Mustacchi 	}
4720*7687d0d8SRobert Mustacchi 
4721*7687d0d8SRobert Mustacchi 	argc -= optind;
4722*7687d0d8SRobert Mustacchi 	argv += optind;
4723*7687d0d8SRobert Mustacchi 
4724*7687d0d8SRobert Mustacchi 	if (device == NULL && file == NULL) {
4725*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("one of -d or -f must be specified");
4726*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4727*7687d0d8SRobert Mustacchi 	}
4728*7687d0d8SRobert Mustacchi 
4729*7687d0d8SRobert Mustacchi 	if (device != NULL && file != NULL) {
4730*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("only one of -d and -f must be "
4731*7687d0d8SRobert Mustacchi 		    "specified");
4732*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4733*7687d0d8SRobert Mustacchi 	}
4734*7687d0d8SRobert Mustacchi 
4735*7687d0d8SRobert Mustacchi 	if (parse && fields == NULL) {
4736*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-p requires fields specified with "
4737*7687d0d8SRobert Mustacchi 		    "-o");
4738*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4739*7687d0d8SRobert Mustacchi 	}
4740*7687d0d8SRobert Mustacchi 
4741*7687d0d8SRobert Mustacchi 	if (!parse && fields != NULL) {
4742*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-o can only be used with -p");
4743*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4744*7687d0d8SRobert Mustacchi 	}
4745*7687d0d8SRobert Mustacchi 
4746*7687d0d8SRobert Mustacchi 	if ((oflags & OFMT_NOHEADER) && !(list || parse)) {
4747*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-H must be used with either -L or "
4748*7687d0d8SRobert Mustacchi 		    "-p");
4749*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4750*7687d0d8SRobert Mustacchi 	}
4751*7687d0d8SRobert Mustacchi 
4752*7687d0d8SRobert Mustacchi 	if ((flags & PCIEADM_CFGSPACE_F_SHORT) && (list || parse)) {
4753*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-n cannot be used with either -L "
4754*7687d0d8SRobert Mustacchi 		    "or -p");
4755*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4756*7687d0d8SRobert Mustacchi 	}
4757*7687d0d8SRobert Mustacchi 
4758*7687d0d8SRobert Mustacchi 	if (list && parse != 0) {
4759*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-L and -p cannot be used together");
4760*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4761*7687d0d8SRobert Mustacchi 	}
4762*7687d0d8SRobert Mustacchi 
4763*7687d0d8SRobert Mustacchi 	if (list && fields != NULL) {
4764*7687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-L and -o cannot be used together");
4765*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4766*7687d0d8SRobert Mustacchi 	}
4767*7687d0d8SRobert Mustacchi 
4768*7687d0d8SRobert Mustacchi 	if (list) {
4769*7687d0d8SRobert Mustacchi 		fields = "short,human";
4770*7687d0d8SRobert Mustacchi 	}
4771*7687d0d8SRobert Mustacchi 
4772*7687d0d8SRobert Mustacchi 	if (argc > 0) {
4773*7687d0d8SRobert Mustacchi 		nfilts = argc;
4774*7687d0d8SRobert Mustacchi 		filts = calloc(nfilts, sizeof (pcieadm_cfgspace_filter_t));
4775*7687d0d8SRobert Mustacchi 
4776*7687d0d8SRobert Mustacchi 		for (int i = 0; i < argc; i++) {
4777*7687d0d8SRobert Mustacchi 			filts[i].pcf_string = argv[i];
4778*7687d0d8SRobert Mustacchi 			filts[i].pcf_len = strlen(argv[i]);
4779*7687d0d8SRobert Mustacchi 		}
4780*7687d0d8SRobert Mustacchi 	}
4781*7687d0d8SRobert Mustacchi 
4782*7687d0d8SRobert Mustacchi 	if (list || parse) {
4783*7687d0d8SRobert Mustacchi 		ofmt_status_t oferr;
4784*7687d0d8SRobert Mustacchi 		oferr = ofmt_open(fields, pcieadm_cfgspace_ofmt, oflags, 0,
4785*7687d0d8SRobert Mustacchi 		    &ofmt);
4786*7687d0d8SRobert Mustacchi 		ofmt_check(oferr, parse, ofmt, pcieadm_ofmt_errx, warnx);
4787*7687d0d8SRobert Mustacchi 	}
4788*7687d0d8SRobert Mustacchi 
4789*7687d0d8SRobert Mustacchi 	/*
4790*7687d0d8SRobert Mustacchi 	 * Initialize privileges that we require. For reading from the kernel
4791*7687d0d8SRobert Mustacchi 	 * we require all privileges. For a file, we just intersect with things
4792*7687d0d8SRobert Mustacchi 	 * that would allow someone to read from any file.
4793*7687d0d8SRobert Mustacchi 	 */
4794*7687d0d8SRobert Mustacchi 	if (device != NULL) {
4795*7687d0d8SRobert Mustacchi 		/*
4796*7687d0d8SRobert Mustacchi 		 * We need full privileges if reading from a device,
4797*7687d0d8SRobert Mustacchi 		 * unfortunately.
4798*7687d0d8SRobert Mustacchi 		 */
4799*7687d0d8SRobert Mustacchi 		priv_fillset(pcip->pia_priv_eff);
4800*7687d0d8SRobert Mustacchi 	} else {
4801*7687d0d8SRobert Mustacchi 		VERIFY0(priv_addset(pcip->pia_priv_eff, PRIV_FILE_DAC_READ));
4802*7687d0d8SRobert Mustacchi 		VERIFY0(priv_addset(pcip->pia_priv_eff, PRIV_FILE_DAC_SEARCH));
4803*7687d0d8SRobert Mustacchi 	}
4804*7687d0d8SRobert Mustacchi 	pcieadm_init_privs(pcip);
4805*7687d0d8SRobert Mustacchi 
4806*7687d0d8SRobert Mustacchi 	if (device != NULL) {
4807*7687d0d8SRobert Mustacchi 		pcieadm_find_dip(pcip, device);
4808*7687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_kernel(pcip, &readf, &readarg);
4809*7687d0d8SRobert Mustacchi 	} else {
4810*7687d0d8SRobert Mustacchi 		pcip->pia_devstr = file;
4811*7687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_file(pcip, file, &readf, &readarg);
4812*7687d0d8SRobert Mustacchi 	}
4813*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace(pcip, PCIEADM_CFGSPACE_OP_PRINT, readf, -1, readarg,
4814*7687d0d8SRobert Mustacchi 	    nfilts, filts, flags, ofmt);
4815*7687d0d8SRobert Mustacchi 	if (device != NULL) {
4816*7687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_kernel(readarg);
4817*7687d0d8SRobert Mustacchi 	} else {
4818*7687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_file(readarg);
4819*7687d0d8SRobert Mustacchi 	}
4820*7687d0d8SRobert Mustacchi 
4821*7687d0d8SRobert Mustacchi 	ofmt_close(ofmt);
4822*7687d0d8SRobert Mustacchi 	ret = EXIT_SUCCESS;
4823*7687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < nfilts; i++) {
4824*7687d0d8SRobert Mustacchi 		if (!filts[i].pcf_used) {
4825*7687d0d8SRobert Mustacchi 			warnx("filter '%s' did not match any fields",
4826*7687d0d8SRobert Mustacchi 			    filts[i].pcf_string);
4827*7687d0d8SRobert Mustacchi 			ret = EXIT_FAILURE;
4828*7687d0d8SRobert Mustacchi 		}
4829*7687d0d8SRobert Mustacchi 	}
4830*7687d0d8SRobert Mustacchi 
4831*7687d0d8SRobert Mustacchi 	return (ret);
4832*7687d0d8SRobert Mustacchi }
4833*7687d0d8SRobert Mustacchi 
4834*7687d0d8SRobert Mustacchi typedef struct pcieadm_save_cfgspace {
4835*7687d0d8SRobert Mustacchi 	pcieadm_t *psc_pci;
4836*7687d0d8SRobert Mustacchi 	int psc_dirfd;
4837*7687d0d8SRobert Mustacchi 	uint_t psc_nsaved;
4838*7687d0d8SRobert Mustacchi 	int psc_ret;
4839*7687d0d8SRobert Mustacchi } pcieadm_save_cfgspace_t;
4840*7687d0d8SRobert Mustacchi 
4841*7687d0d8SRobert Mustacchi static int
4842*7687d0d8SRobert Mustacchi pcieadm_save_cfgspace_cb(di_node_t devi, void *arg)
4843*7687d0d8SRobert Mustacchi {
4844*7687d0d8SRobert Mustacchi 	int fd, nregs, *regs;
4845*7687d0d8SRobert Mustacchi 	pcieadm_save_cfgspace_t *psc = arg;
4846*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
4847*7687d0d8SRobert Mustacchi 	void *readarg;
4848*7687d0d8SRobert Mustacchi 	char fname[128];
4849*7687d0d8SRobert Mustacchi 
4850*7687d0d8SRobert Mustacchi 	psc->psc_pci->pia_devstr = di_node_name(devi);
4851*7687d0d8SRobert Mustacchi 	psc->psc_pci->pia_devi = devi;
4852*7687d0d8SRobert Mustacchi 	psc->psc_pci->pia_nexus = DI_NODE_NIL;
4853*7687d0d8SRobert Mustacchi 	pcieadm_find_nexus(psc->psc_pci);
4854*7687d0d8SRobert Mustacchi 	if (psc->psc_pci->pia_nexus == DI_NODE_NIL) {
4855*7687d0d8SRobert Mustacchi 		warnx("failed to find nexus for %s", di_node_name(devi));
4856*7687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
4857*7687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
4858*7687d0d8SRobert Mustacchi 	}
4859*7687d0d8SRobert Mustacchi 
4860*7687d0d8SRobert Mustacchi 	nregs = di_prop_lookup_ints(DDI_DEV_T_ANY, devi, "reg", &regs);
4861*7687d0d8SRobert Mustacchi 	if (nregs <= 0) {
4862*7687d0d8SRobert Mustacchi 		warnx("failed to lookup regs array for %s",
4863*7687d0d8SRobert Mustacchi 		    psc->psc_pci->pia_devstr);
4864*7687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
4865*7687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
4866*7687d0d8SRobert Mustacchi 	}
4867*7687d0d8SRobert Mustacchi 
4868*7687d0d8SRobert Mustacchi 	(void) snprintf(fname, sizeof (fname), "%02x-%02x-%02x.pci",
4869*7687d0d8SRobert Mustacchi 	    PCI_REG_BUS_G(regs[0]), PCI_REG_DEV_G(regs[0]),
4870*7687d0d8SRobert Mustacchi 	    PCI_REG_FUNC_G(regs[0]));
4871*7687d0d8SRobert Mustacchi 
4872*7687d0d8SRobert Mustacchi 	if ((fd = openat(psc->psc_dirfd, fname, O_WRONLY | O_TRUNC | O_CREAT,
4873*7687d0d8SRobert Mustacchi 	    0666)) < 0) {
4874*7687d0d8SRobert Mustacchi 		warn("failed to create output file %s", fname);
4875*7687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
4876*7687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
4877*7687d0d8SRobert Mustacchi 	}
4878*7687d0d8SRobert Mustacchi 
4879*7687d0d8SRobert Mustacchi 	pcieadm_init_cfgspace_kernel(psc->psc_pci, &readf, &readarg);
4880*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace(psc->psc_pci, PCIEADM_CFGSPACE_OP_WRITE, readf, fd,
4881*7687d0d8SRobert Mustacchi 	    readarg, 0, NULL, 0, NULL);
4882*7687d0d8SRobert Mustacchi 	pcieadm_fini_cfgspace_kernel(readarg);
4883*7687d0d8SRobert Mustacchi 
4884*7687d0d8SRobert Mustacchi 	if (close(fd) != 0) {
4885*7687d0d8SRobert Mustacchi 		warn("failed to close output fd for %s", fname);
4886*7687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
4887*7687d0d8SRobert Mustacchi 	} else {
4888*7687d0d8SRobert Mustacchi 		psc->psc_nsaved++;
4889*7687d0d8SRobert Mustacchi 	}
4890*7687d0d8SRobert Mustacchi 
4891*7687d0d8SRobert Mustacchi 	return (DI_WALK_CONTINUE);
4892*7687d0d8SRobert Mustacchi }
4893*7687d0d8SRobert Mustacchi 
4894*7687d0d8SRobert Mustacchi void
4895*7687d0d8SRobert Mustacchi pcieadm_save_cfgspace_usage(FILE *f)
4896*7687d0d8SRobert Mustacchi {
4897*7687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tsave-devs\t-d device output-file\n");
4898*7687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tsave-devs\t-a output-directory\n");
4899*7687d0d8SRobert Mustacchi }
4900*7687d0d8SRobert Mustacchi 
4901*7687d0d8SRobert Mustacchi static void
4902*7687d0d8SRobert Mustacchi pcieadm_save_cfgspace_help(const char *fmt, ...)
4903*7687d0d8SRobert Mustacchi {
4904*7687d0d8SRobert Mustacchi 	if (fmt != NULL) {
4905*7687d0d8SRobert Mustacchi 		va_list ap;
4906*7687d0d8SRobert Mustacchi 
4907*7687d0d8SRobert Mustacchi 		va_start(ap, fmt);
4908*7687d0d8SRobert Mustacchi 		vwarnx(fmt, ap);
4909*7687d0d8SRobert Mustacchi 		va_end(ap);
4910*7687d0d8SRobert Mustacchi 		(void) fprintf(stderr, "\n");
4911*7687d0d8SRobert Mustacchi 	}
4912*7687d0d8SRobert Mustacchi 
4913*7687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "Usage:  %s save-cfgspace -d device "
4914*7687d0d8SRobert Mustacchi 	    "output-file\n", pcieadm_progname);
4915*7687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "        %s save-cfgspace -a "
4916*7687d0d8SRobert Mustacchi 	    "output-directory\n", pcieadm_progname);
4917*7687d0d8SRobert Mustacchi 
4918*7687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "\nSave PCI configuration space data from a "
4919*7687d0d8SRobert Mustacchi 	    "device to a file or\nsave all devices to a specified directory."
4920*7687d0d8SRobert Mustacchi 	    "\n\n"
4921*7687d0d8SRobert Mustacchi 	    "\t-a\t\tsave data from all devices\n"
4922*7687d0d8SRobert Mustacchi 	    "\t-d device\tread data from the specified device (driver instance,"
4923*7687d0d8SRobert Mustacchi 	    "\n\t\t\t/devices path, or b/d/f)\n");
4924*7687d0d8SRobert Mustacchi }
4925*7687d0d8SRobert Mustacchi 
4926*7687d0d8SRobert Mustacchi int
4927*7687d0d8SRobert Mustacchi pcieadm_save_cfgspace(pcieadm_t *pcip, int argc, char *argv[])
4928*7687d0d8SRobert Mustacchi {
4929*7687d0d8SRobert Mustacchi 	int c;
4930*7687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
4931*7687d0d8SRobert Mustacchi 	void *readarg;
4932*7687d0d8SRobert Mustacchi 	const char *device = NULL;
4933*7687d0d8SRobert Mustacchi 	boolean_t do_all = B_FALSE;
4934*7687d0d8SRobert Mustacchi 
4935*7687d0d8SRobert Mustacchi 	while ((c = getopt(argc, argv, ":ad:")) != -1) {
4936*7687d0d8SRobert Mustacchi 		switch (c) {
4937*7687d0d8SRobert Mustacchi 		case 'a':
4938*7687d0d8SRobert Mustacchi 			do_all = B_TRUE;
4939*7687d0d8SRobert Mustacchi 			break;
4940*7687d0d8SRobert Mustacchi 		case 'd':
4941*7687d0d8SRobert Mustacchi 			device = optarg;
4942*7687d0d8SRobert Mustacchi 			break;
4943*7687d0d8SRobert Mustacchi 		case ':':
4944*7687d0d8SRobert Mustacchi 			pcieadm_save_cfgspace_help("Option -%c requires an "
4945*7687d0d8SRobert Mustacchi 			    "argument", optopt);
4946*7687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
4947*7687d0d8SRobert Mustacchi 		case '?':
4948*7687d0d8SRobert Mustacchi 		default:
4949*7687d0d8SRobert Mustacchi 			pcieadm_save_cfgspace_help("unknown option: -%c",
4950*7687d0d8SRobert Mustacchi 			    optopt);
4951*7687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
4952*7687d0d8SRobert Mustacchi 		}
4953*7687d0d8SRobert Mustacchi 	}
4954*7687d0d8SRobert Mustacchi 
4955*7687d0d8SRobert Mustacchi 	argc -= optind;
4956*7687d0d8SRobert Mustacchi 	argv += optind;
4957*7687d0d8SRobert Mustacchi 
4958*7687d0d8SRobert Mustacchi 	if (device == NULL && !do_all) {
4959*7687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_help("missing required -d option to "
4960*7687d0d8SRobert Mustacchi 		    "indicate device to dump");
4961*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4962*7687d0d8SRobert Mustacchi 	}
4963*7687d0d8SRobert Mustacchi 
4964*7687d0d8SRobert Mustacchi 	if (argc != 1) {
4965*7687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_help("missing required output path");
4966*7687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
4967*7687d0d8SRobert Mustacchi 	}
4968*7687d0d8SRobert Mustacchi 
4969*7687d0d8SRobert Mustacchi 	/*
4970*7687d0d8SRobert Mustacchi 	 * For reading from devices, we need to full privileges, unfortunately.
4971*7687d0d8SRobert Mustacchi 	 */
4972*7687d0d8SRobert Mustacchi 	priv_fillset(pcip->pia_priv_eff);
4973*7687d0d8SRobert Mustacchi 	pcieadm_init_privs(pcip);
4974*7687d0d8SRobert Mustacchi 
4975*7687d0d8SRobert Mustacchi 	if (!do_all) {
4976*7687d0d8SRobert Mustacchi 		int fd;
4977*7687d0d8SRobert Mustacchi 
4978*7687d0d8SRobert Mustacchi 		pcieadm_find_dip(pcip, device);
4979*7687d0d8SRobert Mustacchi 
4980*7687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_eff) !=
4981*7687d0d8SRobert Mustacchi 		    0) {
4982*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to raise privileges");
4983*7687d0d8SRobert Mustacchi 		}
4984*7687d0d8SRobert Mustacchi 
4985*7687d0d8SRobert Mustacchi 		if ((fd = open(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666)) <
4986*7687d0d8SRobert Mustacchi 		    0) {
4987*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to open output file %s",
4988*7687d0d8SRobert Mustacchi 			    argv[0]);
4989*7687d0d8SRobert Mustacchi 		}
4990*7687d0d8SRobert Mustacchi 
4991*7687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_min) !=
4992*7687d0d8SRobert Mustacchi 		    0) {
4993*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to reduce privileges");
4994*7687d0d8SRobert Mustacchi 		}
4995*7687d0d8SRobert Mustacchi 
4996*7687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_kernel(pcip, &readf, &readarg);
4997*7687d0d8SRobert Mustacchi 		pcieadm_cfgspace(pcip, PCIEADM_CFGSPACE_OP_WRITE, readf, fd,
4998*7687d0d8SRobert Mustacchi 		    readarg, 0, NULL, 0, NULL);
4999*7687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_kernel(readarg);
5000*7687d0d8SRobert Mustacchi 
5001*7687d0d8SRobert Mustacchi 		if (close(fd) != 0) {
5002*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to close output file "
5003*7687d0d8SRobert Mustacchi 			    "descriptor");
5004*7687d0d8SRobert Mustacchi 		}
5005*7687d0d8SRobert Mustacchi 
5006*7687d0d8SRobert Mustacchi 		return (EXIT_SUCCESS);
5007*7687d0d8SRobert Mustacchi 	} else {
5008*7687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_t psc;
5009*7687d0d8SRobert Mustacchi 		pcieadm_di_walk_t walk;
5010*7687d0d8SRobert Mustacchi 
5011*7687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_eff) !=
5012*7687d0d8SRobert Mustacchi 		    0) {
5013*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to raise privileges");
5014*7687d0d8SRobert Mustacchi 		}
5015*7687d0d8SRobert Mustacchi 
5016*7687d0d8SRobert Mustacchi 		if ((psc.psc_dirfd = open(argv[0], O_RDONLY | O_DIRECTORY)) <
5017*7687d0d8SRobert Mustacchi 		    0) {
5018*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to open output directory %s",
5019*7687d0d8SRobert Mustacchi 			    argv[0]);
5020*7687d0d8SRobert Mustacchi 		}
5021*7687d0d8SRobert Mustacchi 
5022*7687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_min) !=
5023*7687d0d8SRobert Mustacchi 		    0) {
5024*7687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to reduce privileges");
5025*7687d0d8SRobert Mustacchi 		}
5026*7687d0d8SRobert Mustacchi 
5027*7687d0d8SRobert Mustacchi 		psc.psc_nsaved = 0;
5028*7687d0d8SRobert Mustacchi 		psc.psc_ret = EXIT_SUCCESS;
5029*7687d0d8SRobert Mustacchi 		psc.psc_pci = pcip;
5030*7687d0d8SRobert Mustacchi 
5031*7687d0d8SRobert Mustacchi 		walk.pdw_arg = &psc;
5032*7687d0d8SRobert Mustacchi 		walk.pdw_func = pcieadm_save_cfgspace_cb;
5033*7687d0d8SRobert Mustacchi 		pcieadm_di_walk(pcip, &walk);
5034*7687d0d8SRobert Mustacchi 
5035*7687d0d8SRobert Mustacchi 		VERIFY0(close(psc.psc_dirfd));
5036*7687d0d8SRobert Mustacchi 
5037*7687d0d8SRobert Mustacchi 		if (psc.psc_nsaved == 0) {
5038*7687d0d8SRobert Mustacchi 			warnx("failed to save any PCI devices");
5039*7687d0d8SRobert Mustacchi 			return (EXIT_FAILURE);
5040*7687d0d8SRobert Mustacchi 		}
5041*7687d0d8SRobert Mustacchi 
5042*7687d0d8SRobert Mustacchi 		pcieadm_print("successfully saved %u devices to %s\n",
5043*7687d0d8SRobert Mustacchi 		    psc.psc_nsaved, argv[0]);
5044*7687d0d8SRobert Mustacchi 		return (psc.psc_ret);
5045*7687d0d8SRobert Mustacchi 	}
5046*7687d0d8SRobert Mustacchi }
5047