17687d0d8SRobert Mustacchi /*
27687d0d8SRobert Mustacchi  * This file and its contents are supplied under the terms of the
37687d0d8SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
47687d0d8SRobert Mustacchi  * You may only use this file in accordance with the terms of version
57687d0d8SRobert Mustacchi  * 1.0 of the CDDL.
67687d0d8SRobert Mustacchi  *
77687d0d8SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
87687d0d8SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
97687d0d8SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
107687d0d8SRobert Mustacchi  */
117687d0d8SRobert Mustacchi 
127687d0d8SRobert Mustacchi /*
13*92f11af9SRobert Mustacchi  * Copyright 2022 Oxide Computer Company
147687d0d8SRobert Mustacchi  */
157687d0d8SRobert Mustacchi 
167687d0d8SRobert Mustacchi /*
177687d0d8SRobert Mustacchi  * This file contains logic to walk and print a large chunk of configuration
187687d0d8SRobert Mustacchi  * space and many of the capabilities. There are multiple sub-commands that
197687d0d8SRobert Mustacchi  * vector into the same logic (e.g. 'save-cfgspace' and 'show-cfgspace'). In
207687d0d8SRobert Mustacchi  * general, there are a few major goals with this bit of code:
217687d0d8SRobert Mustacchi  *
227687d0d8SRobert Mustacchi  *  o Every field should strive to be parsable and therefore selectable for
237687d0d8SRobert Mustacchi  *    output. This drove the idea that every field has both a short name and a
247687d0d8SRobert Mustacchi  *    human name. The short name is a dot-delineated name. When in parsable
257687d0d8SRobert Mustacchi  *    mode, the name will always refer to a single field. However, for
267687d0d8SRobert Mustacchi  *    convenience for humans, when not trying to be parsable, we show the
277687d0d8SRobert Mustacchi  *    parents in the tree. That is if you specify something like
287687d0d8SRobert Mustacchi  *    'pcie.linkcap.maxspeed', in parsable mode you'll only get that; however,
297687d0d8SRobert Mustacchi  *    in non-parsable mode, you'll get an indication of the capability and
307687d0d8SRobert Mustacchi  *    register that field was in.
317687d0d8SRobert Mustacchi  *
327687d0d8SRobert Mustacchi  *  o Related to the above, parsable mode always outputs a raw, uninterpreted
337687d0d8SRobert Mustacchi  *    value. This was done on purpose. Some fields require interpreting multiple
347687d0d8SRobert Mustacchi  *    registers to have meaning and long strings aren't always the most useful.
357687d0d8SRobert Mustacchi  *
367687d0d8SRobert Mustacchi  *  o Every field isn't always pretty printed. This was generally just a
377687d0d8SRobert Mustacchi  *    decision based upon the field itself and how much work it'd be to fit it
387687d0d8SRobert Mustacchi  *    into the framework we have. In general, the ones we're mostly guilty of
397687d0d8SRobert Mustacchi  *    doing this with are related to cases where there's a scaling value in a
407687d0d8SRobert Mustacchi  *    subsequent register. If you find yourself wanting this, feel free to add
417687d0d8SRobert Mustacchi  *    it.
427687d0d8SRobert Mustacchi  *
437687d0d8SRobert Mustacchi  *  o Currently designated vendor-specific capabilities aren't included here (or
447687d0d8SRobert Mustacchi  *    any specific vendor-specific capabilities for that matter). If they are
457687d0d8SRobert Mustacchi  *    added, they should follow the same angle of using a name to represent a
467687d0d8SRobert Mustacchi  *    sub-capability as we did with HyperTransport.
477687d0d8SRobert Mustacchi  */
487687d0d8SRobert Mustacchi 
497687d0d8SRobert Mustacchi #include <err.h>
507687d0d8SRobert Mustacchi #include <strings.h>
517687d0d8SRobert Mustacchi #include <sys/sysmacros.h>
527687d0d8SRobert Mustacchi #include <sys/pci.h>
537687d0d8SRobert Mustacchi #include <sys/pcie.h>
547687d0d8SRobert Mustacchi #include <sys/debug.h>
557687d0d8SRobert Mustacchi #include <ofmt.h>
567687d0d8SRobert Mustacchi #include <sys/types.h>
577687d0d8SRobert Mustacchi #include <sys/stat.h>
587687d0d8SRobert Mustacchi #include <fcntl.h>
597687d0d8SRobert Mustacchi #include <unistd.h>
607687d0d8SRobert Mustacchi 
617687d0d8SRobert Mustacchi #include "pcieadm.h"
627687d0d8SRobert Mustacchi 
637687d0d8SRobert Mustacchi typedef enum pcieadm_cfgspace_op {
647687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OP_PRINT,
657687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OP_WRITE
667687d0d8SRobert Mustacchi } pcieadm_cfgspace_op_t;
677687d0d8SRobert Mustacchi 
687687d0d8SRobert Mustacchi typedef enum piceadm_cfgspace_flag {
697687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_F_PARSE	= 1 << 0,
707687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_F_SHORT	= 1 << 1,
717687d0d8SRobert Mustacchi } pcieadm_cfgspace_flags_t;
727687d0d8SRobert Mustacchi 
737687d0d8SRobert Mustacchi typedef enum pcieadm_cfgspace_otype {
747687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_SHORT,
757687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_HUMAN,
767687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_VALUE
777687d0d8SRobert Mustacchi } pcieadm_cfgsapce_otype_t;
787687d0d8SRobert Mustacchi 
797687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_ofmt {
807687d0d8SRobert Mustacchi 	const char *pco_base;
817687d0d8SRobert Mustacchi 	const char *pco_short;
827687d0d8SRobert Mustacchi 	const char *pco_human;
837687d0d8SRobert Mustacchi 	uint64_t pco_value;
847687d0d8SRobert Mustacchi 	const char *pco_strval;
857687d0d8SRobert Mustacchi } pcieadm_cfgspace_ofmt_t;
867687d0d8SRobert Mustacchi 
877687d0d8SRobert Mustacchi typedef enum pcieadm_regdef_val {
887687d0d8SRobert Mustacchi 	PRDV_STRVAL,
897687d0d8SRobert Mustacchi 	PRDV_BITFIELD,
907687d0d8SRobert Mustacchi 	PRDV_HEX
917687d0d8SRobert Mustacchi } pcieadm_regdef_val_t;
927687d0d8SRobert Mustacchi 
937687d0d8SRobert Mustacchi typedef struct pcieadm_regdef_addend {
947687d0d8SRobert Mustacchi 	uint8_t pra_shift;
957687d0d8SRobert Mustacchi 	int64_t pra_addend;
967687d0d8SRobert Mustacchi } pcieadm_regdef_addend_t;
977687d0d8SRobert Mustacchi 
987687d0d8SRobert Mustacchi typedef struct pcieadm_regdef {
997687d0d8SRobert Mustacchi 	uint8_t prd_lowbit;
1007687d0d8SRobert Mustacchi 	uint8_t prd_hibit;
1017687d0d8SRobert Mustacchi 	const char *prd_short;
1027687d0d8SRobert Mustacchi 	const char *prd_human;
1037687d0d8SRobert Mustacchi 	pcieadm_regdef_val_t prd_valtype;
1047687d0d8SRobert Mustacchi 	union {
1057687d0d8SRobert Mustacchi 		/*
1067687d0d8SRobert Mustacchi 		 * Enough space for up to an 8-bit fields worth of values
1077687d0d8SRobert Mustacchi 		 * (though we expect most to be sparse).
1087687d0d8SRobert Mustacchi 		 */
1097687d0d8SRobert Mustacchi 		const char *prdv_strval[128];
1107687d0d8SRobert Mustacchi 		pcieadm_regdef_addend_t prdv_hex;
1117687d0d8SRobert Mustacchi 	} prd_val;
1127687d0d8SRobert Mustacchi } pcieadm_regdef_t;
1137687d0d8SRobert Mustacchi 
1147687d0d8SRobert Mustacchi typedef struct pcieadm_unitdef {
1157687d0d8SRobert Mustacchi 	const char *pcd_unit;
1167687d0d8SRobert Mustacchi 	uint32_t pcd_mult;
1177687d0d8SRobert Mustacchi } pcieadm_unitdef_t;
1187687d0d8SRobert Mustacchi 
1197687d0d8SRobert Mustacchi typedef struct pcieadm_strmap {
1207687d0d8SRobert Mustacchi 	const char *psr_str;
1217687d0d8SRobert Mustacchi 	uint64_t psr_val;
1227687d0d8SRobert Mustacchi } pcieadm_strmap_t;
1237687d0d8SRobert Mustacchi 
1247687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_filter {
1257687d0d8SRobert Mustacchi 	const char *pcf_string;
1267687d0d8SRobert Mustacchi 	size_t pcf_len;
1277687d0d8SRobert Mustacchi 	boolean_t pcf_used;
1287687d0d8SRobert Mustacchi } pcieadm_cfgspace_filter_t;
1297687d0d8SRobert Mustacchi 
1307687d0d8SRobert Mustacchi typedef struct pcieadm_strfilt {
1317687d0d8SRobert Mustacchi 	struct pcieadm_strfilt *pstr_next;
1327687d0d8SRobert Mustacchi 	const char *pstr_str;
1337687d0d8SRobert Mustacchi 	char pstr_curgen[256];
1347687d0d8SRobert Mustacchi } pcieadm_strfilt_t;
1357687d0d8SRobert Mustacchi 
1367687d0d8SRobert Mustacchi /*
1377687d0d8SRobert Mustacchi  * Data is sized to be large enough that we can hold all of PCIe extended
1387687d0d8SRobert Mustacchi  * configuration space.
1397687d0d8SRobert Mustacchi  */
1407687d0d8SRobert Mustacchi typedef union pcieadm_cfgspace_data {
1417687d0d8SRobert Mustacchi 	uint8_t pcb_u8[PCIE_CONF_HDR_SIZE];
1427687d0d8SRobert Mustacchi 	uint32_t pcb_u32[PCIE_CONF_HDR_SIZE / 4];
1437687d0d8SRobert Mustacchi } pcieadm_cfgspace_data_t;
1447687d0d8SRobert Mustacchi 
1457687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_walk {
1467687d0d8SRobert Mustacchi 	pcieadm_t *pcw_pcieadm;
1477687d0d8SRobert Mustacchi 	pcieadm_cfgspace_op_t pcw_op;
1487687d0d8SRobert Mustacchi 	uint32_t pcw_valid;
1497687d0d8SRobert Mustacchi 	pcieadm_cfgspace_data_t *pcw_data;
1507687d0d8SRobert Mustacchi 	uint16_t pcw_capoff;
1517687d0d8SRobert Mustacchi 	uint32_t pcw_caplen;
1527687d0d8SRobert Mustacchi 	int pcw_outfd;
1537687d0d8SRobert Mustacchi 	uint_t pcw_dtype;
1547687d0d8SRobert Mustacchi 	uint_t pcw_nlanes;
1557687d0d8SRobert Mustacchi 	uint_t pcw_pcietype;
1567687d0d8SRobert Mustacchi 	uint_t pcw_nfilters;
1577687d0d8SRobert Mustacchi 	pcieadm_cfgspace_filter_t *pcw_filters;
1587687d0d8SRobert Mustacchi 	pcieadm_cfgspace_flags_t pcw_flags;
1597687d0d8SRobert Mustacchi 	ofmt_handle_t pcw_ofmt;
1607687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *pcw_filt;
1617687d0d8SRobert Mustacchi } pcieadm_cfgspace_walk_t;
1627687d0d8SRobert Mustacchi 
1637687d0d8SRobert Mustacchi void
1647687d0d8SRobert Mustacchi pcieadm_strfilt_pop(pcieadm_cfgspace_walk_t *walkp)
1657687d0d8SRobert Mustacchi {
1667687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *filt;
1677687d0d8SRobert Mustacchi 
1687687d0d8SRobert Mustacchi 	VERIFY3P(walkp->pcw_filt, !=, NULL);
1697687d0d8SRobert Mustacchi 	filt = walkp->pcw_filt;
1707687d0d8SRobert Mustacchi 	walkp->pcw_filt = filt->pstr_next;
1717687d0d8SRobert Mustacchi 	free(filt);
1727687d0d8SRobert Mustacchi }
1737687d0d8SRobert Mustacchi 
1747687d0d8SRobert Mustacchi void
1757687d0d8SRobert Mustacchi pcieadm_strfilt_push(pcieadm_cfgspace_walk_t *walkp, const char *str)
1767687d0d8SRobert Mustacchi {
1777687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *filt;
1787687d0d8SRobert Mustacchi 	size_t len;
1797687d0d8SRobert Mustacchi 
1807687d0d8SRobert Mustacchi 	filt = calloc(1, sizeof (*filt));
1817687d0d8SRobert Mustacchi 	if (filt == NULL) {
1827687d0d8SRobert Mustacchi 		errx(EXIT_FAILURE, "failed to allocate memory for string "
1837687d0d8SRobert Mustacchi 		    "filter");
1847687d0d8SRobert Mustacchi 	}
1857687d0d8SRobert Mustacchi 
1867687d0d8SRobert Mustacchi 	filt->pstr_str = str;
1877687d0d8SRobert Mustacchi 	if (walkp->pcw_filt == NULL) {
1887687d0d8SRobert Mustacchi 		len = strlcat(filt->pstr_curgen, str,
1897687d0d8SRobert Mustacchi 		    sizeof (filt->pstr_curgen));
1907687d0d8SRobert Mustacchi 	} else {
1917687d0d8SRobert Mustacchi 		len = snprintf(filt->pstr_curgen, sizeof (filt->pstr_curgen),
1927687d0d8SRobert Mustacchi 		    "%s.%s", walkp->pcw_filt->pstr_curgen, str);
1937687d0d8SRobert Mustacchi 		filt->pstr_next = walkp->pcw_filt;
1947687d0d8SRobert Mustacchi 	}
1957687d0d8SRobert Mustacchi 
1967687d0d8SRobert Mustacchi 	if (len >= sizeof (filt->pstr_curgen)) {
1977687d0d8SRobert Mustacchi 		errx(EXIT_FAILURE, "overflowed internal string buffer "
1987687d0d8SRobert Mustacchi 		    "appending %s", str);
1997687d0d8SRobert Mustacchi 	}
2007687d0d8SRobert Mustacchi 
2017687d0d8SRobert Mustacchi 	walkp->pcw_filt = filt;
2027687d0d8SRobert Mustacchi }
2037687d0d8SRobert Mustacchi 
2047687d0d8SRobert Mustacchi static boolean_t
2057687d0d8SRobert Mustacchi pcieadm_cfgspace_filter(pcieadm_cfgspace_walk_t *walkp, const char *str)
2067687d0d8SRobert Mustacchi {
2077687d0d8SRobert Mustacchi 	char buf[1024];
2087687d0d8SRobert Mustacchi 	size_t len;
2097687d0d8SRobert Mustacchi 
2107687d0d8SRobert Mustacchi 	if (walkp->pcw_nfilters == 0) {
2117687d0d8SRobert Mustacchi 		return (B_TRUE);
2127687d0d8SRobert Mustacchi 	}
2137687d0d8SRobert Mustacchi 
2147687d0d8SRobert Mustacchi 	if (str == NULL) {
2157687d0d8SRobert Mustacchi 		return (B_FALSE);
2167687d0d8SRobert Mustacchi 	}
2177687d0d8SRobert Mustacchi 
2187687d0d8SRobert Mustacchi 	if (walkp->pcw_filt != NULL) {
2197687d0d8SRobert Mustacchi 		len = snprintf(buf, sizeof (buf), "%s.%s",
2207687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, str);
2217687d0d8SRobert Mustacchi 	} else {
2227687d0d8SRobert Mustacchi 		len = snprintf(buf, sizeof (buf), "%s", str);
2237687d0d8SRobert Mustacchi 	}
2247687d0d8SRobert Mustacchi 
2257687d0d8SRobert Mustacchi 	if (len >= sizeof (buf)) {
2267687d0d8SRobert Mustacchi 		abort();
2277687d0d8SRobert Mustacchi 	}
2287687d0d8SRobert Mustacchi 
2297687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nfilters; i++) {
2307687d0d8SRobert Mustacchi 		if (strcmp(buf, walkp->pcw_filters[i].pcf_string) == 0) {
2317687d0d8SRobert Mustacchi 			walkp->pcw_filters[i].pcf_used = B_TRUE;
2327687d0d8SRobert Mustacchi 			return (B_TRUE);
2337687d0d8SRobert Mustacchi 		}
2347687d0d8SRobert Mustacchi 
2357687d0d8SRobert Mustacchi 		/*
2367687d0d8SRobert Mustacchi 		 * If we're in non-parsable mode, we want to do a little bit
2377687d0d8SRobert Mustacchi 		 * more in a few cases. We want to make sure that we print the
2387687d0d8SRobert Mustacchi 		 * parents of more-specific entries. That is, if someone
2397687d0d8SRobert Mustacchi 		 * specified 'header.command.serr', then we want to print
2407687d0d8SRobert Mustacchi 		 * 'header', and 'header.command'. Similarly, if someone
2417687d0d8SRobert Mustacchi 		 * specifies an individual field, we want to print all of its
2427687d0d8SRobert Mustacchi 		 * subfields, that is asking for 'header.command', really gets
2437687d0d8SRobert Mustacchi 		 * that and all of 'header.command.*'.
2447687d0d8SRobert Mustacchi 		 */
2457687d0d8SRobert Mustacchi 		if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_PARSE) != 0) {
2467687d0d8SRobert Mustacchi 			continue;
2477687d0d8SRobert Mustacchi 		}
2487687d0d8SRobert Mustacchi 
2497687d0d8SRobert Mustacchi 		if (len >= walkp->pcw_filters[i].pcf_len) {
2507687d0d8SRobert Mustacchi 			if (strncmp(buf, walkp->pcw_filters[i].pcf_string,
2517687d0d8SRobert Mustacchi 			    walkp->pcw_filters[i].pcf_len) == 0 &&
2527687d0d8SRobert Mustacchi 			    buf[walkp->pcw_filters[i].pcf_len] == '.') {
2537687d0d8SRobert Mustacchi 				return (B_TRUE);
2547687d0d8SRobert Mustacchi 			}
2557687d0d8SRobert Mustacchi 		} else {
2567687d0d8SRobert Mustacchi 			if (strncmp(buf, walkp->pcw_filters[i].pcf_string,
2577687d0d8SRobert Mustacchi 			    len) == 0 &&
2587687d0d8SRobert Mustacchi 			    walkp->pcw_filters[i].pcf_string[len] == '.') {
2597687d0d8SRobert Mustacchi 				return (B_TRUE);
2607687d0d8SRobert Mustacchi 			}
2617687d0d8SRobert Mustacchi 		}
2627687d0d8SRobert Mustacchi 	}
2637687d0d8SRobert Mustacchi 
2647687d0d8SRobert Mustacchi 	return (B_FALSE);
2657687d0d8SRobert Mustacchi }
2667687d0d8SRobert Mustacchi 
2677687d0d8SRobert Mustacchi static boolean_t
2687687d0d8SRobert Mustacchi pcieadm_cfgspace_ofmt_cb(ofmt_arg_t *ofarg, char *buf, uint_t buflen)
2697687d0d8SRobert Mustacchi {
2707687d0d8SRobert Mustacchi 	pcieadm_cfgspace_ofmt_t *pco = ofarg->ofmt_cbarg;
2717687d0d8SRobert Mustacchi 
2727687d0d8SRobert Mustacchi 	switch (ofarg->ofmt_id) {
2737687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_SHORT:
2747687d0d8SRobert Mustacchi 		if (snprintf(buf, buflen, "%s.%s", pco->pco_base,
2757687d0d8SRobert Mustacchi 		    pco->pco_short) >= buflen) {
2767687d0d8SRobert Mustacchi 			return (B_FALSE);
2777687d0d8SRobert Mustacchi 		}
2787687d0d8SRobert Mustacchi 		break;
2797687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_HUMAN:
2807687d0d8SRobert Mustacchi 		if (strlcpy(buf, pco->pco_human, buflen) >= buflen) {
2817687d0d8SRobert Mustacchi 			return (B_FALSE);
2827687d0d8SRobert Mustacchi 		}
2837687d0d8SRobert Mustacchi 		break;
2847687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_VALUE:
2857687d0d8SRobert Mustacchi 		if (pco->pco_strval != NULL) {
2867687d0d8SRobert Mustacchi 			if (strlcpy(buf, pco->pco_strval, buflen) >= buflen) {
2877687d0d8SRobert Mustacchi 				return (B_FALSE);
2887687d0d8SRobert Mustacchi 			}
2897687d0d8SRobert Mustacchi 		} else {
2907687d0d8SRobert Mustacchi 			if (snprintf(buf, buflen, "0x%" PRIx64,
2917687d0d8SRobert Mustacchi 			    pco->pco_value) >= buflen) {
2927687d0d8SRobert Mustacchi 				return (B_FALSE);
2937687d0d8SRobert Mustacchi 			}
2947687d0d8SRobert Mustacchi 		}
2957687d0d8SRobert Mustacchi 		break;
2967687d0d8SRobert Mustacchi 	default:
2977687d0d8SRobert Mustacchi 		abort();
2987687d0d8SRobert Mustacchi 	}
2997687d0d8SRobert Mustacchi 
3007687d0d8SRobert Mustacchi 	return (B_TRUE);
3017687d0d8SRobert Mustacchi }
3027687d0d8SRobert Mustacchi 
3037687d0d8SRobert Mustacchi 
3047687d0d8SRobert Mustacchi static const ofmt_field_t pcieadm_cfgspace_ofmt[] = {
3057687d0d8SRobert Mustacchi 	{ "SHORT", 30, PCIEADM_CFGSPACE_OT_SHORT, pcieadm_cfgspace_ofmt_cb },
3067687d0d8SRobert Mustacchi 	{ "HUMAN", 30, PCIEADM_CFGSPACE_OT_HUMAN, pcieadm_cfgspace_ofmt_cb },
3077687d0d8SRobert Mustacchi 	{ "VALUE", 20, PCIEADM_CFGSPACE_OT_VALUE, pcieadm_cfgspace_ofmt_cb },
3087687d0d8SRobert Mustacchi 	{ NULL, 0, 0, NULL }
3097687d0d8SRobert Mustacchi };
3107687d0d8SRobert Mustacchi 
3117687d0d8SRobert Mustacchi static void
3127687d0d8SRobert Mustacchi pcieadm_cfgspace_print_parse(pcieadm_cfgspace_walk_t *walkp,
3137687d0d8SRobert Mustacchi     const char *sname, const char *human, uint64_t value)
3147687d0d8SRobert Mustacchi {
3157687d0d8SRobert Mustacchi 	pcieadm_cfgspace_ofmt_t pco;
3167687d0d8SRobert Mustacchi 
3177687d0d8SRobert Mustacchi 	VERIFY3P(walkp->pcw_filt, !=, NULL);
3187687d0d8SRobert Mustacchi 	pco.pco_base = walkp->pcw_filt->pstr_curgen;
3197687d0d8SRobert Mustacchi 	pco.pco_short = sname;
3207687d0d8SRobert Mustacchi 	pco.pco_human = human;
3217687d0d8SRobert Mustacchi 	pco.pco_value = value;
3227687d0d8SRobert Mustacchi 	pco.pco_strval = NULL;
3237687d0d8SRobert Mustacchi 	ofmt_print(walkp->pcw_ofmt, &pco);
3247687d0d8SRobert Mustacchi }
3257687d0d8SRobert Mustacchi 
3267687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_print pcieadm_cfgspace_print_t;
3277687d0d8SRobert Mustacchi typedef void (*pcieadm_cfgspace_print_f)(pcieadm_cfgspace_walk_t *,
3287687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *, void *);
3297687d0d8SRobert Mustacchi 
3307687d0d8SRobert Mustacchi struct pcieadm_cfgspace_print {
3317687d0d8SRobert Mustacchi 	uint8_t pcp_off;
3327687d0d8SRobert Mustacchi 	uint8_t pcp_len;
3337687d0d8SRobert Mustacchi 	const char *pcp_short;
3347687d0d8SRobert Mustacchi 	const char *pcp_human;
3357687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_f pcp_print;
3367687d0d8SRobert Mustacchi 	void *pcp_arg;
3377687d0d8SRobert Mustacchi };
3387687d0d8SRobert Mustacchi 
3397687d0d8SRobert Mustacchi static void
3407687d0d8SRobert Mustacchi pcieadm_field_printf(pcieadm_cfgspace_walk_t *walkp, const char *shortf,
3417687d0d8SRobert Mustacchi     const char *humanf, uint64_t val, const char *fmt, ...)
3427687d0d8SRobert Mustacchi {
3437687d0d8SRobert Mustacchi 	va_list ap;
3447687d0d8SRobert Mustacchi 
3457687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, shortf))
3467687d0d8SRobert Mustacchi 		return;
3477687d0d8SRobert Mustacchi 
3487687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
3497687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_parse(walkp, shortf, humanf, val);
3507687d0d8SRobert Mustacchi 		return;
3517687d0d8SRobert Mustacchi 	}
3527687d0d8SRobert Mustacchi 
3537687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
3547687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
3557687d0d8SRobert Mustacchi 	}
3567687d0d8SRobert Mustacchi 
3577687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
3587687d0d8SRobert Mustacchi 		(void) printf("|--> %s (%s.%s): ", humanf,
3597687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, shortf);
3607687d0d8SRobert Mustacchi 	} else {
3617687d0d8SRobert Mustacchi 		(void) printf("|--> %s: ", humanf);
3627687d0d8SRobert Mustacchi 	}
3637687d0d8SRobert Mustacchi 
3647687d0d8SRobert Mustacchi 	va_start(ap, fmt);
3657687d0d8SRobert Mustacchi 	(void) vprintf(fmt, ap);
3667687d0d8SRobert Mustacchi 	va_end(ap);
3677687d0d8SRobert Mustacchi 
3687687d0d8SRobert Mustacchi }
3697687d0d8SRobert Mustacchi 
3707687d0d8SRobert Mustacchi static void
3717687d0d8SRobert Mustacchi pcieadm_cfgspace_printf(pcieadm_cfgspace_walk_t *walkp,
3727687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, uint64_t val, const char *fmt, ...)
3737687d0d8SRobert Mustacchi {
3747687d0d8SRobert Mustacchi 	va_list ap;
3757687d0d8SRobert Mustacchi 
3767687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, print->pcp_short))
3777687d0d8SRobert Mustacchi 		return;
3787687d0d8SRobert Mustacchi 
3797687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
3807687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_parse(walkp, print->pcp_short,
3817687d0d8SRobert Mustacchi 		    print->pcp_human, val);
3827687d0d8SRobert Mustacchi 		return;
3837687d0d8SRobert Mustacchi 	}
3847687d0d8SRobert Mustacchi 
3857687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
3867687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
3877687d0d8SRobert Mustacchi 	}
3887687d0d8SRobert Mustacchi 
3897687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
3907687d0d8SRobert Mustacchi 		(void) printf("%s (%s.%s): ", print->pcp_human,
3917687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, print->pcp_short);
3927687d0d8SRobert Mustacchi 	} else {
3937687d0d8SRobert Mustacchi 		(void) printf("%s: ", print->pcp_human);
3947687d0d8SRobert Mustacchi 	}
3957687d0d8SRobert Mustacchi 
3967687d0d8SRobert Mustacchi 	va_start(ap, fmt);
3977687d0d8SRobert Mustacchi 	(void) vprintf(fmt, ap);
3987687d0d8SRobert Mustacchi 	va_end(ap);
3997687d0d8SRobert Mustacchi }
4007687d0d8SRobert Mustacchi 
4017687d0d8SRobert Mustacchi static void
4027687d0d8SRobert Mustacchi pcieadm_cfgspace_puts(pcieadm_cfgspace_walk_t *walkp,
4037687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, const char *str)
4047687d0d8SRobert Mustacchi {
4057687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, print->pcp_short))
4067687d0d8SRobert Mustacchi 		return;
4077687d0d8SRobert Mustacchi 
4087687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
4097687d0d8SRobert Mustacchi 		pcieadm_cfgspace_ofmt_t pco;
4107687d0d8SRobert Mustacchi 
4117687d0d8SRobert Mustacchi 		VERIFY3P(walkp->pcw_filt, !=, NULL);
4127687d0d8SRobert Mustacchi 		pco.pco_base = walkp->pcw_filt->pstr_curgen;
4137687d0d8SRobert Mustacchi 		pco.pco_short = print->pcp_short;
4147687d0d8SRobert Mustacchi 		pco.pco_human = print->pcp_human;
4157687d0d8SRobert Mustacchi 		pco.pco_strval = str;
4167687d0d8SRobert Mustacchi 		ofmt_print(walkp->pcw_ofmt, &pco);
4177687d0d8SRobert Mustacchi 		return;
4187687d0d8SRobert Mustacchi 	}
4197687d0d8SRobert Mustacchi 
4207687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
4217687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
4227687d0d8SRobert Mustacchi 	}
4237687d0d8SRobert Mustacchi 
4247687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
4257687d0d8SRobert Mustacchi 		(void) printf("%s (%s.%s): %s\n", print->pcp_human,
4267687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, print->pcp_short, str);
4277687d0d8SRobert Mustacchi 	} else {
4287687d0d8SRobert Mustacchi 		(void) printf("%s: %s\n", print->pcp_human, str);
4297687d0d8SRobert Mustacchi 	}
4307687d0d8SRobert Mustacchi }
4317687d0d8SRobert Mustacchi 
4327687d0d8SRobert Mustacchi static uint64_t
4337687d0d8SRobert Mustacchi pcieadm_cfgspace_extract(pcieadm_cfgspace_walk_t *walkp,
4347687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print)
4357687d0d8SRobert Mustacchi {
4367687d0d8SRobert Mustacchi 	uint32_t val = 0;
4377687d0d8SRobert Mustacchi 
4387687d0d8SRobert Mustacchi 	VERIFY3U(print->pcp_len, <=, 8);
4397687d0d8SRobert Mustacchi 	VERIFY3U(print->pcp_off + print->pcp_len + walkp->pcw_capoff, <=,
4407687d0d8SRobert Mustacchi 	    walkp->pcw_valid);
4417687d0d8SRobert Mustacchi 	for (uint8_t i = print->pcp_len; i > 0; i--) {
4427687d0d8SRobert Mustacchi 		val <<= 8;
4437687d0d8SRobert Mustacchi 		val |= walkp->pcw_data->pcb_u8[walkp->pcw_capoff +
4447687d0d8SRobert Mustacchi 		    print->pcp_off + i - 1];
4457687d0d8SRobert Mustacchi 	}
4467687d0d8SRobert Mustacchi 
4477687d0d8SRobert Mustacchi 	return (val);
4487687d0d8SRobert Mustacchi }
4497687d0d8SRobert Mustacchi 
4507687d0d8SRobert Mustacchi static uint16_t
4517687d0d8SRobert Mustacchi pcieadm_cfgspace_extract_u16(pcieadm_cfgspace_walk_t *walkp,
4527687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print)
4537687d0d8SRobert Mustacchi {
4547687d0d8SRobert Mustacchi 	VERIFY(print->pcp_len == 2);
4557687d0d8SRobert Mustacchi 	return ((uint16_t)pcieadm_cfgspace_extract(walkp, print));
4567687d0d8SRobert Mustacchi }
4577687d0d8SRobert Mustacchi 
4587687d0d8SRobert Mustacchi static void
4597687d0d8SRobert Mustacchi pcieadm_cfgspace_print_unit(pcieadm_cfgspace_walk_t *walkp,
4607687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
4617687d0d8SRobert Mustacchi {
4627687d0d8SRobert Mustacchi 	pcieadm_unitdef_t *unit = arg;
4637687d0d8SRobert Mustacchi 	uint64_t rawval = pcieadm_cfgspace_extract(walkp, print);
4647687d0d8SRobert Mustacchi 	uint64_t val = rawval;
4657687d0d8SRobert Mustacchi 
4667687d0d8SRobert Mustacchi 	if (unit->pcd_mult > 1) {
4677687d0d8SRobert Mustacchi 		val *= unit->pcd_mult;
4687687d0d8SRobert Mustacchi 	}
4697687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, rawval, "0x%" PRIx64 " %s%s\n",
4707687d0d8SRobert Mustacchi 	    val, unit->pcd_unit, val != 1 ? "s" : "");
4717687d0d8SRobert Mustacchi }
4727687d0d8SRobert Mustacchi 
4737687d0d8SRobert Mustacchi static void
4747687d0d8SRobert Mustacchi pcieadm_cfgspace_print_regdef(pcieadm_cfgspace_walk_t *walkp,
4757687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
4767687d0d8SRobert Mustacchi {
4777687d0d8SRobert Mustacchi 	pcieadm_regdef_t *regdef = arg;
4787687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
4797687d0d8SRobert Mustacchi 
4807687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val);
4817687d0d8SRobert Mustacchi 
4827687d0d8SRobert Mustacchi 	pcieadm_indent();
4837687d0d8SRobert Mustacchi 	pcieadm_strfilt_push(walkp, print->pcp_short);
4847687d0d8SRobert Mustacchi 
4857687d0d8SRobert Mustacchi 	for (regdef = arg; regdef->prd_short != NULL; regdef++) {
4867687d0d8SRobert Mustacchi 		uint32_t nbits = regdef->prd_hibit - regdef->prd_lowbit + 1UL;
4877687d0d8SRobert Mustacchi 		uint32_t bitmask = (1UL << nbits) - 1UL;
4887687d0d8SRobert Mustacchi 		uint64_t regval = (val >> regdef->prd_lowbit) & bitmask;
4897687d0d8SRobert Mustacchi 		const char *strval;
4907687d0d8SRobert Mustacchi 		uint64_t actval;
4917687d0d8SRobert Mustacchi 
4927687d0d8SRobert Mustacchi 		if (!pcieadm_cfgspace_filter(walkp, regdef->prd_short)) {
4937687d0d8SRobert Mustacchi 			continue;
4947687d0d8SRobert Mustacchi 		}
4957687d0d8SRobert Mustacchi 
4967687d0d8SRobert Mustacchi 		switch (regdef->prd_valtype) {
4977687d0d8SRobert Mustacchi 		case PRDV_STRVAL:
4987687d0d8SRobert Mustacchi 			strval = regdef->prd_val.prdv_strval[regval];
4997687d0d8SRobert Mustacchi 			if (strval == NULL) {
5007687d0d8SRobert Mustacchi 				strval = "reserved";
5017687d0d8SRobert Mustacchi 			}
502*92f11af9SRobert Mustacchi 
5037687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
5047687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "%s (0x%" PRIx64 ")\n",
5057687d0d8SRobert Mustacchi 			    strval, regval << regdef->prd_lowbit);
5067687d0d8SRobert Mustacchi 			break;
5077687d0d8SRobert Mustacchi 		case PRDV_HEX:
5087687d0d8SRobert Mustacchi 			actval = regval;
5097687d0d8SRobert Mustacchi 			if (regdef->prd_val.prdv_hex.pra_shift > 0) {
5107687d0d8SRobert Mustacchi 				actval <<= regdef->prd_val.prdv_hex.pra_shift;
5117687d0d8SRobert Mustacchi 			}
5127687d0d8SRobert Mustacchi 			actval += regdef->prd_val.prdv_hex.pra_addend;
5137687d0d8SRobert Mustacchi 
5147687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
5157687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "0x% " PRIx64 "\n",
5167687d0d8SRobert Mustacchi 			    actval);
5177687d0d8SRobert Mustacchi 			break;
5187687d0d8SRobert Mustacchi 		case PRDV_BITFIELD:
5197687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
5207687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "0x%" PRIx64 "\n",
5217687d0d8SRobert Mustacchi 			    regval << regdef->prd_lowbit);
5227687d0d8SRobert Mustacchi 
5237687d0d8SRobert Mustacchi 			if (walkp->pcw_ofmt == NULL) {
5247687d0d8SRobert Mustacchi 				pcieadm_indent();
5257687d0d8SRobert Mustacchi 				for (uint32_t i = 0; i < nbits; i++) {
5267687d0d8SRobert Mustacchi 					if (((1 << i) & regval) == 0)
5277687d0d8SRobert Mustacchi 						continue;
5287687d0d8SRobert Mustacchi 					pcieadm_print("|--> %s (0x%x)\n",
5297687d0d8SRobert Mustacchi 					    regdef->prd_val.prdv_strval[i],
5307687d0d8SRobert Mustacchi 					    1UL << (i + regdef->prd_lowbit));
5317687d0d8SRobert Mustacchi 				}
5327687d0d8SRobert Mustacchi 				pcieadm_deindent();
5337687d0d8SRobert Mustacchi 			}
5347687d0d8SRobert Mustacchi 			break;
5357687d0d8SRobert Mustacchi 		}
5367687d0d8SRobert Mustacchi 	}
5377687d0d8SRobert Mustacchi 
5387687d0d8SRobert Mustacchi 	pcieadm_strfilt_pop(walkp);
5397687d0d8SRobert Mustacchi 	pcieadm_deindent();
5407687d0d8SRobert Mustacchi }
5417687d0d8SRobert Mustacchi 
5427687d0d8SRobert Mustacchi static void
5437687d0d8SRobert Mustacchi pcieadm_cfgspace_print_strmap(pcieadm_cfgspace_walk_t *walkp,
5447687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
5457687d0d8SRobert Mustacchi {
5467687d0d8SRobert Mustacchi 	pcieadm_strmap_t *strmap = arg;
5477687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
5487687d0d8SRobert Mustacchi 	const char *str = "reserved";
5497687d0d8SRobert Mustacchi 
5507687d0d8SRobert Mustacchi 	for (uint_t i = 0; strmap[i].psr_str != NULL; i++) {
5517687d0d8SRobert Mustacchi 		if (strmap[i].psr_val == val) {
5527687d0d8SRobert Mustacchi 			str = strmap[i].psr_str;
5537687d0d8SRobert Mustacchi 			break;
5547687d0d8SRobert Mustacchi 		}
5557687d0d8SRobert Mustacchi 	}
5567687d0d8SRobert Mustacchi 
5577687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%x -- %s\n", val, str);
5587687d0d8SRobert Mustacchi }
5597687d0d8SRobert Mustacchi 
5607687d0d8SRobert Mustacchi static void
5617687d0d8SRobert Mustacchi pcieadm_cfgspace_print_hex(pcieadm_cfgspace_walk_t *walkp,
5627687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
5637687d0d8SRobert Mustacchi {
5647687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
5657687d0d8SRobert Mustacchi 
5667687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val);
5677687d0d8SRobert Mustacchi }
5687687d0d8SRobert Mustacchi 
5697687d0d8SRobert Mustacchi static void
5707687d0d8SRobert Mustacchi pcieadm_cfgspace_print_vendor(pcieadm_cfgspace_walk_t *walkp,
5717687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
5727687d0d8SRobert Mustacchi {
5737687d0d8SRobert Mustacchi 	pcidb_vendor_t *vend;
5747687d0d8SRobert Mustacchi 	uint16_t vid = pcieadm_cfgspace_extract_u16(walkp, print);
5757687d0d8SRobert Mustacchi 
5767687d0d8SRobert Mustacchi 	vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb, vid);
5777687d0d8SRobert Mustacchi 	if (vend != NULL) {
5787687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, vid, "0x%x -- %s\n", vid,
5797687d0d8SRobert Mustacchi 		    pcidb_vendor_name(vend));
5807687d0d8SRobert Mustacchi 	} else {
5817687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, vid, "0x%x\n", vid);
5827687d0d8SRobert Mustacchi 	}
5837687d0d8SRobert Mustacchi }
5847687d0d8SRobert Mustacchi 
5857687d0d8SRobert Mustacchi static void
5867687d0d8SRobert Mustacchi pcieadm_cfgspace_print_device(pcieadm_cfgspace_walk_t *walkp,
5877687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
5887687d0d8SRobert Mustacchi {
5897687d0d8SRobert Mustacchi 	pcidb_device_t *dev;
5907687d0d8SRobert Mustacchi 	uint16_t did = pcieadm_cfgspace_extract_u16(walkp, print);
5917687d0d8SRobert Mustacchi 	uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] +
5927687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8);
5937687d0d8SRobert Mustacchi 
5947687d0d8SRobert Mustacchi 	dev = pcidb_lookup_device(walkp->pcw_pcieadm->pia_pcidb, vid, did);
5957687d0d8SRobert Mustacchi 	if (dev != NULL) {
5967687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, did, "0x%x -- %s\n", did,
5977687d0d8SRobert Mustacchi 		    pcidb_device_name(dev));
5987687d0d8SRobert Mustacchi 	} else {
5997687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, did, "0x%x\n", did);
6007687d0d8SRobert Mustacchi 	}
6017687d0d8SRobert Mustacchi }
6027687d0d8SRobert Mustacchi 
6037687d0d8SRobert Mustacchi /*
6047687d0d8SRobert Mustacchi  * To print out detailed information about a subsystem vendor or device, we need
6057687d0d8SRobert Mustacchi  * all of the information about the vendor and device due to the organization of
6067687d0d8SRobert Mustacchi  * the PCI IDs db.
6077687d0d8SRobert Mustacchi  */
6087687d0d8SRobert Mustacchi static void
6097687d0d8SRobert Mustacchi pcieadm_cfgspace_print_subid(pcieadm_cfgspace_walk_t *walkp,
6107687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
6117687d0d8SRobert Mustacchi {
6127687d0d8SRobert Mustacchi 	uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] +
6137687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8);
6147687d0d8SRobert Mustacchi 	uint16_t did = walkp->pcw_data->pcb_u8[PCI_CONF_DEVID] +
6157687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_DEVID + 1] << 8);
6167687d0d8SRobert Mustacchi 	uint16_t svid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID] +
6177687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID + 1] << 8);
6187687d0d8SRobert Mustacchi 	uint16_t sdid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID] +
6197687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID + 1] << 8);
6207687d0d8SRobert Mustacchi 	uint16_t val = pcieadm_cfgspace_extract_u16(walkp, print);
6217687d0d8SRobert Mustacchi 	boolean_t isvendor = print->pcp_off == PCI_CONF_SUBVENID;
6227687d0d8SRobert Mustacchi 
6237687d0d8SRobert Mustacchi 	if (isvendor) {
6247687d0d8SRobert Mustacchi 		pcidb_vendor_t *vend;
6257687d0d8SRobert Mustacchi 		vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb,
6267687d0d8SRobert Mustacchi 		    svid);
6277687d0d8SRobert Mustacchi 		if (vend != NULL) {
6287687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
6297687d0d8SRobert Mustacchi 			    "0x%x -- %s\n", val, pcidb_vendor_name(vend));
6307687d0d8SRobert Mustacchi 		} else {
6317687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
6327687d0d8SRobert Mustacchi 			    "0x%x\n", val);
6337687d0d8SRobert Mustacchi 		}
6347687d0d8SRobert Mustacchi 	} else {
6357687d0d8SRobert Mustacchi 		pcidb_subvd_t *subvd;
6367687d0d8SRobert Mustacchi 		subvd = pcidb_lookup_subvd(walkp->pcw_pcieadm->pia_pcidb, vid,
6377687d0d8SRobert Mustacchi 		    did, svid, sdid);
6387687d0d8SRobert Mustacchi 		if (subvd != NULL) {
6397687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
6407687d0d8SRobert Mustacchi 			    "0x%x -- %s\n", val, pcidb_subvd_name(subvd));
6417687d0d8SRobert Mustacchi 		} else {
6427687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val, "0x%x\n",
6437687d0d8SRobert Mustacchi 			    val);
6447687d0d8SRobert Mustacchi 		}
6457687d0d8SRobert Mustacchi 	}
6467687d0d8SRobert Mustacchi }
6477687d0d8SRobert Mustacchi 
6487687d0d8SRobert Mustacchi /*
6497687d0d8SRobert Mustacchi  * The variable natures of BARs is a pain. This makes printing this out and the
6507687d0d8SRobert Mustacchi  * fields all a bit gross.
6517687d0d8SRobert Mustacchi  */
6527687d0d8SRobert Mustacchi static void
6537687d0d8SRobert Mustacchi pcieadm_cfgspace_print_bars(pcieadm_cfgspace_walk_t *walkp,
6547687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
6557687d0d8SRobert Mustacchi {
6567687d0d8SRobert Mustacchi 	uint32_t *barp = &walkp->pcw_data->pcb_u32[(walkp->pcw_capoff +
6577687d0d8SRobert Mustacchi 	    print->pcp_off) / 4];
6587687d0d8SRobert Mustacchi 	char barname[32];
6597687d0d8SRobert Mustacchi 	const char *typestrs[2] = { "Memory Space", "I/O Space" };
6607687d0d8SRobert Mustacchi 
6617687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < print->pcp_len / 4; i++) {
6627687d0d8SRobert Mustacchi 		uint_t type;
6637687d0d8SRobert Mustacchi 		(void) snprintf(barname, sizeof (barname), "%s%u",
6647687d0d8SRobert Mustacchi 		    print->pcp_short, i);
6657687d0d8SRobert Mustacchi 
6667687d0d8SRobert Mustacchi 		type = barp[i] & PCI_BASE_SPACE_M;
6677687d0d8SRobert Mustacchi 
6687687d0d8SRobert Mustacchi 		if (pcieadm_cfgspace_filter(walkp, barname) &&
6697687d0d8SRobert Mustacchi 		    walkp->pcw_ofmt == NULL) {
6707687d0d8SRobert Mustacchi 			if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) !=
6717687d0d8SRobert Mustacchi 			    0) {
6727687d0d8SRobert Mustacchi 				pcieadm_print("%s %u (%s.%s)\n",
6737687d0d8SRobert Mustacchi 				    print->pcp_human, i,
6747687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, barname);
6757687d0d8SRobert Mustacchi 			} else {
6767687d0d8SRobert Mustacchi 				pcieadm_print("%s %u\n", print->pcp_human, i);
6777687d0d8SRobert Mustacchi 			}
6787687d0d8SRobert Mustacchi 		}
6797687d0d8SRobert Mustacchi 
6807687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(walkp, barname);
6817687d0d8SRobert Mustacchi 		pcieadm_indent();
6827687d0d8SRobert Mustacchi 
6837687d0d8SRobert Mustacchi 		pcieadm_field_printf(walkp, "space", "Space", type,
6847687d0d8SRobert Mustacchi 		    "%s (0x%x)\n", typestrs[type], type);
6857687d0d8SRobert Mustacchi 
6867687d0d8SRobert Mustacchi 		if (type == PCI_BASE_SPACE_IO) {
6877687d0d8SRobert Mustacchi 			uint32_t addr = barp[i] & PCI_BASE_IO_ADDR_M;
6887687d0d8SRobert Mustacchi 
6897687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
6907687d0d8SRobert Mustacchi 			    "0x%" PRIx32 "\n", addr);
6917687d0d8SRobert Mustacchi 		} else {
6927687d0d8SRobert Mustacchi 			uint8_t type, pre;
6937687d0d8SRobert Mustacchi 			uint64_t addr;
6947687d0d8SRobert Mustacchi 			const char *locstr;
6957687d0d8SRobert Mustacchi 
6967687d0d8SRobert Mustacchi 			type = barp[i] & PCI_BASE_TYPE_M;
6977687d0d8SRobert Mustacchi 			pre = barp[i] & PCI_BASE_PREF_M;
6987687d0d8SRobert Mustacchi 			addr = barp[i] & PCI_BASE_M_ADDR_M;
6997687d0d8SRobert Mustacchi 
7007687d0d8SRobert Mustacchi 			if (type == PCI_BASE_TYPE_ALL) {
7017687d0d8SRobert Mustacchi 				addr += (uint64_t)barp[i+1] << 32;
7027687d0d8SRobert Mustacchi 				i++;
7037687d0d8SRobert Mustacchi 			}
7047687d0d8SRobert Mustacchi 
7057687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
7067687d0d8SRobert Mustacchi 			    "0x%" PRIx64 "\n", addr);
7077687d0d8SRobert Mustacchi 
7087687d0d8SRobert Mustacchi 			switch (type) {
7097687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_MEM:
7107687d0d8SRobert Mustacchi 				locstr = "32-bit";
7117687d0d8SRobert Mustacchi 				break;
7127687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_LOW:
7137687d0d8SRobert Mustacchi 				locstr = "Sub-1 MiB";
7147687d0d8SRobert Mustacchi 				break;
7157687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_ALL:
7167687d0d8SRobert Mustacchi 				locstr = "64-bit";
7177687d0d8SRobert Mustacchi 				break;
7187687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_RES:
7197687d0d8SRobert Mustacchi 			default:
7207687d0d8SRobert Mustacchi 				locstr = "Reserved";
7217687d0d8SRobert Mustacchi 				break;
7227687d0d8SRobert Mustacchi 			}
7237687d0d8SRobert Mustacchi 
7247687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
7257687d0d8SRobert Mustacchi 			    "%s (0x%x)\n", locstr, type >> 1);
7267687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "prefetch", "Prefetchable",
7277687d0d8SRobert Mustacchi 			    pre != 0, "%s (0x%x)\n", pre != 0 ? "yes" : "no",
7287687d0d8SRobert Mustacchi 			    pre != 0);
7297687d0d8SRobert Mustacchi 		}
7307687d0d8SRobert Mustacchi 
7317687d0d8SRobert Mustacchi 		pcieadm_deindent();
7327687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(walkp);
7337687d0d8SRobert Mustacchi 	}
7347687d0d8SRobert Mustacchi }
7357687d0d8SRobert Mustacchi 
7367687d0d8SRobert Mustacchi static void
7377687d0d8SRobert Mustacchi pcieadm_cfgspace_print_ecv(pcieadm_cfgspace_walk_t *walkp,
7387687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
7397687d0d8SRobert Mustacchi {
7407687d0d8SRobert Mustacchi 	uint16_t bitlen, nwords;
7417687d0d8SRobert Mustacchi 
7427687d0d8SRobert Mustacchi 	if (BITX(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 5, 5) == 0) {
7437687d0d8SRobert Mustacchi 		return;
7447687d0d8SRobert Mustacchi 	}
7457687d0d8SRobert Mustacchi 
7467687d0d8SRobert Mustacchi 	bitlen = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 5];
7477687d0d8SRobert Mustacchi 	if (bitlen == 0) {
7487687d0d8SRobert Mustacchi 		bitlen = 256;
7497687d0d8SRobert Mustacchi 	}
7507687d0d8SRobert Mustacchi 
7517687d0d8SRobert Mustacchi 	nwords = bitlen / 32;
7527687d0d8SRobert Mustacchi 	if ((bitlen % 8) != 0) {
7537687d0d8SRobert Mustacchi 		nwords++;
7547687d0d8SRobert Mustacchi 	}
7557687d0d8SRobert Mustacchi 
7567687d0d8SRobert Mustacchi 	for (uint16_t i = 0; i < nwords; i++) {
7577687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
7587687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
7597687d0d8SRobert Mustacchi 
7607687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "ecv%u", i);
7617687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "Egress Control "
7627687d0d8SRobert Mustacchi 		    "Vector %u", i);
7637687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
7647687d0d8SRobert Mustacchi 		p.pcp_len = 4;
7657687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
7667687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
7677687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
7687687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
7697687d0d8SRobert Mustacchi 
7707687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
7717687d0d8SRobert Mustacchi 	}
7727687d0d8SRobert Mustacchi }
7737687d0d8SRobert Mustacchi 
7747687d0d8SRobert Mustacchi static void
7757687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpa_paa(pcieadm_cfgspace_walk_t *walkp,
7767687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
7777687d0d8SRobert Mustacchi {
7787687d0d8SRobert Mustacchi 	uint8_t nents;
7797687d0d8SRobert Mustacchi 
7807687d0d8SRobert Mustacchi 	nents = BITX(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 4, 0) + 1;
7817687d0d8SRobert Mustacchi 	if (nents == 0) {
7827687d0d8SRobert Mustacchi 		return;
7837687d0d8SRobert Mustacchi 	}
7847687d0d8SRobert Mustacchi 
7857687d0d8SRobert Mustacchi 	for (uint8_t i = 0; i < nents; i++) {
7867687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
7877687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
7887687d0d8SRobert Mustacchi 
7897687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "%s%u",
7907687d0d8SRobert Mustacchi 		    print->pcp_short, i);
7917687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "%s %u",
7927687d0d8SRobert Mustacchi 		    print->pcp_human, i);
7937687d0d8SRobert Mustacchi 
7947687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i;
7957687d0d8SRobert Mustacchi 		p.pcp_len = 1;
7967687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
7977687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
7987687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
7997687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
8007687d0d8SRobert Mustacchi 
8017687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
8027687d0d8SRobert Mustacchi 	}
8037687d0d8SRobert Mustacchi }
8047687d0d8SRobert Mustacchi 
8057687d0d8SRobert Mustacchi /*
8067687d0d8SRobert Mustacchi  * Config Space Header Table Definitions
8077687d0d8SRobert Mustacchi  */
8087687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_command[] = {
8097687d0d8SRobert Mustacchi 	{ 0, 0, "io", "I/O Space", PRDV_STRVAL,
8107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8117687d0d8SRobert Mustacchi 	{ 1, 1, "mem", "Memory Space", PRDV_STRVAL,
8127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8137687d0d8SRobert Mustacchi 	{ 2, 2, "bus", "Bus Master", PRDV_STRVAL,
8147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8157687d0d8SRobert Mustacchi 	{ 3, 3, "spec", "Special Cycle", PRDV_STRVAL,
8167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8177687d0d8SRobert Mustacchi 	{ 4, 4, "mwi", "Memory Write and Invalidate", PRDV_STRVAL,
8187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8197687d0d8SRobert Mustacchi 	{ 5, 5, "vga", "VGA Palette Snoop", PRDV_STRVAL,
8207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8217687d0d8SRobert Mustacchi 	{ 6, 6, "per", "Parity Error Response", PRDV_STRVAL,
8227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8237687d0d8SRobert Mustacchi 	{ 7, 7, "idsel", "IDSEL Stepping/Wait Cycle Control", PRDV_STRVAL,
8247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
8257687d0d8SRobert Mustacchi 	{ 8, 8, "serr", "SERR# Enable", PRDV_STRVAL,
8267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } }, },
8277687d0d8SRobert Mustacchi 	{ 9, 9, "fbtx", "Fast Back-to-Back Transactions", PRDV_STRVAL,
8287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } }, },
8297687d0d8SRobert Mustacchi 	{ 10, 10, "intx", "Interrupt X", PRDV_STRVAL,
8307687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
8317687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8327687d0d8SRobert Mustacchi };
8337687d0d8SRobert Mustacchi 
8347687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_status[] = {
8357687d0d8SRobert Mustacchi 	{ 0, 0, "imm", "Immediate Readiness", PRDV_STRVAL,
8367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8377687d0d8SRobert Mustacchi 	{ 3, 3, "istat", "Interrupt Status", PRDV_STRVAL,
8387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not pending", "pending" } }, },
8397687d0d8SRobert Mustacchi 	{ 4, 4, "capsup", "Capabilities List", PRDV_STRVAL,
8407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8417687d0d8SRobert Mustacchi 	{ 5, 5, "66mhz", "66 MHz Capable", PRDV_STRVAL,
8427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8437687d0d8SRobert Mustacchi 	{ 7, 7, "fbtxcap", "Fast Back-to-Back Capable", PRDV_STRVAL,
8447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8457687d0d8SRobert Mustacchi 	{ 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL,
8467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } }, },
8477687d0d8SRobert Mustacchi 	{ 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL,
8487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "fast", "medium", "slow",
8497687d0d8SRobert Mustacchi 	    "reserved" } } },
8507687d0d8SRobert Mustacchi 	{ 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL,
8517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8527687d0d8SRobert Mustacchi 	{ 12, 12, "rta", "Received Target Abort", PRDV_STRVAL,
8537687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8547687d0d8SRobert Mustacchi 	{ 13, 13, "rma", "Received Master Abort", PRDV_STRVAL,
8557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8567687d0d8SRobert Mustacchi 	{ 14, 14, "sse", "Signaled System Error", PRDV_STRVAL,
8577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8587687d0d8SRobert Mustacchi 	{ 15, 15, "dpe", "Detected Parity Error", PRDV_STRVAL,
8597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8607687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8617687d0d8SRobert Mustacchi };
8627687d0d8SRobert Mustacchi 
8637687d0d8SRobert Mustacchi /*
8647687d0d8SRobert Mustacchi  * It might be interesting to translate these into numbers at a future point.
8657687d0d8SRobert Mustacchi  */
8667687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_class[] = {
8677687d0d8SRobert Mustacchi 	{ 16, 23, "class", "Class Code", PRDV_HEX },
8687687d0d8SRobert Mustacchi 	{ 7, 15, "sclass", "Sub-Class Code", PRDV_HEX },
8697687d0d8SRobert Mustacchi 	{ 0, 7, "pi", "Programming Interface", PRDV_HEX },
8707687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8717687d0d8SRobert Mustacchi };
8727687d0d8SRobert Mustacchi 
8737687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_iobase[] = {
8747687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
8757687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } },
8767687d0d8SRobert Mustacchi 	{ 4, 7, "base", "Base", PRDV_HEX,
8777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12 } } },
8787687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8797687d0d8SRobert Mustacchi };
8807687d0d8SRobert Mustacchi 
8817687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_iolim[] = {
8827687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
8837687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } },
8847687d0d8SRobert Mustacchi 	{ 4, 7, "limit", "Limit", PRDV_HEX,
8857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12, 0xfff } } },
8867687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8877687d0d8SRobert Mustacchi };
8887687d0d8SRobert Mustacchi 
8897687d0d8SRobert Mustacchi 
8907687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridgests[] = {
8917687d0d8SRobert Mustacchi 	{ 5, 5, "66mhz", "66 MHz", PRDV_STRVAL,
8927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
8937687d0d8SRobert Mustacchi 	{ 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL,
8947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
8957687d0d8SRobert Mustacchi 	{ 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL,
8967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } } },
8977687d0d8SRobert Mustacchi 	{ 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL,
8987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "fast", "medium", "slow" } } },
8997687d0d8SRobert Mustacchi 	{ 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL,
9007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
9017687d0d8SRobert Mustacchi 	{ 12, 12, "rta", "Received Target Abort", PRDV_STRVAL,
9027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
9037687d0d8SRobert Mustacchi 	{ 13, 13, "rma", "Received Master Abort", PRDV_STRVAL,
9047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
9057687d0d8SRobert Mustacchi 	{ 14, 14, "rsyserr", "Received System Error", PRDV_STRVAL,
9067687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error received" } } },
9077687d0d8SRobert Mustacchi 	{ 15, 15, "dperr", "Detected Parity Error", PRDV_STRVAL,
9087687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } } },
9097687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9107687d0d8SRobert Mustacchi };
9117687d0d8SRobert Mustacchi 
9127687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_membase[] = {
9137687d0d8SRobert Mustacchi 	{ 4, 16, "base", "Base", PRDV_HEX,
9147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20 } } },
9157687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9167687d0d8SRobert Mustacchi };
9177687d0d8SRobert Mustacchi 
9187687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_memlim[] = {
9197687d0d8SRobert Mustacchi 	{ 4, 16, "limit", "Limit", PRDV_HEX,
9207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20, 0xfffff } } },
9217687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9227687d0d8SRobert Mustacchi };
9237687d0d8SRobert Mustacchi 
9247687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_pfbase[] = {
9257687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
9267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } },
9277687d0d8SRobert Mustacchi 	{ 4, 16, "base", "Base", PRDV_HEX,
9287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20 } } },
9297687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9307687d0d8SRobert Mustacchi };
9317687d0d8SRobert Mustacchi 
9327687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_pflim[] = {
9337687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
9347687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } },
9357687d0d8SRobert Mustacchi 	{ 4, 16, "limit", "Limit", PRDV_HEX,
9367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20, 0xfffff } } },
9377687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9387687d0d8SRobert Mustacchi };
9397687d0d8SRobert Mustacchi 
9407687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bridge_ctl[] = {
9417687d0d8SRobert Mustacchi 	{ 0, 0, "perrresp", "Parity Error Response", PRDV_STRVAL,
9427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9437687d0d8SRobert Mustacchi 	{ 1, 1, "serr", "SERR#", PRDV_STRVAL,
9447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9457687d0d8SRobert Mustacchi 	{ 2, 2, "isa", "ISA", PRDV_STRVAL,
9467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9477687d0d8SRobert Mustacchi 	{ 3, 3, "vga", "VGA", PRDV_STRVAL,
9487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9497687d0d8SRobert Mustacchi 	{ 4, 4, "vgadec", "VGA 16-bit Decode", PRDV_STRVAL,
9507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "10-bit", "16-bit" } } },
9517687d0d8SRobert Mustacchi 	{ 5, 5, "mabort", "Master Abort", PRDV_STRVAL,
9527687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9537687d0d8SRobert Mustacchi 	{ 6, 6, "secrst", "Secondary Bus Reset", PRDV_HEX },
9547687d0d8SRobert Mustacchi 	{ 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL,
9557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9567687d0d8SRobert Mustacchi 	{ 8, 8, "pridisc", "Primary Discard Timer", PRDV_STRVAL,
9577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } },
9587687d0d8SRobert Mustacchi 	{ 9, 9, "secdisc", "Secondary Discard Timer", PRDV_STRVAL,
9597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } },
9607687d0d8SRobert Mustacchi 	{ 10, 10, "disctimer", "Discard Timer Error", PRDV_STRVAL,
9617687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9627687d0d8SRobert Mustacchi 	{ 11, 11, "discserr", "Discard Timer SERR#", PRDV_STRVAL,
9637687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9647687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9657687d0d8SRobert Mustacchi };
9667687d0d8SRobert Mustacchi 
9677687d0d8SRobert Mustacchi static pcieadm_unitdef_t pcieadm_unitdef_cache = {
9687687d0d8SRobert Mustacchi 	"byte", 4
9697687d0d8SRobert Mustacchi };
9707687d0d8SRobert Mustacchi 
9717687d0d8SRobert Mustacchi static pcieadm_unitdef_t pcieadm_unitdef_latreg = { "cycle" };
9727687d0d8SRobert Mustacchi 
9737687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_header[] = {
9747687d0d8SRobert Mustacchi 	{ 0, 6, "layout", "Header Layout", PRDV_STRVAL,
9757687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Device", "Bridge", "PC Card" } } },
9767687d0d8SRobert Mustacchi 	{ 7, 7, "mfd", "Multi-Function Device", PRDV_STRVAL,
9777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
9787687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9797687d0d8SRobert Mustacchi };
9807687d0d8SRobert Mustacchi 
9817687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_bist[] = {
9827687d0d8SRobert Mustacchi 	{ 0, 3, "code", "Completion Code", PRDV_HEX },
9837687d0d8SRobert Mustacchi 	{ 6, 6, "start", "Start BIST", PRDV_HEX },
9847687d0d8SRobert Mustacchi 	{ 7, 7, "cap", "BIST Capable", PRDV_STRVAL,
9857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
9867687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9877687d0d8SRobert Mustacchi };
9887687d0d8SRobert Mustacchi 
9897687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_exprom[] = {
9907687d0d8SRobert Mustacchi 	{ 0, 0, "enable", "Enable", PRDV_STRVAL,
9917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9927687d0d8SRobert Mustacchi 	{ 11, 31, "addr", "Base Address", PRDV_HEX,
9937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 21 } } },
9947687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9957687d0d8SRobert Mustacchi };
9967687d0d8SRobert Mustacchi 
9977687d0d8SRobert Mustacchi static pcieadm_strmap_t pcieadm_strmap_ipin[] = {
9987687d0d8SRobert Mustacchi 	{ "none", 0 },
9997687d0d8SRobert Mustacchi 	{ "INTA", PCI_INTA },
10007687d0d8SRobert Mustacchi 	{ "INTB", PCI_INTB },
10017687d0d8SRobert Mustacchi 	{ "INTC", PCI_INTC },
10027687d0d8SRobert Mustacchi 	{ "INTD", PCI_INTD },
10037687d0d8SRobert Mustacchi 	{ NULL }
10047687d0d8SRobert Mustacchi };
10057687d0d8SRobert Mustacchi 
10067687d0d8SRobert Mustacchi 
10077687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cfgspace_type0[] = {
10087687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
10097687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
10107687d0d8SRobert Mustacchi 	{ 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef,
10117687d0d8SRobert Mustacchi 	    pcieadm_regdef_command },
10127687d0d8SRobert Mustacchi 	{ 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef,
10137687d0d8SRobert Mustacchi 	    pcieadm_regdef_status },
10147687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
10157687d0d8SRobert Mustacchi 	{ 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef,
10167687d0d8SRobert Mustacchi 	    pcieadm_regdef_class },
10177687d0d8SRobert Mustacchi 	{ 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit,
10187687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_cache },
10197687d0d8SRobert Mustacchi 	{ 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit,
10207687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_latreg },
10217687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
10227687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
10237687d0d8SRobert Mustacchi 	{ 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef,
10247687d0d8SRobert Mustacchi 	    pcieadm_regdef_bist },
10257687d0d8SRobert Mustacchi 	{ 0x10, 24, "bar", "Base Address Register",
10267687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
10277687d0d8SRobert Mustacchi 	{ 0x28, 4, "cis", "Cardbus CIS Pointer", pcieadm_cfgspace_print_hex },
10287687d0d8SRobert Mustacchi 	{ 0x2c, 2, "subvid", "Subsystem Vendor ID",
10297687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_subid },
10307687d0d8SRobert Mustacchi 	{ 0x2e, 2, "subdev", "Subsystem Device ID",
10317687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_subid },
10327687d0d8SRobert Mustacchi 	{ 0x30, 4, "rom", "Expansion ROM", pcieadm_cfgspace_print_regdef,
10337687d0d8SRobert Mustacchi 	    pcieadm_regdef_exprom },
10347687d0d8SRobert Mustacchi 	{ 0x34, 1, "cap", "Capabilities Pointer", pcieadm_cfgspace_print_hex },
10357687d0d8SRobert Mustacchi 	{ 0x3c, 1, "iline", "Interrupt Line", pcieadm_cfgspace_print_hex },
10367687d0d8SRobert Mustacchi 	{ 0x3d, 1, "ipin", "Interrupt Pin", pcieadm_cfgspace_print_strmap,
10377687d0d8SRobert Mustacchi 	    pcieadm_strmap_ipin },
10387687d0d8SRobert Mustacchi 	{ 0x3e, 1, "gnt", "Min_Gnt", pcieadm_cfgspace_print_hex },
10397687d0d8SRobert Mustacchi 	{ 0x3f, 1, "lat", "Min_Lat", pcieadm_cfgspace_print_hex },
10407687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
10417687d0d8SRobert Mustacchi };
10427687d0d8SRobert Mustacchi 
10437687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cfgspace_type1[] = {
10447687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
10457687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
10467687d0d8SRobert Mustacchi 	{ 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef,
10477687d0d8SRobert Mustacchi 	    pcieadm_regdef_command },
10487687d0d8SRobert Mustacchi 	{ 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef,
10497687d0d8SRobert Mustacchi 	    pcieadm_regdef_status },
10507687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
10517687d0d8SRobert Mustacchi 	{ 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef,
10527687d0d8SRobert Mustacchi 	    pcieadm_regdef_class },
10537687d0d8SRobert Mustacchi 	{ 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit,
10547687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_cache },
10557687d0d8SRobert Mustacchi 	{ 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit,
10567687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_latreg },
10577687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
10587687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
10597687d0d8SRobert Mustacchi 	{ 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef,
10607687d0d8SRobert Mustacchi 	    pcieadm_regdef_bist },
10617687d0d8SRobert Mustacchi 	{ 0x10, 8, "bar", "Base Address Register",
10627687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
10637687d0d8SRobert Mustacchi 	{ PCI_BCNF_PRIBUS, 1, "pribus", "Primary Bus Number",
10647687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10657687d0d8SRobert Mustacchi 	{ PCI_BCNF_SECBUS, 1, "secbus", "Secondary Bus Number",
10667687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10677687d0d8SRobert Mustacchi 	{ PCI_BCNF_SUBBUS, 1, "subbus", "Subordinate Bus Number",
10687687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10697687d0d8SRobert Mustacchi 	{ PCI_BCNF_LATENCY_TIMER, 1, "latency2", "Secondary Latency timer",
10707687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_unit, &pcieadm_unitdef_latreg },
10717687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_BASE_LOW, 1, "iobase", "I/O Base Low",
10727687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iobase },
10737687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_LIMIT_LOW, 1, "iolimit", "I/O Limit Low",
10747687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iolim },
10757687d0d8SRobert Mustacchi 	{ PCI_BCNF_SEC_STATUS, 2, "status2", "Secondary Status",
10767687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridgests },
10777687d0d8SRobert Mustacchi 	{ PCI_BCNF_MEM_BASE, 2, "membase", "Memory Base",
10787687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_membase },
10797687d0d8SRobert Mustacchi 	{ PCI_BCNF_MEM_LIMIT, 2, "memlimit", "Memory Limit",
10807687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_memlim },
10817687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_BASE_LOW, 2, "pfbase", "Prefetchable Memory Base",
10827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pfbase },
10837687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_LIMIT_LOW, 2, "pflimit", "Prefetchable Memory Limit",
10847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pflim },
10857687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_BASE_HIGH, 4, "pfbasehi",
10867687d0d8SRobert Mustacchi 	    "Prefetchable Base Upper 32 bits",
10877687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10887687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_LIMIT_HIGH, 4, "pflimihi",
10897687d0d8SRobert Mustacchi 	    "Prefetchable Limit Upper 32 bits",
10907687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10917687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_BASE_HI, 2, "iobasehi", "I/O Base Upper 16 bits",
10927687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10937687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_LIMIT_HI, 2, "iobasehi", "I/O Limit Upper 16 bits",
10947687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10957687d0d8SRobert Mustacchi 	{ PCI_BCNF_CAP_PTR, 1, "cap", "Capabilities Pointer",
10967687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10977687d0d8SRobert Mustacchi 	{ PCI_BCNF_ROM, 4, "rom", "Expansion ROM",
10987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_exprom },
10997687d0d8SRobert Mustacchi 	{ PCI_BCNF_ILINE, 1, "iline", "Interrupt Line",
11007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11017687d0d8SRobert Mustacchi 	{ PCI_BCNF_IPIN, 1, "ipin", "Interrupt Pin",
11027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_strmap, pcieadm_strmap_ipin },
11037687d0d8SRobert Mustacchi 	{ PCI_BCNF_BCNTRL, 2, "bctl", "Bridge Control",
11047687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_ctl },
11057687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11067687d0d8SRobert Mustacchi };
11077687d0d8SRobert Mustacchi 
11087687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cfgspace_unknown[] = {
11097687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
11107687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
11117687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
11127687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
11137687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
11147687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11157687d0d8SRobert Mustacchi };
11167687d0d8SRobert Mustacchi 
11177687d0d8SRobert Mustacchi /*
11187687d0d8SRobert Mustacchi  * Power Management Capability Version 3. Note versions two and three seem to be
11197687d0d8SRobert Mustacchi  * the same, but are used to indicate compliance to different revisions of the
11207687d0d8SRobert Mustacchi  * PCI power management specification.
11217687d0d8SRobert Mustacchi  */
11227687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pmcap[] = {
11237687d0d8SRobert Mustacchi 	{ 0, 2, "vers", "Version", PRDV_HEX },
11247687d0d8SRobert Mustacchi 	{ 3, 3, "clock", "PME Clock", PRDV_STRVAL,
11257687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
11267687d0d8SRobert Mustacchi 	{ 4, 4, "irrd0", "Immediate Readiness on Return to D0", PRDV_STRVAL,
11277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
11287687d0d8SRobert Mustacchi 	{ 5, 5, "dsi", "Device Specific Initialization", PRDV_STRVAL,
11297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
11307687d0d8SRobert Mustacchi 	{ 6, 8, "auxcur", "Auxiliary Current", PRDV_STRVAL,
11317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "0", "55 mA", "100 mA", "160 mA",
11327687d0d8SRobert Mustacchi 	    "220 mA", "270 mA", "320 mA", "375 mA" } } },
11337687d0d8SRobert Mustacchi 	{ 9, 9, "d1", "D1", PRDV_STRVAL,
11347687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
11357687d0d8SRobert Mustacchi 	{ 10, 10, "d2", "D2", PRDV_STRVAL,
11367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
11377687d0d8SRobert Mustacchi 	{ 11, 15, "pme", "PME Support", PRDV_BITFIELD,
11387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "D0", "D1", "D2", "D3hot",
11397687d0d8SRobert Mustacchi 	    "D3cold" } } },
11407687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11417687d0d8SRobert Mustacchi };
11427687d0d8SRobert Mustacchi 
11437687d0d8SRobert Mustacchi 
11447687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcipm_v3[] = {
11457687d0d8SRobert Mustacchi 	{ PCI_PMCAP, 2, "pmcap", "Power Management Capabilities",
11467687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pmcap },
11477687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11487687d0d8SRobert Mustacchi };
11497687d0d8SRobert Mustacchi 
11507687d0d8SRobert Mustacchi /*
11517687d0d8SRobert Mustacchi  * PCI Bridge Subsystem Capability
11527687d0d8SRobert Mustacchi  */
11537687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_bridge_subsys[] = {
11547687d0d8SRobert Mustacchi 	{ 0x4, 2, "subvid", "Subsystem Vendor ID", pcieadm_cfgspace_print_hex },
11557687d0d8SRobert Mustacchi 	{ 0x6, 2, "subdev", "Subsystem Device ID", pcieadm_cfgspace_print_hex },
11567687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11577687d0d8SRobert Mustacchi };
11587687d0d8SRobert Mustacchi 
11597687d0d8SRobert Mustacchi /*
11607687d0d8SRobert Mustacchi  * MSI Capability
11617687d0d8SRobert Mustacchi  */
11627687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msictrl[] = {
11637687d0d8SRobert Mustacchi 	{ 0, 0, "enable", "MSI Enable", PRDV_STRVAL,
11647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
11657687d0d8SRobert Mustacchi 	{ 1, 3, "mmsgcap", "Multiple Message Capable", PRDV_STRVAL,
11667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 vector", "2 vectors",
11677687d0d8SRobert Mustacchi 	    "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } },
11687687d0d8SRobert Mustacchi 	{ 4, 6, "mmsgen", "Multiple Message Enabled", PRDV_STRVAL,
11697687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 vector", "2 vectors",
11707687d0d8SRobert Mustacchi 	    "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } },
11717687d0d8SRobert Mustacchi 	{ 7, 7, "addr64", "64-bit Address Capable", PRDV_STRVAL,
11727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
11737687d0d8SRobert Mustacchi 	{ 8, 8, "pvm", "Per-Vector Masking Capable", PRDV_STRVAL,
11747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1175*92f11af9SRobert Mustacchi 	{ 9, 9, "extmdcap", "Extended Message Data Capable", PRDV_STRVAL,
11767687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
1177*92f11af9SRobert Mustacchi 	{ 10, 10, "extmden", "extended Message Data Enable", PRDV_STRVAL,
11787687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
11797687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11807687d0d8SRobert Mustacchi };
11817687d0d8SRobert Mustacchi 
11827687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_32[] = {
11837687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
11847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
11857687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
11867687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11877687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
11887687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11897687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11907687d0d8SRobert Mustacchi };
11917687d0d8SRobert Mustacchi 
11927687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_32ext[] = {
11937687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
11947687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
11957687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
11967687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11977687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
11987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11997687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12017687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12027687d0d8SRobert Mustacchi };
12037687d0d8SRobert Mustacchi 
12047687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_32pvm[] = {
12057687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12067687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12077687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12087687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12097687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
12107687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12117687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12127687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12137687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_MASK, 4, "mask", "Mask Bits",
12147687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12157687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_PENDING, 4, "pend", "Pending Bits",
12167687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12177687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12187687d0d8SRobert Mustacchi };
12197687d0d8SRobert Mustacchi 
12207687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_64[] = {
12217687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12237687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12257687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
12267687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12277687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
12287687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12297687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12307687d0d8SRobert Mustacchi };
12317687d0d8SRobert Mustacchi 
12327687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_64ext[] = {
12337687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12347687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12357687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12367687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12377687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
12387687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12397687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
12407687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12417687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12427687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12437687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12447687d0d8SRobert Mustacchi };
12457687d0d8SRobert Mustacchi 
12467687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msi_64pvm[] = {
12477687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12497687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12507687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12517687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
12527687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12537687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
12547687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12557687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12567687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12577687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_MASKBITS, 4, "mask", "Mask Bits",
12587687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12597687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_PENDING, 4, "pend", "Pending Bits",
12607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12617687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12627687d0d8SRobert Mustacchi };
12637687d0d8SRobert Mustacchi 
12647687d0d8SRobert Mustacchi /*
12657687d0d8SRobert Mustacchi  * MSI-X Capability
12667687d0d8SRobert Mustacchi  */
12677687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msixctrl[] = {
12687687d0d8SRobert Mustacchi 	{ 0, 10, "size", "Table Size", PRDV_HEX,
12697687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
12707687d0d8SRobert Mustacchi 	{ 14, 14, "mask", "Function Mask", PRDV_STRVAL,
12717687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unmasked", "masked" } } },
12727687d0d8SRobert Mustacchi 	{ 15, 15, "enable", "MSI-X Enable", PRDV_STRVAL,
12737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
12747687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12757687d0d8SRobert Mustacchi };
12767687d0d8SRobert Mustacchi 
12777687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msixtable[] = {
12787687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "Table BIR", PRDV_STRVAL,
12797687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
12807687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
12817687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "Table Offset", PRDV_HEX,
12827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
12837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12847687d0d8SRobert Mustacchi };
12857687d0d8SRobert Mustacchi 
12867687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_msixpba[] = {
12877687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "PBA BIR", PRDV_STRVAL,
12887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
12897687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
12907687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "PBA Offset", PRDV_HEX,
12917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
12927687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12937687d0d8SRobert Mustacchi };
12947687d0d8SRobert Mustacchi 
12957687d0d8SRobert Mustacchi 
12967687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_msix[] = {
12977687d0d8SRobert Mustacchi 	{ PCI_MSIX_CTRL, 2, "ctrl", "Control Register",
12987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixctrl },
12997687d0d8SRobert Mustacchi 	{ PCI_MSIX_TBL_OFFSET, 4, "table", "Table Offset",
13007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixtable },
13017687d0d8SRobert Mustacchi 	{ PCI_MSIX_PBA_OFFSET, 4, "pba", "PBA Offset",
13027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixpba },
13037687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13047687d0d8SRobert Mustacchi };
13057687d0d8SRobert Mustacchi 
13067687d0d8SRobert Mustacchi /*
13077687d0d8SRobert Mustacchi  * PCI Express Capability
13087687d0d8SRobert Mustacchi  */
13097687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_cap[] = {
13107687d0d8SRobert Mustacchi 	{ 0, 3, "vers", "Version", PRDV_HEX },
13117687d0d8SRobert Mustacchi 	{ 4, 7, "type", "Device/Port Type", PRDV_STRVAL,
13127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PCIe Endpoint",
13137687d0d8SRobert Mustacchi 	    "Legacy PCIe Endpoint", NULL, NULL,
13147687d0d8SRobert Mustacchi 	    "Root Port of PCIe Root Complex",
13157687d0d8SRobert Mustacchi 	    "Upstream Port of PCIe Switch",
13167687d0d8SRobert Mustacchi 	    "Downstream Port of PCIe Switch",
13177687d0d8SRobert Mustacchi 	    "PCIe to PCI/PCI-X Bridge",
13187687d0d8SRobert Mustacchi 	    "PCI/PCI-x to PCIe Bridge",
13197687d0d8SRobert Mustacchi 	    "RCiEP",
13207687d0d8SRobert Mustacchi 	    "Root Complex Event Collector" } } },
13217687d0d8SRobert Mustacchi 	{ 8, 8, "slot", "Slot Implemented", PRDV_STRVAL,
13227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No", "Yes" } } },
13237687d0d8SRobert Mustacchi 	{ 9, 13, "intno", "Interrupt Message Number", PRDV_HEX },
13247687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13257687d0d8SRobert Mustacchi };
13267687d0d8SRobert Mustacchi 
13277687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devcap[] = {
13287687d0d8SRobert Mustacchi 	{ 0, 2, "mps", "Max Payload Size Supported", PRDV_STRVAL,
13297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
13307687d0d8SRobert Mustacchi 	    "512 bytes", "1024 byes", "2048 bytes", "4096 bytes" } } },
13317687d0d8SRobert Mustacchi 	{ 3, 4, "pfunc", "Phantom Functions Supported", PRDV_STRVAL,
13327687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No", "1-bit", "2-bits",
13337687d0d8SRobert Mustacchi 	    "3-bits" } } },
13347687d0d8SRobert Mustacchi 	{ 5, 5, "exttag", "Extended Tag Field", PRDV_STRVAL,
13357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "5-bit", "8-bit" } } },
13367687d0d8SRobert Mustacchi 	{ 6, 8, "l0slat", "L0s Acceptable Latency", PRDV_STRVAL,
13377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "64 ns", "128 ns", "256 ns",
13387687d0d8SRobert Mustacchi 	    "512 ns", "1 us", "2 us", "4 us", "No limit" } } },
13397687d0d8SRobert Mustacchi 	{ 9, 11, "l1lat", "L1 Acceptable Latency", PRDV_STRVAL,
13407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 us", "2 us", "4 us", "8 us",
13417687d0d8SRobert Mustacchi 	    "16 us", "32 us", "64 us", "No limit" } } },
13427687d0d8SRobert Mustacchi 	{ 15, 15, "rber", "Role Based Error Reporting", PRDV_STRVAL,
13437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
13447687d0d8SRobert Mustacchi 	{ 16, 16, "errcor", "ERR_COR Subclass", PRDV_STRVAL,
13457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
13467687d0d8SRobert Mustacchi 	{ 18, 25, "csplv", "Captured Slot Power Limit", PRDV_HEX },
13477687d0d8SRobert Mustacchi 	{ 26, 27, "cspls", "Captured Slot Power Limit Scale", PRDV_STRVAL,
13487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1.0x", "0.1x", "0.01x",
13497687d0d8SRobert Mustacchi 	    "0.001x" } } },
13507687d0d8SRobert Mustacchi 	{ 28, 28, "flr", "Function Level Reset", PRDV_STRVAL,
13517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
13527687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13537687d0d8SRobert Mustacchi };
13547687d0d8SRobert Mustacchi 
13557687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devctl[] = {
13567687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL,
13577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13587687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL,
13597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13607687d0d8SRobert Mustacchi 	{ 2, 2, "ferr", "Fatal Error Reporting", PRDV_STRVAL,
13617687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13627687d0d8SRobert Mustacchi 	{ 3, 3, "unsupreq", "Unsupported Request Reporting", PRDV_STRVAL,
13637687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13647687d0d8SRobert Mustacchi 	{ 4, 4, "relord", "Relaxed Ordering", PRDV_STRVAL,
13657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13667687d0d8SRobert Mustacchi 	{ 5, 7, "mps", "Max Payload Size", PRDV_STRVAL,
13677687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
13687687d0d8SRobert Mustacchi 	    "512 bytes", "1024 byes", "2048 bytes", "4096 bytes" } } },
13697687d0d8SRobert Mustacchi 	{ 8, 8, "exttag", "Extended Tag Field", PRDV_STRVAL,
13707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13717687d0d8SRobert Mustacchi 	{ 9, 9, "pfunc", "Phantom Functions", PRDV_STRVAL,
13727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13737687d0d8SRobert Mustacchi 	{ 9, 9, "auxpm", "Aux Power PM", PRDV_STRVAL,
13747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13757687d0d8SRobert Mustacchi 	{ 11, 11, "nosnoop", "No Snoop", PRDV_STRVAL,
13767687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13777687d0d8SRobert Mustacchi 	{ 12, 14, "mrrs", "Max Read Request Size", PRDV_STRVAL,
13787687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
13797687d0d8SRobert Mustacchi 	    "512 bytes", "1024 byes", "2048 bytes", "4096 bytes" } } },
13807687d0d8SRobert Mustacchi 	{ 15, 15, "bcrflr", "Bridge Configuration Retry / Function Level Reset",
13817687d0d8SRobert Mustacchi 	    PRDV_HEX },
13827687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13837687d0d8SRobert Mustacchi };
13847687d0d8SRobert Mustacchi 
13857687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devsts[] = {
13867687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Detected", PRDV_STRVAL,
13877687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
13887687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Detected", PRDV_STRVAL,
13897687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
13907687d0d8SRobert Mustacchi 	{ 2, 2, "ferr", "Fatal Error Detected", PRDV_STRVAL,
13917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
13927687d0d8SRobert Mustacchi 	{ 3, 3, "unsupreq", "Unsupported Request Detected", PRDV_STRVAL,
13937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
13947687d0d8SRobert Mustacchi 	{ 4, 4, "auxpm", "AUX Power Detected", PRDV_STRVAL,
13957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
13967687d0d8SRobert Mustacchi 	{ 5, 5, "txpend", "Transactions Pending", PRDV_STRVAL,
13977687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
13987687d0d8SRobert Mustacchi 	{ 6, 6, "eprd", "Emergency Power Reduction Detected", PRDV_STRVAL,
13997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14007687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14017687d0d8SRobert Mustacchi };
14027687d0d8SRobert Mustacchi 
14037687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkcap[] = {
14047687d0d8SRobert Mustacchi 	{ 0, 3, "maxspeed", "Maximum Link Speed", PRDV_STRVAL,
14057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
14067687d0d8SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s" } } },
14077687d0d8SRobert Mustacchi 	{ 4, 9, "maxwidth", "Maximum Link Width", PRDV_HEX },
14087687d0d8SRobert Mustacchi 	{ 10, 11, "aspm", "ASPM Support", PRDV_STRVAL,
14097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } },
14107687d0d8SRobert Mustacchi 	{ 12, 14, "l0slat", "L0s Exit Latency", PRDV_STRVAL,
14117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "<64ns", "64-128ns", "128-256ns",
14127687d0d8SRobert Mustacchi 	    "256-512ns", "512ns-1us", "1-2us", "2-4us", ">4us" } } },
14137687d0d8SRobert Mustacchi 	{ 15, 17, "l1lat", "L1 Exit Latency", PRDV_STRVAL,
14147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "<1us", "1-2us", "2-4us", "4-8us",
14157687d0d8SRobert Mustacchi 	    "8-16us", "16-32us" "32-64us", ">64us" } } },
14167687d0d8SRobert Mustacchi 	{ 18, 18, "clockpm", "Clock Power Management", PRDV_STRVAL,
14177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14187687d0d8SRobert Mustacchi 	{ 19, 19, "supdown", "Surprise Down Error Reporting", PRDV_STRVAL,
14197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14207687d0d8SRobert Mustacchi 	{ 20, 20, "dlact", "Data Link Layer Active Reporting", PRDV_STRVAL,
14217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14227687d0d8SRobert Mustacchi 	{ 21, 21, "linkbw", "Link Bandwidth Notification Capability",
14237687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
14247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14257687d0d8SRobert Mustacchi 	{ 22, 22, "aspmcomp", "ASPM Optionality Compliance", PRDV_STRVAL,
14267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not compliant", "compliant" } } },
14277687d0d8SRobert Mustacchi 	{ 24, 31, "portno", "Port Number", PRDV_HEX },
14287687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14297687d0d8SRobert Mustacchi };
14307687d0d8SRobert Mustacchi 
14317687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkctl[] = {
14327687d0d8SRobert Mustacchi 	{ 0, 1, "aspmctl", "ASPM Control", PRDV_STRVAL,
14337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } },
14347687d0d8SRobert Mustacchi 	{ 3, 3, "rcb", "Read Completion Boundary", PRDV_STRVAL,
14357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "64 byte", "128 byte" } } },
14367687d0d8SRobert Mustacchi 	{ 4, 4, "disable", "Link Disable", PRDV_STRVAL,
14377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not force disabled",
14387687d0d8SRobert Mustacchi 	    "force disabled" } } },
14397687d0d8SRobert Mustacchi 	{ 5, 5, "retrain", "Retrain Link", PRDV_HEX },
14407687d0d8SRobert Mustacchi 	{ 6, 6, "ccc", "Common Clock Configuration", PRDV_STRVAL,
14417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "asynchronous", "common" } } },
1442*92f11af9SRobert Mustacchi 	{ 7, 7, "extsync", "Extended Sync", PRDV_STRVAL,
14437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1444*92f11af9SRobert Mustacchi 	{ 8, 8, "clkpm", "Clock Power Management", PRDV_STRVAL,
14457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
1446*92f11af9SRobert Mustacchi 	{ 9, 9, "hwawd", "Hardware Autonomous Width", PRDV_STRVAL,
14477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
1448*92f11af9SRobert Mustacchi 	{ 10, 10, "linkbwint", "Link Bandwidth Management Interrupt",
1449*92f11af9SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled",
1450*92f11af9SRobert Mustacchi 	    "enabled" } } },
1451*92f11af9SRobert Mustacchi 	{ 11, 11, "linkabwint", "Link Autonomous Bandwidth Interrupt",
1452*92f11af9SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled",
1453*92f11af9SRobert Mustacchi 	    "enabled" } } },
1454*92f11af9SRobert Mustacchi 	{ 14, 15, "drs", "DRS Signaling Control", PRDV_STRVAL,
14557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not reported", "Interrupt enabled",
14567687d0d8SRobert Mustacchi 	    "DRS->FRS enabled" } } },
14577687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14587687d0d8SRobert Mustacchi };
14597687d0d8SRobert Mustacchi 
14607687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linksts[] = {
14617687d0d8SRobert Mustacchi 	{ 0, 3, "speed", "Link Speed", PRDV_STRVAL,
14627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
14637687d0d8SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s" } } },
14647687d0d8SRobert Mustacchi 	{ 4, 9, "width", "Link Width", PRDV_HEX },
14657687d0d8SRobert Mustacchi 	{ 11, 11, "training", "Link Training", PRDV_STRVAL,
14667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14677687d0d8SRobert Mustacchi 	{ 12, 12, "slotclk", "Slot Clock Configuration", PRDV_STRVAL,
14687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "asynchronous", "common" } } },
14697687d0d8SRobert Mustacchi 	{ 13, 13, "dllact", "Data Link Layer Link Active", PRDV_STRVAL,
14707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14717687d0d8SRobert Mustacchi 	{ 14, 14, "linkbw", "Link Bandwidth Management Status", PRDV_STRVAL,
14727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no change", "change occurred" } } },
14737687d0d8SRobert Mustacchi 	{ 15, 15, "linkabw", "Link Autonomous Bandwidth Status", PRDV_STRVAL,
14747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no change", "change occurred" } } },
14757687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14767687d0d8SRobert Mustacchi };
14777687d0d8SRobert Mustacchi 
14787687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotcap[] = {
14797687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Present", PRDV_STRVAL,
14807687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14817687d0d8SRobert Mustacchi 	{ 1, 1, "pwrctrl", "Power Controller Present", PRDV_STRVAL,
14827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14837687d0d8SRobert Mustacchi 	{ 2, 2, "mrlsen", "MRL Sensor Present", PRDV_STRVAL,
14847687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14857687d0d8SRobert Mustacchi 	{ 3, 3, "attnind", "Attention Indicator Present", PRDV_STRVAL,
14867687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14877687d0d8SRobert Mustacchi 	{ 4, 4, "powind", "Power Indicator Present", PRDV_STRVAL,
14887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14897687d0d8SRobert Mustacchi 	{ 5, 5, "hpsup", "Hot-Plug Surprise", PRDV_STRVAL,
14907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14917687d0d8SRobert Mustacchi 	{ 6, 6, "hpcap", "Hot-Plug Capable ", PRDV_STRVAL,
14927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14937687d0d8SRobert Mustacchi 	{ 7, 14, "slotplv", "Slot Power Limit Value", PRDV_HEX },
14947687d0d8SRobert Mustacchi 	{ 15, 16, "slotpls", "Slot Power Limit Scale", PRDV_HEX },
1495*92f11af9SRobert Mustacchi 	{ 17, 17, "emi", "Electromechanical Interlock Present", PRDV_STRVAL,
14967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
1497*92f11af9SRobert Mustacchi 	{ 18, 18, "ncc", "No Command Completed", PRDV_STRVAL,
14987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14997687d0d8SRobert Mustacchi 	{ 19, 31, "slotno", "Physical Slot Number", PRDV_HEX },
15007687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15017687d0d8SRobert Mustacchi };
15027687d0d8SRobert Mustacchi 
15037687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotctl[] = {
15047687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Pressed", PRDV_STRVAL,
15057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15067687d0d8SRobert Mustacchi 	{ 1, 1, "powflt", "Power Fault Detected", PRDV_STRVAL,
15077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15087687d0d8SRobert Mustacchi 	{ 2, 2, "mrlsen", "MRL Sensor Changed", PRDV_STRVAL,
15097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15107687d0d8SRobert Mustacchi 	{ 3, 3, "presdet", "Presence Detect Changed", PRDV_STRVAL,
15117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15127687d0d8SRobert Mustacchi 	{ 4, 4, "ccmpltint", "Command Complete Interrupt", PRDV_STRVAL,
15137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "Enabled" } } },
15147687d0d8SRobert Mustacchi 	{ 5, 5, "hpi", "Hot Plug Interrupt Enable", PRDV_STRVAL,
15157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15167687d0d8SRobert Mustacchi 	{ 6, 7, "attnind", "Attention Indicator Control", PRDV_STRVAL,
15177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } },
15187687d0d8SRobert Mustacchi 	{ 8, 9, "powin", "Power Indicator Control", PRDV_STRVAL,
15197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } },
15207687d0d8SRobert Mustacchi 	{ 10, 10, "pwrctrl", "Power Controller Control", PRDV_STRVAL,
15217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "power on", "power off" } } },
15227687d0d8SRobert Mustacchi 	{ 11, 11, "emi", "Electromechanical Interlock Control", PRDV_HEX },
15237687d0d8SRobert Mustacchi 	{ 12, 12, "dll", "Data Link Layer State Changed", PRDV_STRVAL,
15247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15257687d0d8SRobert Mustacchi 	{ 13, 13, "autopowdis", "Auto Slot Power Limit", PRDV_STRVAL,
15267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
15277687d0d8SRobert Mustacchi 	{ 14, 14, "ibpddis", "In-Band PD", PRDV_STRVAL,
15287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
15297687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15307687d0d8SRobert Mustacchi };
15317687d0d8SRobert Mustacchi 
15327687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotsts[] = {
15337687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Pressed", PRDV_STRVAL,
15347687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15357687d0d8SRobert Mustacchi 	{ 1, 1, "powflt", "Power Fault Detected", PRDV_STRVAL,
15367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15377687d0d8SRobert Mustacchi 	{ 2, 2, "mrlsen", "MRL Sensor Changed", PRDV_STRVAL,
15387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15397687d0d8SRobert Mustacchi 	{ 3, 3, "presdet", "Presence Detect Changed", PRDV_STRVAL,
15407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15417687d0d8SRobert Mustacchi 	{ 4, 4, "ccmplt", "Command Complete", PRDV_STRVAL,
15427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15437687d0d8SRobert Mustacchi 	{ 5, 5, "mrlsen", "MRL Sensor State", PRDV_STRVAL,
15447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "closed", "open" } } },
15457687d0d8SRobert Mustacchi 	{ 6, 6, "presdet", "Presence Detect State", PRDV_STRVAL,
15467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not present", "present" } } },
15477687d0d8SRobert Mustacchi 	{ 7, 7, "emi", "Electromechanical Interlock", PRDV_STRVAL,
15487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disengaged", "engaged" } } },
15497687d0d8SRobert Mustacchi 	{ 8, 8, "dll", "Data Link Layer State Changed", PRDV_STRVAL,
15507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15517687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15527687d0d8SRobert Mustacchi };
15537687d0d8SRobert Mustacchi 
15547687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_rootcap[] = {
15557687d0d8SRobert Mustacchi 	{ 0, 0, "syscorerr", "System Error on Correctable Error", PRDV_STRVAL,
15567687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15577687d0d8SRobert Mustacchi 	{ 1, 1, "sysnonftl", "System Error on Non-Fatal Error", PRDV_STRVAL,
15587687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15597687d0d8SRobert Mustacchi 	{ 2, 2, "sysfatal", "System Error on Fatal Error", PRDV_STRVAL,
15607687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15617687d0d8SRobert Mustacchi 	{ 3, 3, "pmeie", "PME Interrupt", PRDV_STRVAL,
15627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15637687d0d8SRobert Mustacchi 	{ 4, 4,  "crssw", "CRS Software Visibility", PRDV_STRVAL,
15647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15657687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15667687d0d8SRobert Mustacchi };
15677687d0d8SRobert Mustacchi 
15687687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_rootctl[] = {
15697687d0d8SRobert Mustacchi 	{ 0, 0, "crssw", "CRS Software Visibility", PRDV_STRVAL,
15707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15717687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15727687d0d8SRobert Mustacchi };
15737687d0d8SRobert Mustacchi 
15747687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_rootsts[] = {
15757687d0d8SRobert Mustacchi 	{ 0, 15, "pmereqid", "PME Requester ID", PRDV_HEX },
15767687d0d8SRobert Mustacchi 	{ 16, 16, "pmests", "PME Status", PRDV_STRVAL,
15777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "deasserted", "asserted" } } },
15787687d0d8SRobert Mustacchi 	{ 17, 17, "pmepend", "PME Pending", PRDV_STRVAL,
15797687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15807687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15817687d0d8SRobert Mustacchi };
15827687d0d8SRobert Mustacchi 
15837687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devcap2[] = {
15847687d0d8SRobert Mustacchi 	{ 0, 3, "cmpto", "Completion Timeout Ranges Supported", PRDV_BITFIELD,
15857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "50us-10ms", "10ms-250ms",
15867687d0d8SRobert Mustacchi 	    "250ms-4s", "4s-64s" } } },
15877687d0d8SRobert Mustacchi 	{ 4, 4, "cmptodis", "Completion Timeout Disable", PRDV_STRVAL,
15887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15897687d0d8SRobert Mustacchi 	{ 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL,
15907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15917687d0d8SRobert Mustacchi 	{ 6, 6, "atomroute", "AtomicOp Routing", PRDV_STRVAL,
15927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15937687d0d8SRobert Mustacchi 	{ 7, 7, "atom32", "32-bit AtomicOp Completer", PRDV_STRVAL,
15947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15957687d0d8SRobert Mustacchi 	{ 8, 8, "atom64", "64-bit AtomicOp Completer", PRDV_STRVAL,
15967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15977687d0d8SRobert Mustacchi 	{ 9, 9, "cas128", "128-bit CAS Completer", PRDV_STRVAL,
15987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15997687d0d8SRobert Mustacchi 	{ 10, 10, "norelord", "No Ro-enabld PR-PR Passing", PRDV_STRVAL,
16007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16017687d0d8SRobert Mustacchi 	{ 11, 11, "ltr", "LTR Mechanism", PRDV_STRVAL,
16027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16037687d0d8SRobert Mustacchi 	{ 12, 13, "tph", "TPH Completer", PRDV_STRVAL,
16047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "TPH supported",
16057687d0d8SRobert Mustacchi 	    NULL, "TPH and Extended TPH supported" } } },
16067687d0d8SRobert Mustacchi 	{ 14, 15, "lncls", "LN System CLS", PRDV_STRVAL,
16077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported",
16087687d0d8SRobert Mustacchi 	    "LN with 64-byte cachelines", "LN with 128-byte cachelines" } } },
16097687d0d8SRobert Mustacchi 	{ 16, 16, "tag10comp", "10-bit Tag Completer", PRDV_STRVAL,
16107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16117687d0d8SRobert Mustacchi 	{ 17, 17, "tag10req", "10-bit Tag Requester", PRDV_STRVAL,
16127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16137687d0d8SRobert Mustacchi 	{ 18, 19, "obff", "OBFF", PRDV_STRVAL,
16147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "Message Signaling",
16157687d0d8SRobert Mustacchi 	    "WAKE# Signaling", "WAKE# and Message Signaling" } } },
16167687d0d8SRobert Mustacchi 	{ 20, 20, "extfmt", "Extended Fmt Field Supported", PRDV_STRVAL,
16177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16187687d0d8SRobert Mustacchi 	{ 21, 21, "eetlp", "End-End TLP Prefix Supported", PRDV_STRVAL,
16197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16207687d0d8SRobert Mustacchi 	{ 22, 23, "maxeetlp", "Max End-End TLP Prefixes", PRDV_STRVAL,
16217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4", "1", "2", "3" } } },
16227687d0d8SRobert Mustacchi 	{ 24, 25, "empr", "Emergency Power Reduction", PRDV_STRVAL,
16237687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported",
16247687d0d8SRobert Mustacchi 	    "supported, device-specific",
16257687d0d8SRobert Mustacchi 	    "supported, from factor or device-specific" } } },
16267687d0d8SRobert Mustacchi 	{ 21, 21, "emprinit",
16277687d0d8SRobert Mustacchi 	    "Emergency Power Reduction Initialization Required", PRDV_STRVAL,
16287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
16297687d0d8SRobert Mustacchi 	{ 31, 31, "frs", "Function Readiness Status", PRDV_STRVAL,
16307687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16317687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16327687d0d8SRobert Mustacchi };
16337687d0d8SRobert Mustacchi 
16347687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devctl2[] = {
16357687d0d8SRobert Mustacchi 	{ 0, 3, "cmpto", "Completion Timeout", PRDV_STRVAL,
16367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "50us-50ms", "50us-100us",
16377687d0d8SRobert Mustacchi 	    "1ms-10ms", NULL, NULL, "16ms-55ms", "65ms-210ms", NULL, NULL,
16387687d0d8SRobert Mustacchi 	    "260ms-900ms", "1s-3.5s", NULL, NULL, "4s-13s", "17s-64s" } } },
16397687d0d8SRobert Mustacchi 	{ 4, 4, "cmptodis", "Completion Timeout Disabled", PRDV_STRVAL,
16407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not disabled", "disabled" } } },
16417687d0d8SRobert Mustacchi 	{ 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL,
16427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16437687d0d8SRobert Mustacchi 	{ 6, 6, "atomreq", "AtomicOp Requester", PRDV_STRVAL,
16447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16457687d0d8SRobert Mustacchi 	{ 7, 7, "atomblock", "AtomicOp Egress Blocking", PRDV_STRVAL,
16467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unblocked", "blocked" } } },
16477687d0d8SRobert Mustacchi 	{ 8, 8, "idoreq", "ID-Based Ordering Request", PRDV_STRVAL,
16487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16497687d0d8SRobert Mustacchi 	{ 9, 9, "idocomp", "ID-Based Ordering Completion", PRDV_STRVAL,
16507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16517687d0d8SRobert Mustacchi 	{ 10, 10, "ltr", "LTR Mechanism", PRDV_STRVAL,
16527687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16537687d0d8SRobert Mustacchi 	{ 11, 11, "empowred", "Emergency Power Reduction", PRDV_STRVAL,
16547687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not requested", "requested" } } },
16557687d0d8SRobert Mustacchi 	{ 12, 12, "tag10req", "10-bit Tag Requester", PRDV_STRVAL,
16567687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16577687d0d8SRobert Mustacchi 	{ 13, 14, "obff", "OBFF", PRDV_STRVAL,
16587687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "message signaling - A",
16597687d0d8SRobert Mustacchi 	    "message signaling - B", "WAKE# signaling" } } },
16607687d0d8SRobert Mustacchi 	{ 15, 15, "eetlpblk", "End-End TLP Prefix Blocking", PRDV_STRVAL,
16617687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unblocked", "blocked" } } },
16627687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16637687d0d8SRobert Mustacchi };
16647687d0d8SRobert Mustacchi 
16657687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_devsts2[] = {
16667687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16677687d0d8SRobert Mustacchi };
16687687d0d8SRobert Mustacchi 
16697687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkcap2[] = {
16707687d0d8SRobert Mustacchi 	{ 1, 7, "supspeeds", "Supported Link Speeds", PRDV_BITFIELD,
16717687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
16727687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
16737687d0d8SRobert Mustacchi 	{ 8, 8, "crosslink", "Crosslink", PRDV_STRVAL,
16747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16757687d0d8SRobert Mustacchi 	{ 9, 15, "skposgen", "Lower SKP OS Generation Supported Speeds Vector",
16767687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
16777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
16787687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
16797687d0d8SRobert Mustacchi 	{ 16, 22, "skposrecv", "Lower SKP OS Reception Supported Speeds Vector",
16807687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
16817687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
16827687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
16837687d0d8SRobert Mustacchi 	{ 23, 23, "retimedet", "Retimer Presence Detect Supported", PRDV_STRVAL,
16847687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16857687d0d8SRobert Mustacchi 	{ 24, 24, "retime2det", "Two Retimers Presence Detect Supported",
16867687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
16877687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16887687d0d8SRobert Mustacchi 	{ 31, 31, "drs", "Device Readiness Status", PRDV_STRVAL,
16897687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16907687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16917687d0d8SRobert Mustacchi };
16927687d0d8SRobert Mustacchi 
16937687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linkctl2[] = {
16947687d0d8SRobert Mustacchi 	{ 0, 3, "targspeed", "Target Link Speed", PRDV_STRVAL,
16957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
16967687d0d8SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s" } } },
16977687d0d8SRobert Mustacchi 	{ 4, 4, "comp", "Enter Compliance", PRDV_STRVAL,
16987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
16997687d0d8SRobert Mustacchi 	{ 5, 5, "hwautosp", "Hardware Autonomous Speed Disable", PRDV_STRVAL,
17007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not disabled", "disabled" } } },
17017687d0d8SRobert Mustacchi 	{ 6, 6, "seldeemph", "Selectable De-emphasis", PRDV_STRVAL,
17027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } },
17037687d0d8SRobert Mustacchi 	{ 7, 9, "txmarg", "TX Margin", PRDV_HEX },
17047687d0d8SRobert Mustacchi 	{ 10, 10, "modcomp", "Enter Modified Compliance", PRDV_STRVAL,
17057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17067687d0d8SRobert Mustacchi 	{ 11, 11, "compsos", "Compliance SOS",
17077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
17087687d0d8SRobert Mustacchi 	{ 12, 15, "compemph", "Compliance Preset/De-emphasis", PRDV_HEX },
17097687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17107687d0d8SRobert Mustacchi };
17117687d0d8SRobert Mustacchi 
17127687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_linksts2[] = {
17137687d0d8SRobert Mustacchi 	{ 0, 0, "curdeemph", "Current De-emphasis Level", PRDV_STRVAL,
17147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } },
17157687d0d8SRobert Mustacchi 	{ 1, 1, "eq8comp", "Equalization 8.0 GT/s Complete", PRDV_STRVAL,
17167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17177687d0d8SRobert Mustacchi 	{ 2, 2, "eq8p1comp", "Equalization 8.0 GT/s Phase 1", PRDV_STRVAL,
17187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
17197687d0d8SRobert Mustacchi 	{ 3, 3, "eq8p2comp", "Equalization 8.0 GT/s Phase 2", PRDV_STRVAL,
17207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
17217687d0d8SRobert Mustacchi 	{ 4, 4, "eq8p3comp", "Equalization 8.0 GT/s Phase 3", PRDV_STRVAL,
17227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
17237687d0d8SRobert Mustacchi 	{ 5, 5, "linkeq8req", "Link Equalization Request 8.0 GT/s", PRDV_STRVAL,
17247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not requested", "requested" } } },
17257687d0d8SRobert Mustacchi 	{ 6, 6, "retimedet", "Retimer Presence Detected", PRDV_STRVAL,
17267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17277687d0d8SRobert Mustacchi 	{ 7, 7, "retime2det", "Two Retimers Presence Detected", PRDV_STRVAL,
17287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17297687d0d8SRobert Mustacchi 	{ 8, 9, "crosslink", "Crosslink Resolution", PRDV_STRVAL,
17307687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "upstream port",
17317687d0d8SRobert Mustacchi 	    "downstream port", "incomplete" } } },
17327687d0d8SRobert Mustacchi 	{ 12, 14, "dscomppres", "Downstream Component Presence", PRDV_STRVAL,
17337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "link down - undetermined",
17347687d0d8SRobert Mustacchi 	    "link down - not present", "link down - present", NULL,
17357687d0d8SRobert Mustacchi 	    "link up - present", "link up - present and DRS" } } },
17367687d0d8SRobert Mustacchi 	{ 15, 15, "drsrx", "DRS Message Received", PRDV_STRVAL,
17377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17387687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17397687d0d8SRobert Mustacchi };
17407687d0d8SRobert Mustacchi 
17417687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotcap2[] = {
17427687d0d8SRobert Mustacchi 	{ 0, 0, "ibpddis", "In-Band PD Disable", PRDV_STRVAL,
17437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
17447687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17457687d0d8SRobert Mustacchi };
17467687d0d8SRobert Mustacchi 
17477687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotctl2[] = {
17487687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17497687d0d8SRobert Mustacchi };
17507687d0d8SRobert Mustacchi 
17517687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_slotsts2[] = {
17527687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17537687d0d8SRobert Mustacchi };
17547687d0d8SRobert Mustacchi 
1755bc729d49SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_dev[] = {
1756bc729d49SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1757bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1758bc729d49SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1759bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1760bc729d49SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1761bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1762bc729d49SRobert Mustacchi 	{ -1, -1, NULL }
1763bc729d49SRobert Mustacchi };
1764bc729d49SRobert Mustacchi 
1765bc729d49SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_link[] = {
1766bc729d49SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1767bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1768bc729d49SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1769bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1770bc729d49SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1771bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1772bc729d49SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
1773bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
1774bc729d49SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
1775bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
1776bc729d49SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
1777bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
1778bc729d49SRobert Mustacchi 	{ -1, -1, NULL }
1779bc729d49SRobert Mustacchi };
1780bc729d49SRobert Mustacchi 
1781bc729d49SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_slot[] = {
1782bc729d49SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1783bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1784bc729d49SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1785bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1786bc729d49SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1787bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1788bc729d49SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
1789bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
1790bc729d49SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
1791bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
1792bc729d49SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
1793bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
1794bc729d49SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
1795bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
1796bc729d49SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
1797bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
1798bc729d49SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
1799bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
1800bc729d49SRobert Mustacchi 	{ -1, -1, NULL }
1801bc729d49SRobert Mustacchi };
18027687d0d8SRobert Mustacchi 
1803bc729d49SRobert Mustacchi 
1804bc729d49SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_all[] = {
18057687d0d8SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
18067687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
18077687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
18087687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
18097687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
18107687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
18117687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
18127687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
18137687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
18147687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
18157687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
18167687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
18177687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
18187687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
18197687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
18207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
18217687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
18227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
18237687d0d8SRobert Mustacchi 	{ PCIE_ROOTCTL, 2, "rootctl", "Root control",
18247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl },
18257687d0d8SRobert Mustacchi 	{ PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities",
18267687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap },
18277687d0d8SRobert Mustacchi 	{ PCIE_ROOTSTS, 4, "rootsts", "Root Status",
18287687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts },
18297687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
18307687d0d8SRobert Mustacchi };
18317687d0d8SRobert Mustacchi 
18327687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie_v2[] = {
18337687d0d8SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
18347687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
18357687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
18367687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
18377687d0d8SRobert Mustacchi 	{ PCIE_DEVCTL, 2, "devctl", "Device Control",
18387687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl },
18397687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
18407687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
18417687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
18427687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
18437687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
18447687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
18457687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
18467687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
18477687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
18487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
18497687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
18507687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
18517687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
18527687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
18537687d0d8SRobert Mustacchi 	{ PCIE_ROOTCTL, 2, "rootctl", "Root Control",
18547687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl },
18557687d0d8SRobert Mustacchi 	{ PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities",
18567687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap },
18577687d0d8SRobert Mustacchi 	{ PCIE_ROOTSTS, 4, "rootsts", "Root Status",
18587687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts },
18597687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP2, 4, "devcap2", "Device Capabilities 2",
18607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap2 },
18617687d0d8SRobert Mustacchi 	{ PCIE_DEVCTL2, 2, "devctl2", "Device Control 2",
18627687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl2 },
18637687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS2, 2, "devsts2", "Device Status 2",
18647687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts2 },
18657687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP2, 4, "linkcap2", "Link Capabilities 2",
18667687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap2 },
18677687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL2, 2, "linkctl2", "Link Control 2",
18687687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl2 },
18697687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS2, 2, "linksts2", "Link Status 2",
18707687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts2 },
18717687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP2, 4, "slotcap2", "Slot Capabilities 2",
18727687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap2 },
18737687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL2, 2, "slotctl2", "Slot Control 2",
18747687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl2 },
18757687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS2, 2, "slotsts2", "Slot Status 2",
18767687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts2 },
18777687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
18787687d0d8SRobert Mustacchi };
18797687d0d8SRobert Mustacchi 
18807687d0d8SRobert Mustacchi /*
18817687d0d8SRobert Mustacchi  * PCIe Extended Capability Header
18827687d0d8SRobert Mustacchi  */
18837687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie_caphdr[] = {
18847687d0d8SRobert Mustacchi 	{ 0, 15, "capid", "Capability ID", PRDV_HEX },
18857687d0d8SRobert Mustacchi 	{ 16, 19, "version", "Capability Version", PRDV_HEX },
18867687d0d8SRobert Mustacchi 	{ 20, 32, "offset", "Next Capability Offset", PRDV_HEX },
18877687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
18887687d0d8SRobert Mustacchi };
18897687d0d8SRobert Mustacchi 
18907687d0d8SRobert Mustacchi /*
18917687d0d8SRobert Mustacchi  * VPD Capability
18927687d0d8SRobert Mustacchi  */
18937687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vpd_addr[] = {
18947687d0d8SRobert Mustacchi 	{ 0, 14, "addr", "VPD Address", PRDV_HEX },
18957687d0d8SRobert Mustacchi 	{ 15, 15, "flag", "Flag", PRDV_HEX },
18967687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
18977687d0d8SRobert Mustacchi };
18987687d0d8SRobert Mustacchi 
18997687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vpd[] = {
19007687d0d8SRobert Mustacchi 	{ 0x2, 2, "addr", "VPD Address Register",
19017687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vpd_addr },
19027687d0d8SRobert Mustacchi 	{ 0x4, 4, "data", "VPD Data", pcieadm_cfgspace_print_hex },
19037687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19047687d0d8SRobert Mustacchi };
19057687d0d8SRobert Mustacchi 
19067687d0d8SRobert Mustacchi /*
19077687d0d8SRobert Mustacchi  * SATA Capability per AHCI 1.3.1
19087687d0d8SRobert Mustacchi  */
19097687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sata_cr0[] = {
19107687d0d8SRobert Mustacchi 	{ 0, 3, "minrev", "Minor Revision", PRDV_HEX },
19117687d0d8SRobert Mustacchi 	{ 4, 7, "majrev", "Major Revision", PRDV_HEX },
19127687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19137687d0d8SRobert Mustacchi };
19147687d0d8SRobert Mustacchi 
19157687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sata_cr1[] = {
19167687d0d8SRobert Mustacchi 	{ 0, 3, "bar", "BAR Location", PRDV_HEX,
19177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 2 } } },
19187687d0d8SRobert Mustacchi 	{ 4, 23, "offset", "BAR Offset", PRDV_HEX,
19197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 2 } } },
19207687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19217687d0d8SRobert Mustacchi };
19227687d0d8SRobert Mustacchi 
19237687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_sata[] = {
19247687d0d8SRobert Mustacchi 	{ 0x2, 2, "satacr0", "SATA Capability Register 0",
19257687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr0 },
19267687d0d8SRobert Mustacchi 	{ 0x4, 4, "satacr1", "SATA Capability Register 1",
19277687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr1 },
19287687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19297687d0d8SRobert Mustacchi };
19307687d0d8SRobert Mustacchi 
19317687d0d8SRobert Mustacchi /*
19327687d0d8SRobert Mustacchi  * Debug Capability per EHCI
19337687d0d8SRobert Mustacchi  */
19347687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_debug[] = {
19357687d0d8SRobert Mustacchi 	{ 0, 12, "offset", "BAR Offset", PRDV_HEX },
19367687d0d8SRobert Mustacchi 	{ 13, 15, "bar", "BAR Location ", PRDV_STRVAL,
19377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "BAR 0", "BAR 1", "BAR 2",
19387687d0d8SRobert Mustacchi 	    "BAR 3", "BAR 4", "BAR 5" } } },
19397687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19407687d0d8SRobert Mustacchi };
19417687d0d8SRobert Mustacchi 
19427687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_debug[] = {
19437687d0d8SRobert Mustacchi 	{ 0x2, 2, "port", "Debug Port",
19447687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_debug },
19457687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19467687d0d8SRobert Mustacchi };
19477687d0d8SRobert Mustacchi 
19487687d0d8SRobert Mustacchi /*
19497687d0d8SRobert Mustacchi  * AER Capability
19507687d0d8SRobert Mustacchi  */
19517687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_ue[] = {
19527687d0d8SRobert Mustacchi 	{ 4, 4, "dlp", "Data Link Protocol Error", PRDV_HEX },
19537687d0d8SRobert Mustacchi 	{ 5, 5, "sde", "Surprise Down Error", PRDV_HEX },
19547687d0d8SRobert Mustacchi 	{ 12, 12, "ptlp", "Poisoned TLP Received", PRDV_HEX },
19557687d0d8SRobert Mustacchi 	{ 13, 13, "fcp", "Flow Control Protocol Error", PRDV_HEX },
19567687d0d8SRobert Mustacchi 	{ 14, 14, "cto", "Completion Timeout", PRDV_HEX },
19577687d0d8SRobert Mustacchi 	{ 15, 15, "cab", "Completion Abort", PRDV_HEX },
19587687d0d8SRobert Mustacchi 	{ 16, 16, "unco", "Unexpected Completion", PRDV_HEX },
19597687d0d8SRobert Mustacchi 	{ 17, 17, "rxov", "Receiver Overflow", PRDV_HEX },
19607687d0d8SRobert Mustacchi 	{ 18, 18, "maltlp", "Malformed TLP", PRDV_HEX },
19617687d0d8SRobert Mustacchi 	{ 19, 19, "ecrc", "ECRC Error", PRDV_HEX },
19627687d0d8SRobert Mustacchi 	{ 20, 20, "usuprx", "Unsupported Request Error", PRDV_HEX },
19637687d0d8SRobert Mustacchi 	{ 21, 21, "acs", "ACS Violation", PRDV_HEX },
19647687d0d8SRobert Mustacchi 	{ 22, 22, "ueint", "Uncorrectable Internal Error", PRDV_HEX },
19657687d0d8SRobert Mustacchi 	{ 23, 23, "mcbtlp", "MC Blocked TLP", PRDV_HEX },
19667687d0d8SRobert Mustacchi 	{ 24, 24, "atoomeb", "AtomicOp Egress Blocked", PRDV_HEX },
19677687d0d8SRobert Mustacchi 	{ 25, 25, "tlppb", "TLP Prefix Blocked Error", PRDV_HEX },
19687687d0d8SRobert Mustacchi 	{ 26, 26, "ptlpeb", "Poisoned TLP Egress Blocked", PRDV_HEX },
19697687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19707687d0d8SRobert Mustacchi };
19717687d0d8SRobert Mustacchi 
19727687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_ce[] = {
19737687d0d8SRobert Mustacchi 	{ 0, 0, "rxerr", "Receiver Error", PRDV_HEX },
19747687d0d8SRobert Mustacchi 	{ 6, 6, "badtlp", "Bad TLP", PRDV_HEX },
19757687d0d8SRobert Mustacchi 	{ 7, 7, "baddllp", "Bad DLLP", PRDV_HEX },
19767687d0d8SRobert Mustacchi 	{ 8, 8, "replayro", "REPLAY_NUM Rollover", PRDV_HEX },
19777687d0d8SRobert Mustacchi 	{ 12, 12, "rtto", "Replay timer Timeout", PRDV_HEX },
19787687d0d8SRobert Mustacchi 	{ 13, 13, "advnfe", "Advisory Non-Fatal Error", PRDV_HEX },
19797687d0d8SRobert Mustacchi 	{ 14, 14, "ceint", "Correctable Internal Error", PRDV_HEX },
19807687d0d8SRobert Mustacchi 	{ 15, 15, "headlov", "Header Log Overflow", PRDV_HEX },
19817687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19827687d0d8SRobert Mustacchi };
19837687d0d8SRobert Mustacchi 
19847687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_ctrl[] = {
19857687d0d8SRobert Mustacchi 	{ 0, 4, "feptr", "First Error Pointer", PRDV_HEX },
19867687d0d8SRobert Mustacchi 	{ 5, 5, "ecgencap", "ECRC Generation Capable", PRDV_STRVAL,
19877687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
19887687d0d8SRobert Mustacchi 	{ 6, 6, "ecgenen", "ECRC Generation Enable", PRDV_STRVAL,
19897687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
19907687d0d8SRobert Mustacchi 	{ 7, 7, "ecchkcap", "ECRC Check Capable", PRDV_STRVAL,
19917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
19927687d0d8SRobert Mustacchi 	{ 8, 8, "ecchken", "ECRC Check Enable", PRDV_STRVAL,
19937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
19947687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19957687d0d8SRobert Mustacchi };
19967687d0d8SRobert Mustacchi 
19977687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_rootcom[] = {
19987687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL,
19997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20007687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL,
20017687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20027687d0d8SRobert Mustacchi 	{ 2, 2, "faterr", "Fatal Error Reporting", PRDV_STRVAL,
20037687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20047687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20057687d0d8SRobert Mustacchi };
20067687d0d8SRobert Mustacchi 
20077687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_rootsts[] = {
20087687d0d8SRobert Mustacchi 	{ 0, 0, "errcor", "ERR_COR Received", PRDV_HEX },
20097687d0d8SRobert Mustacchi 	{ 1, 1, "merrcor", "Multiple ERR_COR Received", PRDV_HEX },
20107687d0d8SRobert Mustacchi 	{ 2, 2, "errfnf", "ERR_FATAL/NONFATAL Received", PRDV_HEX },
20117687d0d8SRobert Mustacchi 	{ 3, 3, "merrfnf", "Multiple ERR_FATAL/NONFATAL Received", PRDV_HEX },
20127687d0d8SRobert Mustacchi 	{ 4, 4, "fuefat", "First Uncorrectable Fatal", PRDV_HEX },
20137687d0d8SRobert Mustacchi 	{ 5, 5, "nferrrx", "Non-Fatal Error Messages Received", PRDV_HEX },
20147687d0d8SRobert Mustacchi 	{ 6, 6, "faterrx", "Fatal Error Messages Received", PRDV_HEX },
20157687d0d8SRobert Mustacchi 	{ 7, 8, "errcorsc", "ERR_COR Subclass", PRDV_STRVAL,
20167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "ECS Legacy", "ECS SIG_SFW",
20177687d0d8SRobert Mustacchi 	    "ECS SIG_OS", "ECS Extended" } } },
20187687d0d8SRobert Mustacchi 	{ 27, 31, "inum", "Advanced Error Interrupt Message", PRDV_HEX },
20197687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20207687d0d8SRobert Mustacchi };
20217687d0d8SRobert Mustacchi 
20227687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_esi[] = {
20237687d0d8SRobert Mustacchi 	{ 0, 15, "errcorr", "ERR_COR Source", PRDV_HEX },
20247687d0d8SRobert Mustacchi 	{ 16, 31, "errfnf", "ERR_FATAL/NONFATAL Source", PRDV_HEX },
20257687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20267687d0d8SRobert Mustacchi };
20277687d0d8SRobert Mustacchi 
20287687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_secue[] = {
20297687d0d8SRobert Mustacchi 	{ 0, 0, "taosc", "Target-Abort on Split Completion", PRDV_HEX },
20307687d0d8SRobert Mustacchi 	{ 1, 1, "maosc", "Master-Abort on Split Completion", PRDV_HEX },
20317687d0d8SRobert Mustacchi 	{ 2, 2, "rxta", "Received Target-Abort", PRDV_HEX },
20327687d0d8SRobert Mustacchi 	{ 3, 3, "rxma", "Received Master-Abort", PRDV_HEX },
20337687d0d8SRobert Mustacchi 	{ 5, 5, "unsce", "Unexpected Split Completion Error", PRDV_HEX },
20347687d0d8SRobert Mustacchi 	{ 6, 6, "uescmd", "Uncorrectable Split Completion Message Data Error",
20357687d0d8SRobert Mustacchi 	    PRDV_HEX },
20367687d0d8SRobert Mustacchi 	{ 7, 7, "uede", "Uncorrectable Data Error", PRDV_HEX },
20377687d0d8SRobert Mustacchi 	{ 8, 8, "ueattre", "Uncorrectable Attribute Error", PRDV_HEX },
20387687d0d8SRobert Mustacchi 	{ 9, 9, "ueaddre", "Uncorrectable Address Error", PRDV_HEX },
20397687d0d8SRobert Mustacchi 	{ 10, 10, "dtdte", "Delayed Transaction Discard Timer Expired",
20407687d0d8SRobert Mustacchi 	    PRDV_HEX },
20417687d0d8SRobert Mustacchi 	{ 11, 11, "perr", "PERR# Assertion", PRDV_HEX },
20427687d0d8SRobert Mustacchi 	{ 12, 12, "serr", "SERR# Assertion", PRDV_HEX },
20437687d0d8SRobert Mustacchi 	{ 13, 13, "internal", "Internal Bridge Error", PRDV_HEX },
20447687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20457687d0d8SRobert Mustacchi };
20467687d0d8SRobert Mustacchi 
20477687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_aer_secctl[] = {
20487687d0d8SRobert Mustacchi 	{ 0, 4, "feptr", "Secondary Uncorrectable First Error Pointer",
20497687d0d8SRobert Mustacchi 	    PRDV_HEX },
20507687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20517687d0d8SRobert Mustacchi };
20527687d0d8SRobert Mustacchi 
20537687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_aer_v1[] = {
20547687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
20557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
20567687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
20577687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20587687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
20597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20607687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
20617687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20627687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
20637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
20647687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
20657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
20667687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
20677687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
20687687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
20697687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20707687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
20717687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20727687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
20737687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20747687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
20757687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20767687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "rootcmd", "Root Error Command",
20777687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
20787687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
20797687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
20807687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_SRC_ID, 4, "esi", "Error Source Identification",
20817687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_esi },
20827687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20837687d0d8SRobert Mustacchi };
20847687d0d8SRobert Mustacchi 
20857687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_aer_v2[] = {
20867687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
20877687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
20887687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
20897687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20907687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
20917687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20927687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
20937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20947687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
20957687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
20967687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
20977687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
20987687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
20997687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
21007687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
21017687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21027687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
21037687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21047687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
21057687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21067687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
21077687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21087687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "rootcmd", "Root Error Command",
21097687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
21107687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
21117687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
21127687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG, 4, "tlplog0", "TLP Prefix Log 0",
21137687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21147687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 4, 4, "tlplog1", "TLP Prefix Log 1",
21157687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21167687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 8, 4, "tlplog2", "TLP Prefix Log 2",
21177687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21187687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 12, 4, "tlplog3", "TLP Prefix Log 3",
21197687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21207687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
21217687d0d8SRobert Mustacchi };
21227687d0d8SRobert Mustacchi 
21237687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_aer_bridge[] = {
21247687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
21257687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
21267687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
21277687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21287687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
21297687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21307687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
21317687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21327687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
21337687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
21347687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
21357687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
21367687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
21377687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
21387687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
21397687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21407687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
21417687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21427687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
21437687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21447687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
21457687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21467687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "rootcmd", "Root Error Command",
21477687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
21487687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
21497687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
21507687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_SRC_ID, 4, "esi", "Error Source Identification",
21517687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_esi },
21527687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_STS, 4, "secuests",
21537687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Status",
21547687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
21557687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_MASK, 4, "secuests",
21567687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Mask",
21577687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
21587687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_SERV, 4, "secuests",
21597687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Severity",
21607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
21617687d0d8SRobert Mustacchi 	{ PCIE_AER_SCTL, 4, "secctrl",
21627687d0d8SRobert Mustacchi 	    "Secondary Error Capabilityes and Control",
21637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secctl },
21647687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG, 4, "shl0", "Secondary Header Log 0",
21657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21667687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 4, 4, "shl1", "Secondary Header Log 1",
21677687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21687687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 8, 4, "shl1", "Secondary Header Log 2",
21697687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21707687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 12, 4, "shl1", "Secondary Header Log 3",
21717687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21727687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
21737687d0d8SRobert Mustacchi };
21747687d0d8SRobert Mustacchi 
21757687d0d8SRobert Mustacchi /*
21767687d0d8SRobert Mustacchi  * Secondary PCI Express Extended Capability
21777687d0d8SRobert Mustacchi  */
21787687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie2_linkctl3[] = {
21797687d0d8SRobert Mustacchi 	{ 0, 0, "peq", "Perform Equalization", PRDV_HEX },
21807687d0d8SRobert Mustacchi 	{ 1, 1, "leqrie", "Link Equalization Request Interrupt Enable",
21817687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
21827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
21837687d0d8SRobert Mustacchi 	{ 9, 15, "elskpos", "Enable Lower SKP OS Generation Vector",
21847687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
21857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
21867687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
21877687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
21887687d0d8SRobert Mustacchi };
21897687d0d8SRobert Mustacchi 
21907687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcie2_linkeq[] = {
21917687d0d8SRobert Mustacchi 	{ 0, 3, "dstxpre", "Downstream Port 8.0 GT/s Transmitter Preset",
21927687d0d8SRobert Mustacchi 	    PRDV_HEX },
21937687d0d8SRobert Mustacchi 	{ 4, 6, "dstxhint", "Downstream Port 8.0 GT/s Receiver Hint",
21947687d0d8SRobert Mustacchi 	    PRDV_HEX },
21957687d0d8SRobert Mustacchi 	{ 8, 11, "ustxpre", "Upstream Port 8.0 GT/s Transmitter Preset",
21967687d0d8SRobert Mustacchi 	    PRDV_HEX },
21977687d0d8SRobert Mustacchi 	{ 12, 14, "ustxhint", "Upstream Port 8.0 GT/s Receiver Hint",
21987687d0d8SRobert Mustacchi 	    PRDV_HEX },
21997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22007687d0d8SRobert Mustacchi };
22017687d0d8SRobert Mustacchi 
22027687d0d8SRobert Mustacchi static void
22037687d0d8SRobert Mustacchi pcieadm_cfgspace_print_laneq(pcieadm_cfgspace_walk_t *walkp,
22047687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
22057687d0d8SRobert Mustacchi {
22067687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
22077687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
22087687d0d8SRobert Mustacchi 		    "secondary PCIe cap");
22097687d0d8SRobert Mustacchi 		return;
22107687d0d8SRobert Mustacchi 	}
22117687d0d8SRobert Mustacchi 
22127687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
22137687d0d8SRobert Mustacchi 		char eqshort[32], eqhuman[128];
22147687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
22157687d0d8SRobert Mustacchi 
22167687d0d8SRobert Mustacchi 		(void) snprintf(eqshort, sizeof (eqshort), "lane%u", i);
22177687d0d8SRobert Mustacchi 		(void) snprintf(eqhuman, sizeof (eqhuman), "Lane %u EQ Control",
22187687d0d8SRobert Mustacchi 		    i);
22197687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 2;
22207687d0d8SRobert Mustacchi 		p.pcp_len = 2;
22217687d0d8SRobert Mustacchi 		p.pcp_short = eqshort;
22227687d0d8SRobert Mustacchi 		p.pcp_human = eqhuman;
22237687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
22247687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_pcie2_linkeq;
22257687d0d8SRobert Mustacchi 
22267687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
22277687d0d8SRobert Mustacchi 	}
22287687d0d8SRobert Mustacchi }
22297687d0d8SRobert Mustacchi 
22307687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcie2[] = {
22317687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
22327687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
22337687d0d8SRobert Mustacchi 	{ 0x4, 4, "linkctl3", "Link Control 3",
22347687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie2_linkctl3 },
22357687d0d8SRobert Mustacchi 	{ 0x8, 4, "laneerr", "Lane Error Status", pcieadm_cfgspace_print_hex },
22367687d0d8SRobert Mustacchi 	{ 0xc, 2, "eqctl", "Lane Equalization Control",
22377687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_laneq },
22387687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22397687d0d8SRobert Mustacchi };
22407687d0d8SRobert Mustacchi 
22417687d0d8SRobert Mustacchi /*
22427687d0d8SRobert Mustacchi  * Access Control Services
22437687d0d8SRobert Mustacchi  */
22447687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_acs_cap[] = {
22457687d0d8SRobert Mustacchi 	{ 0, 0, "srcvd", "ACS Source Validation", PRDV_STRVAL,
22467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22477687d0d8SRobert Mustacchi 	{ 1, 1, "tranblk", "ACS Transaction Blocking", PRDV_STRVAL,
22487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22497687d0d8SRobert Mustacchi 	{ 2, 2, "p2prr", "ACS P2P Request Redirect", PRDV_STRVAL,
22507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22517687d0d8SRobert Mustacchi 	{ 3, 3, "p2pcr", "ACS P2P Completion Redirect", PRDV_STRVAL,
22527687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22537687d0d8SRobert Mustacchi 	{ 4, 4, "upfwd", "ACS Upstream Forwarding", PRDV_STRVAL,
22547687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22557687d0d8SRobert Mustacchi 	{ 5, 5, "p2pegctl", "ACS P2P Egress Control", PRDV_STRVAL,
22567687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22577687d0d8SRobert Mustacchi 	{ 6, 6, "dtp2p", "ACS Direct Translated P2P", PRDV_STRVAL,
22587687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22597687d0d8SRobert Mustacchi 	{ 7, 7, "enhcap", "ACS Enhanced Capability", PRDV_STRVAL,
22607687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22617687d0d8SRobert Mustacchi 	{ 8, 15, "ecvsz", "Egress Control Vector Size", PRDV_HEX },
22627687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22637687d0d8SRobert Mustacchi };
22647687d0d8SRobert Mustacchi 
22657687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_acs_ctl[] = {
22667687d0d8SRobert Mustacchi 	{ 0, 0, "srcvd", "ACS Source Validation", PRDV_STRVAL,
22677687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22687687d0d8SRobert Mustacchi 	{ 1, 1, "tranblk", "ACS Transaction Blocking", PRDV_STRVAL,
22697687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22707687d0d8SRobert Mustacchi 	{ 2, 2, "p2prr", "ACS P2P Request Redirect", PRDV_STRVAL,
22717687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22727687d0d8SRobert Mustacchi 	{ 3, 3, "p2pcr", "ACS P2P Completion Redirect", PRDV_STRVAL,
22737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22747687d0d8SRobert Mustacchi 	{ 4, 4, "upfwd", "ACS Upstream Forwarding", PRDV_STRVAL,
22757687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22767687d0d8SRobert Mustacchi 	{ 5, 5, "p2pegctl", "ACS P2P Egress Control", PRDV_STRVAL,
22777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22787687d0d8SRobert Mustacchi 	{ 6, 6, "dtp2p", "ACS Direct Translated P2P", PRDV_STRVAL,
22797687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22807687d0d8SRobert Mustacchi 	{ 7, 7, "iorb", "ACS I/O Request Blocking", PRDV_STRVAL,
22817687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22827687d0d8SRobert Mustacchi 	{ 8, 9, "dspmta", "ACS DSP Memory Target Access Control", PRDV_STRVAL,
22837687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Direct Request access",
22847687d0d8SRobert Mustacchi 	    "Request blocking", "Request redirect" } } },
22857687d0d8SRobert Mustacchi 	{ 10, 11, "uspmta", "ACS USP Memory Target Access Control", PRDV_STRVAL,
22867687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Direct Request access",
22877687d0d8SRobert Mustacchi 	    "Request blocking", "Request redirect" } } },
22887687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22897687d0d8SRobert Mustacchi };
22907687d0d8SRobert Mustacchi 
22917687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_acs[] = {
22927687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
22937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
22947687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ACS Capability",
22957687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_acs_cap },
22967687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "ACS Control",
22977687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_acs_ctl },
22987687d0d8SRobert Mustacchi 	{ 0x8, 4, "ecv", "Egress Control Vector", pcieadm_cfgspace_print_ecv },
22997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23007687d0d8SRobert Mustacchi };
23017687d0d8SRobert Mustacchi 
23027687d0d8SRobert Mustacchi /*
23037687d0d8SRobert Mustacchi  * L1 PM Substates
23047687d0d8SRobert Mustacchi  */
23057687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_cap[] = {
23067687d0d8SRobert Mustacchi 	{ 0, 0, "pcil1.2", "PCI-PM L1.2", PRDV_STRVAL,
23077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23087687d0d8SRobert Mustacchi 	{ 1, 1, "pcil1.1", "PCI-PM L1.1", PRDV_STRVAL,
23097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23107687d0d8SRobert Mustacchi 	{ 2, 2, "aspml1.2", "ASPM L1.2", PRDV_STRVAL,
23117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23127687d0d8SRobert Mustacchi 	{ 3, 3, "aspml1.1", "ASPM L1.1", PRDV_STRVAL,
23137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23147687d0d8SRobert Mustacchi 	{ 4, 4, "l1pmsub", "L1 PM Substates", PRDV_STRVAL,
23157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23167687d0d8SRobert Mustacchi 	{ 5, 5, "linkact", "Link Activation", PRDV_STRVAL,
23177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23187687d0d8SRobert Mustacchi 	{ 8, 15, "pcmrt", "Port Common_Mode_Restore_Time", PRDV_HEX },
23197687d0d8SRobert Mustacchi 	{ 16, 17, "poscale", "Port T_POWER_ON Scale", PRDV_STRVAL,
23207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2 us", "10 us", "100 us" } } },
23217687d0d8SRobert Mustacchi 	{ 19, 23, "portpo", "Port T_POWER_ON Value", PRDV_HEX },
23227687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23237687d0d8SRobert Mustacchi };
23247687d0d8SRobert Mustacchi 
23257687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_ctl1[] = {
23267687d0d8SRobert Mustacchi 	{ 0, 0, "pcil1.2", "PCI-PM L1.2", PRDV_STRVAL,
23277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23287687d0d8SRobert Mustacchi 	{ 1, 1, "pcil1.1", "PCI-PM L1.1", PRDV_STRVAL,
23297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23307687d0d8SRobert Mustacchi 	{ 2, 2, "aspml1.2", "ASPM L1.2", PRDV_STRVAL,
23317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23327687d0d8SRobert Mustacchi 	{ 3, 3, "aspml1.1", "ASPM L1.1", PRDV_STRVAL,
23337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23347687d0d8SRobert Mustacchi 	{ 4, 4, "laie", "Link Activation Interrupt Enable", PRDV_STRVAL,
23357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23367687d0d8SRobert Mustacchi 	{ 5, 5, "lactl", "Link Activation Control", PRDV_STRVAL,
23377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23387687d0d8SRobert Mustacchi 	{ 8, 15, "cmrt", "Common_Mode_Restore_Time", PRDV_HEX },
23397687d0d8SRobert Mustacchi 	{ 16, 25, "ltrl1.2", "LTR L1.2 Threshold Value", PRDV_HEX },
23407687d0d8SRobert Mustacchi 	{ 29, 31, "ltrl1.2s", "LTR L1.2 Threshold Scale", PRDV_STRVAL,
23417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ns", "32 ns", "1024 ns",
23427687d0d8SRobert Mustacchi 	    "32,768 ns", "1,048,576 ns", "33,554,432 ns" } } },
23437687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23447687d0d8SRobert Mustacchi };
23457687d0d8SRobert Mustacchi 
23467687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_ctl2[] = {
23477687d0d8SRobert Mustacchi 	{ 0, 1, "poscale", "T_POWER_ON Scale", PRDV_STRVAL,
23487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2 us", "10 us", "100 us" } } },
23497687d0d8SRobert Mustacchi 	{ 3, 7, "portpo", "T_POWER_ON Value", PRDV_HEX },
23507687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23517687d0d8SRobert Mustacchi };
23527687d0d8SRobert Mustacchi 
23537687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_l1pm_sts[] = {
23547687d0d8SRobert Mustacchi 	{ 0, 0, "la", "Link Activation", PRDV_HEX },
23557687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23567687d0d8SRobert Mustacchi };
23577687d0d8SRobert Mustacchi 
23587687d0d8SRobert Mustacchi 
23597687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_l1pm_v1[] = {
23607687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
23617687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
23627687d0d8SRobert Mustacchi 	{ 0x4, 4, "caps", "L1 PM Substates Capabilities",
23637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_cap },
23647687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl1", "L1 PM Substates Control 1",
23657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl1 },
23667687d0d8SRobert Mustacchi 	{ 0xc, 4, "ctl1", "L1 PM Substates Control 2",
23677687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl2 },
23687687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23697687d0d8SRobert Mustacchi };
23707687d0d8SRobert Mustacchi 
23717687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_l1pm_v2[] = {
23727687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
23737687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
23747687d0d8SRobert Mustacchi 	{ 0x4, 4, "caps", "L1 PM Substates Capabilities",
23757687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_cap },
23767687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl1", "L1 PM Substates Control 1",
23777687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl1 },
23787687d0d8SRobert Mustacchi 	{ 0xc, 4, "ctl1", "L1 PM Substates Control 2",
23797687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl2 },
23807687d0d8SRobert Mustacchi 	{ 0x10, 4, "sts", "L1 PM Substates Status",
23817687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_sts },
23827687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23837687d0d8SRobert Mustacchi };
23847687d0d8SRobert Mustacchi 
23857687d0d8SRobert Mustacchi /*
23867687d0d8SRobert Mustacchi  * Latency Tolerance Reporting (LTR)
23877687d0d8SRobert Mustacchi  */
23887687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ltr[] = {
23897687d0d8SRobert Mustacchi 	{ 0, 9, "latval", "Latency Value", PRDV_HEX },
23907687d0d8SRobert Mustacchi 	{ 10, 12, "latscale", "Latency Scale", PRDV_STRVAL,
23917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ns", "32 ns", "1024 ns",
23927687d0d8SRobert Mustacchi 	    "32,768 ns", "1,048,576 ns", "33,554,432 ns" } } },
23937687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23947687d0d8SRobert Mustacchi };
23957687d0d8SRobert Mustacchi 
23967687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ltr[] = {
23977687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
23987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
23997687d0d8SRobert Mustacchi 	{ 0x4, 2, "snoop", "Max Snoop Latency",
24007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ltr },
24017687d0d8SRobert Mustacchi 	{ 0x6, 2, "snoop", "Max No-Snoop Latency",
24027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ltr },
24037687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24047687d0d8SRobert Mustacchi };
24057687d0d8SRobert Mustacchi 
24067687d0d8SRobert Mustacchi /*
24077687d0d8SRobert Mustacchi  * Alternative Routing ID
24087687d0d8SRobert Mustacchi  */
24097687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ari_cap[] = {
24107687d0d8SRobert Mustacchi 	{ 0, 0, "mfvcfg", "MFVC Function Groups", PRDV_STRVAL,
24117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24127687d0d8SRobert Mustacchi 	{ 1, 1, "acsfg", "ACS Function Groups", PRDV_STRVAL,
24137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24147687d0d8SRobert Mustacchi 	{ 8, 15, "nfunc", "Next Function Number", PRDV_HEX },
24157687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24167687d0d8SRobert Mustacchi };
24177687d0d8SRobert Mustacchi 
24187687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ari_ctl[] = {
24197687d0d8SRobert Mustacchi 	{ 0, 0, "mfvcfg", "MFVC Function Groups", PRDV_STRVAL,
24207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24217687d0d8SRobert Mustacchi 	{ 1, 1, "acsfg", "ACS Function Groups", PRDV_STRVAL,
24227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24237687d0d8SRobert Mustacchi 	{ 4, 6, "fgrp", "Function Group", PRDV_HEX },
24247687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24257687d0d8SRobert Mustacchi };
24267687d0d8SRobert Mustacchi 
24277687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ari[] = {
24287687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
24297687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
24307687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ARI Capability",
24317687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ari_cap },
24327687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "ARI Control",
24337687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ari_ctl },
24347687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24357687d0d8SRobert Mustacchi };
24367687d0d8SRobert Mustacchi 
24377687d0d8SRobert Mustacchi /*
24387687d0d8SRobert Mustacchi  * PASID
24397687d0d8SRobert Mustacchi  */
24407687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pasid_cap[] = {
24417687d0d8SRobert Mustacchi 	{ 1, 1, "exec", "Execution Permission", PRDV_STRVAL,
24427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24437687d0d8SRobert Mustacchi 	{ 2, 2, "priv", "Privileged Mode", PRDV_STRVAL,
24447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24457687d0d8SRobert Mustacchi 	{ 8, 12, "width", "Max PASID Width", PRDV_HEX },
24467687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24477687d0d8SRobert Mustacchi };
24487687d0d8SRobert Mustacchi 
24497687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pasid_ctl[] = {
24507687d0d8SRobert Mustacchi 	{ 0, 0, "pasid", "PASID", PRDV_STRVAL,
24517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24527687d0d8SRobert Mustacchi 	{ 1, 1, "exec", "Execution Permission", PRDV_STRVAL,
24537687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24547687d0d8SRobert Mustacchi 	{ 2, 2, "priv", "Privileged Mode", PRDV_STRVAL,
24557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24567687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24577687d0d8SRobert Mustacchi };
24587687d0d8SRobert Mustacchi 
24597687d0d8SRobert Mustacchi 
24607687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pasid[] = {
24617687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
24627687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
24637687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "PASID Capability",
24647687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pasid_cap },
24657687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "PASID Control",
24667687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pasid_ctl },
24677687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24687687d0d8SRobert Mustacchi };
24697687d0d8SRobert Mustacchi 
24707687d0d8SRobert Mustacchi /*
24717687d0d8SRobert Mustacchi  * "Advanced Features"
24727687d0d8SRobert Mustacchi  */
24737687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_af_cap[] = {
24747687d0d8SRobert Mustacchi 	{ 0, 0, "tp", "Transactions Pending", PRDV_STRVAL,
24757687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24767687d0d8SRobert Mustacchi 	{ 1, 1, "flr", "Function Level Reset", PRDV_STRVAL,
24777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24787687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24797687d0d8SRobert Mustacchi };
24807687d0d8SRobert Mustacchi 
24817687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_af_ctl[] = {
24827687d0d8SRobert Mustacchi 	{ 0, 0, "flr", "Function Level Reset", PRDV_HEX },
24837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24847687d0d8SRobert Mustacchi };
24857687d0d8SRobert Mustacchi 
24867687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_af_sts[] = {
24877687d0d8SRobert Mustacchi 	{ 0, 0, "tp", "Transactions Pending", PRDV_STRVAL,
24887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "none pending", "pending" } } },
24897687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24907687d0d8SRobert Mustacchi };
24917687d0d8SRobert Mustacchi 
24927687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_af[] = {
24937687d0d8SRobert Mustacchi 	{ 0x2, 2, "cap", "AF Capabilities",
24947687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_cap },
24957687d0d8SRobert Mustacchi 	{ 0x4, 1, "ctl", "AF Control",
24967687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_ctl },
24977687d0d8SRobert Mustacchi 	{ 0x5, 1, "sts", "AF Status",
24987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_sts },
24997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25007687d0d8SRobert Mustacchi };
25017687d0d8SRobert Mustacchi 
25027687d0d8SRobert Mustacchi /*
25037687d0d8SRobert Mustacchi  * Multicast
25047687d0d8SRobert Mustacchi  */
25057687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_cap[] = {
25067687d0d8SRobert Mustacchi 	{ 0, 5, "maxgrp", "Max Group", PRDV_HEX,
25077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
25087687d0d8SRobert Mustacchi 	{ 8, 13, "winsize", "Window Size (raw)", PRDV_HEX },
25097687d0d8SRobert Mustacchi 	{ 15, 15, "ecrc", "ECRC Regeneration", PRDV_STRVAL,
25107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
25117687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25127687d0d8SRobert Mustacchi };
25137687d0d8SRobert Mustacchi 
25147687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_ctl[] = {
25157687d0d8SRobert Mustacchi 	{ 0, 5, "numgrp", "Number of Groups", PRDV_HEX,
25167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
25177687d0d8SRobert Mustacchi 	{ 15, 15, "enable", "Enable", PRDV_STRVAL,
25187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
25197687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25207687d0d8SRobert Mustacchi };
25217687d0d8SRobert Mustacchi 
25227687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_base[] = {
25237687d0d8SRobert Mustacchi 	{ 0, 5, "index", "Multicast Index Position", PRDV_HEX },
25247687d0d8SRobert Mustacchi 	{ 12, 63, "addr", "Base Address", PRDV_HEX,
25257687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12 } } },
25267687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25277687d0d8SRobert Mustacchi };
25287687d0d8SRobert Mustacchi 
25297687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_mcast_overlay[] = {
25307687d0d8SRobert Mustacchi 	{ 0, 5, "size", "Overlay Size (raw)", PRDV_HEX },
25317687d0d8SRobert Mustacchi 	{ 6, 63, "addr", "Overlay Base Address", PRDV_HEX,
25327687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 6 } } },
25337687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25347687d0d8SRobert Mustacchi };
25357687d0d8SRobert Mustacchi 
25367687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_mcast[] = {
25377687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
25387687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
25397687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "Multicast Capability",
25407687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_cap },
25417687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "Multicast Control",
25427687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_ctl },
25437687d0d8SRobert Mustacchi 	{ 0x8, 8, "base", "Multicast Base Address",
25447687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_base },
25457687d0d8SRobert Mustacchi 	{ 0x10, 8, "rx", "Multicast Receive", pcieadm_cfgspace_print_hex },
25467687d0d8SRobert Mustacchi 	{ 0x18, 8, "block", "Multicast Block All", pcieadm_cfgspace_print_hex },
25477687d0d8SRobert Mustacchi 	{ 0x20, 8, "blockun", "Multicast Block Untranslated",
25487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
25497687d0d8SRobert Mustacchi 	{ 0x28, 8, "overlay", "Multicast Overlay BAR",
25507687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_overlay },
25517687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25527687d0d8SRobert Mustacchi };
25537687d0d8SRobert Mustacchi 
25547687d0d8SRobert Mustacchi /*
25557687d0d8SRobert Mustacchi  * Various vendor extensions
25567687d0d8SRobert Mustacchi  */
25577687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vsec[] = {
25587687d0d8SRobert Mustacchi 	{ 0, 15, "id", "ID", PRDV_HEX },
25597687d0d8SRobert Mustacchi 	{ 16, 19, "rev", "Revision", PRDV_HEX },
25607687d0d8SRobert Mustacchi 	{ 20, 31, "len", "Length", PRDV_HEX },
25617687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25627687d0d8SRobert Mustacchi };
25637687d0d8SRobert Mustacchi 
25647687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vs[] = {
25657687d0d8SRobert Mustacchi 	{ 0x2, 2, "length", "Length", pcieadm_cfgspace_print_hex },
25667687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25677687d0d8SRobert Mustacchi };
25687687d0d8SRobert Mustacchi 
25697687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vsec[] = {
25707687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
25717687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
25727687d0d8SRobert Mustacchi 	{ 0x4, 4, "header", "Vendor-Specific Header",
25737687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vsec },
25747687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25757687d0d8SRobert Mustacchi };
25767687d0d8SRobert Mustacchi 
25777687d0d8SRobert Mustacchi /*
25787687d0d8SRobert Mustacchi  * Data Link Feature
25797687d0d8SRobert Mustacchi  */
25807687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dlf_cap[] = {
25817687d0d8SRobert Mustacchi 	{ 0, 0, "lsfc", "Local Scaled Flow Control", PRDV_STRVAL,
25827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
25837687d0d8SRobert Mustacchi 	{ 31, 31, "dlex", "Data Link Exchange", PRDV_STRVAL,
25847687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
25857687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25867687d0d8SRobert Mustacchi };
25877687d0d8SRobert Mustacchi 
25887687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dlf_sts[] = {
25897687d0d8SRobert Mustacchi 	{ 0, 0, "rsfc", "Remote Scaled Flow Control", PRDV_STRVAL,
25907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
25917687d0d8SRobert Mustacchi 	{ 31, 31, "valid", "Remote Data Link Feature Valid", PRDV_STRVAL,
25927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "invalid", "valid" } } },
25937687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25947687d0d8SRobert Mustacchi };
25957687d0d8SRobert Mustacchi 
25967687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_dlf[] = {
25977687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
25987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
25997687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "Data Link Feature Capabilities",
26007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dlf_cap },
26017687d0d8SRobert Mustacchi 	{ 0x8, 4, "sts", "Data Link Feature Status",
26027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dlf_sts },
26037687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26047687d0d8SRobert Mustacchi };
26057687d0d8SRobert Mustacchi 
26067687d0d8SRobert Mustacchi /*
26077687d0d8SRobert Mustacchi  * 16.0 GT/s cap
26087687d0d8SRobert Mustacchi  */
26097687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_cap[] = {
26107687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26117687d0d8SRobert Mustacchi };
26127687d0d8SRobert Mustacchi 
26137687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_ctl[] = {
26147687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26157687d0d8SRobert Mustacchi };
26167687d0d8SRobert Mustacchi 
26177687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_sts[] = {
26187687d0d8SRobert Mustacchi 	{ 0, 0, "eqcomp", "Equalization 16.0 GT/s Complete", PRDV_STRVAL,
26197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26207687d0d8SRobert Mustacchi 	{ 1, 1, "eqp1", "Equalization 16.0 GT/s Phase 1", PRDV_STRVAL,
26217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26227687d0d8SRobert Mustacchi 	{ 2, 2, "eqp2", "Equalization 16.0 GT/s Phase 2", PRDV_STRVAL,
26237687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26247687d0d8SRobert Mustacchi 	{ 3, 3, "eqp3", "Equalization 16.0 GT/s Phase 3", PRDV_STRVAL,
26257687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26267687d0d8SRobert Mustacchi 	{ 4, 4, "req", "Link Equalization Request 16.0 GT/s", PRDV_HEX },
26277687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26287687d0d8SRobert Mustacchi };
26297687d0d8SRobert Mustacchi 
26307687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_16g_eq[] = {
26317687d0d8SRobert Mustacchi 	{ 0, 3, "dstxpre", "Downstream Port 16.0 GT/s Transmitter Preset",
26327687d0d8SRobert Mustacchi 	    PRDV_HEX },
26337687d0d8SRobert Mustacchi 	{ 4, 7, "ustxpre", "Upstream Port 16.0 GT/s Transmitter Preset",
26347687d0d8SRobert Mustacchi 	    PRDV_HEX },
26357687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26367687d0d8SRobert Mustacchi };
26377687d0d8SRobert Mustacchi 
26387687d0d8SRobert Mustacchi static void
26397687d0d8SRobert Mustacchi pcieadm_cfgspace_print_16geq(pcieadm_cfgspace_walk_t *walkp,
26407687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
26417687d0d8SRobert Mustacchi {
26427687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
26437687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
26447687d0d8SRobert Mustacchi 		    "secondary PCIe cap");
26457687d0d8SRobert Mustacchi 		return;
26467687d0d8SRobert Mustacchi 	}
26477687d0d8SRobert Mustacchi 
26487687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
26497687d0d8SRobert Mustacchi 		char eqshort[32], eqhuman[128];
26507687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
26517687d0d8SRobert Mustacchi 
26527687d0d8SRobert Mustacchi 		(void) snprintf(eqshort, sizeof (eqshort), "lane%u", i);
26537687d0d8SRobert Mustacchi 		(void) snprintf(eqhuman, sizeof (eqhuman), "Lane %u EQ Control",
26547687d0d8SRobert Mustacchi 		    i);
26557687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 1;
26567687d0d8SRobert Mustacchi 		p.pcp_len = 1;
26577687d0d8SRobert Mustacchi 		p.pcp_short = eqshort;
26587687d0d8SRobert Mustacchi 		p.pcp_human = eqhuman;
26597687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
26607687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_16g_eq;
26617687d0d8SRobert Mustacchi 
26627687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
26637687d0d8SRobert Mustacchi 	}
26647687d0d8SRobert Mustacchi }
26657687d0d8SRobert Mustacchi 
26667687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_16g[] = {
26677687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
26687687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
26697687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "16.0 GT/s Capabilities",
26707687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_cap },
26717687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl", "16.0 GT/s Control",
26727687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_ctl },
26737687d0d8SRobert Mustacchi 	{ 0xc, 4, "sts", "16.0 GT/s Status",
26747687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_sts },
26757687d0d8SRobert Mustacchi 	{ 0x10, 4, "ldpmis", "16.0 GT/s Local Data Parity Mismatch",
26767687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
26777687d0d8SRobert Mustacchi 	{ 0x14, 4, "frpmis", "16.0 GT/s First Retimer Data Parity Mismatch",
26787687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
26797687d0d8SRobert Mustacchi 	{ 0x18, 4, "srpmis", "16.0 GT/s Second Retimer Data Parity Mismatch",
26807687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
26817687d0d8SRobert Mustacchi 	{ 0x1c, 4, "rsvd", "16.0 GT/s Second Retimer Data Parity Mismatch",
26827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
26837687d0d8SRobert Mustacchi 	{ 0x20, 1, "eqctl", "16.0 GT/s EQ Control",
26847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_16geq },
26857687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26867687d0d8SRobert Mustacchi };
26877687d0d8SRobert Mustacchi 
26887687d0d8SRobert Mustacchi /*
26897687d0d8SRobert Mustacchi  * Receiver Margining
26907687d0d8SRobert Mustacchi  */
26917687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_margin_cap[] = {
26927687d0d8SRobert Mustacchi 	{ 0, 0, "sw", "Margining uses Driver Software", PRDV_STRVAL,
26937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
26947687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26957687d0d8SRobert Mustacchi };
26967687d0d8SRobert Mustacchi 
26977687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_margin_sts[] = {
26987687d0d8SRobert Mustacchi 	{ 0, 0, "ready", "Margining Ready", PRDV_STRVAL,
26997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
27007687d0d8SRobert Mustacchi 	{ 1, 1, "sw", "Margining Software Ready", PRDV_STRVAL,
27017687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
27027687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27037687d0d8SRobert Mustacchi };
27047687d0d8SRobert Mustacchi 
27057687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_margin_lane[] = {
27067687d0d8SRobert Mustacchi 	{ 0, 2, "rxno", "Receiver Number", PRDV_HEX },
27077687d0d8SRobert Mustacchi 	{ 3, 5, "type", "Margin Type", PRDV_HEX },
27087687d0d8SRobert Mustacchi 	{ 6, 6, "model", "Usage Model", PRDV_HEX },
27097687d0d8SRobert Mustacchi 	{ 8, 15, "payload", "Margin Payload", PRDV_HEX },
27107687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27117687d0d8SRobert Mustacchi };
27127687d0d8SRobert Mustacchi 
27137687d0d8SRobert Mustacchi static void
27147687d0d8SRobert Mustacchi pcieadm_cfgspace_print_margin(pcieadm_cfgspace_walk_t *walkp,
27157687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
27167687d0d8SRobert Mustacchi {
27177687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
27187687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
27197687d0d8SRobert Mustacchi 		    "lane margining capability");
27207687d0d8SRobert Mustacchi 		return;
27217687d0d8SRobert Mustacchi 	}
27227687d0d8SRobert Mustacchi 
27237687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
27247687d0d8SRobert Mustacchi 		char mshort[32], mhuman[128];
27257687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
27267687d0d8SRobert Mustacchi 
27277687d0d8SRobert Mustacchi 		(void) snprintf(mshort, sizeof (mshort), "lane%uctl", i);
27287687d0d8SRobert Mustacchi 		(void) snprintf(mhuman, sizeof (mhuman), "Lane %u Margining "
27297687d0d8SRobert Mustacchi 		    "Control", i);
27307687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
27317687d0d8SRobert Mustacchi 		p.pcp_len = 2;
27327687d0d8SRobert Mustacchi 		p.pcp_short = mshort;
27337687d0d8SRobert Mustacchi 		p.pcp_human = mhuman;
27347687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
27357687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_margin_lane;
27367687d0d8SRobert Mustacchi 
27377687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
27387687d0d8SRobert Mustacchi 
27397687d0d8SRobert Mustacchi 		(void) snprintf(mshort, sizeof (mshort), "lane%usts", i);
27407687d0d8SRobert Mustacchi 		(void) snprintf(mhuman, sizeof (mhuman), "Lane %u Margining "
27417687d0d8SRobert Mustacchi 		    "Status", i);
27427687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + 2 + i * 4;
27437687d0d8SRobert Mustacchi 		p.pcp_len = 2;
27447687d0d8SRobert Mustacchi 		p.pcp_short = mshort;
27457687d0d8SRobert Mustacchi 		p.pcp_human = mhuman;
27467687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
27477687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_margin_lane;
27487687d0d8SRobert Mustacchi 
27497687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
27507687d0d8SRobert Mustacchi 	}
27517687d0d8SRobert Mustacchi }
27527687d0d8SRobert Mustacchi 
27537687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_margin[] = {
27547687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
27557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
27567687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "Margining Port Capabilities",
27577687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_margin_cap },
27587687d0d8SRobert Mustacchi 	{ 0x6, 2, "sts", "Margining Port Status",
27597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_margin_sts },
27607687d0d8SRobert Mustacchi 	{ 0x8, 4, "lane", "Margining Lane", pcieadm_cfgspace_print_margin },
27617687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27627687d0d8SRobert Mustacchi };
27637687d0d8SRobert Mustacchi 
27647687d0d8SRobert Mustacchi /*
27657687d0d8SRobert Mustacchi  * Serial Number Capability
27667687d0d8SRobert Mustacchi  */
27677687d0d8SRobert Mustacchi static void
27687687d0d8SRobert Mustacchi pcieadm_cfgspace_print_sn(pcieadm_cfgspace_walk_t *walkp,
27697687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
27707687d0d8SRobert Mustacchi {
27717687d0d8SRobert Mustacchi 	char sn[64];
27727687d0d8SRobert Mustacchi 	uint16_t off = walkp->pcw_capoff + print->pcp_off;
27737687d0d8SRobert Mustacchi 
27747687d0d8SRobert Mustacchi 	(void) snprintf(sn, sizeof (sn),
27757687d0d8SRobert Mustacchi 	    "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
27767687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 7], walkp->pcw_data->pcb_u8[off + 6],
27777687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 5], walkp->pcw_data->pcb_u8[off + 4],
27787687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 3], walkp->pcw_data->pcb_u8[off + 2],
27797687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 1], walkp->pcw_data->pcb_u8[off]);
27807687d0d8SRobert Mustacchi 
27817687d0d8SRobert Mustacchi 	pcieadm_cfgspace_puts(walkp, print, sn);
27827687d0d8SRobert Mustacchi }
27837687d0d8SRobert Mustacchi 
27847687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_sn[] = {
27857687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
27867687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
27877687d0d8SRobert Mustacchi 	{ 0x4, 8, "sn", "Serial Number", pcieadm_cfgspace_print_sn },
27887687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27897687d0d8SRobert Mustacchi };
27907687d0d8SRobert Mustacchi 
27917687d0d8SRobert Mustacchi /*
27927687d0d8SRobert Mustacchi  * TLP Processing Hints (TPH)
27937687d0d8SRobert Mustacchi  */
27947687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_tph_cap[] = {
27957687d0d8SRobert Mustacchi 	{ 0, 0, "nost", "No ST Mode", PRDV_STRVAL,
27967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
27977687d0d8SRobert Mustacchi 	{ 1, 1, "ivec", "Interrupt Vector Mode", PRDV_STRVAL,
27987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
27997687d0d8SRobert Mustacchi 	{ 2, 2, "dev", "Device Specific Mode", PRDV_STRVAL,
28007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
28017687d0d8SRobert Mustacchi 	{ 8, 8, "exttph", "Extended TPH Requester", PRDV_STRVAL,
28027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
28037687d0d8SRobert Mustacchi 	{ 9, 10, "loc", "ST Table Location", PRDV_STRVAL,
28047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Not Present",
28057687d0d8SRobert Mustacchi 	    "In Capability Structure", "MSI-X" } } },
28067687d0d8SRobert Mustacchi 	{ 16, 26, "size", "ST Table Size", PRDV_HEX, { .prdv_hex = { 0, 1 } } },
28077687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28087687d0d8SRobert Mustacchi };
28097687d0d8SRobert Mustacchi 
28107687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_tph_ctl[] = {
28117687d0d8SRobert Mustacchi 	{ 0, 2, "mode", "ST Mode Select", PRDV_STRVAL,
28127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No ST", "Interrupt Vector",
28137687d0d8SRobert Mustacchi 	    "Device Specific" } } },
28147687d0d8SRobert Mustacchi 	{ 8, 9, "en", "TPH Requester", PRDV_STRVAL,
28157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Not Permitted", "TPH", NULL,
28167687d0d8SRobert Mustacchi 	    "TPH and Extended TPH" } } },
28177687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28187687d0d8SRobert Mustacchi };
28197687d0d8SRobert Mustacchi 
28207687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_tph_st[] = {
28217687d0d8SRobert Mustacchi 	{ 0, 7, "low", "ST Lower", PRDV_HEX },
28227687d0d8SRobert Mustacchi 	{ 8, 15, "up", "ST Upper", PRDV_HEX },
28237687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28247687d0d8SRobert Mustacchi };
28257687d0d8SRobert Mustacchi 
28267687d0d8SRobert Mustacchi /*
28277687d0d8SRobert Mustacchi  * The TPH ST table is only conditionally present in the capability. So we need
28287687d0d8SRobert Mustacchi  * to read the TPH capability register and then check if the table location and
28297687d0d8SRobert Mustacchi  * size are set here.
28307687d0d8SRobert Mustacchi  */
28317687d0d8SRobert Mustacchi static void
28327687d0d8SRobert Mustacchi pcieadm_cfgspace_print_tphst(pcieadm_cfgspace_walk_t *walkp,
28337687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
28347687d0d8SRobert Mustacchi {
28357687d0d8SRobert Mustacchi 	uint_t nents;
28367687d0d8SRobert Mustacchi 	uint32_t tphcap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
28377687d0d8SRobert Mustacchi 
28387687d0d8SRobert Mustacchi 	if (BITX(tphcap, 10, 9) != 1) {
28397687d0d8SRobert Mustacchi 		return;
28407687d0d8SRobert Mustacchi 	}
28417687d0d8SRobert Mustacchi 
28427687d0d8SRobert Mustacchi 	nents = BITX(tphcap, 26, 16) + 1;
28437687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < nents; i++) {
28447687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
28457687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
28467687d0d8SRobert Mustacchi 
28477687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "st%u", i);
28487687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "ST Table %u",
28497687d0d8SRobert Mustacchi 		    i);
28507687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 2;
28517687d0d8SRobert Mustacchi 		p.pcp_len = 2;
28527687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
28537687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
28547687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
28557687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_tph_st;
28567687d0d8SRobert Mustacchi 
28577687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
28587687d0d8SRobert Mustacchi 	}
28597687d0d8SRobert Mustacchi }
28607687d0d8SRobert Mustacchi 
28617687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_tph[] = {
28627687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
28637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
28647687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "TPH Requester Capability",
28657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_tph_cap },
28667687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl", "TPH Requester Control",
28677687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_tph_ctl },
28687687d0d8SRobert Mustacchi 	{ 0xc, 2, "table", "ST Table", pcieadm_cfgspace_print_tphst },
28697687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28707687d0d8SRobert Mustacchi };
28717687d0d8SRobert Mustacchi 
28727687d0d8SRobert Mustacchi /*
28737687d0d8SRobert Mustacchi  * SR-IOV
28747687d0d8SRobert Mustacchi  */
28757687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_cap[] = {
28767687d0d8SRobert Mustacchi 	{ 0, 0, "migration", "Migration", PRDV_STRVAL,
28777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
28787687d0d8SRobert Mustacchi 	{ 1, 1, "ari", "ARI Capable Hierarchy Preserved", PRDV_STRVAL,
28797687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unpreserved", "preserved" } } },
28807687d0d8SRobert Mustacchi 	{ 2, 2, "vf10b", "VF 10-bit Tag Requester", PRDV_STRVAL,
28817687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unpreserved", "preserved" } } },
28827687d0d8SRobert Mustacchi 	{ 21, 31, "inum", "VF Migration Interrupt Message Number", PRDV_HEX },
28837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28847687d0d8SRobert Mustacchi };
28857687d0d8SRobert Mustacchi 
28867687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_ctl[] = {
28877687d0d8SRobert Mustacchi 	{ 0, 0, "vf", "VF", PRDV_STRVAL,
28887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
28897687d0d8SRobert Mustacchi 	{ 1, 1, "vfm", "VF Migration", PRDV_STRVAL,
28907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
28917687d0d8SRobert Mustacchi 	{ 2, 2, "vfmi", "VF Migration Interrupt", PRDV_STRVAL,
28927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
28937687d0d8SRobert Mustacchi 	{ 3, 3, "ari", "ARI Capable Hierarchy", PRDV_STRVAL,
28947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
28957687d0d8SRobert Mustacchi 	{ 4, 4, "vf10b", "VF 10-bit Tag Requester", PRDV_STRVAL,
28967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
28977687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28987687d0d8SRobert Mustacchi };
28997687d0d8SRobert Mustacchi 
29007687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_sts[] = {
29017687d0d8SRobert Mustacchi 	{ 0, 0, "vfm", "VF Migration", PRDV_STRVAL,
29027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "none", "requested" } } },
29037687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29047687d0d8SRobert Mustacchi };
29057687d0d8SRobert Mustacchi 
29067687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_pgsup[] = {
29077687d0d8SRobert Mustacchi 	{ 0, 31, "pgsz", "Supported Page Sizes", PRDV_BITFIELD,
29087687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4 KB", "8 KB", "16 KB", "32 KB",
29097687d0d8SRobert Mustacchi 	    "64 KB", "128 KB", "256 KB", "512 KB", "1 MB", "2 MB", "4 MB",
29107687d0d8SRobert Mustacchi 	    "8 MB", "16 MB", "32 MB", "64 MB", "128 MB", "256 MB", "512 MB",
29117687d0d8SRobert Mustacchi 	    "1 GB", "2 GB", "4 GB", "8 GB", "16 GB", "32 GB", "64 GB",
29127687d0d8SRobert Mustacchi 	    "128 GB", "256 GB", "512 GB", "1 TB", "2 TB", "4 TB", "8 TB" } } },
29137687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29147687d0d8SRobert Mustacchi };
29157687d0d8SRobert Mustacchi 
29167687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_pgen[] = {
29177687d0d8SRobert Mustacchi 	{ 0, 31, "pgsz", "System Page Sizes", PRDV_BITFIELD,
29187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4 KB", "8 KB", "16 KB", "32 KB",
29197687d0d8SRobert Mustacchi 	    "64 KB", "128 KB", "256 KB", "512 KB", "1 MB", "2 MB", "4 MB",
29207687d0d8SRobert Mustacchi 	    "8 MB", "16 MB", "32 MB", "64 MB", "128 MB", "256 MB", "512 MB",
29217687d0d8SRobert Mustacchi 	    "1 GB", "2 GB", "4 GB", "8 GB", "16 GB", "32 GB", "64 GB",
29227687d0d8SRobert Mustacchi 	    "128 GB", "256 GB", "512 GB", "1 TB", "2 TB", "4 TB", "8 TB" } } },
29237687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29247687d0d8SRobert Mustacchi };
29257687d0d8SRobert Mustacchi 
29267687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_sriov_mig[] = {
29277687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "VF Migration State BIR", PRDV_STRVAL,
29287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
29297687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
29307687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "VF Migration State Offset", PRDV_HEX,
29317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
29327687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29337687d0d8SRobert Mustacchi };
29347687d0d8SRobert Mustacchi 
29357687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_sriov[] = {
29367687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
29377687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
29387687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "SR-IOV Capabilities",
29397687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_cap },
29407687d0d8SRobert Mustacchi 	{ 0x8, 2, "ctl", "SR-IOV Control",
29417687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_ctl },
29427687d0d8SRobert Mustacchi 	{ 0xa, 2, "sts", "SR-IOV Status",
29437687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_sts },
29447687d0d8SRobert Mustacchi 	{ 0xc, 2, "initvfs", "Initial VFs", pcieadm_cfgspace_print_hex },
29457687d0d8SRobert Mustacchi 	{ 0xe, 2, "totvfs", "Total VFs", pcieadm_cfgspace_print_hex },
29467687d0d8SRobert Mustacchi 	{ 0x10, 2, "numvfs", "Number VFs", pcieadm_cfgspace_print_hex },
29477687d0d8SRobert Mustacchi 	{ 0x12, 1, "dep", "Function Dependency Link",
29487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
29497687d0d8SRobert Mustacchi 	{ 0x14, 2, "offset", "First VF Offset", pcieadm_cfgspace_print_hex },
29507687d0d8SRobert Mustacchi 	{ 0x16, 2, "stride", "VF Stride", pcieadm_cfgspace_print_hex },
29517687d0d8SRobert Mustacchi 	{ 0x1a, 2, "devid", "VF Device ID", pcieadm_cfgspace_print_hex },
29527687d0d8SRobert Mustacchi 	{ 0x1c, 4, "pgsz", "Supported Page Sizes",
29537687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_pgsup },
29547687d0d8SRobert Mustacchi 	{ 0x20, 4, "pgsz", "System Page Sizes",
29557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_pgen },
29567687d0d8SRobert Mustacchi 	{ 0x24, 24, "vfbar", "Virtual Base Address Register",
29577687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
29587687d0d8SRobert Mustacchi 	{ 0x3c, 4, "migration", "VF Migration State Array",
29597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_mig },
29607687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29617687d0d8SRobert Mustacchi };
29627687d0d8SRobert Mustacchi 
29637687d0d8SRobert Mustacchi /*
29647687d0d8SRobert Mustacchi  * PCI-X
29657687d0d8SRobert Mustacchi  */
29667687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_dev_ctl[] = {
29677687d0d8SRobert Mustacchi 	{ 0, 0, "dper", "Data Parity Error Recovery", PRDV_STRVAL,
29687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29697687d0d8SRobert Mustacchi 	{ 1, 1, "ro", "Relaxed Ordering", PRDV_STRVAL,
29707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29717687d0d8SRobert Mustacchi 	{ 2, 3, "maxread", "Maximum Memory Read Byte Count", PRDV_STRVAL,
29727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "512 bytes", "1024 bytes",
29737687d0d8SRobert Mustacchi 	    "2048 byes", "4096 bytes" } } },
29747687d0d8SRobert Mustacchi 	{ 4, 6, "maxsplit", "Maximum Outstanding Split Transactions",
29757687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "1", "2", "3", "4", "8",
29767687d0d8SRobert Mustacchi 	    "12", "16", "32" } } },
29777687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29787687d0d8SRobert Mustacchi };
29797687d0d8SRobert Mustacchi 
29807687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_dev_sts[] = {
29817687d0d8SRobert Mustacchi 	{ 0, 2, "func", "Function Number", PRDV_HEX },
29827687d0d8SRobert Mustacchi 	{ 3, 7, "dev", "Device Number", PRDV_HEX },
29837687d0d8SRobert Mustacchi 	{ 8, 15, "bus", "Bus Number", PRDV_HEX },
29847687d0d8SRobert Mustacchi 	{ 16, 16, "64bit", "64-bit Device", PRDV_STRVAL,
29857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
29867687d0d8SRobert Mustacchi 	    "supported" } } },
29877687d0d8SRobert Mustacchi 	{ 17, 17, "133mhz", "133 MHz Capable", PRDV_STRVAL,
29887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
29897687d0d8SRobert Mustacchi 	    "supported" } } },
29907687d0d8SRobert Mustacchi 	{ 18, 18, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
29917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
29927687d0d8SRobert Mustacchi 	{ 19, 19, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
29937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
29947687d0d8SRobert Mustacchi 	{ 20, 20, "complex", "Device Complexity", PRDV_STRVAL,
29957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "simple", "bridge" } } },
29967687d0d8SRobert Mustacchi 	{ 21, 22, "maxread", "Designed Maximum Memory Read Byte Count",
29977687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "512 bytes",
29987687d0d8SRobert Mustacchi 	    "1024 bytes", "2048 byes", "4096 bytes" } } },
29997687d0d8SRobert Mustacchi 	{ 23, 25, "maxsplit", "Designed Maximum Outstanding Split Transactions",
30007687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "1", "2", "3", "4", "8",
30017687d0d8SRobert Mustacchi 	    "12", "16", "32" } } },
30027687d0d8SRobert Mustacchi 	{ 26, 28, "maxcread", "Designed Maximum Cumulative Read Size",
30037687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "8/1KB", "16/2KB",
30047687d0d8SRobert Mustacchi 	    "32/4KB", "64/8KB", "128/16KB", "256/32KB", "512/64KB",
30057687d0d8SRobert Mustacchi 	    "1024/128KB" } } },
30067687d0d8SRobert Mustacchi 	{ 29, 29, "rxspcoer", "Received Split Completion Error Message",
30077687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "no", "yes" } } },
30087687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30097687d0d8SRobert Mustacchi };
30107687d0d8SRobert Mustacchi 
30117687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_sec_sts[] = {
30127687d0d8SRobert Mustacchi 	{ 0, 0, "64bit", "64-bit Device", PRDV_STRVAL,
30137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
30147687d0d8SRobert Mustacchi 	    "supported" } } },
30157687d0d8SRobert Mustacchi 	{ 1, 1, "133mhz", "133 MHz Capable", PRDV_STRVAL,
30167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
30177687d0d8SRobert Mustacchi 	    "supported" } } },
30187687d0d8SRobert Mustacchi 	{ 2, 2, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
30197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30207687d0d8SRobert Mustacchi 	{ 3, 3, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
30217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30227687d0d8SRobert Mustacchi 	{ 4, 4, "spcoor", "Split Completion Overrun", PRDV_STRVAL,
30237687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30247687d0d8SRobert Mustacchi 	{ 5, 5, "sprde", "Split Request Delayed", PRDV_STRVAL,
30257687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30267687d0d8SRobert Mustacchi 	{ 6, 8, "freq", "Secondary Clock Frequency", PRDV_STRVAL,
30277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "conventional", "66 MHz", "100 Mhz",
30287687d0d8SRobert Mustacchi 	    "133 MHz" } } },
30297687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30307687d0d8SRobert Mustacchi };
30317687d0d8SRobert Mustacchi 
30327687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_bridge_sts[] = {
30337687d0d8SRobert Mustacchi 	{ 0, 2, "func", "Function Number", PRDV_HEX },
30347687d0d8SRobert Mustacchi 	{ 3, 7, "dev", "Device Number", PRDV_HEX },
30357687d0d8SRobert Mustacchi 	{ 8, 15, "bus", "Bus Number", PRDV_HEX },
30367687d0d8SRobert Mustacchi 	{ 16, 16, "64bit", "64-bit Device", PRDV_STRVAL,
30377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
30387687d0d8SRobert Mustacchi 	    "supported" } } },
30397687d0d8SRobert Mustacchi 	{ 17, 17, "133mhz", "133 MHz Capable", PRDV_STRVAL,
30407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
30417687d0d8SRobert Mustacchi 	    "supported" } } },
30427687d0d8SRobert Mustacchi 	{ 18, 18, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
30437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30447687d0d8SRobert Mustacchi 	{ 19, 19, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
30457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30467687d0d8SRobert Mustacchi 	{ 20, 20, "spcoor", "Split Completion Overrun", PRDV_STRVAL,
30477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30487687d0d8SRobert Mustacchi 	{ 21, 21, "sprde", "Split Request Delayed", PRDV_STRVAL,
30497687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30507687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30517687d0d8SRobert Mustacchi };
30527687d0d8SRobert Mustacchi 
30537687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pcix_bridge_split[] = {
30547687d0d8SRobert Mustacchi 	{ 0, 15, "cap", "Split Transaction Capacity", PRDV_HEX },
30557687d0d8SRobert Mustacchi 	{ 16, 31, "limit", "Split Transaction Commitment Limit", PRDV_HEX },
30567687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30577687d0d8SRobert Mustacchi };
30587687d0d8SRobert Mustacchi 
30597687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcix_dev[] = {
30607687d0d8SRobert Mustacchi 	{ 0x2, 2, "ctl", "PCI-X Command",
30617687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_dev_ctl },
30627687d0d8SRobert Mustacchi 	{ 0x4, 4, "sts", "PCI-X Status",
30637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_dev_sts },
30647687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30657687d0d8SRobert Mustacchi };
30667687d0d8SRobert Mustacchi 
30677687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pcix_bridge[] = {
30687687d0d8SRobert Mustacchi 	{ 0x2, 2, "secsts", "PCI-X Secondary Status",
30697687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_sec_sts },
30707687d0d8SRobert Mustacchi 	{ 0x4, 4, "sts", "PCI-X Bridge Status",
30717687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_sts },
30727687d0d8SRobert Mustacchi 	{ 0x8, 4, "ussplit", "Upstream Split Transaction",
30737687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_split },
30747687d0d8SRobert Mustacchi 	{ 0x8, 4, "dssplit", "Downstream Split Transaction",
30757687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_split },
30767687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30777687d0d8SRobert Mustacchi };
30787687d0d8SRobert Mustacchi 
30797687d0d8SRobert Mustacchi /*
30807687d0d8SRobert Mustacchi  * Dynamic Power Allocation
30817687d0d8SRobert Mustacchi  */
30827687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpa_cap[] = {
30837687d0d8SRobert Mustacchi 	{ 0, 4, "substates", "Substate Max", PRDV_HEX,
30847687d0d8SRobert Mustacchi 	    { .prdv_hex = { 0, 1 } } },
30857687d0d8SRobert Mustacchi 	{ 8, 9, "tlu", "Transition Latency Unit", PRDV_STRVAL,
30867687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ms", "10 ms", "100 ms" } } },
30877687d0d8SRobert Mustacchi 	{ 12, 13, "pas", "Power Allocation Scale", PRDV_STRVAL,
30887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "10.0x", "1.0x", "0.1x",
30897687d0d8SRobert Mustacchi 	    "0.01x" } } },
30907687d0d8SRobert Mustacchi 	{ 16, 23, "tlv0", "Transition Latency Value 0", PRDV_HEX },
30917687d0d8SRobert Mustacchi 	{ 24, 31, "tlv0", "Transition Latency Value 1", PRDV_HEX },
30927687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30937687d0d8SRobert Mustacchi };
30947687d0d8SRobert Mustacchi 
30957687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpa_sts[] = {
30967687d0d8SRobert Mustacchi 	{ 0, 4, "substate", "Substate Status", PRDV_HEX },
30977687d0d8SRobert Mustacchi 	{ 8, 8, "ctlen", "Substate Control Enabled", PRDV_STRVAL,
30987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
30997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31007687d0d8SRobert Mustacchi };
31017687d0d8SRobert Mustacchi 
31027687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpa_ctl[] = {
31037687d0d8SRobert Mustacchi 	{ 0, 4, "substate", "Substate Control", PRDV_HEX },
31047687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31057687d0d8SRobert Mustacchi };
31067687d0d8SRobert Mustacchi 
31077687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_dpa[] = {
31087687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
31097687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
31107687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "DPA Capability",
31117687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_cap },
31127687d0d8SRobert Mustacchi 	{ 0x8, 4, "lat", "DPA Latency Indicator", pcieadm_cfgspace_print_hex },
31137687d0d8SRobert Mustacchi 	{ 0xc, 2, "sts", "DPA Status",
31147687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_sts },
31157687d0d8SRobert Mustacchi 	{ 0xe, 2, "sts", "DPA Control",
31167687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_ctl },
31177687d0d8SRobert Mustacchi 	{ 0x10, 1, "paa", "DPA Power Allocation Array",
31187687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpa_paa },
31197687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31207687d0d8SRobert Mustacchi };
31217687d0d8SRobert Mustacchi 
31227687d0d8SRobert Mustacchi /*
31237687d0d8SRobert Mustacchi  * Power Budgeting
31247687d0d8SRobert Mustacchi  */
31257687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_powbudg_data[] = {
31267687d0d8SRobert Mustacchi 	{ 0, 7, "base", "Base Power", PRDV_HEX },
31277687d0d8SRobert Mustacchi 	{ 8, 9, "scale", "Data Scale", PRDV_STRVAL,
31287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1.0x", "0.1x", "0.01x",
31297687d0d8SRobert Mustacchi 	    "0.001x" } } },
31307687d0d8SRobert Mustacchi 	{ 10, 12, "pmsub", "PM Substate", PRDV_STRVAL,
31317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Default", "Device Specific",
31327687d0d8SRobert Mustacchi 	    "Device Specific", "Device Specific", "Device Specific",
31337687d0d8SRobert Mustacchi 	    "Device Specific", "Device Specific", "Device Specific" } } },
31347687d0d8SRobert Mustacchi 	{ 13, 14, "pmstate", "PM State", PRDV_STRVAL,
31357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "D0", "D1", "D2", "D3" } } },
31367687d0d8SRobert Mustacchi 	{ 15, 17, "type", "Type", PRDV_STRVAL,
31377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PME Aux", "Axiliary", "Idle",
31387687d0d8SRobert Mustacchi 	    "Sustained", "Sustained - EPRS", "Maximum - EPRS", NULL,
31397687d0d8SRobert Mustacchi 	    "Maximum" } } },
31407687d0d8SRobert Mustacchi 	{ 18, 20, "rail", "Power Rail", PRDV_STRVAL,
31417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Power (12V)", "Power (3.3V)",
31427687d0d8SRobert Mustacchi 	    "Power (1.5V or 1.8V)", NULL, NULL, NULL, NULL, "Thermal" } } },
31437687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31447687d0d8SRobert Mustacchi };
31457687d0d8SRobert Mustacchi 
31467687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_powbudg_cap[] = {
31477687d0d8SRobert Mustacchi 	{ 0, 0, "sa", "System Allocated", PRDV_STRVAL,
31487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
31497687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31507687d0d8SRobert Mustacchi };
31517687d0d8SRobert Mustacchi 
31527687d0d8SRobert Mustacchi 
31537687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_powbudg[] = {
31547687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
31557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
31567687d0d8SRobert Mustacchi 	{ 0x4, 1, "sel", "Data Select", pcieadm_cfgspace_print_hex },
31577687d0d8SRobert Mustacchi 	{ 0x8, 4, "data", "Data Regiser", pcieadm_cfgspace_print_regdef,
31587687d0d8SRobert Mustacchi 	    pcieadm_regdef_powbudg_data },
31597687d0d8SRobert Mustacchi 	{ 0xc, 0x1, "cap", "Power Budget Capability",
31607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_powbudg_cap },
31617687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31627687d0d8SRobert Mustacchi };
31637687d0d8SRobert Mustacchi 
31647687d0d8SRobert Mustacchi /*
31657687d0d8SRobert Mustacchi  * Precision Time Management
31667687d0d8SRobert Mustacchi  */
31677687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ptm_cap[] = {
31687687d0d8SRobert Mustacchi 	{ 0, 0, "req", "PTM Requester", PRDV_STRVAL,
31697687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31707687d0d8SRobert Mustacchi 	{ 1, 1, "resp", "PTM Responder", PRDV_STRVAL,
31717687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31727687d0d8SRobert Mustacchi 	{ 2, 2, "root", "PTM Root", PRDV_STRVAL,
31737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31747687d0d8SRobert Mustacchi 	{ 3, 3, "eptm", "ePTM", PRDV_STRVAL,
31757687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31767687d0d8SRobert Mustacchi 	{ 8, 15, "gran", "Local Clock Granularity", PRDV_HEX },
31777687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31787687d0d8SRobert Mustacchi };
31797687d0d8SRobert Mustacchi 
31807687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ptm_ctl[] = {
31817687d0d8SRobert Mustacchi 	{ 0, 0, "en", "PTM Enable", PRDV_STRVAL,
31827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
31837687d0d8SRobert Mustacchi 	{ 1, 1, "root", "Root Select", PRDV_STRVAL,
31847687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
31857687d0d8SRobert Mustacchi 	{ 8, 15, "gran", "Effective Granularity", PRDV_HEX },
31867687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31877687d0d8SRobert Mustacchi };
31887687d0d8SRobert Mustacchi 
31897687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_info_ptm[] = {
31907687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
31917687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
31927687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "PTM Capability",
31937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ptm_cap },
31947687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap", "PTM Control",
31957687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ptm_ctl },
31967687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31977687d0d8SRobert Mustacchi };
31987687d0d8SRobert Mustacchi 
31997687d0d8SRobert Mustacchi /*
32007687d0d8SRobert Mustacchi  * Address Translation Services (ATS)
32017687d0d8SRobert Mustacchi  */
32027687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ats_cap[] = {
32037687d0d8SRobert Mustacchi 	{ 0, 4, "invqd", "Invalidate Queue Depth", PRDV_HEX },
32047687d0d8SRobert Mustacchi 	{ 5, 5, "pgalign", "Page Aligned Request", PRDV_STRVAL,
32057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
32067687d0d8SRobert Mustacchi 	{ 6, 6, "glbinv", "Global Invalidate", PRDV_STRVAL,
32077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32087687d0d8SRobert Mustacchi 	{ 7, 7, "relo", "Relaxed Ordering", PRDV_STRVAL,
32097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32107687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32117687d0d8SRobert Mustacchi };
32127687d0d8SRobert Mustacchi 
32137687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ats_ctl[] = {
32147687d0d8SRobert Mustacchi 	{ 0, 4, "stu", "Smallest Translation Unit", PRDV_HEX },
32157687d0d8SRobert Mustacchi 	{ 15, 15, "en", "Enable", PRDV_STRVAL,
32167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
32177687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32187687d0d8SRobert Mustacchi };
32197687d0d8SRobert Mustacchi 
32207687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ats[] = {
32217687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
32227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
32237687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ATS Capability",
32247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ats_cap },
32257687d0d8SRobert Mustacchi 	{ 0x6, 2, "cap", "ATS Control",
32267687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ats_ctl },
32277687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32287687d0d8SRobert Mustacchi };
32297687d0d8SRobert Mustacchi 
32307687d0d8SRobert Mustacchi /*
32317687d0d8SRobert Mustacchi  * Page Request
32327687d0d8SRobert Mustacchi  */
32337687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pgreq_ctl[] = {
32347687d0d8SRobert Mustacchi 	{ 0, 0, "en", "Enable", PRDV_STRVAL,
32357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
32367687d0d8SRobert Mustacchi 	{ 1, 1, "reset", "Reset", PRDV_HEX },
32377687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32387687d0d8SRobert Mustacchi };
32397687d0d8SRobert Mustacchi 
32407687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_pgreq_sts[] = {
32417687d0d8SRobert Mustacchi 	{ 0, 0, "rf", "Response Failure", PRDV_STRVAL,
32427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
32437687d0d8SRobert Mustacchi 	{ 1, 1, "uprgi", "Unexpected Page Request Group Index", PRDV_STRVAL,
32447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
32457687d0d8SRobert Mustacchi 	{ 8, 8, "stopped", "Stopped", PRDV_STRVAL,
32467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
32477687d0d8SRobert Mustacchi 	{ 15, 15, "prgrpreq", "PRG Response PASID", PRDV_STRVAL,
32487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
32497687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32507687d0d8SRobert Mustacchi };
32517687d0d8SRobert Mustacchi 
32527687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_pgreq[] = {
32537687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
32547687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
32557687d0d8SRobert Mustacchi 	{ 0x4, 2, "ctl", "Page Request Control",
32567687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pgreq_ctl },
32577687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "Page Request Status",
32587687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pgreq_sts },
32597687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap", "Outstanding Page Request Capacity",
32607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
32617687d0d8SRobert Mustacchi 	{ 0xc, 4, "alloc", "Outstanding Page Request Allocation",
32627687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
32637687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32647687d0d8SRobert Mustacchi };
32657687d0d8SRobert Mustacchi 
32667687d0d8SRobert Mustacchi /*
32677687d0d8SRobert Mustacchi  * NULL Capability
32687687d0d8SRobert Mustacchi  */
32697687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_null[] = {
32707687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
32717687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
32727687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32737687d0d8SRobert Mustacchi };
32747687d0d8SRobert Mustacchi 
32757687d0d8SRobert Mustacchi /*
32767687d0d8SRobert Mustacchi  * Downstream Port Containment
32777687d0d8SRobert Mustacchi  */
32787687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_cap[] = {
32797687d0d8SRobert Mustacchi 	{ 0, 4, "inum", "DPC Interrupt Message Number", PRDV_HEX },
32807687d0d8SRobert Mustacchi 	{ 5, 5, "rpext", "Root Port Extensions", PRDV_STRVAL,
32817687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32827687d0d8SRobert Mustacchi 	{ 6, 6, "ptlpeb", "Poisoned TLP Egress Blocking", PRDV_STRVAL,
32837687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32847687d0d8SRobert Mustacchi 	{ 7, 7, "swtrig", "Software Triggering", PRDV_STRVAL,
32857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32867687d0d8SRobert Mustacchi 	{ 8, 11, "logsz", "RP PIO Log Size", PRDV_HEX },
32877687d0d8SRobert Mustacchi 	{ 12, 12, "errcorr", "DL_Active ERR_COR Signaling", PRDV_STRVAL,
32887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32897687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32907687d0d8SRobert Mustacchi };
32917687d0d8SRobert Mustacchi 
32927687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_ctl[] = {
32937687d0d8SRobert Mustacchi 	{ 0, 1, "trigger", "DPC Trigger", PRDV_STRVAL,
32947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled, fatal",
32957687d0d8SRobert Mustacchi 	    "enabled, non-fatal" } } },
32967687d0d8SRobert Mustacchi 	{ 2, 2, "comp", "Completion Control", PRDV_STRVAL,
32977687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Completer Abort",
32987687d0d8SRobert Mustacchi 	    "Unsupported Request" } } },
32997687d0d8SRobert Mustacchi 	{ 3, 3, "intr", "Interrupt",
33007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33017687d0d8SRobert Mustacchi 	{ 4, 4, "errcor", "ERR_COR",
33027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33037687d0d8SRobert Mustacchi 	{ 5, 5, "ptlpeb", "Poisoned TLP Egress Blocking", PRDV_STRVAL,
33047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33057687d0d8SRobert Mustacchi 	{ 6, 6, "swtrig", "Software Trigger", PRDV_HEX },
33067687d0d8SRobert Mustacchi 	{ 7, 7, "corerr", "DL_Active ERR_COR",
33077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33087687d0d8SRobert Mustacchi 	{ 8, 8, "sigsfw", "SIG_SFW",
33097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33107687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
33117687d0d8SRobert Mustacchi };
33127687d0d8SRobert Mustacchi 
33137687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_sts[] = {
33147687d0d8SRobert Mustacchi 	{ 0, 0, "trigger", "Trigger Status", PRDV_STRVAL,
33157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not triggered", "triggered" } } },
33167687d0d8SRobert Mustacchi 	{ 1, 2, "reason", "Trigger Reason", PRDV_STRVAL,
33177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unmasked uncorrectable",
33187687d0d8SRobert Mustacchi 	    "ERR_NONFATAL received", "ERR_FATAL received",
33197687d0d8SRobert Mustacchi 	    "see extension" } } },
33207687d0d8SRobert Mustacchi 	{ 3, 3, "istatus", "Interrupt Status", PRDV_HEX },
33217687d0d8SRobert Mustacchi 	{ 4, 4, "rpbusy", "RP Busy", PRDV_STRVAL,
33227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
33237687d0d8SRobert Mustacchi 	{ 5, 6, "extreason", "Trigger Reason Extension", PRDV_STRVAL,
33247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "RP PIO", "Software Trigger" } } },
33257687d0d8SRobert Mustacchi 	{ 8, 12, "feptr", "RP PIO, First Error Pointer", PRDV_HEX },
33267687d0d8SRobert Mustacchi 	{ 13, 13, "sigsfw", "SIG_SFW Status", PRDV_HEX },
33277687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
33287687d0d8SRobert Mustacchi };
33297687d0d8SRobert Mustacchi 
33307687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_dpc_rppio_bits[] = {
33317687d0d8SRobert Mustacchi 	{ 0, 0, "cfgur", "Configuration Request UR Completion", PRDV_HEX },
33327687d0d8SRobert Mustacchi 	{ 1, 1, "cfgca", "Configuration Request CA Completion", PRDV_HEX },
33337687d0d8SRobert Mustacchi 	{ 2, 2, "cfgcto", "Configuration Request Completion Timeout",
33347687d0d8SRobert Mustacchi 	    PRDV_HEX },
33357687d0d8SRobert Mustacchi 	{ 8, 8, "iour", "I/O UR Completion", PRDV_HEX },
33367687d0d8SRobert Mustacchi 	{ 9, 9, "ioca", "I/O CA Completion", PRDV_HEX },
33377687d0d8SRobert Mustacchi 	{ 10, 10, "iocto", "I/O Completion Timeout", PRDV_HEX },
33387687d0d8SRobert Mustacchi 	{ 8, 8, "memur", "Memory UR Completion", PRDV_HEX },
33397687d0d8SRobert Mustacchi 	{ 9, 9, "memca", "Memory CA Completion", PRDV_HEX },
33407687d0d8SRobert Mustacchi 	{ 10, 10, "memcto", "Memory Completion Timeout", PRDV_HEX },
33417687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
33427687d0d8SRobert Mustacchi };
33437687d0d8SRobert Mustacchi 
33447687d0d8SRobert Mustacchi static void
33457687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_rppio(pcieadm_cfgspace_walk_t *walkp,
33467687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
33477687d0d8SRobert Mustacchi {
33487687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
33497687d0d8SRobert Mustacchi 
33507687d0d8SRobert Mustacchi 	if (BITX(cap, 5, 5) == 0) {
33517687d0d8SRobert Mustacchi 		return;
33527687d0d8SRobert Mustacchi 	}
33537687d0d8SRobert Mustacchi 
33547687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_regdef(walkp, print, arg);
33557687d0d8SRobert Mustacchi }
33567687d0d8SRobert Mustacchi 
33577687d0d8SRobert Mustacchi static void
33587687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_piohead(pcieadm_cfgspace_walk_t *walkp,
33597687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
33607687d0d8SRobert Mustacchi {
33617687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
33627687d0d8SRobert Mustacchi 	uint32_t nwords = BITX(cap, 11, 8);
33637687d0d8SRobert Mustacchi 
33647687d0d8SRobert Mustacchi 	if (BITX(cap, 5, 5) == 0 || nwords < 4) {
33657687d0d8SRobert Mustacchi 		return;
33667687d0d8SRobert Mustacchi 	}
33677687d0d8SRobert Mustacchi 
33687687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, NULL);
33697687d0d8SRobert Mustacchi }
33707687d0d8SRobert Mustacchi 
33717687d0d8SRobert Mustacchi static void
33727687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_impspec(pcieadm_cfgspace_walk_t *walkp,
33737687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
33747687d0d8SRobert Mustacchi {
33757687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
33767687d0d8SRobert Mustacchi 	uint32_t nwords = BITX(cap, 11, 8);
33777687d0d8SRobert Mustacchi 
33787687d0d8SRobert Mustacchi 	if (BITX(cap, 5, 5) == 0 || nwords < 5) {
33797687d0d8SRobert Mustacchi 		return;
33807687d0d8SRobert Mustacchi 	}
33817687d0d8SRobert Mustacchi 
33827687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, NULL);
33837687d0d8SRobert Mustacchi }
33847687d0d8SRobert Mustacchi 
33857687d0d8SRobert Mustacchi static void
33867687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_tlplog(pcieadm_cfgspace_walk_t *walkp,
33877687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
33887687d0d8SRobert Mustacchi {
33897687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
33907687d0d8SRobert Mustacchi 	int32_t nwords = BITX(cap, 11, 8);
33917687d0d8SRobert Mustacchi 
33927687d0d8SRobert Mustacchi 	if (nwords == 0 || BITX(cap, 5, 5) == 0) {
33937687d0d8SRobert Mustacchi 		return;
33947687d0d8SRobert Mustacchi 	}
33957687d0d8SRobert Mustacchi 
33967687d0d8SRobert Mustacchi 	if (nwords <= 9) {
33977687d0d8SRobert Mustacchi 		nwords -= 5;
33987687d0d8SRobert Mustacchi 	} else {
33997687d0d8SRobert Mustacchi 		nwords -= 4;
34007687d0d8SRobert Mustacchi 	}
34017687d0d8SRobert Mustacchi 
34027687d0d8SRobert Mustacchi 	for (int32_t i = 0; i < nwords; i++) {
34037687d0d8SRobert Mustacchi 		char tlpshort[32], tlphuman[128];
34047687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
34057687d0d8SRobert Mustacchi 
34067687d0d8SRobert Mustacchi 		(void) snprintf(tlpshort, sizeof (tlpshort), "%s%u",
34077687d0d8SRobert Mustacchi 		    print->pcp_short, i);
34087687d0d8SRobert Mustacchi 		(void) snprintf(tlphuman, sizeof (tlphuman), "%s %u",
34097687d0d8SRobert Mustacchi 		    print->pcp_human, i);
34107687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
34117687d0d8SRobert Mustacchi 		p.pcp_len = 4;
34127687d0d8SRobert Mustacchi 		p.pcp_short = tlpshort;
34137687d0d8SRobert Mustacchi 		p.pcp_human = tlphuman;
34147687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
34157687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
34167687d0d8SRobert Mustacchi 
34177687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
34187687d0d8SRobert Mustacchi 	}
34197687d0d8SRobert Mustacchi }
34207687d0d8SRobert Mustacchi 
34217687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_dpc[] = {
34227687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
34237687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
34247687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "DPC Capability",
34257687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_cap },
34267687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "DPC Control",
34277687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_ctl },
34287687d0d8SRobert Mustacchi 	{ 0x8, 2, "sts", "DPC Status",
34297687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_sts },
34307687d0d8SRobert Mustacchi 	{ 0xa, 2, "srcid", "DPC Error Source ID",
34317687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
34327687d0d8SRobert Mustacchi 	{ 0x10, 4, "rppiosts", "RP PIO Status",
34337687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34347687d0d8SRobert Mustacchi 	{ 0x14, 4, "rppiomask", "RP PIO Mask ID",
34357687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34367687d0d8SRobert Mustacchi 	{ 0x14, 4, "rppiosev", "RP PIO Severity",
34377687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34387687d0d8SRobert Mustacchi 	{ 0x18, 4, "rppiose", "RP PIO SysError",
34397687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34407687d0d8SRobert Mustacchi 	{ 0x1c, 4, "rppioex", "RP PIO Exception",
34417687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34427687d0d8SRobert Mustacchi 	{ 0x20, 4, "rppiohl0", "RP PIO Header Log 0",
34437687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34447687d0d8SRobert Mustacchi 	{ 0x24, 4, "rppiohl1", "RP PIO Header Log 1",
34457687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34467687d0d8SRobert Mustacchi 	{ 0x28, 4, "rppiohl2", "RP PIO Header Log 2",
34477687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34487687d0d8SRobert Mustacchi 	{ 0x2c, 4, "rppiohl3", "RP PIO Header Log 3",
34497687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34507687d0d8SRobert Mustacchi 	{ 0x30, 4, "impspec", "RP PIO ImpSpec Log",
34517687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_impspec },
34527687d0d8SRobert Mustacchi 	{ 0x34, 16, "tlplog", "RP PIO TLP Prefix Log",
34537687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_tlplog },
34547687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
34557687d0d8SRobert Mustacchi };
34567687d0d8SRobert Mustacchi 
34577687d0d8SRobert Mustacchi /*
34587687d0d8SRobert Mustacchi  * Virtual Channel Capability
34597687d0d8SRobert Mustacchi  */
34607687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_cap1[] = {
34617687d0d8SRobert Mustacchi 	{ 0, 2, "count", "Extended VC Count", PRDV_HEX },
34627687d0d8SRobert Mustacchi 	{ 4, 6, "lpcount", "Low Priority Extended VC Count", PRDV_HEX },
34637687d0d8SRobert Mustacchi 	{ 8, 9, "refclk", "Reference Clock", PRDV_STRVAL,
34647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "100ns" } } },
34657687d0d8SRobert Mustacchi 	{ 10, 11, "patsz", "Port Arbitration Table Size", PRDV_STRVAL,
34667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 bit", "2 bits", "4 bits",
34677687d0d8SRobert Mustacchi 	    "8 bits" } } },
34687687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
34697687d0d8SRobert Mustacchi };
34707687d0d8SRobert Mustacchi 
34717687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_cap2[] = {
34727687d0d8SRobert Mustacchi 	{ 0, 7, "arbcap", "VC Arbitration Capability", PRDV_BITFIELD,
34737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
34747687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
34757687d0d8SRobert Mustacchi 	    "128 phase weighted round robin" } } },
34767687d0d8SRobert Mustacchi 	{ 24, 31, "offset", "VC Arbitration Table Offset", PRDV_HEX },
34777687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
34787687d0d8SRobert Mustacchi };
34797687d0d8SRobert Mustacchi 
34807687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_ctl[] = {
34817687d0d8SRobert Mustacchi 	{ 0, 0, "loadtbl", "Load VC Arbitration Table", PRDV_HEX },
34827687d0d8SRobert Mustacchi 	{ 1, 3, "arbtype", "VC Arbitration Select", PRDV_STRVAL,
34837687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
34847687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
34857687d0d8SRobert Mustacchi 	    "128 phase weighted round robin" } } },
34867687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
34877687d0d8SRobert Mustacchi };
34887687d0d8SRobert Mustacchi 
34897687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_sts[] = {
34907687d0d8SRobert Mustacchi 	{ 0, 0, "table", "VC Arbitration Table Status", PRDV_HEX },
34917687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
34927687d0d8SRobert Mustacchi };
34937687d0d8SRobert Mustacchi 
34947687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_rsrccap[] = {
34957687d0d8SRobert Mustacchi 	{ 0, 7, "arbcap", "Port Arbitration Capability", PRDV_BITFIELD,
34967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
34977687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
34987687d0d8SRobert Mustacchi 	    "128 phase weighted round robin",
34997687d0d8SRobert Mustacchi 	    "128 phase time-based weighted round robin",
35007687d0d8SRobert Mustacchi 	    "256 phase weighted round robin" } } },
35017687d0d8SRobert Mustacchi 	{ 14, 14, "aps", "Advanced Packet Switching", PRDV_STRVAL,
35027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
35037687d0d8SRobert Mustacchi 	{ 15, 15, "rstx", "Reject Snoop Transactions", PRDV_STRVAL,
35047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
35057687d0d8SRobert Mustacchi 	{ 16, 22, "nslots", "Maximum Time Slots", PRDV_HEX,
35067687d0d8SRobert Mustacchi 	    { .prdv_hex = { 0, 1 } } },
35077687d0d8SRobert Mustacchi 	{ 24, 31, "offset", "VC Arbitration Table Offset", PRDV_HEX },
35087687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35097687d0d8SRobert Mustacchi };
35107687d0d8SRobert Mustacchi 
35117687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_rsrcctl[] = {
35127687d0d8SRobert Mustacchi 	{ 0, 7, "tcmap", "TC/VC Map", PRDV_HEX },
35137687d0d8SRobert Mustacchi 	{ 16, 16, "loadtbl", "Load VC Arbitration Table", PRDV_HEX },
35147687d0d8SRobert Mustacchi 	{ 17, 19, "arbtype", "Port Arbitration Select", PRDV_STRVAL,
35157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
35167687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
35177687d0d8SRobert Mustacchi 	    "128 phase weighted round robin",
35187687d0d8SRobert Mustacchi 	    "128 phase time-based weighted round robin",
35197687d0d8SRobert Mustacchi 	    "256 phase weighted round robin" } } },
35207687d0d8SRobert Mustacchi 	{ 24, 26, "vcid", "VC ID", PRDV_HEX },
35217687d0d8SRobert Mustacchi 	{ 31, 31, "en", "VC Enable",
35227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
35237687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35247687d0d8SRobert Mustacchi };
35257687d0d8SRobert Mustacchi 
35267687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_vc_rsrcsts[] = {
35277687d0d8SRobert Mustacchi 	{ 0, 0, "table", "Port Arbitration Table Status", PRDV_HEX },
35287687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35297687d0d8SRobert Mustacchi };
35307687d0d8SRobert Mustacchi 
35317687d0d8SRobert Mustacchi static void
35327687d0d8SRobert Mustacchi pcieadm_cfgspace_print_vc_rsrc(pcieadm_cfgspace_walk_t *walkp,
35337687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
35347687d0d8SRobert Mustacchi {
35357687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
35367687d0d8SRobert Mustacchi 	uint32_t nents = BITX(cap, 2, 0) + 1;
35377687d0d8SRobert Mustacchi 
35387687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < nents; i++) {
35397687d0d8SRobert Mustacchi 		char vcshort[32], vchuman[128];
35407687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
35417687d0d8SRobert Mustacchi 
35427687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrccap%u", i);
35437687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
35447687d0d8SRobert Mustacchi 		    "Capability", i);
35457687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10;
35467687d0d8SRobert Mustacchi 		p.pcp_len = 4;
35477687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
35487687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
35497687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
35507687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrccap;
35517687d0d8SRobert Mustacchi 
35527687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
35537687d0d8SRobert Mustacchi 
35547687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrcctl%u", i);
35557687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
35567687d0d8SRobert Mustacchi 		    "Control", i);
35577687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10 + 4;
35587687d0d8SRobert Mustacchi 		p.pcp_len = 4;
35597687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
35607687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
35617687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
35627687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrcctl;
35637687d0d8SRobert Mustacchi 
35647687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
35657687d0d8SRobert Mustacchi 
35667687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrcsts%u", i);
35677687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
35687687d0d8SRobert Mustacchi 		    "Status", i);
35697687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10 + 0xa;
35707687d0d8SRobert Mustacchi 		p.pcp_len = 2;
35717687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
35727687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
35737687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
35747687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrcsts;
35757687d0d8SRobert Mustacchi 
35767687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
35777687d0d8SRobert Mustacchi 	}
35787687d0d8SRobert Mustacchi }
35797687d0d8SRobert Mustacchi 
35807687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_vc[] = {
35817687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
35827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
35837687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap1", "Port VC Capability 1",
35847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_cap1 },
35857687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap2", "Port VC Capability 2",
35867687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_cap2 },
35877687d0d8SRobert Mustacchi 	{ 0xc, 2, "ctl", "Port VC Control",
35887687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_ctl },
35897687d0d8SRobert Mustacchi 	{ 0xe, 2, "sts", "Port VC Status",
35907687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_sts },
35917687d0d8SRobert Mustacchi 	{ 0x10, 12, "vcrec", "VC Resource", pcieadm_cfgspace_print_vc_rsrc },
35927687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35937687d0d8SRobert Mustacchi };
35947687d0d8SRobert Mustacchi 
35957687d0d8SRobert Mustacchi /*
35967687d0d8SRobert Mustacchi  * HyperTransport
35977687d0d8SRobert Mustacchi  */
35987687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_intr[] = {
35997687d0d8SRobert Mustacchi 	{ 0x2, 1, "index", "Interrupt Discovery Index",
36007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
36017687d0d8SRobert Mustacchi 	{ 0x4, 4, "dataport", "Interrupt Dataport",
36027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
36037687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36047687d0d8SRobert Mustacchi };
36057687d0d8SRobert Mustacchi 
36067687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_command_pri[] = {
36077687d0d8SRobert Mustacchi 	{ 0, 4, "unitid", "Base Unit ID", PRDV_HEX },
36087687d0d8SRobert Mustacchi 	{ 5, 9, "count", "Unit Count", PRDV_HEX },
36097687d0d8SRobert Mustacchi 	{ 10, 10, "host", "Master Host", PRDV_HEX },
36107687d0d8SRobert Mustacchi 	{ 11, 11, "dir", "Default Direction", PRDV_STRVAL,
36117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "towards host",
36127687d0d8SRobert Mustacchi 	    "away from host" } } },
36137687d0d8SRobert Mustacchi 	{ 12, 12, "drop", "Drop on Uninitialized Link", PRDV_HEX },
36147687d0d8SRobert Mustacchi 	{ 13, 15, "cap", "Capability ID", PRDV_HEX },
36157687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36167687d0d8SRobert Mustacchi };
36177687d0d8SRobert Mustacchi 
36187687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_command_sec[] = {
36197687d0d8SRobert Mustacchi 	{ 0, 0, "reset", "Warm Reset", PRDV_HEX },
36207687d0d8SRobert Mustacchi 	{ 1, 1, "de", "Double Ended", PRDV_HEX },
36217687d0d8SRobert Mustacchi 	{ 2, 6, "devno", "Device Number", PRDV_HEX },
36227687d0d8SRobert Mustacchi 	{ 7, 7, "chain", "Chain Side", PRDV_STRVAL,
36237687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "from host", "from chain" } } },
36247687d0d8SRobert Mustacchi 	{ 8, 8, "hide", "Host Hide", PRDV_STRVAL,
36257687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "visible", "hidden" } } },
36267687d0d8SRobert Mustacchi 	{ 10, 10, "target", "Act as Target", PRDV_HEX },
36277687d0d8SRobert Mustacchi 	{ 11, 11, "eocerr", "Host Inbound End of Chain Error", PRDV_HEX },
36287687d0d8SRobert Mustacchi 	{ 12, 12, "drop", "Drop on Uninitialized Link", PRDV_HEX },
36297687d0d8SRobert Mustacchi 	{ 13, 15, "cap", "Capability ID", PRDV_HEX },
36307687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36317687d0d8SRobert Mustacchi };
36327687d0d8SRobert Mustacchi 
36337687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkctl[] = {
36347687d0d8SRobert Mustacchi 	{ 0, 0, "srcid", "Source ID", PRDV_STRVAL,
36357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36367687d0d8SRobert Mustacchi 	{ 1, 1, "cfl", "CRC Flood", PRDV_STRVAL,
36377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36387687d0d8SRobert Mustacchi 	{ 2, 2, "cst", "CRC Start Test", PRDV_HEX },
36397687d0d8SRobert Mustacchi 	{ 3, 3, "cfer", "CRC Force Error", PRDV_STRVAL,
36407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36417687d0d8SRobert Mustacchi 	{ 4, 4, "linkfail", "Link Failure", PRDV_HEX },
36427687d0d8SRobert Mustacchi 	{ 5, 5, "initcmp", "Initialization Complete", PRDV_HEX },
36437687d0d8SRobert Mustacchi 	{ 6, 6, "eoc", "End of Chain", PRDV_HEX },
36447687d0d8SRobert Mustacchi 	{ 7, 7, "txoff", "Transmitter Off", PRDV_STRVAL,
36457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "transmitter on",
36467687d0d8SRobert Mustacchi 	    "transmitter off" } } },
36477687d0d8SRobert Mustacchi 	{ 8, 11, "crcerr", "CRC Error", PRDV_HEX },
36487687d0d8SRobert Mustacchi 	{ 12, 12, "isoc", "Isochronous Flow Control", PRDV_STRVAL,
36497687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36507687d0d8SRobert Mustacchi 	{ 13, 13, "ls", "LDTSTOP# Tristate", PRDV_STRVAL,
36517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36527687d0d8SRobert Mustacchi 	{ 14, 14, "extctl", "Extended CTL Time", PRDV_HEX },
36537687d0d8SRobert Mustacchi 	{ 15, 15, "64b", "64-bit Addressing", PRDV_STRVAL,
36547687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36557687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36567687d0d8SRobert Mustacchi };
36577687d0d8SRobert Mustacchi 
36587687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkcfg[] = {
36597687d0d8SRobert Mustacchi 	{ 0, 2, "maxin", "Maximum Link Width In", PRDV_STRVAL,
36607687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36617687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36627687d0d8SRobert Mustacchi 	{ 3, 3, "dwfcinsup", "Doubleword Flow Control In", PRDV_STRVAL,
36637687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
36647687d0d8SRobert Mustacchi 	{ 4, 6, "maxout", "Maximum Link Width Out", PRDV_STRVAL,
36657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36667687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36677687d0d8SRobert Mustacchi 	{ 7, 7, "dwfcoutsup", "Doubleword Flow Control Out", PRDV_STRVAL,
36687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
36697687d0d8SRobert Mustacchi 	{ 8, 10, "linkin", "Link Width In", PRDV_STRVAL,
36707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36717687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36727687d0d8SRobert Mustacchi 	{ 11, 11, "dwfcin", "Doubleword Flow Control In", PRDV_STRVAL,
36737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36747687d0d8SRobert Mustacchi 	{ 12, 14, "linkout", "Link Width Out", PRDV_STRVAL,
36757687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36767687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36777687d0d8SRobert Mustacchi 	{ 15, 15, "dwfcout", "Doubleword Flow Control Out", PRDV_STRVAL,
36787687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36797687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36807687d0d8SRobert Mustacchi };
36817687d0d8SRobert Mustacchi 
36827687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_rev[] = {
36837687d0d8SRobert Mustacchi 	{ 0, 4, "minor", "Minor Revision", PRDV_HEX },
36847687d0d8SRobert Mustacchi 	{ 5, 7, "major", "Major Revision", PRDV_HEX },
36857687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36867687d0d8SRobert Mustacchi };
36877687d0d8SRobert Mustacchi 
36887687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkfreq[] = {
36897687d0d8SRobert Mustacchi 	{ 0, 4, "freq", "Link Frequency", PRDV_STRVAL,
36907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "200 MHz", "300 MHz", "400 MHz",
36917687d0d8SRobert Mustacchi 	    "500 MHz", "600 MHz", "800 MHz", "1000 MHz", "1200 MHz", "1400 MHz",
36927687d0d8SRobert Mustacchi 	    "1600 MHz", "1800 MHz", "2000 MHz", "2200 MHz", "2400 MHz",
36937687d0d8SRobert Mustacchi 	    "2600 MHz", "Vendor Specfic" } } },
36947687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36957687d0d8SRobert Mustacchi };
36967687d0d8SRobert Mustacchi 
36977687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkerr[] = {
36987687d0d8SRobert Mustacchi 	{ 4, 4, "prot", "Protocol Error", PRDV_HEX },
36997687d0d8SRobert Mustacchi 	{ 5, 5, "over", "Overflow Error", PRDV_HEX },
37007687d0d8SRobert Mustacchi 	{ 6, 6, "eoc", "End of Chain Error", PRDV_HEX },
37017687d0d8SRobert Mustacchi 	{ 7, 7, "ctl", "CTL Timeout", PRDV_HEX },
37027687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37037687d0d8SRobert Mustacchi };
37047687d0d8SRobert Mustacchi 
37057687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_linkcap[] = {
37067687d0d8SRobert Mustacchi 	{ 0, 15, "freq", "Link Frequency", PRDV_BITFIELD,
37077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "200 MHz", "300 MHz", "400 MHz",
37087687d0d8SRobert Mustacchi 	    "500 MHz", "600 MHz", "800 MHz", "1000 MHz", "1200 MHz", "1400 MHz",
37097687d0d8SRobert Mustacchi 	    "1600 MHz", "1800 MHz", "2000 MHz", "2200 MHz", "2400 MHz",
37107687d0d8SRobert Mustacchi 	    "2600 MHz", "Vendor Specfic" } } },
37117687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37127687d0d8SRobert Mustacchi };
37137687d0d8SRobert Mustacchi 
37147687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_feature[] = {
37157687d0d8SRobert Mustacchi 	{ 0, 0, "isofc", "Isochronous Flow Control", PRDV_STRVAL,
37167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37177687d0d8SRobert Mustacchi 	{ 1, 1, "ls", "LDTSTOP#", PRDV_STRVAL,
37187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37197687d0d8SRobert Mustacchi 	{ 2, 2, "crct", "CRC Test Mode", PRDV_STRVAL,
37207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37217687d0d8SRobert Mustacchi 	{ 3, 3, "ectl", "Extended CTL Time", PRDV_STRVAL,
37227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
37237687d0d8SRobert Mustacchi 	{ 4, 4, "64b", "64-bit Addressing", PRDV_STRVAL,
37247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37257687d0d8SRobert Mustacchi 	{ 5, 5, "unitid", "UnitID Reorder", PRDV_STRVAL,
37267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
37277687d0d8SRobert Mustacchi 	{ 6, 6, "srcid", "Source Identification Extension", PRDV_STRVAL,
37287687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
37297687d0d8SRobert Mustacchi 	{ 8, 8, "extreg", "Extended Register Set", PRDV_STRVAL,
37307687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37317687d0d8SRobert Mustacchi 	{ 9, 9, "uscfg", "Upstream Configuration", PRDV_STRVAL,
37327687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37337687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37347687d0d8SRobert Mustacchi };
37357687d0d8SRobert Mustacchi 
37367687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_error[] = {
37377687d0d8SRobert Mustacchi 	{ 0, 0, "protfl", "Protocol Error Flood", PRDV_STRVAL,
37387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37397687d0d8SRobert Mustacchi 	{ 1, 1, "ovfl", "Overflow Error Flood", PRDV_STRVAL,
37407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37417687d0d8SRobert Mustacchi 	{ 2, 2, "protf", "Protocol Error Fatal", PRDV_STRVAL,
37427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37437687d0d8SRobert Mustacchi 	{ 3, 3, "ovf", "Overflow Error Fatal", PRDV_STRVAL,
37447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37457687d0d8SRobert Mustacchi 	{ 4, 4, "eocf", "End of Chain Fatal Error", PRDV_STRVAL,
37467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37477687d0d8SRobert Mustacchi 	{ 5, 5, "respf", "Response Error Fatal", PRDV_STRVAL,
37487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37497687d0d8SRobert Mustacchi 	{ 6, 6, "crcf", "CRC Error Fatal", PRDV_STRVAL,
37507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37517687d0d8SRobert Mustacchi 	{ 7, 7, "sysf", "System Error Fatal", PRDV_STRVAL,
37527687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37537687d0d8SRobert Mustacchi 	{ 8, 8, "chain", "Chain Fail", PRDV_HEX },
37547687d0d8SRobert Mustacchi 	{ 9, 9, "resp", "Response Error", PRDV_HEX },
37557687d0d8SRobert Mustacchi 	{ 10, 10, "protnf", "Protocol Error Non-Fatal", PRDV_STRVAL,
37567687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37577687d0d8SRobert Mustacchi 	{ 11, 11, "ovfnf", "Overflow Error Non-Fatal", PRDV_STRVAL,
37587687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37597687d0d8SRobert Mustacchi 	{ 12, 12, "eocnf", "End of Chain Error Non-Fatal", PRDV_STRVAL,
37607687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37617687d0d8SRobert Mustacchi 	{ 13, 13, "respnf", "Response Error Non-Fatal", PRDV_STRVAL,
37627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37637687d0d8SRobert Mustacchi 	{ 14, 14, "crcnf", "CRC Error Non-Fatal", PRDV_STRVAL,
37647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37657687d0d8SRobert Mustacchi 	{ 15, 15, "sysnf", "System Error Non-Fatal", PRDV_STRVAL,
37667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37677687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37687687d0d8SRobert Mustacchi };
37697687d0d8SRobert Mustacchi 
37707687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_memory[] = {
37717687d0d8SRobert Mustacchi 	{ 0, 8, "base", "Memory Base Upper 8 Bits", PRDV_HEX,
37727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 32 } } },
37737687d0d8SRobert Mustacchi 	{ 9, 15, "limit", "Memory Limit Upper 8 Bits", PRDV_HEX,
37747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 32 } } },
37757687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37767687d0d8SRobert Mustacchi };
37777687d0d8SRobert Mustacchi 
37787687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_pri[] = {
37797687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
37807687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_command_pri },
37817687d0d8SRobert Mustacchi 	{ 0x4, 2, "linkctl0", "Link Control 0",
37827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
37837687d0d8SRobert Mustacchi 	{ 0x6, 2, "linkcfg0", "Link Configuration 0",
37847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
37857687d0d8SRobert Mustacchi 	{ 0x8, 2, "linkctl1", "Link Control 1",
37867687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
37877687d0d8SRobert Mustacchi 	{ 0xa, 2, "linkcfg1", "Link Configuration 1",
37887687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
37897687d0d8SRobert Mustacchi 	{ 0xc, 1, "rev", "Revision",
37907687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_rev },
37917687d0d8SRobert Mustacchi 	{ 0xd, 1, "linkfreq0", "Link Frequency 0",
37927687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
37937687d0d8SRobert Mustacchi 	{ 0xd, 1, "linkerr0", "Link Error 0",
37947687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
37957687d0d8SRobert Mustacchi 	{ 0xe, 2, "linkfcap0", "Link Frequency Cap 0",
37967687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
37977687d0d8SRobert Mustacchi 	{ 0x10, 1, "feature", "Feature Capability",
37987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_feature },
37997687d0d8SRobert Mustacchi 	{ 0x11, 1, "linkfreq1", "Link Frequency 1",
38007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
38017687d0d8SRobert Mustacchi 	{ 0x11, 1, "linkerr1", "Link Error 1",
38027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
38037687d0d8SRobert Mustacchi 	{ 0x12, 2, "linkfcap1", "Link Frequency Cap 1",
38047687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
38057687d0d8SRobert Mustacchi 	{ 0x14, 2, "scratch", "Enumeration Scratchpad",
38067687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
38077687d0d8SRobert Mustacchi 	{ 0x16, 2, "error", "Error Handling",
38087687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_error },
38097687d0d8SRobert Mustacchi 	{ 0x18, 2, "memory", "Memory",
38107687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_memory },
38117687d0d8SRobert Mustacchi 	{ 0x1a, 1, "bus", "Bus Number", pcieadm_cfgspace_print_hex },
38127687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38137687d0d8SRobert Mustacchi };
38147687d0d8SRobert Mustacchi 
38157687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_sec[] = {
38167687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
38177687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_command_sec },
38187687d0d8SRobert Mustacchi 	{ 0x4, 2, "linkctl", "Link Control",
38197687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
38207687d0d8SRobert Mustacchi 	{ 0x6, 2, "linkcfg", "Link Configuration",
38217687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
38227687d0d8SRobert Mustacchi 	{ 0x8, 1, "rev", "Revision",
38237687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_rev },
38247687d0d8SRobert Mustacchi 	{ 0x9, 1, "linkfreq", "Link Frequency 0",
38257687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
38267687d0d8SRobert Mustacchi 	{ 0x9, 1, "linkerr", "Link Error 0",
38277687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
38287687d0d8SRobert Mustacchi 	{ 0xa, 2, "linkfcap", "Link Frequency Cap 0",
38297687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
38307687d0d8SRobert Mustacchi 	{ 0xc, 2, "feature", "Feature Capability",
38317687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_feature },
38327687d0d8SRobert Mustacchi 	{ 0x10, 2, "scratch", "Enumeration Scratchpad",
38337687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
38347687d0d8SRobert Mustacchi 	{ 0x12, 2, "error", "Error Handling",
38357687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_error },
38367687d0d8SRobert Mustacchi 	{ 0x14, 2, "memory", "Memory",
38377687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_memory },
38387687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38397687d0d8SRobert Mustacchi };
38407687d0d8SRobert Mustacchi 
38417687d0d8SRobert Mustacchi static pcieadm_regdef_t pcieadm_regdef_ht_msi[] = {
38427687d0d8SRobert Mustacchi 	{ 0, 0, "en", "Enable", PRDV_STRVAL,
38437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
38447687d0d8SRobert Mustacchi 	{ 1, 1, "fixed", "Fixed", PRDV_STRVAL,
38457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
38467687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38477687d0d8SRobert Mustacchi };
38487687d0d8SRobert Mustacchi 
38497687d0d8SRobert Mustacchi static void
38507687d0d8SRobert Mustacchi pcieadm_cfgspace_print_ht_msi_addr(pcieadm_cfgspace_walk_t *walkp,
38517687d0d8SRobert Mustacchi     pcieadm_cfgspace_print_t *print, void *arg)
38527687d0d8SRobert Mustacchi {
38537687d0d8SRobert Mustacchi 	uint8_t fixed = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 2];
38547687d0d8SRobert Mustacchi 
38557687d0d8SRobert Mustacchi 	if (BITX(fixed, 1, 1) != 0)
38567687d0d8SRobert Mustacchi 		return;
38577687d0d8SRobert Mustacchi 
38587687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, arg);
38597687d0d8SRobert Mustacchi }
38607687d0d8SRobert Mustacchi 
38617687d0d8SRobert Mustacchi static pcieadm_cfgspace_print_t pcieadm_cap_ht_msi[] = {
38627687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
38637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_msi },
38647687d0d8SRobert Mustacchi 	{ 0x4, 8, "address", "MSI Address",
38657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_ht_msi_addr },
38667687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38677687d0d8SRobert Mustacchi };
38687687d0d8SRobert Mustacchi 
38697687d0d8SRobert Mustacchi /*
38707687d0d8SRobert Mustacchi  * Capability related tables
38717687d0d8SRobert Mustacchi  */
38727687d0d8SRobert Mustacchi typedef struct pcieadm_cap_vers {
38737687d0d8SRobert Mustacchi 	uint32_t ppr_vers;
38747687d0d8SRobert Mustacchi 	uint32_t ppr_len;
38757687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_t *ppr_print;
38767687d0d8SRobert Mustacchi } pcieadm_cap_vers_t;
38777687d0d8SRobert Mustacchi 
38787687d0d8SRobert Mustacchi typedef struct pcieadm_subcap {
38797687d0d8SRobert Mustacchi 	const char *psub_short;
38807687d0d8SRobert Mustacchi 	const char *psub_human;
38817687d0d8SRobert Mustacchi } pcieadm_subcap_t;
38827687d0d8SRobert Mustacchi 
38837687d0d8SRobert Mustacchi typedef struct pcieadm_pci_cap pcieadm_pci_cap_t;
38847687d0d8SRobert Mustacchi 
38857687d0d8SRobert Mustacchi typedef void (*pcieadm_cap_info_f)(pcieadm_cfgspace_walk_t *,
38867687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *, uint32_t, const pcieadm_cap_vers_t **,
38877687d0d8SRobert Mustacchi     uint32_t *, const pcieadm_subcap_t **);
38887687d0d8SRobert Mustacchi 
38897687d0d8SRobert Mustacchi struct pcieadm_pci_cap {
38907687d0d8SRobert Mustacchi 	uint32_t ppc_id;
38917687d0d8SRobert Mustacchi 	const char *ppc_short;
38927687d0d8SRobert Mustacchi 	const char *ppc_human;
38937687d0d8SRobert Mustacchi 	pcieadm_cap_info_f ppc_info;
38947687d0d8SRobert Mustacchi 	pcieadm_cap_vers_t ppc_vers[4];
38957687d0d8SRobert Mustacchi };
38967687d0d8SRobert Mustacchi 
38977687d0d8SRobert Mustacchi /*
38987687d0d8SRobert Mustacchi  * Capability version determinations.
38997687d0d8SRobert Mustacchi  */
39007687d0d8SRobert Mustacchi 
39017687d0d8SRobert Mustacchi static void
39027687d0d8SRobert Mustacchi pcieadm_cap_info_fixed(pcieadm_cfgspace_walk_t *walkp,
39037687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
39047687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
39057687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
39067687d0d8SRobert Mustacchi {
39077687d0d8SRobert Mustacchi 	*versp = &cap->ppc_vers[0];
39087687d0d8SRobert Mustacchi 	*lenp = cap->ppc_vers[0].ppr_len;
39097687d0d8SRobert Mustacchi 	*subcap = NULL;
39107687d0d8SRobert Mustacchi }
39117687d0d8SRobert Mustacchi 
39127687d0d8SRobert Mustacchi static void
39137687d0d8SRobert Mustacchi pcieadm_cap_info_vers(pcieadm_cfgspace_walk_t *walkp,
39147687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
39157687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
39167687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
39177687d0d8SRobert Mustacchi {
39187687d0d8SRobert Mustacchi 	uint8_t vers;
39197687d0d8SRobert Mustacchi 
39207687d0d8SRobert Mustacchi 	*subcap = NULL;
39217687d0d8SRobert Mustacchi 	vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
39227687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < ARRAY_SIZE(cap->ppc_vers); i++) {
39237687d0d8SRobert Mustacchi 		if (vers == cap->ppc_vers[i].ppr_vers &&
39247687d0d8SRobert Mustacchi 		    cap->ppc_vers[i].ppr_vers != 0) {
39257687d0d8SRobert Mustacchi 			*versp = &cap->ppc_vers[i];
39267687d0d8SRobert Mustacchi 			*lenp = cap->ppc_vers[i].ppr_len;
39277687d0d8SRobert Mustacchi 			return;
39287687d0d8SRobert Mustacchi 		}
39297687d0d8SRobert Mustacchi 	}
39307687d0d8SRobert Mustacchi 
39317687d0d8SRobert Mustacchi 	*versp = NULL;
39327687d0d8SRobert Mustacchi 	*lenp = 0;
39337687d0d8SRobert Mustacchi }
39347687d0d8SRobert Mustacchi 
39357687d0d8SRobert Mustacchi /*
39367687d0d8SRobert Mustacchi  * The PCI Power Management capability uses a 3-bit version ID as opposed to the
39377687d0d8SRobert Mustacchi  * standard 4-bit version.
39387687d0d8SRobert Mustacchi  */
39397687d0d8SRobert Mustacchi static void
39407687d0d8SRobert Mustacchi pcieadm_cap_info_pcipm(pcieadm_cfgspace_walk_t *walkp,
39417687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
39427687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
39437687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
39447687d0d8SRobert Mustacchi {
39457687d0d8SRobert Mustacchi 	uint8_t vers;
39467687d0d8SRobert Mustacchi 
39477687d0d8SRobert Mustacchi 	*subcap = NULL;
39487687d0d8SRobert Mustacchi 	vers = walkp->pcw_data->pcb_u8[off + 2] & 0x7;
39497687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < ARRAY_SIZE(cap->ppc_vers); i++) {
39507687d0d8SRobert Mustacchi 		if (vers == cap->ppc_vers[i].ppr_vers) {
39517687d0d8SRobert Mustacchi 			*versp = &cap->ppc_vers[i];
39527687d0d8SRobert Mustacchi 			*lenp = cap->ppc_vers[i].ppr_len;
39537687d0d8SRobert Mustacchi 			return;
39547687d0d8SRobert Mustacchi 		}
39557687d0d8SRobert Mustacchi 	}
39567687d0d8SRobert Mustacchi 
39577687d0d8SRobert Mustacchi 	*versp = NULL;
39587687d0d8SRobert Mustacchi 	*lenp = 0;
39597687d0d8SRobert Mustacchi }
39607687d0d8SRobert Mustacchi 
3961bc729d49SRobert Mustacchi /*
3962bc729d49SRobert Mustacchi  * The PCIe capability underwent a few changes. In version 1 of the capability,
3963bc729d49SRobert Mustacchi  * devices were not required to implement the entire capability. In particular,
3964bc729d49SRobert Mustacchi  * endpoints did not need to implement anything more than the link status
3965bc729d49SRobert Mustacchi  * register. In the v2 capability, this was changed such that all devices had to
3966bc729d49SRobert Mustacchi  * implement the entire capbility, but otherwise hardcode registers to zero. As
3967bc729d49SRobert Mustacchi  * such we get to play guess the length based on the device type.
3968bc729d49SRobert Mustacchi  */
3969bc729d49SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_dev = {
3970bc729d49SRobert Mustacchi 	1, 0x0c, pcieadm_cap_pcie_v1_dev
3971bc729d49SRobert Mustacchi };
3972bc729d49SRobert Mustacchi 
3973bc729d49SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_link = {
3974bc729d49SRobert Mustacchi 	1, 0x14, pcieadm_cap_pcie_v1_link
3975bc729d49SRobert Mustacchi };
3976bc729d49SRobert Mustacchi 
3977bc729d49SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_slot = {
3978bc729d49SRobert Mustacchi 	1, 0x1c, pcieadm_cap_pcie_v1_slot
3979bc729d49SRobert Mustacchi };
3980bc729d49SRobert Mustacchi 
3981bc729d49SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_all = {
3982bc729d49SRobert Mustacchi 	1, 0x24, pcieadm_cap_pcie_v1_all
3983bc729d49SRobert Mustacchi };
3984bc729d49SRobert Mustacchi 
3985bc729d49SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v2 = {
3986bc729d49SRobert Mustacchi 	2, 0x4c, pcieadm_cap_pcie_v2
3987bc729d49SRobert Mustacchi };
3988bc729d49SRobert Mustacchi 
3989bc729d49SRobert Mustacchi static void
3990bc729d49SRobert Mustacchi pcieadm_cap_info_pcie(pcieadm_cfgspace_walk_t *walkp,
3991bc729d49SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
3992bc729d49SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
3993bc729d49SRobert Mustacchi     const pcieadm_subcap_t **subcap)
3994bc729d49SRobert Mustacchi {
3995bc729d49SRobert Mustacchi 	uint8_t vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
3996bc729d49SRobert Mustacchi 	uint16_t pcie = walkp->pcw_data->pcb_u8[off + 2] |
3997bc729d49SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[off + 3] << 8);
3998bc729d49SRobert Mustacchi 
3999bc729d49SRobert Mustacchi 	/*
4000bc729d49SRobert Mustacchi 	 * Version 2 is simple. There's only one thing to do, so we do it. For
4001bc729d49SRobert Mustacchi 	 * version 1 we need to look at the device type.
4002bc729d49SRobert Mustacchi 	 */
4003bc729d49SRobert Mustacchi 	*subcap = NULL;
4004bc729d49SRobert Mustacchi 	if (vers == 2) {
4005bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v2;
4006bc729d49SRobert Mustacchi 		*lenp = (*versp)->ppr_len;
4007bc729d49SRobert Mustacchi 		return;
4008bc729d49SRobert Mustacchi 	} else if (vers != 1) {
4009bc729d49SRobert Mustacchi 		*versp = NULL;
4010bc729d49SRobert Mustacchi 		*lenp = 0;
4011bc729d49SRobert Mustacchi 		return;
4012bc729d49SRobert Mustacchi 	}
4013bc729d49SRobert Mustacchi 
4014bc729d49SRobert Mustacchi 	switch (pcie & PCIE_PCIECAP_DEV_TYPE_MASK) {
4015bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCIE_DEV:
4016bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCI_DEV:
4017bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v1_link;
4018bc729d49SRobert Mustacchi 		break;
4019bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_RC_IEP:
4020bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v1_dev;
4021bc729d49SRobert Mustacchi 		break;
4022bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_UP:
4023bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_DOWN:
4024bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCIE2PCI:
4025bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCI2PCIE:
4026bc729d49SRobert Mustacchi 		if ((pcie & PCIE_PCIECAP_SLOT_IMPL) != 0) {
4027bc729d49SRobert Mustacchi 			*versp = &pcieadm_cap_vers_pcie_v1_slot;
4028bc729d49SRobert Mustacchi 		} else {
4029bc729d49SRobert Mustacchi 			*versp = &pcieadm_cap_vers_pcie_v1_link;
4030bc729d49SRobert Mustacchi 		}
4031bc729d49SRobert Mustacchi 		break;
4032bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_ROOT:
4033bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_RC_EC:
4034bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v1_all;
4035bc729d49SRobert Mustacchi 		break;
4036bc729d49SRobert Mustacchi 	default:
4037bc729d49SRobert Mustacchi 		*versp = NULL;
4038bc729d49SRobert Mustacchi 		*lenp = 0;
4039bc729d49SRobert Mustacchi 		return;
4040bc729d49SRobert Mustacchi 	}
4041bc729d49SRobert Mustacchi 
4042bc729d49SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
4043bc729d49SRobert Mustacchi }
4044bc729d49SRobert Mustacchi 
40457687d0d8SRobert Mustacchi /*
40467687d0d8SRobert Mustacchi  * The length of the MSI capability depends on bits in its control field. As
40477687d0d8SRobert Mustacchi  * such we use a custom function to extract the length and treat each of these
40487687d0d8SRobert Mustacchi  * variants as thought it were a different version.
40497687d0d8SRobert Mustacchi  */
40507687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32 = {
40517687d0d8SRobert Mustacchi 	0, 0xa, pcieadm_cap_msi_32
40527687d0d8SRobert Mustacchi };
40537687d0d8SRobert Mustacchi 
40547687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32ext = {
40557687d0d8SRobert Mustacchi 	0, 0xc, pcieadm_cap_msi_32ext
40567687d0d8SRobert Mustacchi };
40577687d0d8SRobert Mustacchi 
40587687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64 = {
40597687d0d8SRobert Mustacchi 	0, 0xe, pcieadm_cap_msi_64
40607687d0d8SRobert Mustacchi };
40617687d0d8SRobert Mustacchi 
40627687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64ext = {
40637687d0d8SRobert Mustacchi 	0, 0x10, pcieadm_cap_msi_64ext
40647687d0d8SRobert Mustacchi };
40657687d0d8SRobert Mustacchi 
40667687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32pvm = {
40677687d0d8SRobert Mustacchi 	0, 0x14, pcieadm_cap_msi_32pvm
40687687d0d8SRobert Mustacchi };
40697687d0d8SRobert Mustacchi 
40707687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64pvm = {
40717687d0d8SRobert Mustacchi 	0, 0x18, pcieadm_cap_msi_64pvm
40727687d0d8SRobert Mustacchi };
40737687d0d8SRobert Mustacchi 
40747687d0d8SRobert Mustacchi static void
40757687d0d8SRobert Mustacchi pcieadm_cap_info_msi(pcieadm_cfgspace_walk_t *walkp,
40767687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
40777687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
40787687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
40797687d0d8SRobert Mustacchi {
40807687d0d8SRobert Mustacchi 	uint16_t ctrl;
40817687d0d8SRobert Mustacchi 	boolean_t addr64, pvm, ext;
40827687d0d8SRobert Mustacchi 
40837687d0d8SRobert Mustacchi 	*subcap = NULL;
40847687d0d8SRobert Mustacchi 	ctrl = walkp->pcw_data->pcb_u8[off + 2] |
40857687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[off + 3] << 8);
40867687d0d8SRobert Mustacchi 	if (ctrl == PCI_EINVAL16) {
40877687d0d8SRobert Mustacchi 		warnx("failed to read MSI Message Control register");
40887687d0d8SRobert Mustacchi 		*lenp = 0;
40897687d0d8SRobert Mustacchi 		*versp = NULL;
40907687d0d8SRobert Mustacchi 		return;
40917687d0d8SRobert Mustacchi 	}
40927687d0d8SRobert Mustacchi 
40937687d0d8SRobert Mustacchi 	/*
40947687d0d8SRobert Mustacchi 	 * The MSI capability has three main things that control its size.
40957687d0d8SRobert Mustacchi 	 * 64-bit addressing adds 4 bytes. Per-Vector Masking adds 8 bytes and
40967687d0d8SRobert Mustacchi 	 * causes the Extended data addressing piece to always be present.
40977687d0d8SRobert Mustacchi 	 * Therefore we check first for pvm as it implies evt, effectively.
40987687d0d8SRobert Mustacchi 	 */
40997687d0d8SRobert Mustacchi 	addr64 = (ctrl & PCI_MSI_64BIT_MASK) != 0;
41007687d0d8SRobert Mustacchi 	pvm = (ctrl & PCI_MSI_PVM_MASK) != 0;
41017687d0d8SRobert Mustacchi 	ext = (ctrl & PCI_MSI_EMD_MASK) != 0;
41027687d0d8SRobert Mustacchi 
41037687d0d8SRobert Mustacchi 	if (pvm && addr64) {
41047687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64pvm;
41057687d0d8SRobert Mustacchi 	} else if (pvm) {
41067687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32pvm;
41077687d0d8SRobert Mustacchi 	} else if (addr64 && ext) {
41087687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64ext;
41097687d0d8SRobert Mustacchi 	} else if (addr64) {
41107687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64;
41117687d0d8SRobert Mustacchi 	} else if (ext) {
41127687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32ext;
41137687d0d8SRobert Mustacchi 	} else {
41147687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32;
41157687d0d8SRobert Mustacchi 	}
41167687d0d8SRobert Mustacchi 
41177687d0d8SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
41187687d0d8SRobert Mustacchi }
41197687d0d8SRobert Mustacchi 
41207687d0d8SRobert Mustacchi /*
41217687d0d8SRobert Mustacchi  * The AER Capability is technically different for PCIe-PCI bridges. If we find
41227687d0d8SRobert Mustacchi  * that device type here, then we need to use a different version information
41237687d0d8SRobert Mustacchi  * rather than the actual set defined with the device (which have changed over
41247687d0d8SRobert Mustacchi  * time).
41257687d0d8SRobert Mustacchi  */
41267687d0d8SRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_aer_bridge = {
41277687d0d8SRobert Mustacchi 	1, 0x4c, pcieadm_cap_aer_bridge
41287687d0d8SRobert Mustacchi };
41297687d0d8SRobert Mustacchi 
41307687d0d8SRobert Mustacchi static void
41317687d0d8SRobert Mustacchi pcieadm_cap_info_aer(pcieadm_cfgspace_walk_t *walkp,
41327687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
41337687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
41347687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
41357687d0d8SRobert Mustacchi {
4136bc729d49SRobert Mustacchi 	if (walkp->pcw_pcietype == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
41377687d0d8SRobert Mustacchi 		uint8_t vers;
41387687d0d8SRobert Mustacchi 
41397687d0d8SRobert Mustacchi 		*subcap = NULL;
41407687d0d8SRobert Mustacchi 		vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
41417687d0d8SRobert Mustacchi 		if (vers != pcieadm_cap_vers_aer_bridge.ppr_vers) {
41427687d0d8SRobert Mustacchi 			warnx("encountered PCIe to PCI bridge with unknown "
41437687d0d8SRobert Mustacchi 			    "AER capability version: %u", vers);
41447687d0d8SRobert Mustacchi 			*lenp = 0;
41457687d0d8SRobert Mustacchi 			*versp = NULL;
41467687d0d8SRobert Mustacchi 			return;
41477687d0d8SRobert Mustacchi 		}
41487687d0d8SRobert Mustacchi 		*lenp = pcieadm_cap_vers_aer_bridge.ppr_len;
41497687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_aer_bridge;
41507687d0d8SRobert Mustacchi 	}
41517687d0d8SRobert Mustacchi 
41527687d0d8SRobert Mustacchi 	return (pcieadm_cap_info_vers(walkp, cap, off, versp, lenp, subcap));
41537687d0d8SRobert Mustacchi }
41547687d0d8SRobert Mustacchi 
41557687d0d8SRobert Mustacchi /*
41567687d0d8SRobert Mustacchi  * The PCI-X capability varies depending on the header type of the device.
41577687d0d8SRobert Mustacchi  * Therefore we simply use the device type to figure out what to do.
41587687d0d8SRobert Mustacchi  */
41597687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcix_dev = {
41607687d0d8SRobert Mustacchi 	0, 0x8, pcieadm_cap_pcix_dev
41617687d0d8SRobert Mustacchi };
41627687d0d8SRobert Mustacchi 
41637687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcix_bridge = {
41647687d0d8SRobert Mustacchi 	0, 0x10, pcieadm_cap_pcix_bridge
41657687d0d8SRobert Mustacchi };
41667687d0d8SRobert Mustacchi 
41677687d0d8SRobert Mustacchi static void
41687687d0d8SRobert Mustacchi pcieadm_cap_info_pcix(pcieadm_cfgspace_walk_t *walkp,
41697687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
41707687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
41717687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
41727687d0d8SRobert Mustacchi {
41737687d0d8SRobert Mustacchi 
41747687d0d8SRobert Mustacchi 	*subcap = NULL;
41757687d0d8SRobert Mustacchi 	switch (walkp->pcw_dtype) {
41767687d0d8SRobert Mustacchi 	case PCI_HEADER_ZERO:
41777687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcix_dev;
41787687d0d8SRobert Mustacchi 		break;
41797687d0d8SRobert Mustacchi 	case PCI_HEADER_ONE:
41807687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcix_bridge;
41817687d0d8SRobert Mustacchi 		break;
41827687d0d8SRobert Mustacchi 	default:
41837687d0d8SRobert Mustacchi 		warnx("encountered PCI-X capability with unsupported device "
41847687d0d8SRobert Mustacchi 		    "type: 0x%x\n", walkp->pcw_dtype);
41857687d0d8SRobert Mustacchi 		*lenp = 0;
41867687d0d8SRobert Mustacchi 		*versp = NULL;
41877687d0d8SRobert Mustacchi 		return;
41887687d0d8SRobert Mustacchi 	}
41897687d0d8SRobert Mustacchi 
41907687d0d8SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
41917687d0d8SRobert Mustacchi }
41927687d0d8SRobert Mustacchi 
41937687d0d8SRobert Mustacchi typedef struct pcieadm_cap_ht {
41947687d0d8SRobert Mustacchi 	uint32_t pch_capid;
41957687d0d8SRobert Mustacchi 	pcieadm_subcap_t pch_subcap;
41967687d0d8SRobert Mustacchi 	pcieadm_cap_vers_t pch_vers;
41977687d0d8SRobert Mustacchi } pcieadm_cap_ht_t;
41987687d0d8SRobert Mustacchi 
41997687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_cap_pri = {
42007687d0d8SRobert Mustacchi 	0x00, { "pri", "Primary" }, { 0, 0x1c, pcieadm_cap_ht_pri }
42017687d0d8SRobert Mustacchi };
42027687d0d8SRobert Mustacchi 
42037687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_cap_sec = {
42047687d0d8SRobert Mustacchi 	0x01, { "sec", "Secondary" }, { 0, 0x18, pcieadm_cap_ht_sec }
42057687d0d8SRobert Mustacchi };
42067687d0d8SRobert Mustacchi 
42077687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_caps[] = {
42087687d0d8SRobert Mustacchi 	{ 0x08, { "switch", "Switch" } },
42097687d0d8SRobert Mustacchi 	{ 0x10, { "intr", "Interrupt Discovery and Configuration" },
42107687d0d8SRobert Mustacchi 	    { 0, 8, pcieadm_cap_ht_intr } },
42117687d0d8SRobert Mustacchi 	{ 0x11, { "rev", "Revision ID" } },
42127687d0d8SRobert Mustacchi 	{ 0x12, { "unitid", "UnitID Clumping" } },
42137687d0d8SRobert Mustacchi 	{ 0x13, { "extcfg", "Extended Configuration Space Access" } },
42147687d0d8SRobert Mustacchi 	{ 0x14, { "addrmap", "Address Mapping" } },
42157687d0d8SRobert Mustacchi 	{ 0x15, { "msi", "MSI Mapping" },
42167687d0d8SRobert Mustacchi 	    { 0, 4, pcieadm_cap_ht_msi } },
42177687d0d8SRobert Mustacchi 	{ 0x16, { "dir", "DirectRoute" } },
42187687d0d8SRobert Mustacchi 	{ 0x17, { "vcset", "VCSet" } },
42197687d0d8SRobert Mustacchi 	{ 0x18, { "retry", "Retry Mode" } },
42207687d0d8SRobert Mustacchi 	{ 0x19, { "x86", "X86 Encoding" } },
42217687d0d8SRobert Mustacchi 	{ 0x1a, { "gen3", "Gen3" } },
42227687d0d8SRobert Mustacchi 	{ 0x1b, { "fle", "Function-Level Extension" } },
42237687d0d8SRobert Mustacchi 	{ 0x1c, { "pm", "Power Management" } },
42247687d0d8SRobert Mustacchi 	{ UINT32_MAX, NULL },
42257687d0d8SRobert Mustacchi };
42267687d0d8SRobert Mustacchi 
42277687d0d8SRobert Mustacchi static void
42287687d0d8SRobert Mustacchi pcieadm_cap_info_ht(pcieadm_cfgspace_walk_t *walkp,
42297687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
42307687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
42317687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
42327687d0d8SRobert Mustacchi {
42337687d0d8SRobert Mustacchi 	uint32_t base = walkp->pcw_data->pcb_u32[off / 4];
42347687d0d8SRobert Mustacchi 	uint32_t caplo = BITX(base, 31, 29);
42357687d0d8SRobert Mustacchi 	pcieadm_cap_ht_t *htcap = NULL;
42367687d0d8SRobert Mustacchi 
42377687d0d8SRobert Mustacchi 	*versp = NULL;
42387687d0d8SRobert Mustacchi 	*lenp = 0;
42397687d0d8SRobert Mustacchi 	*subcap = NULL;
42407687d0d8SRobert Mustacchi 
42417687d0d8SRobert Mustacchi 	if (caplo > 1) {
42427687d0d8SRobert Mustacchi 		uint32_t capid = BITX(base, 31, 27);
42437687d0d8SRobert Mustacchi 
42447687d0d8SRobert Mustacchi 		for (uint32_t i = 0; pcieadm_ht_caps[i].pch_capid != UINT32_MAX;
42457687d0d8SRobert Mustacchi 		    i++) {
42467687d0d8SRobert Mustacchi 			if (capid == pcieadm_ht_caps[i].pch_capid) {
42477687d0d8SRobert Mustacchi 				htcap = &pcieadm_ht_caps[i];
42487687d0d8SRobert Mustacchi 				break;
42497687d0d8SRobert Mustacchi 			}
42507687d0d8SRobert Mustacchi 		}
42517687d0d8SRobert Mustacchi 	} else if (caplo == 0) {
42527687d0d8SRobert Mustacchi 		htcap = &pcieadm_ht_cap_pri;
42537687d0d8SRobert Mustacchi 	} else if (caplo == 1) {
42547687d0d8SRobert Mustacchi 		htcap = &pcieadm_ht_cap_sec;
42557687d0d8SRobert Mustacchi 	}
42567687d0d8SRobert Mustacchi 
42577687d0d8SRobert Mustacchi 	if (htcap == NULL) {
42587687d0d8SRobert Mustacchi 		warnx("encountered unknown HyperTransport Capability 0x%x",
42597687d0d8SRobert Mustacchi 		    BITX(base, 31, 27));
42607687d0d8SRobert Mustacchi 		return;
42617687d0d8SRobert Mustacchi 	}
42627687d0d8SRobert Mustacchi 
42637687d0d8SRobert Mustacchi 	*subcap = &htcap->pch_subcap;
42647687d0d8SRobert Mustacchi 	if (htcap->pch_vers.ppr_print != NULL) {
42657687d0d8SRobert Mustacchi 		*versp = &htcap->pch_vers;
42667687d0d8SRobert Mustacchi 		*lenp = htcap->pch_vers.ppr_len;
42677687d0d8SRobert Mustacchi 	}
42687687d0d8SRobert Mustacchi }
42697687d0d8SRobert Mustacchi 
42707687d0d8SRobert Mustacchi pcieadm_pci_cap_t pcieadm_pci_caps[] = {
42717687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PM, "pcipm", "PCI Power Management",
42727687d0d8SRobert Mustacchi 	    pcieadm_cap_info_pcipm, { { 2, 8, pcieadm_cap_pcipm_v3 },
42737687d0d8SRobert Mustacchi 	    { 3, 8, pcieadm_cap_pcipm_v3 } } },
42747687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_AGP, "agp", "Accelerated Graphics Port" },
42757687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_VPD, "vpd", "Vital Product Data", pcieadm_cap_info_fixed,
42767687d0d8SRobert Mustacchi 	    { { 0, 8, pcieadm_cap_vpd } } },
42777687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SLOT_ID, "slot", "Slot Identification" },
42787687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_MSI, "msi", "Message Signaled Interrupts",
42797687d0d8SRobert Mustacchi 	    pcieadm_cap_info_msi },
42807687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_cPCI_HS, "cpci", "CompactPCI Hot Swap" },
42817687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PCIX, "pcix", "PCI-X", pcieadm_cap_info_pcix },
42827687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_HT, "ht", "HyperTransport", pcieadm_cap_info_ht },
42837687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_VS, "vs", "Vendor Specific", pcieadm_cap_info_fixed,
42847687d0d8SRobert Mustacchi 	    { { 0, 3, pcieadm_cap_vs } } },
42857687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_DEBUG_PORT, "dbg", "Debug Port", pcieadm_cap_info_fixed,
42867687d0d8SRobert Mustacchi 	    { { 0, 4, pcieadm_cap_debug } } },
42877687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_cPCI_CRC, "cpcicrc",
42887687d0d8SRobert Mustacchi 	    "CompactPCI Central Resource Control" },
42897687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PCI_HOTPLUG, "pcihp", "PCI Hot-Plug" },
42907687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_P2P_SUBSYS, "bdgsub", "PCI Bridge Subsystem Vendor ID",
42917687d0d8SRobert Mustacchi 	    pcieadm_cap_info_fixed, { 0, 8, pcieadm_cap_bridge_subsys } },
42927687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_AGP_8X, "agp8x", "AGP 8x" },
42937687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SECURE_DEV, "secdev", "Secure Device" },
4294bc729d49SRobert Mustacchi 	{ PCI_CAP_ID_PCI_E, "pcie", "PCI Express", pcieadm_cap_info_pcie },
42957687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_MSI_X, "msix", "MSI-X", pcieadm_cap_info_fixed,
42967687d0d8SRobert Mustacchi 	    { { 0, 12, pcieadm_cap_msix } } },
42977687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SATA, "sata", "Serial ATA Configuration",
42987687d0d8SRobert Mustacchi 	    pcieadm_cap_info_fixed, { { 0, 8, pcieadm_cap_sata } } },
42997687d0d8SRobert Mustacchi 	/*
43007687d0d8SRobert Mustacchi 	 * Note, the AF feature doesn't have a version but encodes a length in
43017687d0d8SRobert Mustacchi 	 * the version field, so we cheat and use that.
43027687d0d8SRobert Mustacchi 	 */
43037687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_FLR, "af", "Advanced Features", pcieadm_cap_info_vers,
43047687d0d8SRobert Mustacchi 	    { { 6, 6, pcieadm_cap_af } } },
43057687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_EA, "ea", "Enhanced Allocation" },
43067687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_FPB, "fpb", "Flattening Portal Bridge" }
43077687d0d8SRobert Mustacchi };
43087687d0d8SRobert Mustacchi 
43097687d0d8SRobert Mustacchi pcieadm_pci_cap_t pcieadm_pcie_caps[] = {
43107687d0d8SRobert Mustacchi 	{ 0, "null", "NULL Capability", pcieadm_cap_info_fixed,
43117687d0d8SRobert Mustacchi 	    { { 0, 0x4, pcieadm_cap_null } } },
43127687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_AER, "aer", "Advanced Error Reporting",
43137687d0d8SRobert Mustacchi 	    pcieadm_cap_info_aer, { { 1, 0x38, pcieadm_cap_aer_v1 },
43147687d0d8SRobert Mustacchi 	    { 2, 0x48, pcieadm_cap_aer_v2 } } },
43157687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VC, "vc", "Virtual Channel", pcieadm_cap_info_vers,
43167687d0d8SRobert Mustacchi 	    { { 0x1, 0x1c, pcieadm_cap_vc } } },
43177687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SER, "sn", "Serial Number", pcieadm_cap_info_vers,
43187687d0d8SRobert Mustacchi 	    { { 1, 0xc, pcieadm_cap_sn } } },
43197687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PWR_BUDGET, "powbudg", "Power Budgeting",
43207687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_powbudg } } },
43217687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_LINK_DECL, "rcld",
43227687d0d8SRobert Mustacchi 	    "Root Complex Link Declaration" },
43237687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_INT_LINKCTRL, "rcilc",
43247687d0d8SRobert Mustacchi 	    "Root Complex Internal Link Control" },
43257687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_EVNT_CEA, "rcecea",
43267687d0d8SRobert Mustacchi 	    "Root Complex Event Collector Endpoint Aggregation" },
43277687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MFVC, "mfvc", "Multi-Function Virtual Channel" },
43287687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VC_WITH_MFVC, "vcwmfvc", "Virtual Channel with MFVC",
43297687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 0x1, 0x1c, pcieadm_cap_vc } } },
43307687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RCRB, "rcrb", "Root Complex Register Block" },
43317687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VS, "vsec", "Vendor Specific Extended Capability",
43327687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_vsec } } },
43337687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_CAC, "cac", "Configuration Access Correlation" },
43347687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ACS, "acs", "Access Control Services",
43357687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_acs } } },
43367687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ARI, "ari", "Alternative Routing-ID Interpretation",
43377687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ari } } },
43387687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ATS, "ats", "Access Translation Services",
43397687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ats } } },
43407687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SRIOV, "sriov", "Single Root I/O Virtualization",
43417687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x40, pcieadm_cap_sriov } } },
43427687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MRIOV, "mriov", "Multi-Root I/O Virtualization" },
43437687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MULTICAST, "mcast", "Multicast",
43447687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x30, pcieadm_cap_mcast } } },
43457687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PGREQ, "pgreq", "Page Request",
43467687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_pgreq } } },
43477687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_EA, "ea", "Enhanced Allocation" },
43487687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RESIZE_BAR, "rbar", "Resizable Bar" },
43497687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DPA, "dpa", "Dynamic Power Allocation",
43507687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_dpa } } },
43517687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_TPH_REQ, "tph", "TPH Requester",
43527687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_tph } } },
43537687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LTR, "ltr", "Latency Tolerance Reporting",
43547687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ltr } } },
43557687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PCIE2, "pcie2", "Secondary PCI Express",
43567687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_pcie2 } } },
43577687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PASID, "pasid", "Process Address Space ID",
43587687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_pasid } } },
43597687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LNR, "lnr", "LN Requester" },
43607687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DPC, "dpc", "Downstream Port Containment",
43617687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x30, pcieadm_cap_dpc } } },
43627687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_L1PM, "l1pm", "L1 PM Substates",
43637687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_l1pm_v1 },
43647687d0d8SRobert Mustacchi 	    { 2, 0x14, pcieadm_cap_l1pm_v2 } } },
43657687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PTM, "ptm", "Precision Time Management",
43667687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_info_ptm } } },
43677687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FRS, "frs", "FRS Queueing" },
43687687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RTR, "trt", "Readiness Time Reporting" },
43697687d0d8SRobert Mustacchi 	/*
4370e6d654ccSRobert Mustacchi 	 * When we encounter a designated vendor specification, in particular,
43717687d0d8SRobert Mustacchi 	 * for CXL, we'll want to set ppc_subcap so we can use reasonable
43727687d0d8SRobert Mustacchi 	 * filtering.
43737687d0d8SRobert Mustacchi 	 */
43747687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DVS, "dvsec",
43757687d0d8SRobert Mustacchi 	    "Designated Vendor-Specific Extended Capability" },
43767687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VFRBAR, "vfrbar", "Virtual Function Resizable BAR" },
43777687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DLF, "dlf", "Data Link Feature",
43787687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_dlf } } },
43797687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL16GT, "pl16g", "Physical Layer 16.0 GT/s",
43807687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x22, pcieadm_cap_16g } } },
43817687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LANE_MARGIN, "margin",
43827687d0d8SRobert Mustacchi 	    "Lane Margining at the Receiver", pcieadm_cap_info_vers,
43837687d0d8SRobert Mustacchi 	    { { 1, 0x8, pcieadm_cap_margin } } },
43847687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_HIEARCHY_ID, "hierid", "Hierarchy ID" },
43857687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_NPEM, "npem", "Native PCIe Enclosure Management" },
43867687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL32GT, "pl32g", "Physical Layer 32.0 GT/s" },
43877687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_AP, "ap", "Alternative Protocol" },
438893260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SFI, "sfi", "System Firmware Intermediary" },
438993260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SHDW_FUNC, "sfunc", "Shadow Functions" },
439093260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DOE, "doe", "Data Object Exchange" },
439193260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DEV3, "dev3", "Device 3" },
4392e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_IDE, "ide", "Integrity and Data Encryption" },
4393e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL64GT, "pl64g", "Physical Layer 64.0 GT/s" },
4394e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FLIT_LOG, "fltlog", "Flit Logging" },
4395e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FLIT_PERF, "fltperf",
4396e6d654ccSRobert Mustacchi 	    "Flit Performance Measurement" },
4397e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FLIT_ERR, "flterr", "Flit Error Injection" }
43987687d0d8SRobert Mustacchi };
43997687d0d8SRobert Mustacchi 
44007687d0d8SRobert Mustacchi static const pcieadm_pci_cap_t *
44017687d0d8SRobert Mustacchi pcieadm_cfgspace_match_cap(uint32_t capid, boolean_t pcie)
44027687d0d8SRobert Mustacchi {
44037687d0d8SRobert Mustacchi 	uint_t ncaps;
44047687d0d8SRobert Mustacchi 	pcieadm_pci_cap_t *caps;
44057687d0d8SRobert Mustacchi 
44067687d0d8SRobert Mustacchi 	if (pcie) {
44077687d0d8SRobert Mustacchi 		ncaps = ARRAY_SIZE(pcieadm_pcie_caps);
44087687d0d8SRobert Mustacchi 		caps = pcieadm_pcie_caps;
44097687d0d8SRobert Mustacchi 	} else {
44107687d0d8SRobert Mustacchi 		ncaps = ARRAY_SIZE(pcieadm_pci_caps);
44117687d0d8SRobert Mustacchi 		caps = pcieadm_pci_caps;
44127687d0d8SRobert Mustacchi 	}
44137687d0d8SRobert Mustacchi 
44147687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < ncaps; i++) {
44157687d0d8SRobert Mustacchi 		if (caps[i].ppc_id == capid) {
44167687d0d8SRobert Mustacchi 			return (&caps[i]);
44177687d0d8SRobert Mustacchi 		}
44187687d0d8SRobert Mustacchi 	}
44197687d0d8SRobert Mustacchi 
44207687d0d8SRobert Mustacchi 	return (NULL);
44217687d0d8SRobert Mustacchi }
44227687d0d8SRobert Mustacchi 
44237687d0d8SRobert Mustacchi static void
44247687d0d8SRobert Mustacchi pcieadm_cfgspace_print_cap(pcieadm_cfgspace_walk_t *walkp, uint_t capid,
44257687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap_info, const pcieadm_cap_vers_t *vers_info,
44267687d0d8SRobert Mustacchi     const pcieadm_subcap_t *subcap)
44277687d0d8SRobert Mustacchi {
44287687d0d8SRobert Mustacchi 	boolean_t filter = B_FALSE;
44297687d0d8SRobert Mustacchi 
44307687d0d8SRobert Mustacchi 	/*
44317687d0d8SRobert Mustacchi 	 * If we don't recognize the capability, print out the ID if we're not
44327687d0d8SRobert Mustacchi 	 * filtering and not in parsable mode.
44337687d0d8SRobert Mustacchi 	 */
44347687d0d8SRobert Mustacchi 	if (cap_info == NULL) {
44357687d0d8SRobert Mustacchi 		if (walkp->pcw_ofmt == NULL &&
44367687d0d8SRobert Mustacchi 		    pcieadm_cfgspace_filter(walkp, NULL)) {
44377687d0d8SRobert Mustacchi 			warnx("encountered unknown capability ID 0x%x "
44387687d0d8SRobert Mustacchi 			    "unable to print or list", capid);
44397687d0d8SRobert Mustacchi 			pcieadm_print("Unknown Capability (0x%x)\n", capid);
44407687d0d8SRobert Mustacchi 		}
44417687d0d8SRobert Mustacchi 		return;
44427687d0d8SRobert Mustacchi 	}
44437687d0d8SRobert Mustacchi 
44447687d0d8SRobert Mustacchi 	/*
44457687d0d8SRobert Mustacchi 	 * Check to see if we should print this and in particular, if there's
44467687d0d8SRobert Mustacchi 	 * both a capability or subcapability, we need to try and match both.
44477687d0d8SRobert Mustacchi 	 * The reason that the calls to check the filters are conditioned on
44487687d0d8SRobert Mustacchi 	 * pcw_ofmt is that when we're in parsable mode, we cannot match a
44497687d0d8SRobert Mustacchi 	 * top-level capability since it's an arbitrary number of fields.
44507687d0d8SRobert Mustacchi 	 */
44517687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt == NULL) {
44527687d0d8SRobert Mustacchi 		filter = pcieadm_cfgspace_filter(walkp, cap_info->ppc_short);
44537687d0d8SRobert Mustacchi 	}
44547687d0d8SRobert Mustacchi 	pcieadm_strfilt_push(walkp, cap_info->ppc_short);
44557687d0d8SRobert Mustacchi 	if (subcap != NULL) {
44567687d0d8SRobert Mustacchi 		if (walkp->pcw_ofmt == NULL) {
44577687d0d8SRobert Mustacchi 			boolean_t subfilt = pcieadm_cfgspace_filter(walkp,
44587687d0d8SRobert Mustacchi 			    subcap->psub_short);
44597687d0d8SRobert Mustacchi 			filter = subfilt || filter;
44607687d0d8SRobert Mustacchi 		}
44617687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(walkp, subcap->psub_short);
44627687d0d8SRobert Mustacchi 	}
44637687d0d8SRobert Mustacchi 
44647687d0d8SRobert Mustacchi 
44657687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt == NULL && filter) {
44667687d0d8SRobert Mustacchi 		if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
44677687d0d8SRobert Mustacchi 			if (subcap != NULL) {
44687687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability - %s (%s) "
44697687d0d8SRobert Mustacchi 				    "(0x%x)\n", cap_info->ppc_human,
44707687d0d8SRobert Mustacchi 				    subcap->psub_human,
44717687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, capid);
44727687d0d8SRobert Mustacchi 			} else {
44737687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability (%s) (0x%x)\n",
44747687d0d8SRobert Mustacchi 				    cap_info->ppc_human,
44757687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, capid);
44767687d0d8SRobert Mustacchi 			}
44777687d0d8SRobert Mustacchi 		} else {
44787687d0d8SRobert Mustacchi 			if (subcap != NULL) {
44797687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability - %s (0x%x)\n",
44807687d0d8SRobert Mustacchi 				    cap_info->ppc_human, subcap->psub_human,
44817687d0d8SRobert Mustacchi 				    capid);
44827687d0d8SRobert Mustacchi 			} else {
44837687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability (0x%x)\n",
44847687d0d8SRobert Mustacchi 				    cap_info->ppc_human, capid);
44857687d0d8SRobert Mustacchi 			}
44867687d0d8SRobert Mustacchi 		}
44877687d0d8SRobert Mustacchi 	}
44887687d0d8SRobert Mustacchi 
44897687d0d8SRobert Mustacchi 	if (vers_info != NULL) {
44907687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t *print;
44917687d0d8SRobert Mustacchi 
44927687d0d8SRobert Mustacchi 		pcieadm_indent();
44937687d0d8SRobert Mustacchi 		for (print = vers_info->ppr_print;
44947687d0d8SRobert Mustacchi 		    print->pcp_short != NULL; print++) {
44957687d0d8SRobert Mustacchi 			VERIFY3P(print->pcp_print, !=, NULL);
44967687d0d8SRobert Mustacchi 			print->pcp_print(walkp, print,
44977687d0d8SRobert Mustacchi 			    print->pcp_arg);
44987687d0d8SRobert Mustacchi 		}
44997687d0d8SRobert Mustacchi 		pcieadm_deindent();
45007687d0d8SRobert Mustacchi 	} else {
45017687d0d8SRobert Mustacchi 		if (subcap != NULL) {
45027687d0d8SRobert Mustacchi 			warnx("Unable to print or list %s - %s (no support or "
45037687d0d8SRobert Mustacchi 			    "missing version info)", cap_info->ppc_human,
45047687d0d8SRobert Mustacchi 			    subcap->psub_human);
45057687d0d8SRobert Mustacchi 		} else {
45067687d0d8SRobert Mustacchi 			warnx("Unable to print or list %s (no support or "
45077687d0d8SRobert Mustacchi 			    "missing version info)", cap_info->ppc_human);
45087687d0d8SRobert Mustacchi 		}
45097687d0d8SRobert Mustacchi 	}
45107687d0d8SRobert Mustacchi 
45117687d0d8SRobert Mustacchi 	if (subcap != NULL) {
45127687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(walkp);
45137687d0d8SRobert Mustacchi 	}
45147687d0d8SRobert Mustacchi 	pcieadm_strfilt_pop(walkp);
45157687d0d8SRobert Mustacchi }
45167687d0d8SRobert Mustacchi 
45177687d0d8SRobert Mustacchi static void
45187687d0d8SRobert Mustacchi pcieadm_cfgspace_write(int fd, const uint8_t *source, size_t len)
45197687d0d8SRobert Mustacchi {
45207687d0d8SRobert Mustacchi 	size_t off = 0;
45217687d0d8SRobert Mustacchi 
45227687d0d8SRobert Mustacchi 	while (len > 0) {
45237687d0d8SRobert Mustacchi 		ssize_t ret = write(fd, source + off, len - off);
45247687d0d8SRobert Mustacchi 		if (ret < 0) {
45257687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to write config space to "
45267687d0d8SRobert Mustacchi 			    "output file");
45277687d0d8SRobert Mustacchi 		}
45287687d0d8SRobert Mustacchi 
45297687d0d8SRobert Mustacchi 		off += ret;
45307687d0d8SRobert Mustacchi 		len -= ret;
45317687d0d8SRobert Mustacchi 	}
45327687d0d8SRobert Mustacchi }
45337687d0d8SRobert Mustacchi 
45347687d0d8SRobert Mustacchi void
45357687d0d8SRobert Mustacchi pcieadm_cfgspace(pcieadm_t *pcip, pcieadm_cfgspace_op_t op,
45367687d0d8SRobert Mustacchi     pcieadm_cfgspace_f readf, int fd, void *readarg, uint_t nfilts,
45377687d0d8SRobert Mustacchi     pcieadm_cfgspace_filter_t *filters, pcieadm_cfgspace_flags_t flags,
45387687d0d8SRobert Mustacchi     ofmt_handle_t ofmt)
45397687d0d8SRobert Mustacchi {
45407687d0d8SRobert Mustacchi 	uint_t type;
45417687d0d8SRobert Mustacchi 	uint16_t cap;
45427687d0d8SRobert Mustacchi 	pcieadm_cfgspace_data_t data;
45437687d0d8SRobert Mustacchi 	pcieadm_cfgspace_walk_t walk;
45447687d0d8SRobert Mustacchi 	const char *headstr, *headshort;
45457687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_t *header;
45467687d0d8SRobert Mustacchi 	boolean_t capsup = B_FALSE, extcfg = B_FALSE;
45477687d0d8SRobert Mustacchi 	uint_t ncaps;
45487687d0d8SRobert Mustacchi 
45497687d0d8SRobert Mustacchi 	walk.pcw_pcieadm = pcip;
45507687d0d8SRobert Mustacchi 	walk.pcw_op = op;
45517687d0d8SRobert Mustacchi 	walk.pcw_data = &data;
45527687d0d8SRobert Mustacchi 	walk.pcw_outfd = fd;
45537687d0d8SRobert Mustacchi 	walk.pcw_capoff = 0;
45547687d0d8SRobert Mustacchi 	walk.pcw_nlanes = 0;
45557687d0d8SRobert Mustacchi 	walk.pcw_nfilters = nfilts;
45567687d0d8SRobert Mustacchi 	walk.pcw_filters = filters;
45577687d0d8SRobert Mustacchi 	walk.pcw_flags = flags;
45587687d0d8SRobert Mustacchi 	walk.pcw_ofmt = ofmt;
45597687d0d8SRobert Mustacchi 	walk.pcw_filt = NULL;
45607687d0d8SRobert Mustacchi 
45617687d0d8SRobert Mustacchi 	/*
45627687d0d8SRobert Mustacchi 	 * Start by reading all of the basic 40-byte config space header in one
45637687d0d8SRobert Mustacchi 	 * fell swoop.
45647687d0d8SRobert Mustacchi 	 */
45657687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < PCI_CAP_PTR_OFF / 4; i++) {
45667687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
45677687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
45687687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
45697687d0d8SRobert Mustacchi 		}
45707687d0d8SRobert Mustacchi 	}
45717687d0d8SRobert Mustacchi 	walk.pcw_valid = PCI_CAP_PTR_OFF;
45727687d0d8SRobert Mustacchi 	walk.pcw_caplen = PCI_CAP_PTR_OFF;
45737687d0d8SRobert Mustacchi 
45747687d0d8SRobert Mustacchi 	/*
45757687d0d8SRobert Mustacchi 	 * Grab the information from the header that we need to figure out what
45767687d0d8SRobert Mustacchi 	 * kind of device this is, how to print it, if there are any
45777687d0d8SRobert Mustacchi 	 * capabilities, and go from there.
45787687d0d8SRobert Mustacchi 	 */
45797687d0d8SRobert Mustacchi 	type = data.pcb_u8[PCI_CONF_HEADER] & PCI_HEADER_TYPE_M;
45807687d0d8SRobert Mustacchi 	switch (type) {
45817687d0d8SRobert Mustacchi 	case PCI_HEADER_ZERO:
45827687d0d8SRobert Mustacchi 		headstr = "Type 0 Header";
45837687d0d8SRobert Mustacchi 		headshort = "header0";
45847687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_type0;
45857687d0d8SRobert Mustacchi 		capsup = (data.pcb_u8[PCI_CONF_STAT] & PCI_STAT_CAP) != 0;
45867687d0d8SRobert Mustacchi 		break;
45877687d0d8SRobert Mustacchi 	case PCI_HEADER_ONE:
45887687d0d8SRobert Mustacchi 		headstr = "Type 1 Header";
45897687d0d8SRobert Mustacchi 		headshort = "header1";
45907687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_type1;
45917687d0d8SRobert Mustacchi 		capsup = (data.pcb_u8[PCI_CONF_STAT] & PCI_STAT_CAP) != 0;
45927687d0d8SRobert Mustacchi 		break;
45937687d0d8SRobert Mustacchi 	case PCI_HEADER_TWO:
45947687d0d8SRobert Mustacchi 	default:
45957687d0d8SRobert Mustacchi 		headstr = "Unknown Header";
45967687d0d8SRobert Mustacchi 		headshort = "headerX";
45977687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_unknown;
45987687d0d8SRobert Mustacchi 		warnx("unsupported PCI header type: 0x%x, output limited to "
45997687d0d8SRobert Mustacchi 		    "data configuration space");
46007687d0d8SRobert Mustacchi 	}
46017687d0d8SRobert Mustacchi 
46027687d0d8SRobert Mustacchi 	walk.pcw_dtype = type;
46037687d0d8SRobert Mustacchi 
46047687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
46057687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[0], PCI_CAP_PTR_OFF);
46067687d0d8SRobert Mustacchi 	} else if (op == PCIEADM_CFGSPACE_OP_PRINT) {
46077687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t *print;
46087687d0d8SRobert Mustacchi 
46097687d0d8SRobert Mustacchi 		if (walk.pcw_ofmt == NULL &&
46107687d0d8SRobert Mustacchi 		    pcieadm_cfgspace_filter(&walk, headshort)) {
46117687d0d8SRobert Mustacchi 			if ((flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
46127687d0d8SRobert Mustacchi 				pcieadm_print("Device %s -- %s (%s)\n",
46137687d0d8SRobert Mustacchi 				    pcip->pia_devstr, headstr, headshort);
46147687d0d8SRobert Mustacchi 			} else {
46157687d0d8SRobert Mustacchi 				pcieadm_print("Device %s -- %s\n",
46167687d0d8SRobert Mustacchi 				    pcip->pia_devstr, headstr);
46177687d0d8SRobert Mustacchi 			}
46187687d0d8SRobert Mustacchi 		}
46197687d0d8SRobert Mustacchi 
46207687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(&walk, headshort);
46217687d0d8SRobert Mustacchi 		pcieadm_indent();
46227687d0d8SRobert Mustacchi 		for (print = header; print->pcp_short != NULL; print++) {
46237687d0d8SRobert Mustacchi 			print->pcp_print(&walk, print, print->pcp_arg);
46247687d0d8SRobert Mustacchi 		}
46257687d0d8SRobert Mustacchi 		pcieadm_deindent();
46267687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(&walk);
46277687d0d8SRobert Mustacchi 	}
46287687d0d8SRobert Mustacchi 
46297687d0d8SRobert Mustacchi 
46307687d0d8SRobert Mustacchi 	if (!capsup) {
46317687d0d8SRobert Mustacchi 		return;
46327687d0d8SRobert Mustacchi 	}
46337687d0d8SRobert Mustacchi 
46347687d0d8SRobert Mustacchi 	for (uint32_t i = PCI_CAP_PTR_OFF / 4; i < PCI_CONF_HDR_SIZE / 4; i++) {
46357687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
46367687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
46377687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
46387687d0d8SRobert Mustacchi 		}
46397687d0d8SRobert Mustacchi 	}
46407687d0d8SRobert Mustacchi 	walk.pcw_valid = PCIE_EXT_CAP;
46417687d0d8SRobert Mustacchi 	VERIFY3P(walk.pcw_filt, ==, NULL);
46427687d0d8SRobert Mustacchi 
46437687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
46447687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[PCI_CAP_PTR_OFF],
46457687d0d8SRobert Mustacchi 		    PCI_CONF_HDR_SIZE - PCI_CAP_PTR_OFF);
46467687d0d8SRobert Mustacchi 	}
46477687d0d8SRobert Mustacchi 
46487687d0d8SRobert Mustacchi 	ncaps = 0;
46497687d0d8SRobert Mustacchi 	cap = data.pcb_u8[PCI_CONF_CAP_PTR];
46507687d0d8SRobert Mustacchi 	while (cap != 0 && cap != PCI_EINVAL8) {
46517687d0d8SRobert Mustacchi 		const pcieadm_pci_cap_t *cap_info;
46527687d0d8SRobert Mustacchi 		const pcieadm_cap_vers_t *vers_info = NULL;
46537687d0d8SRobert Mustacchi 		const pcieadm_subcap_t *subcap = NULL;
46547687d0d8SRobert Mustacchi 		uint8_t cap_id, nextcap;
46557687d0d8SRobert Mustacchi 		uint32_t read_len = 0;
46567687d0d8SRobert Mustacchi 
46577687d0d8SRobert Mustacchi 		/*
46587687d0d8SRobert Mustacchi 		 * The PCI specification requires that the caller mask off the
46597687d0d8SRobert Mustacchi 		 * bottom two bits. Always check for an invalid value (all 1s)
46607687d0d8SRobert Mustacchi 		 * before this.
46617687d0d8SRobert Mustacchi 		 */
46627687d0d8SRobert Mustacchi 		cap &= PCI_CAP_PTR_MASK;
46637687d0d8SRobert Mustacchi 		cap_id = data.pcb_u8[cap + PCI_CAP_ID];
46647687d0d8SRobert Mustacchi 		nextcap = data.pcb_u8[cap + PCI_CAP_NEXT_PTR];
46657687d0d8SRobert Mustacchi 		cap_info = pcieadm_cfgspace_match_cap(cap_id, B_FALSE);
46667687d0d8SRobert Mustacchi 		if (cap_info != NULL && cap_info->ppc_info != NULL) {
46677687d0d8SRobert Mustacchi 			cap_info->ppc_info(&walk, cap_info, cap, &vers_info,
46687687d0d8SRobert Mustacchi 			    &read_len, &subcap);
46697687d0d8SRobert Mustacchi 		}
46707687d0d8SRobert Mustacchi 
46717687d0d8SRobert Mustacchi 		walk.pcw_caplen = read_len;
46727687d0d8SRobert Mustacchi 		walk.pcw_capoff = cap;
46737687d0d8SRobert Mustacchi 
46747687d0d8SRobert Mustacchi 		if (cap_id == PCI_CAP_ID_PCI_E) {
46757687d0d8SRobert Mustacchi 			extcfg = B_TRUE;
46767687d0d8SRobert Mustacchi 			if (walk.pcw_valid != 0) {
46777687d0d8SRobert Mustacchi 				walk.pcw_pcietype = data.pcb_u8[cap +
46787687d0d8SRobert Mustacchi 				    PCIE_PCIECAP] & PCIE_PCIECAP_DEV_TYPE_MASK;
46797687d0d8SRobert Mustacchi 				walk.pcw_nlanes = (data.pcb_u8[cap +
46807687d0d8SRobert Mustacchi 				    PCIE_LINKCAP] & 0xf0) >> 4;
46817687d0d8SRobert Mustacchi 				walk.pcw_nlanes |= (data.pcb_u8[cap +
46827687d0d8SRobert Mustacchi 				    PCIE_LINKCAP + 1] & 0x01) << 4;
46837687d0d8SRobert Mustacchi 			} else {
46847687d0d8SRobert Mustacchi 				walk.pcw_pcietype = UINT_MAX;
46857687d0d8SRobert Mustacchi 			}
46867687d0d8SRobert Mustacchi 		}
46877687d0d8SRobert Mustacchi 
46887687d0d8SRobert Mustacchi 		if (op == PCIEADM_CFGSPACE_OP_PRINT) {
46897687d0d8SRobert Mustacchi 			pcieadm_cfgspace_print_cap(&walk, cap_id, cap_info,
46907687d0d8SRobert Mustacchi 			    vers_info, subcap);
46917687d0d8SRobert Mustacchi 		}
46927687d0d8SRobert Mustacchi 
46937687d0d8SRobert Mustacchi 		cap = nextcap;
46947687d0d8SRobert Mustacchi 		ncaps++;
46957687d0d8SRobert Mustacchi 		if (ncaps >= PCI_CAP_MAX_PTR) {
46967687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "encountered more PCI capabilities "
46977687d0d8SRobert Mustacchi 			    "than fit in configuration space");
46987687d0d8SRobert Mustacchi 		}
46997687d0d8SRobert Mustacchi 	}
47007687d0d8SRobert Mustacchi 
47017687d0d8SRobert Mustacchi 	if (!extcfg) {
47027687d0d8SRobert Mustacchi 		return;
47037687d0d8SRobert Mustacchi 	}
47047687d0d8SRobert Mustacchi 
47057687d0d8SRobert Mustacchi 	for (uint_t i = PCIE_EXT_CAP / 4; i < PCIE_CONF_HDR_SIZE / 4; i++) {
47067687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
47077687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
47087687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
47097687d0d8SRobert Mustacchi 		}
47107687d0d8SRobert Mustacchi 	}
47117687d0d8SRobert Mustacchi 	walk.pcw_valid = PCIE_CONF_HDR_SIZE;
47127687d0d8SRobert Mustacchi 
47137687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
47147687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[PCIE_EXT_CAP],
47157687d0d8SRobert Mustacchi 		    PCIE_CONF_HDR_SIZE - PCIE_EXT_CAP);
47167687d0d8SRobert Mustacchi 		return;
47177687d0d8SRobert Mustacchi 	}
47187687d0d8SRobert Mustacchi 
47197687d0d8SRobert Mustacchi 	cap = PCIE_EXT_CAP;
47207687d0d8SRobert Mustacchi 	ncaps = 0;
47217687d0d8SRobert Mustacchi 	while (cap != 0 && cap != PCI_EINVAL16) {
47227687d0d8SRobert Mustacchi 		uint16_t cap_id, nextcap;
47237687d0d8SRobert Mustacchi 		const pcieadm_pci_cap_t *cap_info;
47247687d0d8SRobert Mustacchi 		const pcieadm_cap_vers_t *vers_info = NULL;
47257687d0d8SRobert Mustacchi 		const pcieadm_subcap_t *subcap = NULL;
47267687d0d8SRobert Mustacchi 		uint32_t read_len = 0;
47277687d0d8SRobert Mustacchi 
47287687d0d8SRobert Mustacchi 		/*
47297687d0d8SRobert Mustacchi 		 * PCIe has the same masking as PCI. Note, sys/pcie.h currently
47307687d0d8SRobert Mustacchi 		 * has PCIE_EXT_CAP_NEXT_PTR_MASK as 0xfff, instead of the
47317687d0d8SRobert Mustacchi 		 * below. This should be switched to PCIE_EXT_CAP_NEXT_PTR_MASK
47327687d0d8SRobert Mustacchi 		 * when the kernel headers are fixed.
47337687d0d8SRobert Mustacchi 		 */
47347687d0d8SRobert Mustacchi 		cap &= 0xffc;
47357687d0d8SRobert Mustacchi 
47367687d0d8SRobert Mustacchi 		/*
47377687d0d8SRobert Mustacchi 		 * While this seems duplicative of the loop condition, a device
47387687d0d8SRobert Mustacchi 		 * without capabilities indicates it with a zero for the first
47397687d0d8SRobert Mustacchi 		 * cap.
47407687d0d8SRobert Mustacchi 		 */
47417687d0d8SRobert Mustacchi 		if (data.pcb_u32[cap / 4] == 0 ||
47427687d0d8SRobert Mustacchi 		    data.pcb_u32[cap / 4] == PCI_EINVAL32)
47437687d0d8SRobert Mustacchi 			break;
47447687d0d8SRobert Mustacchi 
47457687d0d8SRobert Mustacchi 		cap_id = data.pcb_u32[cap / 4] & PCIE_EXT_CAP_ID_MASK;
47467687d0d8SRobert Mustacchi 		nextcap = (data.pcb_u32[cap / 4] >>
47477687d0d8SRobert Mustacchi 		    PCIE_EXT_CAP_NEXT_PTR_SHIFT) & PCIE_EXT_CAP_NEXT_PTR_MASK;
47487687d0d8SRobert Mustacchi 
47497687d0d8SRobert Mustacchi 		cap_info = pcieadm_cfgspace_match_cap(cap_id, B_TRUE);
47507687d0d8SRobert Mustacchi 		if (cap_info != NULL && cap_info->ppc_info != NULL) {
47517687d0d8SRobert Mustacchi 			cap_info->ppc_info(&walk, cap_info, cap, &vers_info,
47527687d0d8SRobert Mustacchi 			    &read_len, &subcap);
47537687d0d8SRobert Mustacchi 		}
47547687d0d8SRobert Mustacchi 
47557687d0d8SRobert Mustacchi 		walk.pcw_caplen = read_len;
47567687d0d8SRobert Mustacchi 		walk.pcw_capoff = cap;
47577687d0d8SRobert Mustacchi 
47587687d0d8SRobert Mustacchi 		if (op == PCIEADM_CFGSPACE_OP_PRINT) {
47597687d0d8SRobert Mustacchi 			pcieadm_cfgspace_print_cap(&walk, cap_id, cap_info,
47607687d0d8SRobert Mustacchi 			    vers_info, subcap);
47617687d0d8SRobert Mustacchi 		}
47627687d0d8SRobert Mustacchi 
47637687d0d8SRobert Mustacchi 		cap = nextcap;
47647687d0d8SRobert Mustacchi 		ncaps++;
47657687d0d8SRobert Mustacchi 		if (ncaps >= PCIE_EXT_CAP_MAX_PTR) {
47667687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "encountered more PCI capabilities "
47677687d0d8SRobert Mustacchi 			    "than fit in configuration space");
47687687d0d8SRobert Mustacchi 		}
47697687d0d8SRobert Mustacchi 	}
47707687d0d8SRobert Mustacchi }
47717687d0d8SRobert Mustacchi 
47727687d0d8SRobert Mustacchi void
47737687d0d8SRobert Mustacchi pcieadm_show_cfgspace_usage(FILE *f)
47747687d0d8SRobert Mustacchi {
47757687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tshow-cfgspace\t[-L] [-n] [-H] -d device | -f file "
47767687d0d8SRobert Mustacchi 	    "[filter...]\n");
47777687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tshow-cfgspace\t-p -o field[,...] [-H] -d device | "
47787687d0d8SRobert Mustacchi 	    "-f file [filter...]\n");
47797687d0d8SRobert Mustacchi }
47807687d0d8SRobert Mustacchi 
47817687d0d8SRobert Mustacchi static void
47827687d0d8SRobert Mustacchi pcieadm_show_cfgspace_help(const char *fmt, ...)
47837687d0d8SRobert Mustacchi {
47847687d0d8SRobert Mustacchi 	if (fmt != NULL) {
47857687d0d8SRobert Mustacchi 		va_list ap;
47867687d0d8SRobert Mustacchi 
47877687d0d8SRobert Mustacchi 		va_start(ap, fmt);
47887687d0d8SRobert Mustacchi 		vwarnx(fmt, ap);
47897687d0d8SRobert Mustacchi 		va_end(ap);
47907687d0d8SRobert Mustacchi 		(void) fprintf(stderr, "\n");
47917687d0d8SRobert Mustacchi 	}
47927687d0d8SRobert Mustacchi 
47937687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "Usage:  %s show-cfgspace [-L] [-n] [-H] -d "
47947687d0d8SRobert Mustacchi 	    "device | -f file [filter...]\n", pcieadm_progname);
47957687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "        %s show-cfgspace -p -o field[,...] "
47967687d0d8SRobert Mustacchi 	    "[-H] -d device | -f file\n\t\t\t      [filter...]\n",
47977687d0d8SRobert Mustacchi 	    pcieadm_progname);
47987687d0d8SRobert Mustacchi 
47997687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "\nPrint and decode PCI configuration space "
48007687d0d8SRobert Mustacchi 	    "data from a device or file. Each\n<filter> selects a given "
48017687d0d8SRobert Mustacchi 	    "capability, sub-capability, register, or field to print.\n\n"
48027687d0d8SRobert Mustacchi 	    "\t-d device\tread data from the specified device (driver instance,"
48037687d0d8SRobert Mustacchi 	    "\n\t\t\t/devices path, or b/d/f)\n"
48047687d0d8SRobert Mustacchi 	    "\t-f file\t\tread data from the specified file\n"
48057687d0d8SRobert Mustacchi 	    "\t-L\t\tlist printable fields\n"
48067687d0d8SRobert Mustacchi 	    "\t-n\t\tshow printable short names\n"
48077687d0d8SRobert Mustacchi 	    "\t-H\t\tomit the column header (for -L and -p)\n"
48087687d0d8SRobert Mustacchi 	    "\t-p\t\tparsable output (requires -o)\n"
48097687d0d8SRobert Mustacchi 	    "\t-o field\toutput fields to print (required for -p)\n");
48107687d0d8SRobert Mustacchi }
48117687d0d8SRobert Mustacchi 
48127687d0d8SRobert Mustacchi int
48137687d0d8SRobert Mustacchi pcieadm_show_cfgspace(pcieadm_t *pcip, int argc, char *argv[])
48147687d0d8SRobert Mustacchi {
48157687d0d8SRobert Mustacchi 	int c, ret;
48167687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
48177687d0d8SRobert Mustacchi 	void *readarg;
48187687d0d8SRobert Mustacchi 	boolean_t list = B_FALSE, parse = B_FALSE;
48197687d0d8SRobert Mustacchi 	const char *device = NULL, *file = NULL, *fields = NULL;
48207687d0d8SRobert Mustacchi 	uint_t nfilts = 0;
48217687d0d8SRobert Mustacchi 	pcieadm_cfgspace_filter_t *filts = NULL;
48227687d0d8SRobert Mustacchi 	pcieadm_cfgspace_flags_t flags = 0;
48237687d0d8SRobert Mustacchi 	uint_t oflags = 0;
48247687d0d8SRobert Mustacchi 	ofmt_handle_t ofmt = NULL;
48257687d0d8SRobert Mustacchi 
48267687d0d8SRobert Mustacchi 	while ((c = getopt(argc, argv, ":HLd:f:o:np")) != -1) {
48277687d0d8SRobert Mustacchi 		switch (c) {
48287687d0d8SRobert Mustacchi 		case 'd':
48297687d0d8SRobert Mustacchi 			device = optarg;
48307687d0d8SRobert Mustacchi 			break;
48317687d0d8SRobert Mustacchi 		case 'L':
48327687d0d8SRobert Mustacchi 			list = B_TRUE;
48337687d0d8SRobert Mustacchi 			break;
48347687d0d8SRobert Mustacchi 		case 'f':
48357687d0d8SRobert Mustacchi 			file = optarg;
48367687d0d8SRobert Mustacchi 			break;
48377687d0d8SRobert Mustacchi 		case 'p':
48387687d0d8SRobert Mustacchi 			parse = B_TRUE;
48397687d0d8SRobert Mustacchi 			flags |= PCIEADM_CFGSPACE_F_PARSE;
48407687d0d8SRobert Mustacchi 			oflags |= OFMT_PARSABLE;
48417687d0d8SRobert Mustacchi 			break;
48427687d0d8SRobert Mustacchi 		case 'n':
48437687d0d8SRobert Mustacchi 			flags |= PCIEADM_CFGSPACE_F_SHORT;
48447687d0d8SRobert Mustacchi 			break;
48457687d0d8SRobert Mustacchi 		case 'H':
48467687d0d8SRobert Mustacchi 			oflags |= OFMT_NOHEADER;
48477687d0d8SRobert Mustacchi 			break;
48487687d0d8SRobert Mustacchi 		case 'o':
48497687d0d8SRobert Mustacchi 			fields = optarg;
48507687d0d8SRobert Mustacchi 			break;
48517687d0d8SRobert Mustacchi 		case ':':
48527687d0d8SRobert Mustacchi 			pcieadm_show_cfgspace_help("Option -%c requires an "
48537687d0d8SRobert Mustacchi 			    "argument", optopt);
48547687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
48557687d0d8SRobert Mustacchi 		case '?':
48567687d0d8SRobert Mustacchi 		default:
48577687d0d8SRobert Mustacchi 			pcieadm_show_cfgspace_help("unknown option: -%c",
48587687d0d8SRobert Mustacchi 			    optopt);
48597687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
48607687d0d8SRobert Mustacchi 		}
48617687d0d8SRobert Mustacchi 	}
48627687d0d8SRobert Mustacchi 
48637687d0d8SRobert Mustacchi 	argc -= optind;
48647687d0d8SRobert Mustacchi 	argv += optind;
48657687d0d8SRobert Mustacchi 
48667687d0d8SRobert Mustacchi 	if (device == NULL && file == NULL) {
48677687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("one of -d or -f must be specified");
48687687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
48697687d0d8SRobert Mustacchi 	}
48707687d0d8SRobert Mustacchi 
48717687d0d8SRobert Mustacchi 	if (device != NULL && file != NULL) {
48727687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("only one of -d and -f must be "
48737687d0d8SRobert Mustacchi 		    "specified");
48747687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
48757687d0d8SRobert Mustacchi 	}
48767687d0d8SRobert Mustacchi 
48777687d0d8SRobert Mustacchi 	if (parse && fields == NULL) {
48787687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-p requires fields specified with "
48797687d0d8SRobert Mustacchi 		    "-o");
48807687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
48817687d0d8SRobert Mustacchi 	}
48827687d0d8SRobert Mustacchi 
48837687d0d8SRobert Mustacchi 	if (!parse && fields != NULL) {
48847687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-o can only be used with -p");
48857687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
48867687d0d8SRobert Mustacchi 	}
48877687d0d8SRobert Mustacchi 
48887687d0d8SRobert Mustacchi 	if ((oflags & OFMT_NOHEADER) && !(list || parse)) {
48897687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-H must be used with either -L or "
48907687d0d8SRobert Mustacchi 		    "-p");
48917687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
48927687d0d8SRobert Mustacchi 	}
48937687d0d8SRobert Mustacchi 
48947687d0d8SRobert Mustacchi 	if ((flags & PCIEADM_CFGSPACE_F_SHORT) && (list || parse)) {
48957687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-n cannot be used with either -L "
48967687d0d8SRobert Mustacchi 		    "or -p");
48977687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
48987687d0d8SRobert Mustacchi 	}
48997687d0d8SRobert Mustacchi 
49007687d0d8SRobert Mustacchi 	if (list && parse != 0) {
49017687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-L and -p cannot be used together");
49027687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
49037687d0d8SRobert Mustacchi 	}
49047687d0d8SRobert Mustacchi 
49057687d0d8SRobert Mustacchi 	if (list && fields != NULL) {
49067687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-L and -o cannot be used together");
49077687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
49087687d0d8SRobert Mustacchi 	}
49097687d0d8SRobert Mustacchi 
49107687d0d8SRobert Mustacchi 	if (list) {
49117687d0d8SRobert Mustacchi 		fields = "short,human";
49127687d0d8SRobert Mustacchi 	}
49137687d0d8SRobert Mustacchi 
49147687d0d8SRobert Mustacchi 	if (argc > 0) {
49157687d0d8SRobert Mustacchi 		nfilts = argc;
49167687d0d8SRobert Mustacchi 		filts = calloc(nfilts, sizeof (pcieadm_cfgspace_filter_t));
49177687d0d8SRobert Mustacchi 
49187687d0d8SRobert Mustacchi 		for (int i = 0; i < argc; i++) {
49197687d0d8SRobert Mustacchi 			filts[i].pcf_string = argv[i];
49207687d0d8SRobert Mustacchi 			filts[i].pcf_len = strlen(argv[i]);
49217687d0d8SRobert Mustacchi 		}
49227687d0d8SRobert Mustacchi 	}
49237687d0d8SRobert Mustacchi 
49247687d0d8SRobert Mustacchi 	if (list || parse) {
49257687d0d8SRobert Mustacchi 		ofmt_status_t oferr;
49267687d0d8SRobert Mustacchi 		oferr = ofmt_open(fields, pcieadm_cfgspace_ofmt, oflags, 0,
49277687d0d8SRobert Mustacchi 		    &ofmt);
49287687d0d8SRobert Mustacchi 		ofmt_check(oferr, parse, ofmt, pcieadm_ofmt_errx, warnx);
49297687d0d8SRobert Mustacchi 	}
49307687d0d8SRobert Mustacchi 
49317687d0d8SRobert Mustacchi 	/*
49327687d0d8SRobert Mustacchi 	 * Initialize privileges that we require. For reading from the kernel
49337687d0d8SRobert Mustacchi 	 * we require all privileges. For a file, we just intersect with things
49347687d0d8SRobert Mustacchi 	 * that would allow someone to read from any file.
49357687d0d8SRobert Mustacchi 	 */
49367687d0d8SRobert Mustacchi 	if (device != NULL) {
49377687d0d8SRobert Mustacchi 		/*
49387687d0d8SRobert Mustacchi 		 * We need full privileges if reading from a device,
49397687d0d8SRobert Mustacchi 		 * unfortunately.
49407687d0d8SRobert Mustacchi 		 */
49417687d0d8SRobert Mustacchi 		priv_fillset(pcip->pia_priv_eff);
49427687d0d8SRobert Mustacchi 	} else {
49437687d0d8SRobert Mustacchi 		VERIFY0(priv_addset(pcip->pia_priv_eff, PRIV_FILE_DAC_READ));
49447687d0d8SRobert Mustacchi 		VERIFY0(priv_addset(pcip->pia_priv_eff, PRIV_FILE_DAC_SEARCH));
49457687d0d8SRobert Mustacchi 	}
49467687d0d8SRobert Mustacchi 	pcieadm_init_privs(pcip);
49477687d0d8SRobert Mustacchi 
49487687d0d8SRobert Mustacchi 	if (device != NULL) {
49497687d0d8SRobert Mustacchi 		pcieadm_find_dip(pcip, device);
49507687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_kernel(pcip, &readf, &readarg);
49517687d0d8SRobert Mustacchi 	} else {
49527687d0d8SRobert Mustacchi 		pcip->pia_devstr = file;
49537687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_file(pcip, file, &readf, &readarg);
49547687d0d8SRobert Mustacchi 	}
49557687d0d8SRobert Mustacchi 	pcieadm_cfgspace(pcip, PCIEADM_CFGSPACE_OP_PRINT, readf, -1, readarg,
49567687d0d8SRobert Mustacchi 	    nfilts, filts, flags, ofmt);
49577687d0d8SRobert Mustacchi 	if (device != NULL) {
49587687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_kernel(readarg);
49597687d0d8SRobert Mustacchi 	} else {
49607687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_file(readarg);
49617687d0d8SRobert Mustacchi 	}
49627687d0d8SRobert Mustacchi 
49637687d0d8SRobert Mustacchi 	ofmt_close(ofmt);
49647687d0d8SRobert Mustacchi 	ret = EXIT_SUCCESS;
49657687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < nfilts; i++) {
49667687d0d8SRobert Mustacchi 		if (!filts[i].pcf_used) {
49677687d0d8SRobert Mustacchi 			warnx("filter '%s' did not match any fields",
49687687d0d8SRobert Mustacchi 			    filts[i].pcf_string);
49697687d0d8SRobert Mustacchi 			ret = EXIT_FAILURE;
49707687d0d8SRobert Mustacchi 		}
49717687d0d8SRobert Mustacchi 	}
49727687d0d8SRobert Mustacchi 
49737687d0d8SRobert Mustacchi 	return (ret);
49747687d0d8SRobert Mustacchi }
49757687d0d8SRobert Mustacchi 
49767687d0d8SRobert Mustacchi typedef struct pcieadm_save_cfgspace {
49777687d0d8SRobert Mustacchi 	pcieadm_t *psc_pci;
49787687d0d8SRobert Mustacchi 	int psc_dirfd;
49797687d0d8SRobert Mustacchi 	uint_t psc_nsaved;
49807687d0d8SRobert Mustacchi 	int psc_ret;
49817687d0d8SRobert Mustacchi } pcieadm_save_cfgspace_t;
49827687d0d8SRobert Mustacchi 
49837687d0d8SRobert Mustacchi static int
49847687d0d8SRobert Mustacchi pcieadm_save_cfgspace_cb(di_node_t devi, void *arg)
49857687d0d8SRobert Mustacchi {
49867687d0d8SRobert Mustacchi 	int fd, nregs, *regs;
49877687d0d8SRobert Mustacchi 	pcieadm_save_cfgspace_t *psc = arg;
49887687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
49897687d0d8SRobert Mustacchi 	void *readarg;
49907687d0d8SRobert Mustacchi 	char fname[128];
49917687d0d8SRobert Mustacchi 
49927687d0d8SRobert Mustacchi 	psc->psc_pci->pia_devstr = di_node_name(devi);
49937687d0d8SRobert Mustacchi 	psc->psc_pci->pia_devi = devi;
49947687d0d8SRobert Mustacchi 	psc->psc_pci->pia_nexus = DI_NODE_NIL;
49957687d0d8SRobert Mustacchi 	pcieadm_find_nexus(psc->psc_pci);
49967687d0d8SRobert Mustacchi 	if (psc->psc_pci->pia_nexus == DI_NODE_NIL) {
49977687d0d8SRobert Mustacchi 		warnx("failed to find nexus for %s", di_node_name(devi));
49987687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
49997687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
50007687d0d8SRobert Mustacchi 	}
50017687d0d8SRobert Mustacchi 
50027687d0d8SRobert Mustacchi 	nregs = di_prop_lookup_ints(DDI_DEV_T_ANY, devi, "reg", &regs);
50037687d0d8SRobert Mustacchi 	if (nregs <= 0) {
50047687d0d8SRobert Mustacchi 		warnx("failed to lookup regs array for %s",
50057687d0d8SRobert Mustacchi 		    psc->psc_pci->pia_devstr);
50067687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
50077687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
50087687d0d8SRobert Mustacchi 	}
50097687d0d8SRobert Mustacchi 
50107687d0d8SRobert Mustacchi 	(void) snprintf(fname, sizeof (fname), "%02x-%02x-%02x.pci",
50117687d0d8SRobert Mustacchi 	    PCI_REG_BUS_G(regs[0]), PCI_REG_DEV_G(regs[0]),
50127687d0d8SRobert Mustacchi 	    PCI_REG_FUNC_G(regs[0]));
50137687d0d8SRobert Mustacchi 
5014414dafc0SRobert Mustacchi 	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, psc->psc_pci->pia_priv_eff) !=
5015414dafc0SRobert Mustacchi 	    0) {
5016414dafc0SRobert Mustacchi 		err(EXIT_FAILURE, "failed to raise privileges");
5017414dafc0SRobert Mustacchi 	}
5018414dafc0SRobert Mustacchi 	fd = openat(psc->psc_dirfd, fname, O_WRONLY | O_TRUNC | O_CREAT, 0666);
5019414dafc0SRobert Mustacchi 	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, psc->psc_pci->pia_priv_min) !=
5020414dafc0SRobert Mustacchi 	    0) {
5021414dafc0SRobert Mustacchi 		err(EXIT_FAILURE, "failed to reduce privileges");
5022414dafc0SRobert Mustacchi 	}
5023414dafc0SRobert Mustacchi 
5024414dafc0SRobert Mustacchi 	if (fd < 0) {
50257687d0d8SRobert Mustacchi 		warn("failed to create output file %s", fname);
50267687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
50277687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
50287687d0d8SRobert Mustacchi 	}
50297687d0d8SRobert Mustacchi 
50307687d0d8SRobert Mustacchi 	pcieadm_init_cfgspace_kernel(psc->psc_pci, &readf, &readarg);
50317687d0d8SRobert Mustacchi 	pcieadm_cfgspace(psc->psc_pci, PCIEADM_CFGSPACE_OP_WRITE, readf, fd,
50327687d0d8SRobert Mustacchi 	    readarg, 0, NULL, 0, NULL);
50337687d0d8SRobert Mustacchi 	pcieadm_fini_cfgspace_kernel(readarg);
50347687d0d8SRobert Mustacchi 
50357687d0d8SRobert Mustacchi 	if (close(fd) != 0) {
50367687d0d8SRobert Mustacchi 		warn("failed to close output fd for %s", fname);
50377687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
50387687d0d8SRobert Mustacchi 	} else {
50397687d0d8SRobert Mustacchi 		psc->psc_nsaved++;
50407687d0d8SRobert Mustacchi 	}
50417687d0d8SRobert Mustacchi 
50427687d0d8SRobert Mustacchi 	return (DI_WALK_CONTINUE);
50437687d0d8SRobert Mustacchi }
50447687d0d8SRobert Mustacchi 
50457687d0d8SRobert Mustacchi void
50467687d0d8SRobert Mustacchi pcieadm_save_cfgspace_usage(FILE *f)
50477687d0d8SRobert Mustacchi {
5048755ccbcfSRobert Mustacchi 	(void) fprintf(f, "\tsave-cfgspace\t-d device output-file\n");
5049755ccbcfSRobert Mustacchi 	(void) fprintf(f, "\tsave-cfgspace\t-a output-directory\n");
50507687d0d8SRobert Mustacchi }
50517687d0d8SRobert Mustacchi 
50527687d0d8SRobert Mustacchi static void
50537687d0d8SRobert Mustacchi pcieadm_save_cfgspace_help(const char *fmt, ...)
50547687d0d8SRobert Mustacchi {
50557687d0d8SRobert Mustacchi 	if (fmt != NULL) {
50567687d0d8SRobert Mustacchi 		va_list ap;
50577687d0d8SRobert Mustacchi 
50587687d0d8SRobert Mustacchi 		va_start(ap, fmt);
50597687d0d8SRobert Mustacchi 		vwarnx(fmt, ap);
50607687d0d8SRobert Mustacchi 		va_end(ap);
50617687d0d8SRobert Mustacchi 		(void) fprintf(stderr, "\n");
50627687d0d8SRobert Mustacchi 	}
50637687d0d8SRobert Mustacchi 
50647687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "Usage:  %s save-cfgspace -d device "
50657687d0d8SRobert Mustacchi 	    "output-file\n", pcieadm_progname);
50667687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "        %s save-cfgspace -a "
50677687d0d8SRobert Mustacchi 	    "output-directory\n", pcieadm_progname);
50687687d0d8SRobert Mustacchi 
50697687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "\nSave PCI configuration space data from a "
50707687d0d8SRobert Mustacchi 	    "device to a file or\nsave all devices to a specified directory."
50717687d0d8SRobert Mustacchi 	    "\n\n"
50727687d0d8SRobert Mustacchi 	    "\t-a\t\tsave data from all devices\n"
50737687d0d8SRobert Mustacchi 	    "\t-d device\tread data from the specified device (driver instance,"
50747687d0d8SRobert Mustacchi 	    "\n\t\t\t/devices path, or b/d/f)\n");
50757687d0d8SRobert Mustacchi }
50767687d0d8SRobert Mustacchi 
50777687d0d8SRobert Mustacchi int
50787687d0d8SRobert Mustacchi pcieadm_save_cfgspace(pcieadm_t *pcip, int argc, char *argv[])
50797687d0d8SRobert Mustacchi {
50807687d0d8SRobert Mustacchi 	int c;
50817687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
50827687d0d8SRobert Mustacchi 	void *readarg;
50837687d0d8SRobert Mustacchi 	const char *device = NULL;
50847687d0d8SRobert Mustacchi 	boolean_t do_all = B_FALSE;
50857687d0d8SRobert Mustacchi 
50867687d0d8SRobert Mustacchi 	while ((c = getopt(argc, argv, ":ad:")) != -1) {
50877687d0d8SRobert Mustacchi 		switch (c) {
50887687d0d8SRobert Mustacchi 		case 'a':
50897687d0d8SRobert Mustacchi 			do_all = B_TRUE;
50907687d0d8SRobert Mustacchi 			break;
50917687d0d8SRobert Mustacchi 		case 'd':
50927687d0d8SRobert Mustacchi 			device = optarg;
50937687d0d8SRobert Mustacchi 			break;
50947687d0d8SRobert Mustacchi 		case ':':
50957687d0d8SRobert Mustacchi 			pcieadm_save_cfgspace_help("Option -%c requires an "
50967687d0d8SRobert Mustacchi 			    "argument", optopt);
50977687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
50987687d0d8SRobert Mustacchi 		case '?':
50997687d0d8SRobert Mustacchi 		default:
51007687d0d8SRobert Mustacchi 			pcieadm_save_cfgspace_help("unknown option: -%c",
51017687d0d8SRobert Mustacchi 			    optopt);
51027687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
51037687d0d8SRobert Mustacchi 		}
51047687d0d8SRobert Mustacchi 	}
51057687d0d8SRobert Mustacchi 
51067687d0d8SRobert Mustacchi 	argc -= optind;
51077687d0d8SRobert Mustacchi 	argv += optind;
51087687d0d8SRobert Mustacchi 
51097687d0d8SRobert Mustacchi 	if (device == NULL && !do_all) {
51107687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_help("missing required -d option to "
51117687d0d8SRobert Mustacchi 		    "indicate device to dump");
51127687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
51137687d0d8SRobert Mustacchi 	}
51147687d0d8SRobert Mustacchi 
51157687d0d8SRobert Mustacchi 	if (argc != 1) {
51167687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_help("missing required output path");
51177687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
51187687d0d8SRobert Mustacchi 	}
51197687d0d8SRobert Mustacchi 
51207687d0d8SRobert Mustacchi 	/*
51217687d0d8SRobert Mustacchi 	 * For reading from devices, we need to full privileges, unfortunately.
51227687d0d8SRobert Mustacchi 	 */
51237687d0d8SRobert Mustacchi 	priv_fillset(pcip->pia_priv_eff);
51247687d0d8SRobert Mustacchi 	pcieadm_init_privs(pcip);
51257687d0d8SRobert Mustacchi 
51267687d0d8SRobert Mustacchi 	if (!do_all) {
51277687d0d8SRobert Mustacchi 		int fd;
51287687d0d8SRobert Mustacchi 
51297687d0d8SRobert Mustacchi 		pcieadm_find_dip(pcip, device);
51307687d0d8SRobert Mustacchi 
51317687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_eff) !=
51327687d0d8SRobert Mustacchi 		    0) {
51337687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to raise privileges");
51347687d0d8SRobert Mustacchi 		}
51357687d0d8SRobert Mustacchi 
51367687d0d8SRobert Mustacchi 		if ((fd = open(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666)) <
51377687d0d8SRobert Mustacchi 		    0) {
51387687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to open output file %s",
51397687d0d8SRobert Mustacchi 			    argv[0]);
51407687d0d8SRobert Mustacchi 		}
51417687d0d8SRobert Mustacchi 
51427687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_min) !=
51437687d0d8SRobert Mustacchi 		    0) {
51447687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to reduce privileges");
51457687d0d8SRobert Mustacchi 		}
51467687d0d8SRobert Mustacchi 
51477687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_kernel(pcip, &readf, &readarg);
51487687d0d8SRobert Mustacchi 		pcieadm_cfgspace(pcip, PCIEADM_CFGSPACE_OP_WRITE, readf, fd,
51497687d0d8SRobert Mustacchi 		    readarg, 0, NULL, 0, NULL);
51507687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_kernel(readarg);
51517687d0d8SRobert Mustacchi 
51527687d0d8SRobert Mustacchi 		if (close(fd) != 0) {
51537687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to close output file "
51547687d0d8SRobert Mustacchi 			    "descriptor");
51557687d0d8SRobert Mustacchi 		}
51567687d0d8SRobert Mustacchi 
51577687d0d8SRobert Mustacchi 		return (EXIT_SUCCESS);
51587687d0d8SRobert Mustacchi 	} else {
51597687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_t psc;
51607687d0d8SRobert Mustacchi 		pcieadm_di_walk_t walk;
51617687d0d8SRobert Mustacchi 
51627687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_eff) !=
51637687d0d8SRobert Mustacchi 		    0) {
51647687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to raise privileges");
51657687d0d8SRobert Mustacchi 		}
51667687d0d8SRobert Mustacchi 
51677687d0d8SRobert Mustacchi 		if ((psc.psc_dirfd = open(argv[0], O_RDONLY | O_DIRECTORY)) <
51687687d0d8SRobert Mustacchi 		    0) {
51697687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to open output directory %s",
51707687d0d8SRobert Mustacchi 			    argv[0]);
51717687d0d8SRobert Mustacchi 		}
51727687d0d8SRobert Mustacchi 
51737687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_min) !=
51747687d0d8SRobert Mustacchi 		    0) {
51757687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to reduce privileges");
51767687d0d8SRobert Mustacchi 		}
51777687d0d8SRobert Mustacchi 
51787687d0d8SRobert Mustacchi 		psc.psc_nsaved = 0;
51797687d0d8SRobert Mustacchi 		psc.psc_ret = EXIT_SUCCESS;
51807687d0d8SRobert Mustacchi 		psc.psc_pci = pcip;
51817687d0d8SRobert Mustacchi 
51827687d0d8SRobert Mustacchi 		walk.pdw_arg = &psc;
51837687d0d8SRobert Mustacchi 		walk.pdw_func = pcieadm_save_cfgspace_cb;
51847687d0d8SRobert Mustacchi 		pcieadm_di_walk(pcip, &walk);
51857687d0d8SRobert Mustacchi 
51867687d0d8SRobert Mustacchi 		VERIFY0(close(psc.psc_dirfd));
51877687d0d8SRobert Mustacchi 
51887687d0d8SRobert Mustacchi 		if (psc.psc_nsaved == 0) {
51897687d0d8SRobert Mustacchi 			warnx("failed to save any PCI devices");
51907687d0d8SRobert Mustacchi 			return (EXIT_FAILURE);
51917687d0d8SRobert Mustacchi 		}
51927687d0d8SRobert Mustacchi 
51937687d0d8SRobert Mustacchi 		pcieadm_print("successfully saved %u devices to %s\n",
51947687d0d8SRobert Mustacchi 		    psc.psc_nsaved, argv[0]);
51957687d0d8SRobert Mustacchi 		return (psc.psc_ret);
51967687d0d8SRobert Mustacchi 	}
51977687d0d8SRobert Mustacchi }
5198