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*8a300ed6SRobert Mustacchi  * Copyright 2024 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>
604a8bbc0bSRobert Mustacchi #include <sys/bitext.h>
617687d0d8SRobert Mustacchi 
627687d0d8SRobert Mustacchi #include "pcieadm.h"
637687d0d8SRobert Mustacchi 
64*8a300ed6SRobert Mustacchi /*
65*8a300ed6SRobert Mustacchi  * A few required forwards
66*8a300ed6SRobert Mustacchi  */
67*8a300ed6SRobert Mustacchi struct pcieadm_cfgspace_walk;
68*8a300ed6SRobert Mustacchi struct pcieadm_regdef;
69*8a300ed6SRobert Mustacchi 
707687d0d8SRobert Mustacchi typedef enum pcieadm_cfgspace_op {
717687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OP_PRINT,
727687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OP_WRITE
737687d0d8SRobert Mustacchi } pcieadm_cfgspace_op_t;
747687d0d8SRobert Mustacchi 
757687d0d8SRobert Mustacchi typedef enum piceadm_cfgspace_flag {
767687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_F_PARSE	= 1 << 0,
777687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_F_SHORT	= 1 << 1,
787687d0d8SRobert Mustacchi } pcieadm_cfgspace_flags_t;
797687d0d8SRobert Mustacchi 
807687d0d8SRobert Mustacchi typedef enum pcieadm_cfgspace_otype {
817687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_SHORT,
827687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_HUMAN,
837687d0d8SRobert Mustacchi 	PCIEADM_CFGSPACE_OT_VALUE
847687d0d8SRobert Mustacchi } pcieadm_cfgsapce_otype_t;
857687d0d8SRobert Mustacchi 
867687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_ofmt {
877687d0d8SRobert Mustacchi 	const char *pco_base;
887687d0d8SRobert Mustacchi 	const char *pco_short;
897687d0d8SRobert Mustacchi 	const char *pco_human;
907687d0d8SRobert Mustacchi 	uint64_t pco_value;
917687d0d8SRobert Mustacchi 	const char *pco_strval;
927687d0d8SRobert Mustacchi } pcieadm_cfgspace_ofmt_t;
937687d0d8SRobert Mustacchi 
947687d0d8SRobert Mustacchi typedef enum pcieadm_regdef_val {
957687d0d8SRobert Mustacchi 	PRDV_STRVAL,
967687d0d8SRobert Mustacchi 	PRDV_BITFIELD,
97*8a300ed6SRobert Mustacchi 	PRDV_HEX,
98*8a300ed6SRobert Mustacchi 	PRDV_CUSTOM
997687d0d8SRobert Mustacchi } pcieadm_regdef_val_t;
1007687d0d8SRobert Mustacchi 
1017687d0d8SRobert Mustacchi typedef struct pcieadm_regdef_addend {
1027687d0d8SRobert Mustacchi 	uint8_t pra_shift;
1037687d0d8SRobert Mustacchi 	int64_t pra_addend;
1047687d0d8SRobert Mustacchi } pcieadm_regdef_addend_t;
1057687d0d8SRobert Mustacchi 
1067687d0d8SRobert Mustacchi typedef struct pcieadm_regdef {
1077687d0d8SRobert Mustacchi 	uint8_t prd_lowbit;
1087687d0d8SRobert Mustacchi 	uint8_t prd_hibit;
1097687d0d8SRobert Mustacchi 	const char *prd_short;
1107687d0d8SRobert Mustacchi 	const char *prd_human;
1117687d0d8SRobert Mustacchi 	pcieadm_regdef_val_t prd_valtype;
1127687d0d8SRobert Mustacchi 	union {
1137687d0d8SRobert Mustacchi 		/*
1147687d0d8SRobert Mustacchi 		 * Enough space for up to an 8-bit fields worth of values
1157687d0d8SRobert Mustacchi 		 * (though we expect most to be sparse).
1167687d0d8SRobert Mustacchi 		 */
1177687d0d8SRobert Mustacchi 		const char *prdv_strval[128];
1187687d0d8SRobert Mustacchi 		pcieadm_regdef_addend_t prdv_hex;
119*8a300ed6SRobert Mustacchi 		void (*prdv_func)(struct pcieadm_cfgspace_walk *,
120*8a300ed6SRobert Mustacchi 		    const struct pcieadm_regdef *, uint64_t);
1217687d0d8SRobert Mustacchi 	} prd_val;
1227687d0d8SRobert Mustacchi } pcieadm_regdef_t;
1237687d0d8SRobert Mustacchi 
1247687d0d8SRobert Mustacchi typedef struct pcieadm_unitdef {
1257687d0d8SRobert Mustacchi 	const char *pcd_unit;
1267687d0d8SRobert Mustacchi 	uint32_t pcd_mult;
1277687d0d8SRobert Mustacchi } pcieadm_unitdef_t;
1287687d0d8SRobert Mustacchi 
1297687d0d8SRobert Mustacchi typedef struct pcieadm_strmap {
1307687d0d8SRobert Mustacchi 	const char *psr_str;
1317687d0d8SRobert Mustacchi 	uint64_t psr_val;
1327687d0d8SRobert Mustacchi } pcieadm_strmap_t;
1337687d0d8SRobert Mustacchi 
1347687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_filter {
1357687d0d8SRobert Mustacchi 	const char *pcf_string;
1367687d0d8SRobert Mustacchi 	size_t pcf_len;
1377687d0d8SRobert Mustacchi 	boolean_t pcf_used;
1387687d0d8SRobert Mustacchi } pcieadm_cfgspace_filter_t;
1397687d0d8SRobert Mustacchi 
1407687d0d8SRobert Mustacchi typedef struct pcieadm_strfilt {
1417687d0d8SRobert Mustacchi 	struct pcieadm_strfilt *pstr_next;
1427687d0d8SRobert Mustacchi 	const char *pstr_str;
1437687d0d8SRobert Mustacchi 	char pstr_curgen[256];
1447687d0d8SRobert Mustacchi } pcieadm_strfilt_t;
1457687d0d8SRobert Mustacchi 
1467687d0d8SRobert Mustacchi /*
1477687d0d8SRobert Mustacchi  * Data is sized to be large enough that we can hold all of PCIe extended
1487687d0d8SRobert Mustacchi  * configuration space.
1497687d0d8SRobert Mustacchi  */
1507687d0d8SRobert Mustacchi typedef union pcieadm_cfgspace_data {
1517687d0d8SRobert Mustacchi 	uint8_t pcb_u8[PCIE_CONF_HDR_SIZE];
1527687d0d8SRobert Mustacchi 	uint32_t pcb_u32[PCIE_CONF_HDR_SIZE / 4];
1537687d0d8SRobert Mustacchi } pcieadm_cfgspace_data_t;
1547687d0d8SRobert Mustacchi 
1557687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_walk {
1567687d0d8SRobert Mustacchi 	pcieadm_t *pcw_pcieadm;
1577687d0d8SRobert Mustacchi 	pcieadm_cfgspace_op_t pcw_op;
1587687d0d8SRobert Mustacchi 	uint32_t pcw_valid;
1597687d0d8SRobert Mustacchi 	pcieadm_cfgspace_data_t *pcw_data;
1607687d0d8SRobert Mustacchi 	uint16_t pcw_capoff;
1617687d0d8SRobert Mustacchi 	uint32_t pcw_caplen;
1627687d0d8SRobert Mustacchi 	int pcw_outfd;
1637687d0d8SRobert Mustacchi 	uint_t pcw_dtype;
1647687d0d8SRobert Mustacchi 	uint_t pcw_nlanes;
1657687d0d8SRobert Mustacchi 	uint_t pcw_pcietype;
1667687d0d8SRobert Mustacchi 	uint_t pcw_nfilters;
1677687d0d8SRobert Mustacchi 	pcieadm_cfgspace_filter_t *pcw_filters;
1687687d0d8SRobert Mustacchi 	pcieadm_cfgspace_flags_t pcw_flags;
1697687d0d8SRobert Mustacchi 	ofmt_handle_t pcw_ofmt;
1707687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *pcw_filt;
1717687d0d8SRobert Mustacchi } pcieadm_cfgspace_walk_t;
1727687d0d8SRobert Mustacchi 
1737687d0d8SRobert Mustacchi void
pcieadm_strfilt_pop(pcieadm_cfgspace_walk_t * walkp)1747687d0d8SRobert Mustacchi pcieadm_strfilt_pop(pcieadm_cfgspace_walk_t *walkp)
1757687d0d8SRobert Mustacchi {
1767687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *filt;
1777687d0d8SRobert Mustacchi 
1787687d0d8SRobert Mustacchi 	VERIFY3P(walkp->pcw_filt, !=, NULL);
1797687d0d8SRobert Mustacchi 	filt = walkp->pcw_filt;
1807687d0d8SRobert Mustacchi 	walkp->pcw_filt = filt->pstr_next;
1817687d0d8SRobert Mustacchi 	free(filt);
1827687d0d8SRobert Mustacchi }
1837687d0d8SRobert Mustacchi 
1847687d0d8SRobert Mustacchi void
pcieadm_strfilt_push(pcieadm_cfgspace_walk_t * walkp,const char * str)1857687d0d8SRobert Mustacchi pcieadm_strfilt_push(pcieadm_cfgspace_walk_t *walkp, const char *str)
1867687d0d8SRobert Mustacchi {
1877687d0d8SRobert Mustacchi 	pcieadm_strfilt_t *filt;
1887687d0d8SRobert Mustacchi 	size_t len;
1897687d0d8SRobert Mustacchi 
1907687d0d8SRobert Mustacchi 	filt = calloc(1, sizeof (*filt));
1917687d0d8SRobert Mustacchi 	if (filt == NULL) {
1927687d0d8SRobert Mustacchi 		errx(EXIT_FAILURE, "failed to allocate memory for string "
1937687d0d8SRobert Mustacchi 		    "filter");
1947687d0d8SRobert Mustacchi 	}
1957687d0d8SRobert Mustacchi 
1967687d0d8SRobert Mustacchi 	filt->pstr_str = str;
1977687d0d8SRobert Mustacchi 	if (walkp->pcw_filt == NULL) {
1987687d0d8SRobert Mustacchi 		len = strlcat(filt->pstr_curgen, str,
1997687d0d8SRobert Mustacchi 		    sizeof (filt->pstr_curgen));
2007687d0d8SRobert Mustacchi 	} else {
2017687d0d8SRobert Mustacchi 		len = snprintf(filt->pstr_curgen, sizeof (filt->pstr_curgen),
2027687d0d8SRobert Mustacchi 		    "%s.%s", walkp->pcw_filt->pstr_curgen, str);
2037687d0d8SRobert Mustacchi 		filt->pstr_next = walkp->pcw_filt;
2047687d0d8SRobert Mustacchi 	}
2057687d0d8SRobert Mustacchi 
2067687d0d8SRobert Mustacchi 	if (len >= sizeof (filt->pstr_curgen)) {
2077687d0d8SRobert Mustacchi 		errx(EXIT_FAILURE, "overflowed internal string buffer "
2087687d0d8SRobert Mustacchi 		    "appending %s", str);
2097687d0d8SRobert Mustacchi 	}
2107687d0d8SRobert Mustacchi 
2117687d0d8SRobert Mustacchi 	walkp->pcw_filt = filt;
2127687d0d8SRobert Mustacchi }
2137687d0d8SRobert Mustacchi 
2147687d0d8SRobert Mustacchi static boolean_t
pcieadm_cfgspace_filter(pcieadm_cfgspace_walk_t * walkp,const char * str)2157687d0d8SRobert Mustacchi pcieadm_cfgspace_filter(pcieadm_cfgspace_walk_t *walkp, const char *str)
2167687d0d8SRobert Mustacchi {
2177687d0d8SRobert Mustacchi 	char buf[1024];
2187687d0d8SRobert Mustacchi 	size_t len;
2197687d0d8SRobert Mustacchi 
2207687d0d8SRobert Mustacchi 	if (walkp->pcw_nfilters == 0) {
2217687d0d8SRobert Mustacchi 		return (B_TRUE);
2227687d0d8SRobert Mustacchi 	}
2237687d0d8SRobert Mustacchi 
2247687d0d8SRobert Mustacchi 	if (str == NULL) {
2257687d0d8SRobert Mustacchi 		return (B_FALSE);
2267687d0d8SRobert Mustacchi 	}
2277687d0d8SRobert Mustacchi 
2287687d0d8SRobert Mustacchi 	if (walkp->pcw_filt != NULL) {
2297687d0d8SRobert Mustacchi 		len = snprintf(buf, sizeof (buf), "%s.%s",
2307687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, str);
2317687d0d8SRobert Mustacchi 	} else {
2327687d0d8SRobert Mustacchi 		len = snprintf(buf, sizeof (buf), "%s", str);
2337687d0d8SRobert Mustacchi 	}
2347687d0d8SRobert Mustacchi 
2357687d0d8SRobert Mustacchi 	if (len >= sizeof (buf)) {
2367687d0d8SRobert Mustacchi 		abort();
2377687d0d8SRobert Mustacchi 	}
2387687d0d8SRobert Mustacchi 
2397687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nfilters; i++) {
2407687d0d8SRobert Mustacchi 		if (strcmp(buf, walkp->pcw_filters[i].pcf_string) == 0) {
2417687d0d8SRobert Mustacchi 			walkp->pcw_filters[i].pcf_used = B_TRUE;
2427687d0d8SRobert Mustacchi 			return (B_TRUE);
2437687d0d8SRobert Mustacchi 		}
2447687d0d8SRobert Mustacchi 
2457687d0d8SRobert Mustacchi 		/*
2467687d0d8SRobert Mustacchi 		 * If we're in non-parsable mode, we want to do a little bit
2477687d0d8SRobert Mustacchi 		 * more in a few cases. We want to make sure that we print the
2487687d0d8SRobert Mustacchi 		 * parents of more-specific entries. That is, if someone
2497687d0d8SRobert Mustacchi 		 * specified 'header.command.serr', then we want to print
2507687d0d8SRobert Mustacchi 		 * 'header', and 'header.command'. Similarly, if someone
2517687d0d8SRobert Mustacchi 		 * specifies an individual field, we want to print all of its
2527687d0d8SRobert Mustacchi 		 * subfields, that is asking for 'header.command', really gets
2537687d0d8SRobert Mustacchi 		 * that and all of 'header.command.*'.
2547687d0d8SRobert Mustacchi 		 */
2557687d0d8SRobert Mustacchi 		if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_PARSE) != 0) {
2567687d0d8SRobert Mustacchi 			continue;
2577687d0d8SRobert Mustacchi 		}
2587687d0d8SRobert Mustacchi 
2597687d0d8SRobert Mustacchi 		if (len >= walkp->pcw_filters[i].pcf_len) {
2607687d0d8SRobert Mustacchi 			if (strncmp(buf, walkp->pcw_filters[i].pcf_string,
2617687d0d8SRobert Mustacchi 			    walkp->pcw_filters[i].pcf_len) == 0 &&
2627687d0d8SRobert Mustacchi 			    buf[walkp->pcw_filters[i].pcf_len] == '.') {
2637687d0d8SRobert Mustacchi 				return (B_TRUE);
2647687d0d8SRobert Mustacchi 			}
2657687d0d8SRobert Mustacchi 		} else {
2667687d0d8SRobert Mustacchi 			if (strncmp(buf, walkp->pcw_filters[i].pcf_string,
2677687d0d8SRobert Mustacchi 			    len) == 0 &&
2687687d0d8SRobert Mustacchi 			    walkp->pcw_filters[i].pcf_string[len] == '.') {
2697687d0d8SRobert Mustacchi 				return (B_TRUE);
2707687d0d8SRobert Mustacchi 			}
2717687d0d8SRobert Mustacchi 		}
2727687d0d8SRobert Mustacchi 	}
2737687d0d8SRobert Mustacchi 
2747687d0d8SRobert Mustacchi 	return (B_FALSE);
2757687d0d8SRobert Mustacchi }
2767687d0d8SRobert Mustacchi 
2777687d0d8SRobert Mustacchi static boolean_t
pcieadm_cfgspace_ofmt_cb(ofmt_arg_t * ofarg,char * buf,uint_t buflen)2787687d0d8SRobert Mustacchi pcieadm_cfgspace_ofmt_cb(ofmt_arg_t *ofarg, char *buf, uint_t buflen)
2797687d0d8SRobert Mustacchi {
2807687d0d8SRobert Mustacchi 	pcieadm_cfgspace_ofmt_t *pco = ofarg->ofmt_cbarg;
2817687d0d8SRobert Mustacchi 
2827687d0d8SRobert Mustacchi 	switch (ofarg->ofmt_id) {
2837687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_SHORT:
2847687d0d8SRobert Mustacchi 		if (snprintf(buf, buflen, "%s.%s", pco->pco_base,
2857687d0d8SRobert Mustacchi 		    pco->pco_short) >= buflen) {
2867687d0d8SRobert Mustacchi 			return (B_FALSE);
2877687d0d8SRobert Mustacchi 		}
2887687d0d8SRobert Mustacchi 		break;
2897687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_HUMAN:
2907687d0d8SRobert Mustacchi 		if (strlcpy(buf, pco->pco_human, buflen) >= buflen) {
2917687d0d8SRobert Mustacchi 			return (B_FALSE);
2927687d0d8SRobert Mustacchi 		}
2937687d0d8SRobert Mustacchi 		break;
2947687d0d8SRobert Mustacchi 	case PCIEADM_CFGSPACE_OT_VALUE:
2957687d0d8SRobert Mustacchi 		if (pco->pco_strval != NULL) {
2967687d0d8SRobert Mustacchi 			if (strlcpy(buf, pco->pco_strval, buflen) >= buflen) {
2977687d0d8SRobert Mustacchi 				return (B_FALSE);
2987687d0d8SRobert Mustacchi 			}
2997687d0d8SRobert Mustacchi 		} else {
3007687d0d8SRobert Mustacchi 			if (snprintf(buf, buflen, "0x%" PRIx64,
3017687d0d8SRobert Mustacchi 			    pco->pco_value) >= buflen) {
3027687d0d8SRobert Mustacchi 				return (B_FALSE);
3037687d0d8SRobert Mustacchi 			}
3047687d0d8SRobert Mustacchi 		}
3057687d0d8SRobert Mustacchi 		break;
3067687d0d8SRobert Mustacchi 	default:
3077687d0d8SRobert Mustacchi 		abort();
3087687d0d8SRobert Mustacchi 	}
3097687d0d8SRobert Mustacchi 
3107687d0d8SRobert Mustacchi 	return (B_TRUE);
3117687d0d8SRobert Mustacchi }
3127687d0d8SRobert Mustacchi 
3137687d0d8SRobert Mustacchi 
3147687d0d8SRobert Mustacchi static const ofmt_field_t pcieadm_cfgspace_ofmt[] = {
3157687d0d8SRobert Mustacchi 	{ "SHORT", 30, PCIEADM_CFGSPACE_OT_SHORT, pcieadm_cfgspace_ofmt_cb },
3167687d0d8SRobert Mustacchi 	{ "HUMAN", 30, PCIEADM_CFGSPACE_OT_HUMAN, pcieadm_cfgspace_ofmt_cb },
3177687d0d8SRobert Mustacchi 	{ "VALUE", 20, PCIEADM_CFGSPACE_OT_VALUE, pcieadm_cfgspace_ofmt_cb },
3187687d0d8SRobert Mustacchi 	{ NULL, 0, 0, NULL }
3197687d0d8SRobert Mustacchi };
3207687d0d8SRobert Mustacchi 
3217687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_parse(pcieadm_cfgspace_walk_t * walkp,const char * sname,const char * human,uint64_t value)3227687d0d8SRobert Mustacchi pcieadm_cfgspace_print_parse(pcieadm_cfgspace_walk_t *walkp,
3237687d0d8SRobert Mustacchi     const char *sname, const char *human, uint64_t value)
3247687d0d8SRobert Mustacchi {
3257687d0d8SRobert Mustacchi 	pcieadm_cfgspace_ofmt_t pco;
3267687d0d8SRobert Mustacchi 
3277687d0d8SRobert Mustacchi 	VERIFY3P(walkp->pcw_filt, !=, NULL);
3287687d0d8SRobert Mustacchi 	pco.pco_base = walkp->pcw_filt->pstr_curgen;
3297687d0d8SRobert Mustacchi 	pco.pco_short = sname;
3307687d0d8SRobert Mustacchi 	pco.pco_human = human;
3317687d0d8SRobert Mustacchi 	pco.pco_value = value;
3327687d0d8SRobert Mustacchi 	pco.pco_strval = NULL;
3337687d0d8SRobert Mustacchi 	ofmt_print(walkp->pcw_ofmt, &pco);
3347687d0d8SRobert Mustacchi }
3357687d0d8SRobert Mustacchi 
3367687d0d8SRobert Mustacchi typedef struct pcieadm_cfgspace_print pcieadm_cfgspace_print_t;
3377687d0d8SRobert Mustacchi typedef void (*pcieadm_cfgspace_print_f)(pcieadm_cfgspace_walk_t *,
3384a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *, const void *);
3397687d0d8SRobert Mustacchi 
3407687d0d8SRobert Mustacchi struct pcieadm_cfgspace_print {
3417687d0d8SRobert Mustacchi 	uint8_t pcp_off;
3427687d0d8SRobert Mustacchi 	uint8_t pcp_len;
3437687d0d8SRobert Mustacchi 	const char *pcp_short;
3447687d0d8SRobert Mustacchi 	const char *pcp_human;
3457687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_f pcp_print;
3464a8bbc0bSRobert Mustacchi 	const void *pcp_arg;
3477687d0d8SRobert Mustacchi };
3487687d0d8SRobert Mustacchi 
3497687d0d8SRobert Mustacchi static void
pcieadm_field_printf(pcieadm_cfgspace_walk_t * walkp,const char * shortf,const char * humanf,uint64_t val,const char * fmt,...)3507687d0d8SRobert Mustacchi pcieadm_field_printf(pcieadm_cfgspace_walk_t *walkp, const char *shortf,
3517687d0d8SRobert Mustacchi     const char *humanf, uint64_t val, const char *fmt, ...)
3527687d0d8SRobert Mustacchi {
3537687d0d8SRobert Mustacchi 	va_list ap;
3547687d0d8SRobert Mustacchi 
3557687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, shortf))
3567687d0d8SRobert Mustacchi 		return;
3577687d0d8SRobert Mustacchi 
3587687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
3597687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_parse(walkp, shortf, humanf, val);
3607687d0d8SRobert Mustacchi 		return;
3617687d0d8SRobert Mustacchi 	}
3627687d0d8SRobert Mustacchi 
3637687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
3647687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
3657687d0d8SRobert Mustacchi 	}
3667687d0d8SRobert Mustacchi 
3677687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
3687687d0d8SRobert Mustacchi 		(void) printf("|--> %s (%s.%s): ", humanf,
3697687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, shortf);
3707687d0d8SRobert Mustacchi 	} else {
3717687d0d8SRobert Mustacchi 		(void) printf("|--> %s: ", humanf);
3727687d0d8SRobert Mustacchi 	}
3737687d0d8SRobert Mustacchi 
3747687d0d8SRobert Mustacchi 	va_start(ap, fmt);
3757687d0d8SRobert Mustacchi 	(void) vprintf(fmt, ap);
3767687d0d8SRobert Mustacchi 	va_end(ap);
3777687d0d8SRobert Mustacchi 
3787687d0d8SRobert Mustacchi }
3797687d0d8SRobert Mustacchi 
3807687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_printf(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,uint64_t val,const char * fmt,...)3817687d0d8SRobert Mustacchi pcieadm_cfgspace_printf(pcieadm_cfgspace_walk_t *walkp,
3824a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, uint64_t val, const char *fmt, ...)
3837687d0d8SRobert Mustacchi {
3847687d0d8SRobert Mustacchi 	va_list ap;
3857687d0d8SRobert Mustacchi 
3867687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, print->pcp_short))
3877687d0d8SRobert Mustacchi 		return;
3887687d0d8SRobert Mustacchi 
3897687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
3907687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_parse(walkp, print->pcp_short,
3917687d0d8SRobert Mustacchi 		    print->pcp_human, val);
3927687d0d8SRobert Mustacchi 		return;
3937687d0d8SRobert Mustacchi 	}
3947687d0d8SRobert Mustacchi 
3957687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
3967687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
3977687d0d8SRobert Mustacchi 	}
3987687d0d8SRobert Mustacchi 
3997687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
4007687d0d8SRobert Mustacchi 		(void) printf("%s (%s.%s): ", print->pcp_human,
4017687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, print->pcp_short);
4027687d0d8SRobert Mustacchi 	} else {
4037687d0d8SRobert Mustacchi 		(void) printf("%s: ", print->pcp_human);
4047687d0d8SRobert Mustacchi 	}
4057687d0d8SRobert Mustacchi 
4067687d0d8SRobert Mustacchi 	va_start(ap, fmt);
4077687d0d8SRobert Mustacchi 	(void) vprintf(fmt, ap);
4087687d0d8SRobert Mustacchi 	va_end(ap);
4097687d0d8SRobert Mustacchi }
4107687d0d8SRobert Mustacchi 
4117687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_puts(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const char * str)4127687d0d8SRobert Mustacchi pcieadm_cfgspace_puts(pcieadm_cfgspace_walk_t *walkp,
4134a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const char *str)
4147687d0d8SRobert Mustacchi {
4157687d0d8SRobert Mustacchi 	if (!pcieadm_cfgspace_filter(walkp, print->pcp_short))
4167687d0d8SRobert Mustacchi 		return;
4177687d0d8SRobert Mustacchi 
4187687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt != NULL) {
4197687d0d8SRobert Mustacchi 		pcieadm_cfgspace_ofmt_t pco;
4207687d0d8SRobert Mustacchi 
4217687d0d8SRobert Mustacchi 		VERIFY3P(walkp->pcw_filt, !=, NULL);
4227687d0d8SRobert Mustacchi 		pco.pco_base = walkp->pcw_filt->pstr_curgen;
4237687d0d8SRobert Mustacchi 		pco.pco_short = print->pcp_short;
4247687d0d8SRobert Mustacchi 		pco.pco_human = print->pcp_human;
4257687d0d8SRobert Mustacchi 		pco.pco_strval = str;
4267687d0d8SRobert Mustacchi 		ofmt_print(walkp->pcw_ofmt, &pco);
4277687d0d8SRobert Mustacchi 		return;
4287687d0d8SRobert Mustacchi 	}
4297687d0d8SRobert Mustacchi 
4307687d0d8SRobert Mustacchi 	if (walkp->pcw_pcieadm->pia_indent > 0) {
4317687d0d8SRobert Mustacchi 		(void) printf("%*s", walkp->pcw_pcieadm->pia_indent, "");
4327687d0d8SRobert Mustacchi 	}
4337687d0d8SRobert Mustacchi 
4347687d0d8SRobert Mustacchi 	if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
4357687d0d8SRobert Mustacchi 		(void) printf("%s (%s.%s): %s\n", print->pcp_human,
4367687d0d8SRobert Mustacchi 		    walkp->pcw_filt->pstr_curgen, print->pcp_short, str);
4377687d0d8SRobert Mustacchi 	} else {
4387687d0d8SRobert Mustacchi 		(void) printf("%s: %s\n", print->pcp_human, str);
4397687d0d8SRobert Mustacchi 	}
4407687d0d8SRobert Mustacchi }
4417687d0d8SRobert Mustacchi 
4427687d0d8SRobert Mustacchi static uint64_t
pcieadm_cfgspace_extract(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print)4437687d0d8SRobert Mustacchi pcieadm_cfgspace_extract(pcieadm_cfgspace_walk_t *walkp,
4444a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print)
4457687d0d8SRobert Mustacchi {
4467687d0d8SRobert Mustacchi 	uint32_t val = 0;
4477687d0d8SRobert Mustacchi 
4487687d0d8SRobert Mustacchi 	VERIFY3U(print->pcp_len, <=, 8);
4497687d0d8SRobert Mustacchi 	VERIFY3U(print->pcp_off + print->pcp_len + walkp->pcw_capoff, <=,
4507687d0d8SRobert Mustacchi 	    walkp->pcw_valid);
4517687d0d8SRobert Mustacchi 	for (uint8_t i = print->pcp_len; i > 0; i--) {
4527687d0d8SRobert Mustacchi 		val <<= 8;
4537687d0d8SRobert Mustacchi 		val |= walkp->pcw_data->pcb_u8[walkp->pcw_capoff +
4547687d0d8SRobert Mustacchi 		    print->pcp_off + i - 1];
4557687d0d8SRobert Mustacchi 	}
4567687d0d8SRobert Mustacchi 
4577687d0d8SRobert Mustacchi 	return (val);
4587687d0d8SRobert Mustacchi }
4597687d0d8SRobert Mustacchi 
4607687d0d8SRobert Mustacchi static uint16_t
pcieadm_cfgspace_extract_u16(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print)4617687d0d8SRobert Mustacchi pcieadm_cfgspace_extract_u16(pcieadm_cfgspace_walk_t *walkp,
4624a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print)
4637687d0d8SRobert Mustacchi {
4647687d0d8SRobert Mustacchi 	VERIFY(print->pcp_len == 2);
4657687d0d8SRobert Mustacchi 	return ((uint16_t)pcieadm_cfgspace_extract(walkp, print));
4667687d0d8SRobert Mustacchi }
4677687d0d8SRobert Mustacchi 
4687687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_unit(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)4697687d0d8SRobert Mustacchi pcieadm_cfgspace_print_unit(pcieadm_cfgspace_walk_t *walkp,
4704a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
4717687d0d8SRobert Mustacchi {
4724a8bbc0bSRobert Mustacchi 	const pcieadm_unitdef_t *unit = arg;
4737687d0d8SRobert Mustacchi 	uint64_t rawval = pcieadm_cfgspace_extract(walkp, print);
4747687d0d8SRobert Mustacchi 	uint64_t val = rawval;
4757687d0d8SRobert Mustacchi 
4767687d0d8SRobert Mustacchi 	if (unit->pcd_mult > 1) {
4777687d0d8SRobert Mustacchi 		val *= unit->pcd_mult;
4787687d0d8SRobert Mustacchi 	}
4797687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, rawval, "0x%" PRIx64 " %s%s\n",
4807687d0d8SRobert Mustacchi 	    val, unit->pcd_unit, val != 1 ? "s" : "");
4817687d0d8SRobert Mustacchi }
4827687d0d8SRobert Mustacchi 
4837687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_regdef(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)4847687d0d8SRobert Mustacchi pcieadm_cfgspace_print_regdef(pcieadm_cfgspace_walk_t *walkp,
4854a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
4867687d0d8SRobert Mustacchi {
4874a8bbc0bSRobert Mustacchi 	const pcieadm_regdef_t *regdef = arg;
4887687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
4897687d0d8SRobert Mustacchi 
4907687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val);
4917687d0d8SRobert Mustacchi 
4927687d0d8SRobert Mustacchi 	pcieadm_indent();
4937687d0d8SRobert Mustacchi 	pcieadm_strfilt_push(walkp, print->pcp_short);
4947687d0d8SRobert Mustacchi 
4957687d0d8SRobert Mustacchi 	for (regdef = arg; regdef->prd_short != NULL; regdef++) {
4967687d0d8SRobert Mustacchi 		uint32_t nbits = regdef->prd_hibit - regdef->prd_lowbit + 1UL;
4977687d0d8SRobert Mustacchi 		uint32_t bitmask = (1UL << nbits) - 1UL;
4987687d0d8SRobert Mustacchi 		uint64_t regval = (val >> regdef->prd_lowbit) & bitmask;
4997687d0d8SRobert Mustacchi 		const char *strval;
5007687d0d8SRobert Mustacchi 		uint64_t actval;
5017687d0d8SRobert Mustacchi 
5027687d0d8SRobert Mustacchi 		if (!pcieadm_cfgspace_filter(walkp, regdef->prd_short)) {
5037687d0d8SRobert Mustacchi 			continue;
5047687d0d8SRobert Mustacchi 		}
5057687d0d8SRobert Mustacchi 
5067687d0d8SRobert Mustacchi 		switch (regdef->prd_valtype) {
5077687d0d8SRobert Mustacchi 		case PRDV_STRVAL:
5087687d0d8SRobert Mustacchi 			strval = regdef->prd_val.prdv_strval[regval];
5097687d0d8SRobert Mustacchi 			if (strval == NULL) {
5107687d0d8SRobert Mustacchi 				strval = "reserved";
5117687d0d8SRobert Mustacchi 			}
51292f11af9SRobert Mustacchi 
5137687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
5147687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "%s (0x%" PRIx64 ")\n",
5157687d0d8SRobert Mustacchi 			    strval, regval << regdef->prd_lowbit);
5167687d0d8SRobert Mustacchi 			break;
5177687d0d8SRobert Mustacchi 		case PRDV_HEX:
5187687d0d8SRobert Mustacchi 			actval = regval;
5197687d0d8SRobert Mustacchi 			if (regdef->prd_val.prdv_hex.pra_shift > 0) {
5207687d0d8SRobert Mustacchi 				actval <<= regdef->prd_val.prdv_hex.pra_shift;
5217687d0d8SRobert Mustacchi 			}
5227687d0d8SRobert Mustacchi 			actval += regdef->prd_val.prdv_hex.pra_addend;
5237687d0d8SRobert Mustacchi 
5247687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
5257687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "0x% " PRIx64 "\n",
5267687d0d8SRobert Mustacchi 			    actval);
5277687d0d8SRobert Mustacchi 			break;
5287687d0d8SRobert Mustacchi 		case PRDV_BITFIELD:
5297687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, regdef->prd_short,
5307687d0d8SRobert Mustacchi 			    regdef->prd_human, regval, "0x%" PRIx64 "\n",
5317687d0d8SRobert Mustacchi 			    regval << regdef->prd_lowbit);
5327687d0d8SRobert Mustacchi 
5337687d0d8SRobert Mustacchi 			if (walkp->pcw_ofmt == NULL) {
5347687d0d8SRobert Mustacchi 				pcieadm_indent();
5357687d0d8SRobert Mustacchi 				for (uint32_t i = 0; i < nbits; i++) {
5367687d0d8SRobert Mustacchi 					if (((1 << i) & regval) == 0)
5377687d0d8SRobert Mustacchi 						continue;
5387687d0d8SRobert Mustacchi 					pcieadm_print("|--> %s (0x%x)\n",
5397687d0d8SRobert Mustacchi 					    regdef->prd_val.prdv_strval[i],
5407687d0d8SRobert Mustacchi 					    1UL << (i + regdef->prd_lowbit));
5417687d0d8SRobert Mustacchi 				}
5427687d0d8SRobert Mustacchi 				pcieadm_deindent();
5437687d0d8SRobert Mustacchi 			}
5447687d0d8SRobert Mustacchi 			break;
545*8a300ed6SRobert Mustacchi 		case PRDV_CUSTOM:
546*8a300ed6SRobert Mustacchi 			regdef->prd_val.prdv_func(walkp, regdef, regval);
547*8a300ed6SRobert Mustacchi 			break;
5487687d0d8SRobert Mustacchi 		}
5497687d0d8SRobert Mustacchi 	}
5507687d0d8SRobert Mustacchi 
5517687d0d8SRobert Mustacchi 	pcieadm_strfilt_pop(walkp);
5527687d0d8SRobert Mustacchi 	pcieadm_deindent();
5537687d0d8SRobert Mustacchi }
5547687d0d8SRobert Mustacchi 
5557687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_strmap(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)5567687d0d8SRobert Mustacchi pcieadm_cfgspace_print_strmap(pcieadm_cfgspace_walk_t *walkp,
5574a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
5587687d0d8SRobert Mustacchi {
5594a8bbc0bSRobert Mustacchi 	const pcieadm_strmap_t *strmap = arg;
5607687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
5617687d0d8SRobert Mustacchi 	const char *str = "reserved";
5627687d0d8SRobert Mustacchi 
5637687d0d8SRobert Mustacchi 	for (uint_t i = 0; strmap[i].psr_str != NULL; i++) {
5647687d0d8SRobert Mustacchi 		if (strmap[i].psr_val == val) {
5657687d0d8SRobert Mustacchi 			str = strmap[i].psr_str;
5667687d0d8SRobert Mustacchi 			break;
5677687d0d8SRobert Mustacchi 		}
5687687d0d8SRobert Mustacchi 	}
5697687d0d8SRobert Mustacchi 
5707687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%x -- %s\n", val, str);
5717687d0d8SRobert Mustacchi }
5727687d0d8SRobert Mustacchi 
5737687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_hex(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)5747687d0d8SRobert Mustacchi pcieadm_cfgspace_print_hex(pcieadm_cfgspace_walk_t *walkp,
5754a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
5767687d0d8SRobert Mustacchi {
5777687d0d8SRobert Mustacchi 	uint64_t val = pcieadm_cfgspace_extract(walkp, print);
5787687d0d8SRobert Mustacchi 
5797687d0d8SRobert Mustacchi 	pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val);
5807687d0d8SRobert Mustacchi }
5817687d0d8SRobert Mustacchi 
5827687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_vendor(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)5837687d0d8SRobert Mustacchi pcieadm_cfgspace_print_vendor(pcieadm_cfgspace_walk_t *walkp,
5844a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
5857687d0d8SRobert Mustacchi {
5867687d0d8SRobert Mustacchi 	pcidb_vendor_t *vend;
5877687d0d8SRobert Mustacchi 	uint16_t vid = pcieadm_cfgspace_extract_u16(walkp, print);
5887687d0d8SRobert Mustacchi 
5897687d0d8SRobert Mustacchi 	vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb, vid);
5907687d0d8SRobert Mustacchi 	if (vend != NULL) {
5917687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, vid, "0x%x -- %s\n", vid,
5927687d0d8SRobert Mustacchi 		    pcidb_vendor_name(vend));
5937687d0d8SRobert Mustacchi 	} else {
5947687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, vid, "0x%x\n", vid);
5957687d0d8SRobert Mustacchi 	}
5967687d0d8SRobert Mustacchi }
5977687d0d8SRobert Mustacchi 
5987687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_device(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)5997687d0d8SRobert Mustacchi pcieadm_cfgspace_print_device(pcieadm_cfgspace_walk_t *walkp,
6004a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
6017687d0d8SRobert Mustacchi {
6027687d0d8SRobert Mustacchi 	pcidb_device_t *dev;
6037687d0d8SRobert Mustacchi 	uint16_t did = pcieadm_cfgspace_extract_u16(walkp, print);
6047687d0d8SRobert Mustacchi 	uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] +
6057687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8);
6067687d0d8SRobert Mustacchi 
6077687d0d8SRobert Mustacchi 	dev = pcidb_lookup_device(walkp->pcw_pcieadm->pia_pcidb, vid, did);
6087687d0d8SRobert Mustacchi 	if (dev != NULL) {
6097687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, did, "0x%x -- %s\n", did,
6107687d0d8SRobert Mustacchi 		    pcidb_device_name(dev));
6117687d0d8SRobert Mustacchi 	} else {
6127687d0d8SRobert Mustacchi 		pcieadm_cfgspace_printf(walkp, print, did, "0x%x\n", did);
6137687d0d8SRobert Mustacchi 	}
6147687d0d8SRobert Mustacchi }
6157687d0d8SRobert Mustacchi 
6167687d0d8SRobert Mustacchi /*
6177687d0d8SRobert Mustacchi  * To print out detailed information about a subsystem vendor or device, we need
6187687d0d8SRobert Mustacchi  * all of the information about the vendor and device due to the organization of
6197687d0d8SRobert Mustacchi  * the PCI IDs db.
6207687d0d8SRobert Mustacchi  */
6217687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_subid(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)6227687d0d8SRobert Mustacchi pcieadm_cfgspace_print_subid(pcieadm_cfgspace_walk_t *walkp,
6234a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
6247687d0d8SRobert Mustacchi {
6257687d0d8SRobert Mustacchi 	uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] +
6267687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8);
6277687d0d8SRobert Mustacchi 	uint16_t did = walkp->pcw_data->pcb_u8[PCI_CONF_DEVID] +
6287687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_DEVID + 1] << 8);
6297687d0d8SRobert Mustacchi 	uint16_t svid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID] +
6307687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID + 1] << 8);
6317687d0d8SRobert Mustacchi 	uint16_t sdid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID] +
6327687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID + 1] << 8);
6337687d0d8SRobert Mustacchi 	uint16_t val = pcieadm_cfgspace_extract_u16(walkp, print);
6347687d0d8SRobert Mustacchi 	boolean_t isvendor = print->pcp_off == PCI_CONF_SUBVENID;
6357687d0d8SRobert Mustacchi 
6367687d0d8SRobert Mustacchi 	if (isvendor) {
6377687d0d8SRobert Mustacchi 		pcidb_vendor_t *vend;
6387687d0d8SRobert Mustacchi 		vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb,
6397687d0d8SRobert Mustacchi 		    svid);
6407687d0d8SRobert Mustacchi 		if (vend != NULL) {
6417687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
6427687d0d8SRobert Mustacchi 			    "0x%x -- %s\n", val, pcidb_vendor_name(vend));
6437687d0d8SRobert Mustacchi 		} else {
6447687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
6457687d0d8SRobert Mustacchi 			    "0x%x\n", val);
6467687d0d8SRobert Mustacchi 		}
6477687d0d8SRobert Mustacchi 	} else {
6487687d0d8SRobert Mustacchi 		pcidb_subvd_t *subvd;
6497687d0d8SRobert Mustacchi 		subvd = pcidb_lookup_subvd(walkp->pcw_pcieadm->pia_pcidb, vid,
6507687d0d8SRobert Mustacchi 		    did, svid, sdid);
6517687d0d8SRobert Mustacchi 		if (subvd != NULL) {
6527687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val,
6537687d0d8SRobert Mustacchi 			    "0x%x -- %s\n", val, pcidb_subvd_name(subvd));
6547687d0d8SRobert Mustacchi 		} else {
6557687d0d8SRobert Mustacchi 			pcieadm_cfgspace_printf(walkp, print, val, "0x%x\n",
6567687d0d8SRobert Mustacchi 			    val);
6577687d0d8SRobert Mustacchi 		}
6587687d0d8SRobert Mustacchi 	}
6597687d0d8SRobert Mustacchi }
6607687d0d8SRobert Mustacchi 
6617687d0d8SRobert Mustacchi /*
6627687d0d8SRobert Mustacchi  * The variable natures of BARs is a pain. This makes printing this out and the
6637687d0d8SRobert Mustacchi  * fields all a bit gross.
6647687d0d8SRobert Mustacchi  */
6657687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_bars(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)6667687d0d8SRobert Mustacchi pcieadm_cfgspace_print_bars(pcieadm_cfgspace_walk_t *walkp,
6674a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
6687687d0d8SRobert Mustacchi {
6697687d0d8SRobert Mustacchi 	uint32_t *barp = &walkp->pcw_data->pcb_u32[(walkp->pcw_capoff +
6707687d0d8SRobert Mustacchi 	    print->pcp_off) / 4];
6717687d0d8SRobert Mustacchi 	char barname[32];
6727687d0d8SRobert Mustacchi 	const char *typestrs[2] = { "Memory Space", "I/O Space" };
6737687d0d8SRobert Mustacchi 
6747687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < print->pcp_len / 4; i++) {
6757687d0d8SRobert Mustacchi 		uint_t type;
6767687d0d8SRobert Mustacchi 		(void) snprintf(barname, sizeof (barname), "%s%u",
6777687d0d8SRobert Mustacchi 		    print->pcp_short, i);
6787687d0d8SRobert Mustacchi 
6797687d0d8SRobert Mustacchi 		type = barp[i] & PCI_BASE_SPACE_M;
6807687d0d8SRobert Mustacchi 
6817687d0d8SRobert Mustacchi 		if (pcieadm_cfgspace_filter(walkp, barname) &&
6827687d0d8SRobert Mustacchi 		    walkp->pcw_ofmt == NULL) {
6837687d0d8SRobert Mustacchi 			if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) !=
6847687d0d8SRobert Mustacchi 			    0) {
6857687d0d8SRobert Mustacchi 				pcieadm_print("%s %u (%s.%s)\n",
6867687d0d8SRobert Mustacchi 				    print->pcp_human, i,
6877687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, barname);
6887687d0d8SRobert Mustacchi 			} else {
6897687d0d8SRobert Mustacchi 				pcieadm_print("%s %u\n", print->pcp_human, i);
6907687d0d8SRobert Mustacchi 			}
6917687d0d8SRobert Mustacchi 		}
6927687d0d8SRobert Mustacchi 
6937687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(walkp, barname);
6947687d0d8SRobert Mustacchi 		pcieadm_indent();
6957687d0d8SRobert Mustacchi 
6967687d0d8SRobert Mustacchi 		pcieadm_field_printf(walkp, "space", "Space", type,
6977687d0d8SRobert Mustacchi 		    "%s (0x%x)\n", typestrs[type], type);
6987687d0d8SRobert Mustacchi 
6997687d0d8SRobert Mustacchi 		if (type == PCI_BASE_SPACE_IO) {
7007687d0d8SRobert Mustacchi 			uint32_t addr = barp[i] & PCI_BASE_IO_ADDR_M;
7017687d0d8SRobert Mustacchi 
7027687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
7037687d0d8SRobert Mustacchi 			    "0x%" PRIx32 "\n", addr);
7047687d0d8SRobert Mustacchi 		} else {
7057687d0d8SRobert Mustacchi 			uint8_t type, pre;
7067687d0d8SRobert Mustacchi 			uint64_t addr;
7077687d0d8SRobert Mustacchi 			const char *locstr;
7087687d0d8SRobert Mustacchi 
7097687d0d8SRobert Mustacchi 			type = barp[i] & PCI_BASE_TYPE_M;
7107687d0d8SRobert Mustacchi 			pre = barp[i] & PCI_BASE_PREF_M;
7117687d0d8SRobert Mustacchi 			addr = barp[i] & PCI_BASE_M_ADDR_M;
7127687d0d8SRobert Mustacchi 
7137687d0d8SRobert Mustacchi 			if (type == PCI_BASE_TYPE_ALL) {
7147687d0d8SRobert Mustacchi 				addr += (uint64_t)barp[i+1] << 32;
7157687d0d8SRobert Mustacchi 				i++;
7167687d0d8SRobert Mustacchi 			}
7177687d0d8SRobert Mustacchi 
7187687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "addr", "Address", addr,
7197687d0d8SRobert Mustacchi 			    "0x%" PRIx64 "\n", addr);
7207687d0d8SRobert Mustacchi 
7217687d0d8SRobert Mustacchi 			switch (type) {
7227687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_MEM:
7237687d0d8SRobert Mustacchi 				locstr = "32-bit";
7247687d0d8SRobert Mustacchi 				break;
7257687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_LOW:
7267687d0d8SRobert Mustacchi 				locstr = "Sub-1 MiB";
7277687d0d8SRobert Mustacchi 				break;
7287687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_ALL:
7297687d0d8SRobert Mustacchi 				locstr = "64-bit";
7307687d0d8SRobert Mustacchi 				break;
7317687d0d8SRobert Mustacchi 			case PCI_BASE_TYPE_RES:
7327687d0d8SRobert Mustacchi 			default:
7337687d0d8SRobert Mustacchi 				locstr = "Reserved";
7347687d0d8SRobert Mustacchi 				break;
7357687d0d8SRobert Mustacchi 			}
7367687d0d8SRobert Mustacchi 
73766a9cc68SRobert Mustacchi 			pcieadm_field_printf(walkp, "type", "Memory Type", addr,
7387687d0d8SRobert Mustacchi 			    "%s (0x%x)\n", locstr, type >> 1);
7397687d0d8SRobert Mustacchi 			pcieadm_field_printf(walkp, "prefetch", "Prefetchable",
7407687d0d8SRobert Mustacchi 			    pre != 0, "%s (0x%x)\n", pre != 0 ? "yes" : "no",
7417687d0d8SRobert Mustacchi 			    pre != 0);
7427687d0d8SRobert Mustacchi 		}
7437687d0d8SRobert Mustacchi 
7447687d0d8SRobert Mustacchi 		pcieadm_deindent();
7457687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(walkp);
7467687d0d8SRobert Mustacchi 	}
7477687d0d8SRobert Mustacchi }
7487687d0d8SRobert Mustacchi 
7497687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_ecv(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)7507687d0d8SRobert Mustacchi pcieadm_cfgspace_print_ecv(pcieadm_cfgspace_walk_t *walkp,
7514a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
7527687d0d8SRobert Mustacchi {
7537687d0d8SRobert Mustacchi 	uint16_t bitlen, nwords;
7547687d0d8SRobert Mustacchi 
7554a8bbc0bSRobert Mustacchi 	if (bitx8(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 5, 5) == 0) {
7567687d0d8SRobert Mustacchi 		return;
7577687d0d8SRobert Mustacchi 	}
7587687d0d8SRobert Mustacchi 
7597687d0d8SRobert Mustacchi 	bitlen = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 5];
7607687d0d8SRobert Mustacchi 	if (bitlen == 0) {
7617687d0d8SRobert Mustacchi 		bitlen = 256;
7627687d0d8SRobert Mustacchi 	}
7637687d0d8SRobert Mustacchi 
7647687d0d8SRobert Mustacchi 	nwords = bitlen / 32;
7657687d0d8SRobert Mustacchi 	if ((bitlen % 8) != 0) {
7667687d0d8SRobert Mustacchi 		nwords++;
7677687d0d8SRobert Mustacchi 	}
7687687d0d8SRobert Mustacchi 
7697687d0d8SRobert Mustacchi 	for (uint16_t i = 0; i < nwords; i++) {
7707687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
7717687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
7727687d0d8SRobert Mustacchi 
7737687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "ecv%u", i);
7747687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "Egress Control "
7757687d0d8SRobert Mustacchi 		    "Vector %u", i);
7767687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
7777687d0d8SRobert Mustacchi 		p.pcp_len = 4;
7787687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
7797687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
7807687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
7817687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
7827687d0d8SRobert Mustacchi 
7837687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
7847687d0d8SRobert Mustacchi 	}
7857687d0d8SRobert Mustacchi }
7867687d0d8SRobert Mustacchi 
7877687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_dpa_paa(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)7887687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpa_paa(pcieadm_cfgspace_walk_t *walkp,
7894a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
7907687d0d8SRobert Mustacchi {
7917687d0d8SRobert Mustacchi 	uint8_t nents;
7927687d0d8SRobert Mustacchi 
7934a8bbc0bSRobert Mustacchi 	nents = bitx8(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 4, 0) + 1;
7947687d0d8SRobert Mustacchi 	if (nents == 0) {
7957687d0d8SRobert Mustacchi 		return;
7967687d0d8SRobert Mustacchi 	}
7977687d0d8SRobert Mustacchi 
7987687d0d8SRobert Mustacchi 	for (uint8_t i = 0; i < nents; i++) {
7997687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
8007687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
8017687d0d8SRobert Mustacchi 
8027687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "%s%u",
8037687d0d8SRobert Mustacchi 		    print->pcp_short, i);
8047687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "%s %u",
8057687d0d8SRobert Mustacchi 		    print->pcp_human, i);
8067687d0d8SRobert Mustacchi 
8077687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i;
8087687d0d8SRobert Mustacchi 		p.pcp_len = 1;
8097687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
8107687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
8117687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
8127687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
8137687d0d8SRobert Mustacchi 
8147687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
8157687d0d8SRobert Mustacchi 	}
8167687d0d8SRobert Mustacchi }
8177687d0d8SRobert Mustacchi 
8187687d0d8SRobert Mustacchi /*
8197687d0d8SRobert Mustacchi  * Config Space Header Table Definitions
8207687d0d8SRobert Mustacchi  */
8214a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_command[] = {
8227687d0d8SRobert Mustacchi 	{ 0, 0, "io", "I/O Space", PRDV_STRVAL,
8237687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8247687d0d8SRobert Mustacchi 	{ 1, 1, "mem", "Memory Space", PRDV_STRVAL,
8257687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8267687d0d8SRobert Mustacchi 	{ 2, 2, "bus", "Bus Master", PRDV_STRVAL,
8277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8287687d0d8SRobert Mustacchi 	{ 3, 3, "spec", "Special Cycle", PRDV_STRVAL,
8297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8307687d0d8SRobert Mustacchi 	{ 4, 4, "mwi", "Memory Write and Invalidate", PRDV_STRVAL,
8317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8327687d0d8SRobert Mustacchi 	{ 5, 5, "vga", "VGA Palette Snoop", PRDV_STRVAL,
8337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8347687d0d8SRobert Mustacchi 	{ 6, 6, "per", "Parity Error Response", PRDV_STRVAL,
8357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
8367687d0d8SRobert Mustacchi 	{ 7, 7, "idsel", "IDSEL Stepping/Wait Cycle Control", PRDV_STRVAL,
8377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
8387687d0d8SRobert Mustacchi 	{ 8, 8, "serr", "SERR# Enable", PRDV_STRVAL,
8397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } }, },
8407687d0d8SRobert Mustacchi 	{ 9, 9, "fbtx", "Fast Back-to-Back Transactions", PRDV_STRVAL,
8417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } }, },
8427687d0d8SRobert Mustacchi 	{ 10, 10, "intx", "Interrupt X", PRDV_STRVAL,
8437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
8447687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8457687d0d8SRobert Mustacchi };
8467687d0d8SRobert Mustacchi 
8474a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_status[] = {
8487687d0d8SRobert Mustacchi 	{ 0, 0, "imm", "Immediate Readiness", PRDV_STRVAL,
8497687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8507687d0d8SRobert Mustacchi 	{ 3, 3, "istat", "Interrupt Status", PRDV_STRVAL,
8517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not pending", "pending" } }, },
8527687d0d8SRobert Mustacchi 	{ 4, 4, "capsup", "Capabilities List", PRDV_STRVAL,
8537687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8547687d0d8SRobert Mustacchi 	{ 5, 5, "66mhz", "66 MHz Capable", PRDV_STRVAL,
8557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8567687d0d8SRobert Mustacchi 	{ 7, 7, "fbtxcap", "Fast Back-to-Back Capable", PRDV_STRVAL,
8577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } }, },
8587687d0d8SRobert Mustacchi 	{ 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL,
8597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } }, },
8607687d0d8SRobert Mustacchi 	{ 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL,
8617687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "fast", "medium", "slow",
8627687d0d8SRobert Mustacchi 	    "reserved" } } },
8637687d0d8SRobert Mustacchi 	{ 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL,
8647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8657687d0d8SRobert Mustacchi 	{ 12, 12, "rta", "Received Target Abort", PRDV_STRVAL,
8667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8677687d0d8SRobert Mustacchi 	{ 13, 13, "rma", "Received Master Abort", PRDV_STRVAL,
8687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8697687d0d8SRobert Mustacchi 	{ 14, 14, "sse", "Signaled System Error", PRDV_STRVAL,
8707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8717687d0d8SRobert Mustacchi 	{ 15, 15, "dpe", "Detected Parity Error", PRDV_STRVAL,
8727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
8737687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8747687d0d8SRobert Mustacchi };
8757687d0d8SRobert Mustacchi 
8767687d0d8SRobert Mustacchi /*
8777687d0d8SRobert Mustacchi  * It might be interesting to translate these into numbers at a future point.
8787687d0d8SRobert Mustacchi  */
8794a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_class[] = {
8807687d0d8SRobert Mustacchi 	{ 16, 23, "class", "Class Code", PRDV_HEX },
8817687d0d8SRobert Mustacchi 	{ 7, 15, "sclass", "Sub-Class Code", PRDV_HEX },
8827687d0d8SRobert Mustacchi 	{ 0, 7, "pi", "Programming Interface", PRDV_HEX },
8837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8847687d0d8SRobert Mustacchi };
8857687d0d8SRobert Mustacchi 
8864a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridge_iobase[] = {
8877687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
8887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } },
8897687d0d8SRobert Mustacchi 	{ 4, 7, "base", "Base", PRDV_HEX,
8907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12 } } },
8917687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
8927687d0d8SRobert Mustacchi };
8937687d0d8SRobert Mustacchi 
8944a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridge_iolim[] = {
8957687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
8967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } },
8977687d0d8SRobert Mustacchi 	{ 4, 7, "limit", "Limit", PRDV_HEX,
8987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12, 0xfff } } },
8997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9007687d0d8SRobert Mustacchi };
9017687d0d8SRobert Mustacchi 
9027687d0d8SRobert Mustacchi 
9034a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridgests[] = {
9047687d0d8SRobert Mustacchi 	{ 5, 5, "66mhz", "66 MHz", PRDV_STRVAL,
9057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
9067687d0d8SRobert Mustacchi 	{ 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL,
9077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
9087687d0d8SRobert Mustacchi 	{ 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL,
9097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } } },
9107687d0d8SRobert Mustacchi 	{ 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL,
9117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "fast", "medium", "slow" } } },
9127687d0d8SRobert Mustacchi 	{ 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL,
9137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
9147687d0d8SRobert Mustacchi 	{ 12, 12, "rta", "Received Target Abort", PRDV_STRVAL,
9157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
9167687d0d8SRobert Mustacchi 	{ 13, 13, "rma", "Received Master Abort", PRDV_STRVAL,
9177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no abort", "aborted" } } },
9187687d0d8SRobert Mustacchi 	{ 14, 14, "rsyserr", "Received System Error", PRDV_STRVAL,
9197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error received" } } },
9207687d0d8SRobert Mustacchi 	{ 15, 15, "dperr", "Detected Parity Error", PRDV_STRVAL,
9217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no error", "error detected" } } },
9227687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9237687d0d8SRobert Mustacchi };
9247687d0d8SRobert Mustacchi 
9254a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridge_membase[] = {
9267687d0d8SRobert Mustacchi 	{ 4, 16, "base", "Base", PRDV_HEX,
9277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20 } } },
9287687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9297687d0d8SRobert Mustacchi };
9307687d0d8SRobert Mustacchi 
9314a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridge_memlim[] = {
9327687d0d8SRobert Mustacchi 	{ 4, 16, "limit", "Limit", PRDV_HEX,
9337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20, 0xfffff } } },
9347687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9357687d0d8SRobert Mustacchi };
9367687d0d8SRobert Mustacchi 
9374a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridge_pfbase[] = {
9387687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
9397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } },
9407687d0d8SRobert Mustacchi 	{ 4, 16, "base", "Base", PRDV_HEX,
9417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20 } } },
9427687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9437687d0d8SRobert Mustacchi };
9447687d0d8SRobert Mustacchi 
9454a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridge_pflim[] = {
9467687d0d8SRobert Mustacchi 	{ 0, 3, "cap", "Addressing Capability", PRDV_STRVAL,
9477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } },
9487687d0d8SRobert Mustacchi 	{ 4, 16, "limit", "Limit", PRDV_HEX,
9497687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 20, 0xfffff } } },
9507687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9517687d0d8SRobert Mustacchi };
9527687d0d8SRobert Mustacchi 
9534a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bridge_ctl[] = {
9547687d0d8SRobert Mustacchi 	{ 0, 0, "perrresp", "Parity Error Response", PRDV_STRVAL,
9557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9567687d0d8SRobert Mustacchi 	{ 1, 1, "serr", "SERR#", PRDV_STRVAL,
9577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9587687d0d8SRobert Mustacchi 	{ 2, 2, "isa", "ISA", PRDV_STRVAL,
9597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9607687d0d8SRobert Mustacchi 	{ 3, 3, "vga", "VGA", PRDV_STRVAL,
9617687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9627687d0d8SRobert Mustacchi 	{ 4, 4, "vgadec", "VGA 16-bit Decode", PRDV_STRVAL,
9637687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "10-bit", "16-bit" } } },
9647687d0d8SRobert Mustacchi 	{ 5, 5, "mabort", "Master Abort", PRDV_STRVAL,
9657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9667687d0d8SRobert Mustacchi 	{ 6, 6, "secrst", "Secondary Bus Reset", PRDV_HEX },
9677687d0d8SRobert Mustacchi 	{ 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL,
9687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9697687d0d8SRobert Mustacchi 	{ 8, 8, "pridisc", "Primary Discard Timer", PRDV_STRVAL,
9707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } },
9717687d0d8SRobert Mustacchi 	{ 9, 9, "secdisc", "Secondary Discard Timer", PRDV_STRVAL,
9727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } },
9737687d0d8SRobert Mustacchi 	{ 10, 10, "disctimer", "Discard Timer Error", PRDV_STRVAL,
9747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9757687d0d8SRobert Mustacchi 	{ 11, 11, "discserr", "Discard Timer SERR#", PRDV_STRVAL,
9767687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
9777687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9787687d0d8SRobert Mustacchi };
9797687d0d8SRobert Mustacchi 
9807687d0d8SRobert Mustacchi static pcieadm_unitdef_t pcieadm_unitdef_cache = {
9817687d0d8SRobert Mustacchi 	"byte", 4
9827687d0d8SRobert Mustacchi };
9837687d0d8SRobert Mustacchi 
9847687d0d8SRobert Mustacchi static pcieadm_unitdef_t pcieadm_unitdef_latreg = { "cycle" };
9857687d0d8SRobert Mustacchi 
9864a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_header[] = {
9877687d0d8SRobert Mustacchi 	{ 0, 6, "layout", "Header Layout", PRDV_STRVAL,
9887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Device", "Bridge", "PC Card" } } },
9897687d0d8SRobert Mustacchi 	{ 7, 7, "mfd", "Multi-Function Device", PRDV_STRVAL,
9907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
9917687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
9927687d0d8SRobert Mustacchi };
9937687d0d8SRobert Mustacchi 
9944a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_bist[] = {
9957687d0d8SRobert Mustacchi 	{ 0, 3, "code", "Completion Code", PRDV_HEX },
9967687d0d8SRobert Mustacchi 	{ 6, 6, "start", "Start BIST", PRDV_HEX },
9977687d0d8SRobert Mustacchi 	{ 7, 7, "cap", "BIST Capable", PRDV_STRVAL,
9987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
9997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
10007687d0d8SRobert Mustacchi };
10017687d0d8SRobert Mustacchi 
10024a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_exprom[] = {
10037687d0d8SRobert Mustacchi 	{ 0, 0, "enable", "Enable", PRDV_STRVAL,
10047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
10056c489a52SRobert Mustacchi 	{ 1, 3, "valsts", "Validation Status", PRDV_STRVAL,
10066c489a52SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not supported", "in progress",
10076c489a52SRobert Mustacchi 	    "valid contents, no trust test performed",
10086c489a52SRobert Mustacchi 	    "valid and trusted contents",
10096c489a52SRobert Mustacchi 	    "invalid contents",
10106c489a52SRobert Mustacchi 	    "valid but untrusted contents",
10116c489a52SRobert Mustacchi 	    "valid contents with warning, no trust test performed",
10126c489a52SRobert Mustacchi 	    "valid and trusted contents with warning" } } },
10136c489a52SRobert Mustacchi 	{ 4, 7, "valdet", "Validation Details", PRDV_HEX },
10147687d0d8SRobert Mustacchi 	{ 11, 31, "addr", "Base Address", PRDV_HEX,
10156c489a52SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 11 } } },
10167687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
10177687d0d8SRobert Mustacchi };
10187687d0d8SRobert Mustacchi 
10197687d0d8SRobert Mustacchi static pcieadm_strmap_t pcieadm_strmap_ipin[] = {
10207687d0d8SRobert Mustacchi 	{ "none", 0 },
10217687d0d8SRobert Mustacchi 	{ "INTA", PCI_INTA },
10227687d0d8SRobert Mustacchi 	{ "INTB", PCI_INTB },
10237687d0d8SRobert Mustacchi 	{ "INTC", PCI_INTC },
10247687d0d8SRobert Mustacchi 	{ "INTD", PCI_INTD },
10257687d0d8SRobert Mustacchi 	{ NULL }
10267687d0d8SRobert Mustacchi };
10277687d0d8SRobert Mustacchi 
10287687d0d8SRobert Mustacchi 
10294a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cfgspace_type0[] = {
10307687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
10317687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
10327687d0d8SRobert Mustacchi 	{ 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef,
10337687d0d8SRobert Mustacchi 	    pcieadm_regdef_command },
10347687d0d8SRobert Mustacchi 	{ 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef,
10357687d0d8SRobert Mustacchi 	    pcieadm_regdef_status },
10367687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
10377687d0d8SRobert Mustacchi 	{ 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef,
10387687d0d8SRobert Mustacchi 	    pcieadm_regdef_class },
10397687d0d8SRobert Mustacchi 	{ 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit,
10407687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_cache },
10417687d0d8SRobert Mustacchi 	{ 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit,
10427687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_latreg },
10437687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
10447687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
10457687d0d8SRobert Mustacchi 	{ 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef,
10467687d0d8SRobert Mustacchi 	    pcieadm_regdef_bist },
10477687d0d8SRobert Mustacchi 	{ 0x10, 24, "bar", "Base Address Register",
10487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
10497687d0d8SRobert Mustacchi 	{ 0x28, 4, "cis", "Cardbus CIS Pointer", pcieadm_cfgspace_print_hex },
10507687d0d8SRobert Mustacchi 	{ 0x2c, 2, "subvid", "Subsystem Vendor ID",
10517687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_subid },
10527687d0d8SRobert Mustacchi 	{ 0x2e, 2, "subdev", "Subsystem Device ID",
10537687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_subid },
10547687d0d8SRobert Mustacchi 	{ 0x30, 4, "rom", "Expansion ROM", pcieadm_cfgspace_print_regdef,
10557687d0d8SRobert Mustacchi 	    pcieadm_regdef_exprom },
10567687d0d8SRobert Mustacchi 	{ 0x34, 1, "cap", "Capabilities Pointer", pcieadm_cfgspace_print_hex },
10577687d0d8SRobert Mustacchi 	{ 0x3c, 1, "iline", "Interrupt Line", pcieadm_cfgspace_print_hex },
10587687d0d8SRobert Mustacchi 	{ 0x3d, 1, "ipin", "Interrupt Pin", pcieadm_cfgspace_print_strmap,
10597687d0d8SRobert Mustacchi 	    pcieadm_strmap_ipin },
10607687d0d8SRobert Mustacchi 	{ 0x3e, 1, "gnt", "Min_Gnt", pcieadm_cfgspace_print_hex },
10617687d0d8SRobert Mustacchi 	{ 0x3f, 1, "lat", "Min_Lat", pcieadm_cfgspace_print_hex },
10627687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
10637687d0d8SRobert Mustacchi };
10647687d0d8SRobert Mustacchi 
10654a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cfgspace_type1[] = {
10667687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
10677687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
10687687d0d8SRobert Mustacchi 	{ 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef,
10697687d0d8SRobert Mustacchi 	    pcieadm_regdef_command },
10707687d0d8SRobert Mustacchi 	{ 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef,
10717687d0d8SRobert Mustacchi 	    pcieadm_regdef_status },
10727687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
10737687d0d8SRobert Mustacchi 	{ 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef,
10747687d0d8SRobert Mustacchi 	    pcieadm_regdef_class },
10757687d0d8SRobert Mustacchi 	{ 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit,
10767687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_cache },
10777687d0d8SRobert Mustacchi 	{ 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit,
10787687d0d8SRobert Mustacchi 	    &pcieadm_unitdef_latreg },
10797687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
10807687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
10817687d0d8SRobert Mustacchi 	{ 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef,
10827687d0d8SRobert Mustacchi 	    pcieadm_regdef_bist },
10837687d0d8SRobert Mustacchi 	{ 0x10, 8, "bar", "Base Address Register",
10847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
10857687d0d8SRobert Mustacchi 	{ PCI_BCNF_PRIBUS, 1, "pribus", "Primary Bus Number",
10867687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10877687d0d8SRobert Mustacchi 	{ PCI_BCNF_SECBUS, 1, "secbus", "Secondary Bus Number",
10887687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10897687d0d8SRobert Mustacchi 	{ PCI_BCNF_SUBBUS, 1, "subbus", "Subordinate Bus Number",
10907687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
10917687d0d8SRobert Mustacchi 	{ PCI_BCNF_LATENCY_TIMER, 1, "latency2", "Secondary Latency timer",
10927687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_unit, &pcieadm_unitdef_latreg },
10937687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_BASE_LOW, 1, "iobase", "I/O Base Low",
10947687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iobase },
10957687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_LIMIT_LOW, 1, "iolimit", "I/O Limit Low",
10967687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iolim },
10977687d0d8SRobert Mustacchi 	{ PCI_BCNF_SEC_STATUS, 2, "status2", "Secondary Status",
10987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridgests },
10997687d0d8SRobert Mustacchi 	{ PCI_BCNF_MEM_BASE, 2, "membase", "Memory Base",
11007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_membase },
11017687d0d8SRobert Mustacchi 	{ PCI_BCNF_MEM_LIMIT, 2, "memlimit", "Memory Limit",
11027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_memlim },
11037687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_BASE_LOW, 2, "pfbase", "Prefetchable Memory Base",
11047687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pfbase },
11057687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_LIMIT_LOW, 2, "pflimit", "Prefetchable Memory Limit",
11067687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pflim },
11077687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_BASE_HIGH, 4, "pfbasehi",
11087687d0d8SRobert Mustacchi 	    "Prefetchable Base Upper 32 bits",
11097687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11107687d0d8SRobert Mustacchi 	{ PCI_BCNF_PF_LIMIT_HIGH, 4, "pflimihi",
11117687d0d8SRobert Mustacchi 	    "Prefetchable Limit Upper 32 bits",
11127687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11137687d0d8SRobert Mustacchi 	{ PCI_BCNF_IO_BASE_HI, 2, "iobasehi", "I/O Base Upper 16 bits",
11147687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
111566a9cc68SRobert Mustacchi 	{ PCI_BCNF_IO_LIMIT_HI, 2, "iolimithi", "I/O Limit Upper 16 bits",
11167687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11177687d0d8SRobert Mustacchi 	{ PCI_BCNF_CAP_PTR, 1, "cap", "Capabilities Pointer",
11187687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11197687d0d8SRobert Mustacchi 	{ PCI_BCNF_ROM, 4, "rom", "Expansion ROM",
11207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_exprom },
11217687d0d8SRobert Mustacchi 	{ PCI_BCNF_ILINE, 1, "iline", "Interrupt Line",
11227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
11237687d0d8SRobert Mustacchi 	{ PCI_BCNF_IPIN, 1, "ipin", "Interrupt Pin",
11247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_strmap, pcieadm_strmap_ipin },
11257687d0d8SRobert Mustacchi 	{ PCI_BCNF_BCNTRL, 2, "bctl", "Bridge Control",
11267687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_ctl },
11277687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11287687d0d8SRobert Mustacchi };
11297687d0d8SRobert Mustacchi 
11304a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cfgspace_unknown[] = {
11317687d0d8SRobert Mustacchi 	{ 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor },
11327687d0d8SRobert Mustacchi 	{ 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device },
11337687d0d8SRobert Mustacchi 	{ 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex },
11347687d0d8SRobert Mustacchi 	{ 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef,
11357687d0d8SRobert Mustacchi 	    pcieadm_regdef_header },
11367687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11377687d0d8SRobert Mustacchi };
11387687d0d8SRobert Mustacchi 
11397687d0d8SRobert Mustacchi /*
11407687d0d8SRobert Mustacchi  * Power Management Capability Version 3. Note versions two and three seem to be
11417687d0d8SRobert Mustacchi  * the same, but are used to indicate compliance to different revisions of the
11427687d0d8SRobert Mustacchi  * PCI power management specification.
11437687d0d8SRobert Mustacchi  */
11444a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pmcap[] = {
11457687d0d8SRobert Mustacchi 	{ 0, 2, "vers", "Version", PRDV_HEX },
11467687d0d8SRobert Mustacchi 	{ 3, 3, "clock", "PME Clock", PRDV_STRVAL,
11477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
11487687d0d8SRobert Mustacchi 	{ 4, 4, "irrd0", "Immediate Readiness on Return to D0", PRDV_STRVAL,
11497687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
11507687d0d8SRobert Mustacchi 	{ 5, 5, "dsi", "Device Specific Initialization", PRDV_STRVAL,
11517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
11527687d0d8SRobert Mustacchi 	{ 6, 8, "auxcur", "Auxiliary Current", PRDV_STRVAL,
11537687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "0", "55 mA", "100 mA", "160 mA",
11547687d0d8SRobert Mustacchi 	    "220 mA", "270 mA", "320 mA", "375 mA" } } },
11557687d0d8SRobert Mustacchi 	{ 9, 9, "d1", "D1", PRDV_STRVAL,
11567687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
11577687d0d8SRobert Mustacchi 	{ 10, 10, "d2", "D2", PRDV_STRVAL,
11587687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
11597687d0d8SRobert Mustacchi 	{ 11, 15, "pme", "PME Support", PRDV_BITFIELD,
11607687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "D0", "D1", "D2", "D3hot",
11617687d0d8SRobert Mustacchi 	    "D3cold" } } },
11627687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11637687d0d8SRobert Mustacchi };
11647687d0d8SRobert Mustacchi 
11657687d0d8SRobert Mustacchi 
11664a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcipm_v3[] = {
11677687d0d8SRobert Mustacchi 	{ PCI_PMCAP, 2, "pmcap", "Power Management Capabilities",
11687687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pmcap },
11697687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11707687d0d8SRobert Mustacchi };
11717687d0d8SRobert Mustacchi 
11727687d0d8SRobert Mustacchi /*
11737687d0d8SRobert Mustacchi  * PCI Bridge Subsystem Capability
11747687d0d8SRobert Mustacchi  */
11754a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_bridge_subsys[] = {
11767687d0d8SRobert Mustacchi 	{ 0x4, 2, "subvid", "Subsystem Vendor ID", pcieadm_cfgspace_print_hex },
11777687d0d8SRobert Mustacchi 	{ 0x6, 2, "subdev", "Subsystem Device ID", pcieadm_cfgspace_print_hex },
11787687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
11797687d0d8SRobert Mustacchi };
11807687d0d8SRobert Mustacchi 
11817687d0d8SRobert Mustacchi /*
11827687d0d8SRobert Mustacchi  * MSI Capability
11837687d0d8SRobert Mustacchi  */
11844a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_msictrl[] = {
11857687d0d8SRobert Mustacchi 	{ 0, 0, "enable", "MSI Enable", PRDV_STRVAL,
11867687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
11877687d0d8SRobert Mustacchi 	{ 1, 3, "mmsgcap", "Multiple Message Capable", PRDV_STRVAL,
11887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 vector", "2 vectors",
11897687d0d8SRobert Mustacchi 	    "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } },
11907687d0d8SRobert Mustacchi 	{ 4, 6, "mmsgen", "Multiple Message Enabled", PRDV_STRVAL,
11917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 vector", "2 vectors",
11927687d0d8SRobert Mustacchi 	    "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } },
11937687d0d8SRobert Mustacchi 	{ 7, 7, "addr64", "64-bit Address Capable", PRDV_STRVAL,
11947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
11957687d0d8SRobert Mustacchi 	{ 8, 8, "pvm", "Per-Vector Masking Capable", PRDV_STRVAL,
11967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
119792f11af9SRobert Mustacchi 	{ 9, 9, "extmdcap", "Extended Message Data Capable", PRDV_STRVAL,
11987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
119992f11af9SRobert Mustacchi 	{ 10, 10, "extmden", "extended Message Data Enable", PRDV_STRVAL,
12007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
12017687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12027687d0d8SRobert Mustacchi };
12037687d0d8SRobert Mustacchi 
12044a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_msi_32[] = {
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 	{ -1, -1, NULL }
12127687d0d8SRobert Mustacchi };
12137687d0d8SRobert Mustacchi 
12144a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_msi_32ext[] = {
12157687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12167687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12177687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12187687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12197687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
12207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12217687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12237687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12247687d0d8SRobert Mustacchi };
12257687d0d8SRobert Mustacchi 
12264a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_msi_32pvm[] = {
12277687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12287687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12297687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12307687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12317687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_DATA, 2, "data", "Message Data",
12327687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12337687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12347687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12357687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_MASK, 4, "mask", "Mask Bits",
12367687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12377687d0d8SRobert Mustacchi 	{ PCI_MSI_32BIT_PENDING, 4, "pend", "Pending Bits",
12387687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12397687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12407687d0d8SRobert Mustacchi };
12417687d0d8SRobert Mustacchi 
12424a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_msi_64[] = {
12437687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12447687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12457687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12467687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12477687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
12487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12497687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
12507687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12517687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12527687d0d8SRobert Mustacchi };
12537687d0d8SRobert Mustacchi 
12544a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_msi_64ext[] = {
12557687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12567687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12577687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12587687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12597687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
12607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12617687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
12627687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12637687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12647687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12657687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12667687d0d8SRobert Mustacchi };
12677687d0d8SRobert Mustacchi 
12684a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_msi_64pvm[] = {
12697687d0d8SRobert Mustacchi 	{ PCI_MSI_CTRL, 2, "ctrl", "Message Control",
12707687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl },
12717687d0d8SRobert Mustacchi 	{ PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address",
12727687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12737687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address",
12747687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12757687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_DATA, 2, "data", "Message Data",
12767687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12777687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data",
12787687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12797687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_MASKBITS, 4, "mask", "Mask Bits",
12807687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12817687d0d8SRobert Mustacchi 	{ PCI_MSI_64BIT_PENDING, 4, "pend", "Pending Bits",
12827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
12837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12847687d0d8SRobert Mustacchi };
12857687d0d8SRobert Mustacchi 
12867687d0d8SRobert Mustacchi /*
12877687d0d8SRobert Mustacchi  * MSI-X Capability
12887687d0d8SRobert Mustacchi  */
12894a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_msixctrl[] = {
12907687d0d8SRobert Mustacchi 	{ 0, 10, "size", "Table Size", PRDV_HEX,
12917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
12927687d0d8SRobert Mustacchi 	{ 14, 14, "mask", "Function Mask", PRDV_STRVAL,
12937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unmasked", "masked" } } },
12947687d0d8SRobert Mustacchi 	{ 15, 15, "enable", "MSI-X Enable", PRDV_STRVAL,
12957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
12967687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
12977687d0d8SRobert Mustacchi };
12987687d0d8SRobert Mustacchi 
12994a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_msixtable[] = {
13007687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "Table BIR", PRDV_STRVAL,
13017687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
13027687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
13037687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "Table Offset", PRDV_HEX,
13047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
13057687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13067687d0d8SRobert Mustacchi };
13077687d0d8SRobert Mustacchi 
13084a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_msixpba[] = {
13097687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "PBA BIR", PRDV_STRVAL,
13107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
13117687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
13127687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "PBA Offset", PRDV_HEX,
13137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
13147687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13157687d0d8SRobert Mustacchi };
13167687d0d8SRobert Mustacchi 
13177687d0d8SRobert Mustacchi 
13184a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_msix[] = {
13197687d0d8SRobert Mustacchi 	{ PCI_MSIX_CTRL, 2, "ctrl", "Control Register",
13207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixctrl },
13217687d0d8SRobert Mustacchi 	{ PCI_MSIX_TBL_OFFSET, 4, "table", "Table Offset",
13227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixtable },
13237687d0d8SRobert Mustacchi 	{ PCI_MSIX_PBA_OFFSET, 4, "pba", "PBA Offset",
13247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixpba },
13257687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13267687d0d8SRobert Mustacchi };
13277687d0d8SRobert Mustacchi 
13287687d0d8SRobert Mustacchi /*
13297687d0d8SRobert Mustacchi  * PCI Express Capability
13307687d0d8SRobert Mustacchi  */
13314a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_cap[] = {
13327687d0d8SRobert Mustacchi 	{ 0, 3, "vers", "Version", PRDV_HEX },
13337687d0d8SRobert Mustacchi 	{ 4, 7, "type", "Device/Port Type", PRDV_STRVAL,
13347687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PCIe Endpoint",
13357687d0d8SRobert Mustacchi 	    "Legacy PCIe Endpoint", NULL, NULL,
13367687d0d8SRobert Mustacchi 	    "Root Port of PCIe Root Complex",
13377687d0d8SRobert Mustacchi 	    "Upstream Port of PCIe Switch",
13387687d0d8SRobert Mustacchi 	    "Downstream Port of PCIe Switch",
13397687d0d8SRobert Mustacchi 	    "PCIe to PCI/PCI-X Bridge",
13407687d0d8SRobert Mustacchi 	    "PCI/PCI-x to PCIe Bridge",
13417687d0d8SRobert Mustacchi 	    "RCiEP",
13427687d0d8SRobert Mustacchi 	    "Root Complex Event Collector" } } },
13437687d0d8SRobert Mustacchi 	{ 8, 8, "slot", "Slot Implemented", PRDV_STRVAL,
13447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No", "Yes" } } },
13457687d0d8SRobert Mustacchi 	{ 9, 13, "intno", "Interrupt Message Number", PRDV_HEX },
13467687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13477687d0d8SRobert Mustacchi };
13487687d0d8SRobert Mustacchi 
13494a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_devcap[] = {
13507687d0d8SRobert Mustacchi 	{ 0, 2, "mps", "Max Payload Size Supported", PRDV_STRVAL,
13517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
13521bcd6a1aSRobert Mustacchi 	    "512 bytes", "1024 bytes", "2048 bytes", "4096 bytes" } } },
13537687d0d8SRobert Mustacchi 	{ 3, 4, "pfunc", "Phantom Functions Supported", PRDV_STRVAL,
13547687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No", "1-bit", "2-bits",
13557687d0d8SRobert Mustacchi 	    "3-bits" } } },
13567687d0d8SRobert Mustacchi 	{ 5, 5, "exttag", "Extended Tag Field", PRDV_STRVAL,
13577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "5-bit", "8-bit" } } },
13587687d0d8SRobert Mustacchi 	{ 6, 8, "l0slat", "L0s Acceptable Latency", PRDV_STRVAL,
13597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "64 ns", "128 ns", "256 ns",
13607687d0d8SRobert Mustacchi 	    "512 ns", "1 us", "2 us", "4 us", "No limit" } } },
13617687d0d8SRobert Mustacchi 	{ 9, 11, "l1lat", "L1 Acceptable Latency", PRDV_STRVAL,
13627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 us", "2 us", "4 us", "8 us",
13637687d0d8SRobert Mustacchi 	    "16 us", "32 us", "64 us", "No limit" } } },
13647687d0d8SRobert Mustacchi 	{ 15, 15, "rber", "Role Based Error Reporting", PRDV_STRVAL,
13657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
13667687d0d8SRobert Mustacchi 	{ 16, 16, "errcor", "ERR_COR Subclass", PRDV_STRVAL,
13677687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
13687687d0d8SRobert Mustacchi 	{ 18, 25, "csplv", "Captured Slot Power Limit", PRDV_HEX },
13697687d0d8SRobert Mustacchi 	{ 26, 27, "cspls", "Captured Slot Power Limit Scale", PRDV_STRVAL,
13707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1.0x", "0.1x", "0.01x",
13717687d0d8SRobert Mustacchi 	    "0.001x" } } },
13727687d0d8SRobert Mustacchi 	{ 28, 28, "flr", "Function Level Reset", PRDV_STRVAL,
13737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
13747687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
13757687d0d8SRobert Mustacchi };
13767687d0d8SRobert Mustacchi 
13774a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_devctl[] = {
13787687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL,
13797687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13807687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL,
13817687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13827687d0d8SRobert Mustacchi 	{ 2, 2, "ferr", "Fatal Error Reporting", PRDV_STRVAL,
13837687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13847687d0d8SRobert Mustacchi 	{ 3, 3, "unsupreq", "Unsupported Request Reporting", PRDV_STRVAL,
13857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13867687d0d8SRobert Mustacchi 	{ 4, 4, "relord", "Relaxed Ordering", PRDV_STRVAL,
13877687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13887687d0d8SRobert Mustacchi 	{ 5, 7, "mps", "Max Payload Size", PRDV_STRVAL,
13897687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
13901bcd6a1aSRobert Mustacchi 	    "512 bytes", "1024 bytes", "2048 bytes", "4096 bytes" } } },
13917687d0d8SRobert Mustacchi 	{ 8, 8, "exttag", "Extended Tag Field", PRDV_STRVAL,
13927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13937687d0d8SRobert Mustacchi 	{ 9, 9, "pfunc", "Phantom Functions", PRDV_STRVAL,
13947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13957687d0d8SRobert Mustacchi 	{ 9, 9, "auxpm", "Aux Power PM", PRDV_STRVAL,
13967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13977687d0d8SRobert Mustacchi 	{ 11, 11, "nosnoop", "No Snoop", PRDV_STRVAL,
13987687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
13997687d0d8SRobert Mustacchi 	{ 12, 14, "mrrs", "Max Read Request Size", PRDV_STRVAL,
14007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "128 bytes", "256 bytes",
14011bcd6a1aSRobert Mustacchi 	    "512 bytes", "1024 bytes", "2048 bytes", "4096 bytes" } } },
14027687d0d8SRobert Mustacchi 	{ 15, 15, "bcrflr", "Bridge Configuration Retry / Function Level Reset",
14037687d0d8SRobert Mustacchi 	    PRDV_HEX },
14047687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14057687d0d8SRobert Mustacchi };
14067687d0d8SRobert Mustacchi 
14074a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_devsts[] = {
14087687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Detected", PRDV_STRVAL,
14097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14107687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Detected", PRDV_STRVAL,
14117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14127687d0d8SRobert Mustacchi 	{ 2, 2, "ferr", "Fatal Error Detected", PRDV_STRVAL,
14137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14147687d0d8SRobert Mustacchi 	{ 3, 3, "unsupreq", "Unsupported Request Detected", PRDV_STRVAL,
14157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14167687d0d8SRobert Mustacchi 	{ 4, 4, "auxpm", "AUX Power Detected", PRDV_STRVAL,
14177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14187687d0d8SRobert Mustacchi 	{ 5, 5, "txpend", "Transactions Pending", PRDV_STRVAL,
14197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14207687d0d8SRobert Mustacchi 	{ 6, 6, "eprd", "Emergency Power Reduction Detected", PRDV_STRVAL,
14217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14227687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14237687d0d8SRobert Mustacchi };
14247687d0d8SRobert Mustacchi 
14254a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_linkcap[] = {
14267687d0d8SRobert Mustacchi 	{ 0, 3, "maxspeed", "Maximum Link Speed", PRDV_STRVAL,
14277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
142889427192SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } },
14297687d0d8SRobert Mustacchi 	{ 4, 9, "maxwidth", "Maximum Link Width", PRDV_HEX },
14307687d0d8SRobert Mustacchi 	{ 10, 11, "aspm", "ASPM Support", PRDV_STRVAL,
14317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } },
14327687d0d8SRobert Mustacchi 	{ 12, 14, "l0slat", "L0s Exit Latency", PRDV_STRVAL,
14337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "<64ns", "64-128ns", "128-256ns",
14347687d0d8SRobert Mustacchi 	    "256-512ns", "512ns-1us", "1-2us", "2-4us", ">4us" } } },
14357687d0d8SRobert Mustacchi 	{ 15, 17, "l1lat", "L1 Exit Latency", PRDV_STRVAL,
14367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "<1us", "1-2us", "2-4us", "4-8us",
14377687d0d8SRobert Mustacchi 	    "8-16us", "16-32us" "32-64us", ">64us" } } },
14387687d0d8SRobert Mustacchi 	{ 18, 18, "clockpm", "Clock Power Management", PRDV_STRVAL,
14397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14407687d0d8SRobert Mustacchi 	{ 19, 19, "supdown", "Surprise Down Error Reporting", PRDV_STRVAL,
14417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14427687d0d8SRobert Mustacchi 	{ 20, 20, "dlact", "Data Link Layer Active Reporting", PRDV_STRVAL,
14437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14447687d0d8SRobert Mustacchi 	{ 21, 21, "linkbw", "Link Bandwidth Notification Capability",
14457687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
14467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
14477687d0d8SRobert Mustacchi 	{ 22, 22, "aspmcomp", "ASPM Optionality Compliance", PRDV_STRVAL,
14487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not compliant", "compliant" } } },
14497687d0d8SRobert Mustacchi 	{ 24, 31, "portno", "Port Number", PRDV_HEX },
14507687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14517687d0d8SRobert Mustacchi };
14527687d0d8SRobert Mustacchi 
14534a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_linkctl[] = {
14547687d0d8SRobert Mustacchi 	{ 0, 1, "aspmctl", "ASPM Control", PRDV_STRVAL,
14557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } },
14567687d0d8SRobert Mustacchi 	{ 3, 3, "rcb", "Read Completion Boundary", PRDV_STRVAL,
14577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "64 byte", "128 byte" } } },
14587687d0d8SRobert Mustacchi 	{ 4, 4, "disable", "Link Disable", PRDV_STRVAL,
14597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not force disabled",
14607687d0d8SRobert Mustacchi 	    "force disabled" } } },
14617687d0d8SRobert Mustacchi 	{ 5, 5, "retrain", "Retrain Link", PRDV_HEX },
14627687d0d8SRobert Mustacchi 	{ 6, 6, "ccc", "Common Clock Configuration", PRDV_STRVAL,
14637687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "asynchronous", "common" } } },
146492f11af9SRobert Mustacchi 	{ 7, 7, "extsync", "Extended Sync", PRDV_STRVAL,
14657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
146692f11af9SRobert Mustacchi 	{ 8, 8, "clkpm", "Clock Power Management", PRDV_STRVAL,
14677687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
146892f11af9SRobert Mustacchi 	{ 9, 9, "hwawd", "Hardware Autonomous Width", PRDV_STRVAL,
14697687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
147092f11af9SRobert Mustacchi 	{ 10, 10, "linkbwint", "Link Bandwidth Management Interrupt",
147192f11af9SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled",
147292f11af9SRobert Mustacchi 	    "enabled" } } },
147392f11af9SRobert Mustacchi 	{ 11, 11, "linkabwint", "Link Autonomous Bandwidth Interrupt",
147492f11af9SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled",
147592f11af9SRobert Mustacchi 	    "enabled" } } },
147692f11af9SRobert Mustacchi 	{ 14, 15, "drs", "DRS Signaling Control", PRDV_STRVAL,
14777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not reported", "Interrupt enabled",
14787687d0d8SRobert Mustacchi 	    "DRS->FRS enabled" } } },
14797687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14807687d0d8SRobert Mustacchi };
14817687d0d8SRobert Mustacchi 
14824a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_linksts[] = {
14837687d0d8SRobert Mustacchi 	{ 0, 3, "speed", "Link Speed", PRDV_STRVAL,
14847687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
148589427192SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } },
14867687d0d8SRobert Mustacchi 	{ 4, 9, "width", "Link Width", PRDV_HEX },
14877687d0d8SRobert Mustacchi 	{ 11, 11, "training", "Link Training", PRDV_STRVAL,
14887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14897687d0d8SRobert Mustacchi 	{ 12, 12, "slotclk", "Slot Clock Configuration", PRDV_STRVAL,
14907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "asynchronous", "common" } } },
14917687d0d8SRobert Mustacchi 	{ 13, 13, "dllact", "Data Link Layer Link Active", PRDV_STRVAL,
14927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
14937687d0d8SRobert Mustacchi 	{ 14, 14, "linkbw", "Link Bandwidth Management Status", PRDV_STRVAL,
14947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no change", "change occurred" } } },
14957687d0d8SRobert Mustacchi 	{ 15, 15, "linkabw", "Link Autonomous Bandwidth Status", PRDV_STRVAL,
14967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no change", "change occurred" } } },
14977687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
14987687d0d8SRobert Mustacchi };
14997687d0d8SRobert Mustacchi 
15004a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_slotcap[] = {
15017687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Present", PRDV_STRVAL,
15027687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15037687d0d8SRobert Mustacchi 	{ 1, 1, "pwrctrl", "Power Controller Present", PRDV_STRVAL,
15047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15057687d0d8SRobert Mustacchi 	{ 2, 2, "mrlsen", "MRL Sensor Present", PRDV_STRVAL,
15067687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15077687d0d8SRobert Mustacchi 	{ 3, 3, "attnind", "Attention Indicator Present", PRDV_STRVAL,
15087687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
150966a9cc68SRobert Mustacchi 	{ 4, 4, "pwrind", "Power Indicator Present", PRDV_STRVAL,
15107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15117687d0d8SRobert Mustacchi 	{ 5, 5, "hpsup", "Hot-Plug Surprise", PRDV_STRVAL,
15127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15137687d0d8SRobert Mustacchi 	{ 6, 6, "hpcap", "Hot-Plug Capable ", PRDV_STRVAL,
15147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15157687d0d8SRobert Mustacchi 	{ 7, 14, "slotplv", "Slot Power Limit Value", PRDV_HEX },
15167687d0d8SRobert Mustacchi 	{ 15, 16, "slotpls", "Slot Power Limit Scale", PRDV_HEX },
151792f11af9SRobert Mustacchi 	{ 17, 17, "emi", "Electromechanical Interlock Present", PRDV_STRVAL,
15187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
151992f11af9SRobert Mustacchi 	{ 18, 18, "ncc", "No Command Completed", PRDV_STRVAL,
15207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
15217687d0d8SRobert Mustacchi 	{ 19, 31, "slotno", "Physical Slot Number", PRDV_HEX },
15227687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15237687d0d8SRobert Mustacchi };
15247687d0d8SRobert Mustacchi 
15254a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_slotctl[] = {
152633505d19SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Pressed Reporting", PRDV_STRVAL,
15277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
152833505d19SRobert Mustacchi 	{ 1, 1, "pwrflt", "Power Fault Detected Reporting", PRDV_STRVAL,
15297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
153033505d19SRobert Mustacchi 	{ 2, 2, "mrlchg", "MRL Sensor Changed Reporting", PRDV_STRVAL,
15317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
153233505d19SRobert Mustacchi 	{ 3, 3, "preschg", "Presence Detect Changed Reporting", PRDV_STRVAL,
15337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15347687d0d8SRobert Mustacchi 	{ 4, 4, "ccmpltint", "Command Complete Interrupt", PRDV_STRVAL,
153533505d19SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15367687d0d8SRobert Mustacchi 	{ 5, 5, "hpi", "Hot Plug Interrupt Enable", PRDV_STRVAL,
15377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15387687d0d8SRobert Mustacchi 	{ 6, 7, "attnind", "Attention Indicator Control", PRDV_STRVAL,
15397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } },
154066a9cc68SRobert Mustacchi 	{ 8, 9, "pwrin", "Power Indicator Control", PRDV_STRVAL,
15417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } },
15427687d0d8SRobert Mustacchi 	{ 10, 10, "pwrctrl", "Power Controller Control", PRDV_STRVAL,
15437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "power on", "power off" } } },
15447687d0d8SRobert Mustacchi 	{ 11, 11, "emi", "Electromechanical Interlock Control", PRDV_HEX },
15457687d0d8SRobert Mustacchi 	{ 12, 12, "dll", "Data Link Layer State Changed", PRDV_STRVAL,
15467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15477687d0d8SRobert Mustacchi 	{ 13, 13, "autopowdis", "Auto Slot Power Limit", PRDV_STRVAL,
15487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
15497687d0d8SRobert Mustacchi 	{ 14, 14, "ibpddis", "In-Band PD", PRDV_STRVAL,
15507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
15517687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15527687d0d8SRobert Mustacchi };
15537687d0d8SRobert Mustacchi 
15544a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_slotsts[] = {
15557687d0d8SRobert Mustacchi 	{ 0, 0, "attnbtn", "Attention Button Pressed", PRDV_STRVAL,
15567687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
155766a9cc68SRobert Mustacchi 	{ 1, 1, "pwrflt", "Power Fault Detected", PRDV_STRVAL,
15587687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
155966a9cc68SRobert Mustacchi 	{ 2, 2, "mrlchg", "MRL Sensor Changed", PRDV_STRVAL,
15607687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
156166a9cc68SRobert Mustacchi 	{ 3, 3, "preschg", "Presence Detect Changed", PRDV_STRVAL,
15627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15637687d0d8SRobert Mustacchi 	{ 4, 4, "ccmplt", "Command Complete", PRDV_STRVAL,
15647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15657687d0d8SRobert Mustacchi 	{ 5, 5, "mrlsen", "MRL Sensor State", PRDV_STRVAL,
15667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "closed", "open" } } },
15677687d0d8SRobert Mustacchi 	{ 6, 6, "presdet", "Presence Detect State", PRDV_STRVAL,
15687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not present", "present" } } },
15697687d0d8SRobert Mustacchi 	{ 7, 7, "emi", "Electromechanical Interlock", PRDV_STRVAL,
15707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disengaged", "engaged" } } },
15717687d0d8SRobert Mustacchi 	{ 8, 8, "dll", "Data Link Layer State Changed", PRDV_STRVAL,
15727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
15737687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15747687d0d8SRobert Mustacchi };
15757687d0d8SRobert Mustacchi 
15764a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_rootcap[] = {
15777687d0d8SRobert Mustacchi 	{ 0, 0, "syscorerr", "System Error on Correctable Error", PRDV_STRVAL,
15787687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15797687d0d8SRobert Mustacchi 	{ 1, 1, "sysnonftl", "System Error on Non-Fatal Error", PRDV_STRVAL,
15807687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15817687d0d8SRobert Mustacchi 	{ 2, 2, "sysfatal", "System Error on Fatal Error", PRDV_STRVAL,
15827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15837687d0d8SRobert Mustacchi 	{ 3, 3, "pmeie", "PME Interrupt", PRDV_STRVAL,
15847687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15857687d0d8SRobert Mustacchi 	{ 4, 4,  "crssw", "CRS Software Visibility", PRDV_STRVAL,
15867687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15877687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15887687d0d8SRobert Mustacchi };
15897687d0d8SRobert Mustacchi 
15904a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_rootctl[] = {
15917687d0d8SRobert Mustacchi 	{ 0, 0, "crssw", "CRS Software Visibility", PRDV_STRVAL,
15927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
15937687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
15947687d0d8SRobert Mustacchi };
15957687d0d8SRobert Mustacchi 
15964a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_rootsts[] = {
15977687d0d8SRobert Mustacchi 	{ 0, 15, "pmereqid", "PME Requester ID", PRDV_HEX },
15987687d0d8SRobert Mustacchi 	{ 16, 16, "pmests", "PME Status", PRDV_STRVAL,
15997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "deasserted", "asserted" } } },
16007687d0d8SRobert Mustacchi 	{ 17, 17, "pmepend", "PME Pending", PRDV_STRVAL,
16017687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
16027687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16037687d0d8SRobert Mustacchi };
16047687d0d8SRobert Mustacchi 
16054a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_devcap2[] = {
16067687d0d8SRobert Mustacchi 	{ 0, 3, "cmpto", "Completion Timeout Ranges Supported", PRDV_BITFIELD,
16077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "50us-10ms", "10ms-250ms",
16087687d0d8SRobert Mustacchi 	    "250ms-4s", "4s-64s" } } },
16097687d0d8SRobert Mustacchi 	{ 4, 4, "cmptodis", "Completion Timeout Disable", PRDV_STRVAL,
16107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16117687d0d8SRobert Mustacchi 	{ 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL,
16127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16137687d0d8SRobert Mustacchi 	{ 6, 6, "atomroute", "AtomicOp Routing", PRDV_STRVAL,
16147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16157687d0d8SRobert Mustacchi 	{ 7, 7, "atom32", "32-bit AtomicOp Completer", PRDV_STRVAL,
16167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16177687d0d8SRobert Mustacchi 	{ 8, 8, "atom64", "64-bit AtomicOp Completer", PRDV_STRVAL,
16187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16197687d0d8SRobert Mustacchi 	{ 9, 9, "cas128", "128-bit CAS Completer", PRDV_STRVAL,
16207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16217687d0d8SRobert Mustacchi 	{ 10, 10, "norelord", "No Ro-enabld PR-PR Passing", PRDV_STRVAL,
16227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16237687d0d8SRobert Mustacchi 	{ 11, 11, "ltr", "LTR Mechanism", PRDV_STRVAL,
16247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16257687d0d8SRobert Mustacchi 	{ 12, 13, "tph", "TPH Completer", PRDV_STRVAL,
16267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "TPH supported",
16277687d0d8SRobert Mustacchi 	    NULL, "TPH and Extended TPH supported" } } },
16287687d0d8SRobert Mustacchi 	{ 14, 15, "lncls", "LN System CLS", PRDV_STRVAL,
16297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported",
16307687d0d8SRobert Mustacchi 	    "LN with 64-byte cachelines", "LN with 128-byte cachelines" } } },
16317687d0d8SRobert Mustacchi 	{ 16, 16, "tag10comp", "10-bit Tag Completer", PRDV_STRVAL,
16327687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16337687d0d8SRobert Mustacchi 	{ 17, 17, "tag10req", "10-bit Tag Requester", PRDV_STRVAL,
16347687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16357687d0d8SRobert Mustacchi 	{ 18, 19, "obff", "OBFF", PRDV_STRVAL,
16367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "Message Signaling",
16377687d0d8SRobert Mustacchi 	    "WAKE# Signaling", "WAKE# and Message Signaling" } } },
16387687d0d8SRobert Mustacchi 	{ 20, 20, "extfmt", "Extended Fmt Field Supported", PRDV_STRVAL,
16397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16407687d0d8SRobert Mustacchi 	{ 21, 21, "eetlp", "End-End TLP Prefix Supported", PRDV_STRVAL,
16417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16427687d0d8SRobert Mustacchi 	{ 22, 23, "maxeetlp", "Max End-End TLP Prefixes", PRDV_STRVAL,
16437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4", "1", "2", "3" } } },
16447687d0d8SRobert Mustacchi 	{ 24, 25, "empr", "Emergency Power Reduction", PRDV_STRVAL,
16457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported",
16467687d0d8SRobert Mustacchi 	    "supported, device-specific",
16477687d0d8SRobert Mustacchi 	    "supported, from factor or device-specific" } } },
16487687d0d8SRobert Mustacchi 	{ 21, 21, "emprinit",
16497687d0d8SRobert Mustacchi 	    "Emergency Power Reduction Initialization Required", PRDV_STRVAL,
16507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
16517687d0d8SRobert Mustacchi 	{ 31, 31, "frs", "Function Readiness Status", PRDV_STRVAL,
16527687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16537687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16547687d0d8SRobert Mustacchi };
16557687d0d8SRobert Mustacchi 
16564a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_devctl2[] = {
16577687d0d8SRobert Mustacchi 	{ 0, 3, "cmpto", "Completion Timeout", PRDV_STRVAL,
16587687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "50us-50ms", "50us-100us",
16597687d0d8SRobert Mustacchi 	    "1ms-10ms", NULL, NULL, "16ms-55ms", "65ms-210ms", NULL, NULL,
16607687d0d8SRobert Mustacchi 	    "260ms-900ms", "1s-3.5s", NULL, NULL, "4s-13s", "17s-64s" } } },
16617687d0d8SRobert Mustacchi 	{ 4, 4, "cmptodis", "Completion Timeout Disabled", PRDV_STRVAL,
16627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not disabled", "disabled" } } },
16637687d0d8SRobert Mustacchi 	{ 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL,
16647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16657687d0d8SRobert Mustacchi 	{ 6, 6, "atomreq", "AtomicOp Requester", PRDV_STRVAL,
16667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16677687d0d8SRobert Mustacchi 	{ 7, 7, "atomblock", "AtomicOp Egress Blocking", PRDV_STRVAL,
16687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unblocked", "blocked" } } },
16697687d0d8SRobert Mustacchi 	{ 8, 8, "idoreq", "ID-Based Ordering Request", PRDV_STRVAL,
16707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16717687d0d8SRobert Mustacchi 	{ 9, 9, "idocomp", "ID-Based Ordering Completion", PRDV_STRVAL,
16727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16737687d0d8SRobert Mustacchi 	{ 10, 10, "ltr", "LTR Mechanism", PRDV_STRVAL,
16747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16757687d0d8SRobert Mustacchi 	{ 11, 11, "empowred", "Emergency Power Reduction", PRDV_STRVAL,
16767687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not requested", "requested" } } },
16777687d0d8SRobert Mustacchi 	{ 12, 12, "tag10req", "10-bit Tag Requester", PRDV_STRVAL,
16787687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
16797687d0d8SRobert Mustacchi 	{ 13, 14, "obff", "OBFF", PRDV_STRVAL,
16807687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "message signaling - A",
16817687d0d8SRobert Mustacchi 	    "message signaling - B", "WAKE# signaling" } } },
16827687d0d8SRobert Mustacchi 	{ 15, 15, "eetlpblk", "End-End TLP Prefix Blocking", PRDV_STRVAL,
16837687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unblocked", "blocked" } } },
16847687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16857687d0d8SRobert Mustacchi };
16867687d0d8SRobert Mustacchi 
16874a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_devsts2[] = {
16887687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
16897687d0d8SRobert Mustacchi };
16907687d0d8SRobert Mustacchi 
16914a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_linkcap2[] = {
16927687d0d8SRobert Mustacchi 	{ 1, 7, "supspeeds", "Supported Link Speeds", PRDV_BITFIELD,
16937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
169489427192SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } },
16957687d0d8SRobert Mustacchi 	{ 8, 8, "crosslink", "Crosslink", PRDV_STRVAL,
16967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
16977687d0d8SRobert Mustacchi 	{ 9, 15, "skposgen", "Lower SKP OS Generation Supported Speeds Vector",
16987687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
16997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
170089427192SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } },
17017687d0d8SRobert Mustacchi 	{ 16, 22, "skposrecv", "Lower SKP OS Reception Supported Speeds Vector",
17027687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
17037687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
170489427192SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } },
17057687d0d8SRobert Mustacchi 	{ 23, 23, "retimedet", "Retimer Presence Detect Supported", PRDV_STRVAL,
17067687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
17077687d0d8SRobert Mustacchi 	{ 24, 24, "retime2det", "Two Retimers Presence Detect Supported",
17087687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
17097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
17107687d0d8SRobert Mustacchi 	{ 31, 31, "drs", "Device Readiness Status", PRDV_STRVAL,
17117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
17127687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17137687d0d8SRobert Mustacchi };
17147687d0d8SRobert Mustacchi 
17154a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_linkctl2[] = {
17167687d0d8SRobert Mustacchi 	{ 0, 3, "targspeed", "Target Link Speed", PRDV_STRVAL,
17177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s",
171889427192SRobert Mustacchi 	    "8.0 GT/s", "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } },
17197687d0d8SRobert Mustacchi 	{ 4, 4, "comp", "Enter Compliance", PRDV_STRVAL,
17207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17217687d0d8SRobert Mustacchi 	{ 5, 5, "hwautosp", "Hardware Autonomous Speed Disable", PRDV_STRVAL,
17227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not disabled", "disabled" } } },
17237687d0d8SRobert Mustacchi 	{ 6, 6, "seldeemph", "Selectable De-emphasis", PRDV_STRVAL,
17247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } },
17257687d0d8SRobert Mustacchi 	{ 7, 9, "txmarg", "TX Margin", PRDV_HEX },
17267687d0d8SRobert Mustacchi 	{ 10, 10, "modcomp", "Enter Modified Compliance", PRDV_STRVAL,
17277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17287687d0d8SRobert Mustacchi 	{ 11, 11, "compsos", "Compliance SOS",
17297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
17307687d0d8SRobert Mustacchi 	{ 12, 15, "compemph", "Compliance Preset/De-emphasis", PRDV_HEX },
17317687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17327687d0d8SRobert Mustacchi };
17337687d0d8SRobert Mustacchi 
17344a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_linksts2[] = {
17357687d0d8SRobert Mustacchi 	{ 0, 0, "curdeemph", "Current De-emphasis Level", PRDV_STRVAL,
17367687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } },
17377687d0d8SRobert Mustacchi 	{ 1, 1, "eq8comp", "Equalization 8.0 GT/s Complete", PRDV_STRVAL,
17387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17397687d0d8SRobert Mustacchi 	{ 2, 2, "eq8p1comp", "Equalization 8.0 GT/s Phase 1", PRDV_STRVAL,
17407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
17417687d0d8SRobert Mustacchi 	{ 3, 3, "eq8p2comp", "Equalization 8.0 GT/s Phase 2", PRDV_STRVAL,
17427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
17437687d0d8SRobert Mustacchi 	{ 4, 4, "eq8p3comp", "Equalization 8.0 GT/s Phase 3", PRDV_STRVAL,
17447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } },
17457687d0d8SRobert Mustacchi 	{ 5, 5, "linkeq8req", "Link Equalization Request 8.0 GT/s", PRDV_STRVAL,
17467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not requested", "requested" } } },
17477687d0d8SRobert Mustacchi 	{ 6, 6, "retimedet", "Retimer Presence Detected", PRDV_STRVAL,
17487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17497687d0d8SRobert Mustacchi 	{ 7, 7, "retime2det", "Two Retimers Presence Detected", PRDV_STRVAL,
17507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17517687d0d8SRobert Mustacchi 	{ 8, 9, "crosslink", "Crosslink Resolution", PRDV_STRVAL,
17527687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "upstream port",
17537687d0d8SRobert Mustacchi 	    "downstream port", "incomplete" } } },
17547687d0d8SRobert Mustacchi 	{ 12, 14, "dscomppres", "Downstream Component Presence", PRDV_STRVAL,
17557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "link down - undetermined",
17567687d0d8SRobert Mustacchi 	    "link down - not present", "link down - present", NULL,
17577687d0d8SRobert Mustacchi 	    "link up - present", "link up - present and DRS" } } },
17587687d0d8SRobert Mustacchi 	{ 15, 15, "drsrx", "DRS Message Received", PRDV_STRVAL,
17597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
17607687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17617687d0d8SRobert Mustacchi };
17627687d0d8SRobert Mustacchi 
17634a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_slotcap2[] = {
17647687d0d8SRobert Mustacchi 	{ 0, 0, "ibpddis", "In-Band PD Disable", PRDV_STRVAL,
17657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
17667687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17677687d0d8SRobert Mustacchi };
17687687d0d8SRobert Mustacchi 
17694a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_slotctl2[] = {
17707687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17717687d0d8SRobert Mustacchi };
17727687d0d8SRobert Mustacchi 
17734a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_slotsts2[] = {
17747687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
17757687d0d8SRobert Mustacchi };
17767687d0d8SRobert Mustacchi 
17774a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_dev[] = {
1778bc729d49SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1779bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1780bc729d49SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1781bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1782bc729d49SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1783bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1784bc729d49SRobert Mustacchi 	{ -1, -1, NULL }
1785bc729d49SRobert Mustacchi };
17867687d0d8SRobert Mustacchi 
17874a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_link[] = {
1788bc729d49SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1789bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1790bc729d49SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1791bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1792bc729d49SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1793bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1794bc729d49SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
1795bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
1796bc729d49SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
1797bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
1798bc729d49SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
1799bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
1800bc729d49SRobert Mustacchi 	{ -1, -1, NULL }
1801bc729d49SRobert Mustacchi };
1802bc729d49SRobert Mustacchi 
18034a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_slot[] = {
1804bc729d49SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
1805bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
1806bc729d49SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
1807bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
1808bc729d49SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
1809bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
1810bc729d49SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
1811bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
1812bc729d49SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
1813bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
1814bc729d49SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
1815bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
1816bc729d49SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
1817bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
1818bc729d49SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
1819bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
1820bc729d49SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
1821bc729d49SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
1822bc729d49SRobert Mustacchi 	{ -1, -1, NULL }
1823bc729d49SRobert Mustacchi };
1824bc729d49SRobert Mustacchi 
1825bc729d49SRobert Mustacchi 
18264a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_all[] = {
18277687d0d8SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
18287687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
18297687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
18307687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
18317687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
18327687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
18337687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
18347687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
18357687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
18367687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
18377687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
18387687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
18397687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
18407687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
18417687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
18427687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
18437687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
18447687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
18457687d0d8SRobert Mustacchi 	{ PCIE_ROOTCTL, 2, "rootctl", "Root control",
18467687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl },
18477687d0d8SRobert Mustacchi 	{ PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities",
18487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap },
18497687d0d8SRobert Mustacchi 	{ PCIE_ROOTSTS, 4, "rootsts", "Root Status",
18507687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts },
18517687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
18527687d0d8SRobert Mustacchi };
18537687d0d8SRobert Mustacchi 
18544a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v2[] = {
18557687d0d8SRobert Mustacchi 	{ PCIE_PCIECAP, 2, "cap", "Capability Register",
18567687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap },
18577687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP, 4, "devcap", "Device Capabilities",
18587687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap },
18597687d0d8SRobert Mustacchi 	{ PCIE_DEVCTL, 2, "devctl", "Device Control",
18607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl },
18617687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS, 2, "devsts", "Device Status",
18627687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts },
18637687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP, 4, "linkcap", "Link Capabilities",
18647687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap },
18657687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL, 2, "linkctl", "Link Control",
18667687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl },
18677687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS, 2, "linksts", "Link Status",
18687687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts },
18697687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities",
18707687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap },
18717687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL, 2, "slotctl", "Slot Control",
18727687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl },
18737687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS, 2, "slotsts", "Slot Status",
18747687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts },
18757687d0d8SRobert Mustacchi 	{ PCIE_ROOTCTL, 2, "rootctl", "Root Control",
18767687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl },
18777687d0d8SRobert Mustacchi 	{ PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities",
18787687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap },
18797687d0d8SRobert Mustacchi 	{ PCIE_ROOTSTS, 4, "rootsts", "Root Status",
18807687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts },
18817687d0d8SRobert Mustacchi 	{ PCIE_DEVCAP2, 4, "devcap2", "Device Capabilities 2",
18827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap2 },
18837687d0d8SRobert Mustacchi 	{ PCIE_DEVCTL2, 2, "devctl2", "Device Control 2",
18847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl2 },
18857687d0d8SRobert Mustacchi 	{ PCIE_DEVSTS2, 2, "devsts2", "Device Status 2",
18867687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts2 },
18877687d0d8SRobert Mustacchi 	{ PCIE_LINKCAP2, 4, "linkcap2", "Link Capabilities 2",
18887687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap2 },
18897687d0d8SRobert Mustacchi 	{ PCIE_LINKCTL2, 2, "linkctl2", "Link Control 2",
18907687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl2 },
18917687d0d8SRobert Mustacchi 	{ PCIE_LINKSTS2, 2, "linksts2", "Link Status 2",
18927687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts2 },
18937687d0d8SRobert Mustacchi 	{ PCIE_SLOTCAP2, 4, "slotcap2", "Slot Capabilities 2",
18947687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap2 },
18957687d0d8SRobert Mustacchi 	{ PCIE_SLOTCTL2, 2, "slotctl2", "Slot Control 2",
18967687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl2 },
18977687d0d8SRobert Mustacchi 	{ PCIE_SLOTSTS2, 2, "slotsts2", "Slot Status 2",
18987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts2 },
18997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19007687d0d8SRobert Mustacchi };
19017687d0d8SRobert Mustacchi 
19027687d0d8SRobert Mustacchi /*
19037687d0d8SRobert Mustacchi  * PCIe Extended Capability Header
19047687d0d8SRobert Mustacchi  */
19054a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie_caphdr[] = {
19067687d0d8SRobert Mustacchi 	{ 0, 15, "capid", "Capability ID", PRDV_HEX },
19077687d0d8SRobert Mustacchi 	{ 16, 19, "version", "Capability Version", PRDV_HEX },
19087687d0d8SRobert Mustacchi 	{ 20, 32, "offset", "Next Capability Offset", PRDV_HEX },
19097687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19107687d0d8SRobert Mustacchi };
19117687d0d8SRobert Mustacchi 
19127687d0d8SRobert Mustacchi /*
19137687d0d8SRobert Mustacchi  * VPD Capability
19147687d0d8SRobert Mustacchi  */
19154a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vpd_addr[] = {
19167687d0d8SRobert Mustacchi 	{ 0, 14, "addr", "VPD Address", PRDV_HEX },
19177687d0d8SRobert Mustacchi 	{ 15, 15, "flag", "Flag", PRDV_HEX },
19187687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19197687d0d8SRobert Mustacchi };
19207687d0d8SRobert Mustacchi 
19214a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_vpd[] = {
19227687d0d8SRobert Mustacchi 	{ 0x2, 2, "addr", "VPD Address Register",
19237687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vpd_addr },
19247687d0d8SRobert Mustacchi 	{ 0x4, 4, "data", "VPD Data", pcieadm_cfgspace_print_hex },
19257687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19267687d0d8SRobert Mustacchi };
19277687d0d8SRobert Mustacchi 
19287687d0d8SRobert Mustacchi /*
19297687d0d8SRobert Mustacchi  * SATA Capability per AHCI 1.3.1
19307687d0d8SRobert Mustacchi  */
19314a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sata_cr0[] = {
19327687d0d8SRobert Mustacchi 	{ 0, 3, "minrev", "Minor Revision", PRDV_HEX },
19337687d0d8SRobert Mustacchi 	{ 4, 7, "majrev", "Major Revision", PRDV_HEX },
19347687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19357687d0d8SRobert Mustacchi };
19367687d0d8SRobert Mustacchi 
19374a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sata_cr1[] = {
19387687d0d8SRobert Mustacchi 	{ 0, 3, "bar", "BAR Location", PRDV_HEX,
19397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 2 } } },
19407687d0d8SRobert Mustacchi 	{ 4, 23, "offset", "BAR Offset", PRDV_HEX,
19417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 2 } } },
19427687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19437687d0d8SRobert Mustacchi };
19447687d0d8SRobert Mustacchi 
19454a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_sata[] = {
19467687d0d8SRobert Mustacchi 	{ 0x2, 2, "satacr0", "SATA Capability Register 0",
19477687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr0 },
19487687d0d8SRobert Mustacchi 	{ 0x4, 4, "satacr1", "SATA Capability Register 1",
19497687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr1 },
19507687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19517687d0d8SRobert Mustacchi };
19527687d0d8SRobert Mustacchi 
19537687d0d8SRobert Mustacchi /*
19547687d0d8SRobert Mustacchi  * Debug Capability per EHCI
19557687d0d8SRobert Mustacchi  */
19564a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_debug[] = {
19577687d0d8SRobert Mustacchi 	{ 0, 12, "offset", "BAR Offset", PRDV_HEX },
19587687d0d8SRobert Mustacchi 	{ 13, 15, "bar", "BAR Location ", PRDV_STRVAL,
19597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { NULL, "BAR 0", "BAR 1", "BAR 2",
19607687d0d8SRobert Mustacchi 	    "BAR 3", "BAR 4", "BAR 5" } } },
19617687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19627687d0d8SRobert Mustacchi };
19637687d0d8SRobert Mustacchi 
19644a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_debug[] = {
19657687d0d8SRobert Mustacchi 	{ 0x2, 2, "port", "Debug Port",
19667687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_debug },
19677687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19687687d0d8SRobert Mustacchi };
19697687d0d8SRobert Mustacchi 
19707687d0d8SRobert Mustacchi /*
19717687d0d8SRobert Mustacchi  * AER Capability
19727687d0d8SRobert Mustacchi  */
19734a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_ue[] = {
19747687d0d8SRobert Mustacchi 	{ 4, 4, "dlp", "Data Link Protocol Error", PRDV_HEX },
19757687d0d8SRobert Mustacchi 	{ 5, 5, "sde", "Surprise Down Error", PRDV_HEX },
19767687d0d8SRobert Mustacchi 	{ 12, 12, "ptlp", "Poisoned TLP Received", PRDV_HEX },
19777687d0d8SRobert Mustacchi 	{ 13, 13, "fcp", "Flow Control Protocol Error", PRDV_HEX },
19787687d0d8SRobert Mustacchi 	{ 14, 14, "cto", "Completion Timeout", PRDV_HEX },
19797687d0d8SRobert Mustacchi 	{ 15, 15, "cab", "Completion Abort", PRDV_HEX },
19807687d0d8SRobert Mustacchi 	{ 16, 16, "unco", "Unexpected Completion", PRDV_HEX },
19817687d0d8SRobert Mustacchi 	{ 17, 17, "rxov", "Receiver Overflow", PRDV_HEX },
19827687d0d8SRobert Mustacchi 	{ 18, 18, "maltlp", "Malformed TLP", PRDV_HEX },
19837687d0d8SRobert Mustacchi 	{ 19, 19, "ecrc", "ECRC Error", PRDV_HEX },
19847687d0d8SRobert Mustacchi 	{ 20, 20, "usuprx", "Unsupported Request Error", PRDV_HEX },
19857687d0d8SRobert Mustacchi 	{ 21, 21, "acs", "ACS Violation", PRDV_HEX },
19867687d0d8SRobert Mustacchi 	{ 22, 22, "ueint", "Uncorrectable Internal Error", PRDV_HEX },
19877687d0d8SRobert Mustacchi 	{ 23, 23, "mcbtlp", "MC Blocked TLP", PRDV_HEX },
19887687d0d8SRobert Mustacchi 	{ 24, 24, "atoomeb", "AtomicOp Egress Blocked", PRDV_HEX },
19897687d0d8SRobert Mustacchi 	{ 25, 25, "tlppb", "TLP Prefix Blocked Error", PRDV_HEX },
19907687d0d8SRobert Mustacchi 	{ 26, 26, "ptlpeb", "Poisoned TLP Egress Blocked", PRDV_HEX },
19917687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
19927687d0d8SRobert Mustacchi };
19937687d0d8SRobert Mustacchi 
19944a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_ce[] = {
19957687d0d8SRobert Mustacchi 	{ 0, 0, "rxerr", "Receiver Error", PRDV_HEX },
19967687d0d8SRobert Mustacchi 	{ 6, 6, "badtlp", "Bad TLP", PRDV_HEX },
19977687d0d8SRobert Mustacchi 	{ 7, 7, "baddllp", "Bad DLLP", PRDV_HEX },
19987687d0d8SRobert Mustacchi 	{ 8, 8, "replayro", "REPLAY_NUM Rollover", PRDV_HEX },
19997687d0d8SRobert Mustacchi 	{ 12, 12, "rtto", "Replay timer Timeout", PRDV_HEX },
20007687d0d8SRobert Mustacchi 	{ 13, 13, "advnfe", "Advisory Non-Fatal Error", PRDV_HEX },
20017687d0d8SRobert Mustacchi 	{ 14, 14, "ceint", "Correctable Internal Error", PRDV_HEX },
20027687d0d8SRobert Mustacchi 	{ 15, 15, "headlov", "Header Log Overflow", PRDV_HEX },
20037687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20047687d0d8SRobert Mustacchi };
20057687d0d8SRobert Mustacchi 
20064a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_ctrl[] = {
20077687d0d8SRobert Mustacchi 	{ 0, 4, "feptr", "First Error Pointer", PRDV_HEX },
20087687d0d8SRobert Mustacchi 	{ 5, 5, "ecgencap", "ECRC Generation Capable", PRDV_STRVAL,
20097687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
20107687d0d8SRobert Mustacchi 	{ 6, 6, "ecgenen", "ECRC Generation Enable", PRDV_STRVAL,
20117687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20127687d0d8SRobert Mustacchi 	{ 7, 7, "ecchkcap", "ECRC Check Capable", PRDV_STRVAL,
20137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
20147687d0d8SRobert Mustacchi 	{ 8, 8, "ecchken", "ECRC Check Enable", PRDV_STRVAL,
20157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20167687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20177687d0d8SRobert Mustacchi };
20187687d0d8SRobert Mustacchi 
20194a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_rootcom[] = {
20207687d0d8SRobert Mustacchi 	{ 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL,
20217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20227687d0d8SRobert Mustacchi 	{ 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL,
20237687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20247687d0d8SRobert Mustacchi 	{ 2, 2, "faterr", "Fatal Error Reporting", PRDV_STRVAL,
20257687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
20267687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20277687d0d8SRobert Mustacchi };
20287687d0d8SRobert Mustacchi 
20294a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_rootsts[] = {
20307687d0d8SRobert Mustacchi 	{ 0, 0, "errcor", "ERR_COR Received", PRDV_HEX },
20317687d0d8SRobert Mustacchi 	{ 1, 1, "merrcor", "Multiple ERR_COR Received", PRDV_HEX },
20327687d0d8SRobert Mustacchi 	{ 2, 2, "errfnf", "ERR_FATAL/NONFATAL Received", PRDV_HEX },
20337687d0d8SRobert Mustacchi 	{ 3, 3, "merrfnf", "Multiple ERR_FATAL/NONFATAL Received", PRDV_HEX },
20347687d0d8SRobert Mustacchi 	{ 4, 4, "fuefat", "First Uncorrectable Fatal", PRDV_HEX },
20357687d0d8SRobert Mustacchi 	{ 5, 5, "nferrrx", "Non-Fatal Error Messages Received", PRDV_HEX },
20367687d0d8SRobert Mustacchi 	{ 6, 6, "faterrx", "Fatal Error Messages Received", PRDV_HEX },
20377687d0d8SRobert Mustacchi 	{ 7, 8, "errcorsc", "ERR_COR Subclass", PRDV_STRVAL,
20387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "ECS Legacy", "ECS SIG_SFW",
20397687d0d8SRobert Mustacchi 	    "ECS SIG_OS", "ECS Extended" } } },
20407687d0d8SRobert Mustacchi 	{ 27, 31, "inum", "Advanced Error Interrupt Message", PRDV_HEX },
20417687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20427687d0d8SRobert Mustacchi };
20437687d0d8SRobert Mustacchi 
20444a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_esi[] = {
20457687d0d8SRobert Mustacchi 	{ 0, 15, "errcorr", "ERR_COR Source", PRDV_HEX },
20467687d0d8SRobert Mustacchi 	{ 16, 31, "errfnf", "ERR_FATAL/NONFATAL Source", PRDV_HEX },
20477687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20487687d0d8SRobert Mustacchi };
20497687d0d8SRobert Mustacchi 
20504a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_secue[] = {
20517687d0d8SRobert Mustacchi 	{ 0, 0, "taosc", "Target-Abort on Split Completion", PRDV_HEX },
20527687d0d8SRobert Mustacchi 	{ 1, 1, "maosc", "Master-Abort on Split Completion", PRDV_HEX },
20537687d0d8SRobert Mustacchi 	{ 2, 2, "rxta", "Received Target-Abort", PRDV_HEX },
20547687d0d8SRobert Mustacchi 	{ 3, 3, "rxma", "Received Master-Abort", PRDV_HEX },
20557687d0d8SRobert Mustacchi 	{ 5, 5, "unsce", "Unexpected Split Completion Error", PRDV_HEX },
20567687d0d8SRobert Mustacchi 	{ 6, 6, "uescmd", "Uncorrectable Split Completion Message Data Error",
20577687d0d8SRobert Mustacchi 	    PRDV_HEX },
20587687d0d8SRobert Mustacchi 	{ 7, 7, "uede", "Uncorrectable Data Error", PRDV_HEX },
20597687d0d8SRobert Mustacchi 	{ 8, 8, "ueattre", "Uncorrectable Attribute Error", PRDV_HEX },
20607687d0d8SRobert Mustacchi 	{ 9, 9, "ueaddre", "Uncorrectable Address Error", PRDV_HEX },
20617687d0d8SRobert Mustacchi 	{ 10, 10, "dtdte", "Delayed Transaction Discard Timer Expired",
20627687d0d8SRobert Mustacchi 	    PRDV_HEX },
20637687d0d8SRobert Mustacchi 	{ 11, 11, "perr", "PERR# Assertion", PRDV_HEX },
20647687d0d8SRobert Mustacchi 	{ 12, 12, "serr", "SERR# Assertion", PRDV_HEX },
20657687d0d8SRobert Mustacchi 	{ 13, 13, "internal", "Internal Bridge Error", PRDV_HEX },
20667687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20677687d0d8SRobert Mustacchi };
20687687d0d8SRobert Mustacchi 
20694a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_aer_secctl[] = {
20707687d0d8SRobert Mustacchi 	{ 0, 4, "feptr", "Secondary Uncorrectable First Error Pointer",
20717687d0d8SRobert Mustacchi 	    PRDV_HEX },
20727687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
20737687d0d8SRobert Mustacchi };
20747687d0d8SRobert Mustacchi 
20754a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_aer_v1[] = {
20767687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
20777687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
20787687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
20797687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20807687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
20817687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20827687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
20837687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
20847687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
20857687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
20867687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
20877687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
20887687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
20897687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
20907687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
20917687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20927687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
20937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20947687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
20957687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20967687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
20977687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
20988b0ccc49SKeith M Wesolowski 	{ PCIE_AER_RE_CMD, 4, "rootcmd", "Root Error Command",
20997687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
21007687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
21017687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
21027687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_SRC_ID, 4, "esi", "Error Source Identification",
21037687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_esi },
21047687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
21057687d0d8SRobert Mustacchi };
21067687d0d8SRobert Mustacchi 
21074a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_aer_v2[] = {
21087687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
21097687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
21107687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
21117687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21127687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
21137687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21147687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
21157687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21167687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
21177687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
21187687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
21197687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
21207687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
21217687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
21227687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
21237687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21247687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
21257687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21267687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
21277687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21287687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
21297687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21308b0ccc49SKeith M Wesolowski 	{ PCIE_AER_RE_CMD, 4, "rootcmd", "Root Error Command",
21317687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
21327687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
21337687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
21347687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG, 4, "tlplog0", "TLP Prefix Log 0",
21357687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21367687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 4, 4, "tlplog1", "TLP Prefix Log 1",
21377687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21387687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 8, 4, "tlplog2", "TLP Prefix Log 2",
21397687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21407687d0d8SRobert Mustacchi 	{ PCIE_AER_TLP_PRE_LOG + 12, 4, "tlplog3", "TLP Prefix Log 3",
21417687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21427687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
21437687d0d8SRobert Mustacchi };
21447687d0d8SRobert Mustacchi 
21454a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_aer_bridge[] = {
21467687d0d8SRobert Mustacchi 	{ PCIE_AER_CAP, 4, "caphdr", "Capability Header",
21477687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
21487687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_STS, 4, "uestatus", "Uncorrectable Error Status",
21497687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21507687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_MASK, 4, "uemask", "Uncorrectable Error Mask",
21517687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21527687d0d8SRobert Mustacchi 	{ PCIE_AER_UCE_SERV, 4, "ueserv", "Uncorrectable Error Severity",
21537687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ue },
21547687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_STS, 4, "cestatus", "Correctable Error Status",
21557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
21567687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_MASK, 4, "cemask", "Correctable Error Mask",
21577687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ce },
21587687d0d8SRobert Mustacchi 	{ PCIE_AER_CTL, 4, "ctrl", "Advanced Error Capabilities and Control",
21597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_ctrl },
21607687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 4, 4, "hl0", "Header Log 0",
21617687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21627687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 8, 4, "hl1", "Header Log 1",
21637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21647687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl2", "Header Log 2",
21657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21667687d0d8SRobert Mustacchi 	{ PCIE_AER_HDR_LOG + 12, 4, "hl3", "Header Log 3",
21677687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21688b0ccc49SKeith M Wesolowski 	{ PCIE_AER_RE_CMD, 4, "rootcmd", "Root Error Command",
21697687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootcom },
21707687d0d8SRobert Mustacchi 	{ PCIE_AER_RE_STS, 4, "rootsts", "Root Error Status",
21717687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_rootsts },
21727687d0d8SRobert Mustacchi 	{ PCIE_AER_CE_SRC_ID, 4, "esi", "Error Source Identification",
21737687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_esi },
21747687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_STS, 4, "secuests",
21757687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Status",
21767687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
21777687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_MASK, 4, "secuests",
21787687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Mask",
21797687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
21807687d0d8SRobert Mustacchi 	{ PCIE_AER_SUCE_SERV, 4, "secuests",
21817687d0d8SRobert Mustacchi 	    "Secondary Uncorrectable Error Severity",
21827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secue },
21837687d0d8SRobert Mustacchi 	{ PCIE_AER_SCTL, 4, "secctrl",
21847687d0d8SRobert Mustacchi 	    "Secondary Error Capabilityes and Control",
21857687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_aer_secctl },
21867687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG, 4, "shl0", "Secondary Header Log 0",
21877687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21887687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 4, 4, "shl1", "Secondary Header Log 1",
21897687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21907687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 8, 4, "shl1", "Secondary Header Log 2",
21917687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21927687d0d8SRobert Mustacchi 	{ PCIE_AER_SHDR_LOG + 12, 4, "shl1", "Secondary Header Log 3",
21937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
21947687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
21957687d0d8SRobert Mustacchi };
21967687d0d8SRobert Mustacchi 
21977687d0d8SRobert Mustacchi /*
21987687d0d8SRobert Mustacchi  * Secondary PCI Express Extended Capability
21997687d0d8SRobert Mustacchi  */
22004a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie2_linkctl3[] = {
22017687d0d8SRobert Mustacchi 	{ 0, 0, "peq", "Perform Equalization", PRDV_HEX },
22027687d0d8SRobert Mustacchi 	{ 1, 1, "leqrie", "Link Equalization Request Interrupt Enable",
22037687d0d8SRobert Mustacchi 	    PRDV_STRVAL,
22047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22057687d0d8SRobert Mustacchi 	{ 9, 15, "elskpos", "Enable Lower SKP OS Generation Vector",
22067687d0d8SRobert Mustacchi 	    PRDV_BITFIELD,
22077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s",
22087687d0d8SRobert Mustacchi 	    "16.0 GT/s", "32.0 GT/s" } } },
22097687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22107687d0d8SRobert Mustacchi };
22117687d0d8SRobert Mustacchi 
22124a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcie2_linkeq[] = {
22137687d0d8SRobert Mustacchi 	{ 0, 3, "dstxpre", "Downstream Port 8.0 GT/s Transmitter Preset",
22147687d0d8SRobert Mustacchi 	    PRDV_HEX },
22157687d0d8SRobert Mustacchi 	{ 4, 6, "dstxhint", "Downstream Port 8.0 GT/s Receiver Hint",
22167687d0d8SRobert Mustacchi 	    PRDV_HEX },
22177687d0d8SRobert Mustacchi 	{ 8, 11, "ustxpre", "Upstream Port 8.0 GT/s Transmitter Preset",
22187687d0d8SRobert Mustacchi 	    PRDV_HEX },
22197687d0d8SRobert Mustacchi 	{ 12, 14, "ustxhint", "Upstream Port 8.0 GT/s Receiver Hint",
22207687d0d8SRobert Mustacchi 	    PRDV_HEX },
22217687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22227687d0d8SRobert Mustacchi };
22237687d0d8SRobert Mustacchi 
22247687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_laneq(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)22257687d0d8SRobert Mustacchi pcieadm_cfgspace_print_laneq(pcieadm_cfgspace_walk_t *walkp,
22264a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
22277687d0d8SRobert Mustacchi {
22287687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
22297687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
22307687d0d8SRobert Mustacchi 		    "secondary PCIe cap");
22317687d0d8SRobert Mustacchi 		return;
22327687d0d8SRobert Mustacchi 	}
22337687d0d8SRobert Mustacchi 
22347687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
22357687d0d8SRobert Mustacchi 		char eqshort[32], eqhuman[128];
22367687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
22377687d0d8SRobert Mustacchi 
22387687d0d8SRobert Mustacchi 		(void) snprintf(eqshort, sizeof (eqshort), "lane%u", i);
22397687d0d8SRobert Mustacchi 		(void) snprintf(eqhuman, sizeof (eqhuman), "Lane %u EQ Control",
22407687d0d8SRobert Mustacchi 		    i);
22417687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 2;
22427687d0d8SRobert Mustacchi 		p.pcp_len = 2;
22437687d0d8SRobert Mustacchi 		p.pcp_short = eqshort;
22447687d0d8SRobert Mustacchi 		p.pcp_human = eqhuman;
22457687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
22467687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_pcie2_linkeq;
22477687d0d8SRobert Mustacchi 
22487687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
22497687d0d8SRobert Mustacchi 	}
22507687d0d8SRobert Mustacchi }
22517687d0d8SRobert Mustacchi 
22524a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcie2[] = {
22537687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
22547687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
22557687d0d8SRobert Mustacchi 	{ 0x4, 4, "linkctl3", "Link Control 3",
22567687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie2_linkctl3 },
22577687d0d8SRobert Mustacchi 	{ 0x8, 4, "laneerr", "Lane Error Status", pcieadm_cfgspace_print_hex },
22587687d0d8SRobert Mustacchi 	{ 0xc, 2, "eqctl", "Lane Equalization Control",
22597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_laneq },
22607687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22617687d0d8SRobert Mustacchi };
22627687d0d8SRobert Mustacchi 
22637687d0d8SRobert Mustacchi /*
22647687d0d8SRobert Mustacchi  * Access Control Services
22657687d0d8SRobert Mustacchi  */
22664a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_acs_cap[] = {
22677687d0d8SRobert Mustacchi 	{ 0, 0, "srcvd", "ACS Source Validation", PRDV_STRVAL,
22687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22697687d0d8SRobert Mustacchi 	{ 1, 1, "tranblk", "ACS Transaction Blocking", PRDV_STRVAL,
22707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22717687d0d8SRobert Mustacchi 	{ 2, 2, "p2prr", "ACS P2P Request Redirect", PRDV_STRVAL,
22727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22737687d0d8SRobert Mustacchi 	{ 3, 3, "p2pcr", "ACS P2P Completion Redirect", PRDV_STRVAL,
22747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22757687d0d8SRobert Mustacchi 	{ 4, 4, "upfwd", "ACS Upstream Forwarding", PRDV_STRVAL,
22767687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22777687d0d8SRobert Mustacchi 	{ 5, 5, "p2pegctl", "ACS P2P Egress Control", PRDV_STRVAL,
22787687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22797687d0d8SRobert Mustacchi 	{ 6, 6, "dtp2p", "ACS Direct Translated P2P", PRDV_STRVAL,
22807687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22817687d0d8SRobert Mustacchi 	{ 7, 7, "enhcap", "ACS Enhanced Capability", PRDV_STRVAL,
22827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
22837687d0d8SRobert Mustacchi 	{ 8, 15, "ecvsz", "Egress Control Vector Size", PRDV_HEX },
22847687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
22857687d0d8SRobert Mustacchi };
22867687d0d8SRobert Mustacchi 
22874a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_acs_ctl[] = {
22887687d0d8SRobert Mustacchi 	{ 0, 0, "srcvd", "ACS Source Validation", PRDV_STRVAL,
22897687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22907687d0d8SRobert Mustacchi 	{ 1, 1, "tranblk", "ACS Transaction Blocking", PRDV_STRVAL,
22917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22927687d0d8SRobert Mustacchi 	{ 2, 2, "p2prr", "ACS P2P Request Redirect", PRDV_STRVAL,
22937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22947687d0d8SRobert Mustacchi 	{ 3, 3, "p2pcr", "ACS P2P Completion Redirect", PRDV_STRVAL,
22957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22967687d0d8SRobert Mustacchi 	{ 4, 4, "upfwd", "ACS Upstream Forwarding", PRDV_STRVAL,
22977687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
22987687d0d8SRobert Mustacchi 	{ 5, 5, "p2pegctl", "ACS P2P Egress Control", PRDV_STRVAL,
22997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23007687d0d8SRobert Mustacchi 	{ 6, 6, "dtp2p", "ACS Direct Translated P2P", PRDV_STRVAL,
23017687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23027687d0d8SRobert Mustacchi 	{ 7, 7, "iorb", "ACS I/O Request Blocking", PRDV_STRVAL,
23037687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23047687d0d8SRobert Mustacchi 	{ 8, 9, "dspmta", "ACS DSP Memory Target Access Control", PRDV_STRVAL,
23057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Direct Request access",
23067687d0d8SRobert Mustacchi 	    "Request blocking", "Request redirect" } } },
23077687d0d8SRobert Mustacchi 	{ 10, 11, "uspmta", "ACS USP Memory Target Access Control", PRDV_STRVAL,
23087687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Direct Request access",
23097687d0d8SRobert Mustacchi 	    "Request blocking", "Request redirect" } } },
23107687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23117687d0d8SRobert Mustacchi };
23127687d0d8SRobert Mustacchi 
23134a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_acs[] = {
23147687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
23157687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
23167687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ACS Capability",
23177687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_acs_cap },
23187687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "ACS Control",
23197687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_acs_ctl },
23207687d0d8SRobert Mustacchi 	{ 0x8, 4, "ecv", "Egress Control Vector", pcieadm_cfgspace_print_ecv },
23217687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23227687d0d8SRobert Mustacchi };
23237687d0d8SRobert Mustacchi 
23247687d0d8SRobert Mustacchi /*
23257687d0d8SRobert Mustacchi  * L1 PM Substates
23267687d0d8SRobert Mustacchi  */
23274a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_l1pm_cap[] = {
23287687d0d8SRobert Mustacchi 	{ 0, 0, "pcil1.2", "PCI-PM L1.2", PRDV_STRVAL,
23297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23307687d0d8SRobert Mustacchi 	{ 1, 1, "pcil1.1", "PCI-PM L1.1", PRDV_STRVAL,
23317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23327687d0d8SRobert Mustacchi 	{ 2, 2, "aspml1.2", "ASPM L1.2", PRDV_STRVAL,
23337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23347687d0d8SRobert Mustacchi 	{ 3, 3, "aspml1.1", "ASPM L1.1", PRDV_STRVAL,
23357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23367687d0d8SRobert Mustacchi 	{ 4, 4, "l1pmsub", "L1 PM Substates", PRDV_STRVAL,
23377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23387687d0d8SRobert Mustacchi 	{ 5, 5, "linkact", "Link Activation", PRDV_STRVAL,
23397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
23407687d0d8SRobert Mustacchi 	{ 8, 15, "pcmrt", "Port Common_Mode_Restore_Time", PRDV_HEX },
23417687d0d8SRobert Mustacchi 	{ 16, 17, "poscale", "Port T_POWER_ON Scale", PRDV_STRVAL,
23427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2 us", "10 us", "100 us" } } },
23437687d0d8SRobert Mustacchi 	{ 19, 23, "portpo", "Port T_POWER_ON Value", PRDV_HEX },
23447687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23457687d0d8SRobert Mustacchi };
23467687d0d8SRobert Mustacchi 
23474a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_l1pm_ctl1[] = {
23487687d0d8SRobert Mustacchi 	{ 0, 0, "pcil1.2", "PCI-PM L1.2", PRDV_STRVAL,
23497687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23507687d0d8SRobert Mustacchi 	{ 1, 1, "pcil1.1", "PCI-PM L1.1", PRDV_STRVAL,
23517687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23527687d0d8SRobert Mustacchi 	{ 2, 2, "aspml1.2", "ASPM L1.2", PRDV_STRVAL,
23537687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23547687d0d8SRobert Mustacchi 	{ 3, 3, "aspml1.1", "ASPM L1.1", PRDV_STRVAL,
23557687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23567687d0d8SRobert Mustacchi 	{ 4, 4, "laie", "Link Activation Interrupt Enable", PRDV_STRVAL,
23577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23587687d0d8SRobert Mustacchi 	{ 5, 5, "lactl", "Link Activation Control", PRDV_STRVAL,
23597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
23607687d0d8SRobert Mustacchi 	{ 8, 15, "cmrt", "Common_Mode_Restore_Time", PRDV_HEX },
23617687d0d8SRobert Mustacchi 	{ 16, 25, "ltrl1.2", "LTR L1.2 Threshold Value", PRDV_HEX },
23627687d0d8SRobert Mustacchi 	{ 29, 31, "ltrl1.2s", "LTR L1.2 Threshold Scale", PRDV_STRVAL,
23637687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ns", "32 ns", "1024 ns",
23647687d0d8SRobert Mustacchi 	    "32,768 ns", "1,048,576 ns", "33,554,432 ns" } } },
23657687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23667687d0d8SRobert Mustacchi };
23677687d0d8SRobert Mustacchi 
23684a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_l1pm_ctl2[] = {
23697687d0d8SRobert Mustacchi 	{ 0, 1, "poscale", "T_POWER_ON Scale", PRDV_STRVAL,
23707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "2 us", "10 us", "100 us" } } },
23717687d0d8SRobert Mustacchi 	{ 3, 7, "portpo", "T_POWER_ON Value", PRDV_HEX },
23727687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23737687d0d8SRobert Mustacchi };
23747687d0d8SRobert Mustacchi 
23754a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_l1pm_sts[] = {
23767687d0d8SRobert Mustacchi 	{ 0, 0, "la", "Link Activation", PRDV_HEX },
23777687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23787687d0d8SRobert Mustacchi };
23797687d0d8SRobert Mustacchi 
23807687d0d8SRobert Mustacchi 
23814a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_l1pm_v1[] = {
23827687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
23837687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
23847687d0d8SRobert Mustacchi 	{ 0x4, 4, "caps", "L1 PM Substates Capabilities",
23857687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_cap },
23867687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl1", "L1 PM Substates Control 1",
23877687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl1 },
238866a9cc68SRobert Mustacchi 	{ 0xc, 4, "ctl2", "L1 PM Substates Control 2",
23897687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl2 },
23907687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
23917687d0d8SRobert Mustacchi };
23927687d0d8SRobert Mustacchi 
23934a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_l1pm_v2[] = {
23947687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
23957687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
23967687d0d8SRobert Mustacchi 	{ 0x4, 4, "caps", "L1 PM Substates Capabilities",
23977687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_cap },
23987687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl1", "L1 PM Substates Control 1",
23997687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl1 },
240066a9cc68SRobert Mustacchi 	{ 0xc, 4, "ctl2", "L1 PM Substates Control 2",
24017687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_ctl2 },
24027687d0d8SRobert Mustacchi 	{ 0x10, 4, "sts", "L1 PM Substates Status",
24037687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_l1pm_sts },
24047687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24057687d0d8SRobert Mustacchi };
24067687d0d8SRobert Mustacchi 
24077687d0d8SRobert Mustacchi /*
24087687d0d8SRobert Mustacchi  * Latency Tolerance Reporting (LTR)
24097687d0d8SRobert Mustacchi  */
24104a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ltr[] = {
24117687d0d8SRobert Mustacchi 	{ 0, 9, "latval", "Latency Value", PRDV_HEX },
24127687d0d8SRobert Mustacchi 	{ 10, 12, "latscale", "Latency Scale", PRDV_STRVAL,
24137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ns", "32 ns", "1024 ns",
24147687d0d8SRobert Mustacchi 	    "32,768 ns", "1,048,576 ns", "33,554,432 ns" } } },
24157687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24167687d0d8SRobert Mustacchi };
24177687d0d8SRobert Mustacchi 
24184a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ltr[] = {
24197687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
24207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
24217687d0d8SRobert Mustacchi 	{ 0x4, 2, "snoop", "Max Snoop Latency",
24227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ltr },
242366a9cc68SRobert Mustacchi 	{ 0x6, 2, "nosnoop", "Max No-Snoop Latency",
24247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ltr },
24257687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24267687d0d8SRobert Mustacchi };
24277687d0d8SRobert Mustacchi 
24287687d0d8SRobert Mustacchi /*
24297687d0d8SRobert Mustacchi  * Alternative Routing ID
24307687d0d8SRobert Mustacchi  */
24314a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ari_cap[] = {
24327687d0d8SRobert Mustacchi 	{ 0, 0, "mfvcfg", "MFVC Function Groups", PRDV_STRVAL,
24337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24347687d0d8SRobert Mustacchi 	{ 1, 1, "acsfg", "ACS Function Groups", PRDV_STRVAL,
24357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24367687d0d8SRobert Mustacchi 	{ 8, 15, "nfunc", "Next Function Number", PRDV_HEX },
24377687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24387687d0d8SRobert Mustacchi };
24397687d0d8SRobert Mustacchi 
24404a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ari_ctl[] = {
24417687d0d8SRobert Mustacchi 	{ 0, 0, "mfvcfg", "MFVC Function Groups", PRDV_STRVAL,
24427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24437687d0d8SRobert Mustacchi 	{ 1, 1, "acsfg", "ACS Function Groups", PRDV_STRVAL,
24447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24457687d0d8SRobert Mustacchi 	{ 4, 6, "fgrp", "Function Group", PRDV_HEX },
24467687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24477687d0d8SRobert Mustacchi };
24487687d0d8SRobert Mustacchi 
24494a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ari[] = {
24507687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
24517687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
24527687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ARI Capability",
24537687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ari_cap },
24547687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "ARI Control",
24557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ari_ctl },
24567687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24577687d0d8SRobert Mustacchi };
24587687d0d8SRobert Mustacchi 
24597687d0d8SRobert Mustacchi /*
24607687d0d8SRobert Mustacchi  * PASID
24617687d0d8SRobert Mustacchi  */
24624a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pasid_cap[] = {
24637687d0d8SRobert Mustacchi 	{ 1, 1, "exec", "Execution Permission", PRDV_STRVAL,
24647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24657687d0d8SRobert Mustacchi 	{ 2, 2, "priv", "Privileged Mode", PRDV_STRVAL,
24667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24677687d0d8SRobert Mustacchi 	{ 8, 12, "width", "Max PASID Width", PRDV_HEX },
24687687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24697687d0d8SRobert Mustacchi };
24707687d0d8SRobert Mustacchi 
24714a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pasid_ctl[] = {
24727687d0d8SRobert Mustacchi 	{ 0, 0, "pasid", "PASID", PRDV_STRVAL,
24737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24747687d0d8SRobert Mustacchi 	{ 1, 1, "exec", "Execution Permission", PRDV_STRVAL,
24757687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24767687d0d8SRobert Mustacchi 	{ 2, 2, "priv", "Privileged Mode", PRDV_STRVAL,
24777687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
24787687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24797687d0d8SRobert Mustacchi };
24807687d0d8SRobert Mustacchi 
24817687d0d8SRobert Mustacchi 
24824a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pasid[] = {
24837687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
24847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
24857687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "PASID Capability",
24867687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pasid_cap },
24877687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "PASID Control",
24887687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pasid_ctl },
24897687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
24907687d0d8SRobert Mustacchi };
24917687d0d8SRobert Mustacchi 
24927687d0d8SRobert Mustacchi /*
24937687d0d8SRobert Mustacchi  * "Advanced Features"
24947687d0d8SRobert Mustacchi  */
24954a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_af_cap[] = {
24967687d0d8SRobert Mustacchi 	{ 0, 0, "tp", "Transactions Pending", PRDV_STRVAL,
24977687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
24987687d0d8SRobert Mustacchi 	{ 1, 1, "flr", "Function Level Reset", PRDV_STRVAL,
24997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
25007687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25017687d0d8SRobert Mustacchi };
25027687d0d8SRobert Mustacchi 
25034a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_af_ctl[] = {
25047687d0d8SRobert Mustacchi 	{ 0, 0, "flr", "Function Level Reset", PRDV_HEX },
25057687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25067687d0d8SRobert Mustacchi };
25077687d0d8SRobert Mustacchi 
25084a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_af_sts[] = {
25097687d0d8SRobert Mustacchi 	{ 0, 0, "tp", "Transactions Pending", PRDV_STRVAL,
25107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "none pending", "pending" } } },
25117687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25127687d0d8SRobert Mustacchi };
25137687d0d8SRobert Mustacchi 
25144a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_af[] = {
25157687d0d8SRobert Mustacchi 	{ 0x2, 2, "cap", "AF Capabilities",
25167687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_cap },
25177687d0d8SRobert Mustacchi 	{ 0x4, 1, "ctl", "AF Control",
25187687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_ctl },
25197687d0d8SRobert Mustacchi 	{ 0x5, 1, "sts", "AF Status",
25207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_af_sts },
25217687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25227687d0d8SRobert Mustacchi };
25237687d0d8SRobert Mustacchi 
25247687d0d8SRobert Mustacchi /*
25257687d0d8SRobert Mustacchi  * Multicast
25267687d0d8SRobert Mustacchi  */
25274a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_mcast_cap[] = {
25287687d0d8SRobert Mustacchi 	{ 0, 5, "maxgrp", "Max Group", PRDV_HEX,
25297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
25307687d0d8SRobert Mustacchi 	{ 8, 13, "winsize", "Window Size (raw)", PRDV_HEX },
25317687d0d8SRobert Mustacchi 	{ 15, 15, "ecrc", "ECRC Regeneration", PRDV_STRVAL,
25327687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
25337687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25347687d0d8SRobert Mustacchi };
25357687d0d8SRobert Mustacchi 
25364a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_mcast_ctl[] = {
25377687d0d8SRobert Mustacchi 	{ 0, 5, "numgrp", "Number of Groups", PRDV_HEX,
25387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 0, 1 } } },
25397687d0d8SRobert Mustacchi 	{ 15, 15, "enable", "Enable", PRDV_STRVAL,
25407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
25417687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25427687d0d8SRobert Mustacchi };
25437687d0d8SRobert Mustacchi 
25444a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_mcast_base[] = {
25457687d0d8SRobert Mustacchi 	{ 0, 5, "index", "Multicast Index Position", PRDV_HEX },
25467687d0d8SRobert Mustacchi 	{ 12, 63, "addr", "Base Address", PRDV_HEX,
25477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 12 } } },
25487687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25497687d0d8SRobert Mustacchi };
25507687d0d8SRobert Mustacchi 
25514a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_mcast_overlay[] = {
25527687d0d8SRobert Mustacchi 	{ 0, 5, "size", "Overlay Size (raw)", PRDV_HEX },
25537687d0d8SRobert Mustacchi 	{ 6, 63, "addr", "Overlay Base Address", PRDV_HEX,
25547687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 6 } } },
25557687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25567687d0d8SRobert Mustacchi };
25577687d0d8SRobert Mustacchi 
25584a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_mcast[] = {
25597687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
25607687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
25617687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "Multicast Capability",
25627687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_cap },
25637687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "Multicast Control",
25647687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_ctl },
25657687d0d8SRobert Mustacchi 	{ 0x8, 8, "base", "Multicast Base Address",
25667687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_base },
25677687d0d8SRobert Mustacchi 	{ 0x10, 8, "rx", "Multicast Receive", pcieadm_cfgspace_print_hex },
25687687d0d8SRobert Mustacchi 	{ 0x18, 8, "block", "Multicast Block All", pcieadm_cfgspace_print_hex },
25697687d0d8SRobert Mustacchi 	{ 0x20, 8, "blockun", "Multicast Block Untranslated",
25707687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
25717687d0d8SRobert Mustacchi 	{ 0x28, 8, "overlay", "Multicast Overlay BAR",
25727687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_mcast_overlay },
25737687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25747687d0d8SRobert Mustacchi };
25757687d0d8SRobert Mustacchi 
25767687d0d8SRobert Mustacchi /*
25777687d0d8SRobert Mustacchi  * Various vendor extensions
25787687d0d8SRobert Mustacchi  */
25794a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vsec[] = {
25807687d0d8SRobert Mustacchi 	{ 0, 15, "id", "ID", PRDV_HEX },
25817687d0d8SRobert Mustacchi 	{ 16, 19, "rev", "Revision", PRDV_HEX },
25827687d0d8SRobert Mustacchi 	{ 20, 31, "len", "Length", PRDV_HEX },
25837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25847687d0d8SRobert Mustacchi };
25857687d0d8SRobert Mustacchi 
25864a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_vs[] = {
25877687d0d8SRobert Mustacchi 	{ 0x2, 2, "length", "Length", pcieadm_cfgspace_print_hex },
25887687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25897687d0d8SRobert Mustacchi };
25907687d0d8SRobert Mustacchi 
25914a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_vsec[] = {
25927687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
25937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
25947687d0d8SRobert Mustacchi 	{ 0x4, 4, "header", "Vendor-Specific Header",
25957687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vsec },
25967687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
25977687d0d8SRobert Mustacchi };
25987687d0d8SRobert Mustacchi 
25997687d0d8SRobert Mustacchi /*
26007687d0d8SRobert Mustacchi  * Data Link Feature
26017687d0d8SRobert Mustacchi  */
26024a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dlf_cap[] = {
26037687d0d8SRobert Mustacchi 	{ 0, 0, "lsfc", "Local Scaled Flow Control", PRDV_STRVAL,
26047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
26057687d0d8SRobert Mustacchi 	{ 31, 31, "dlex", "Data Link Exchange", PRDV_STRVAL,
26067687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
26077687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26087687d0d8SRobert Mustacchi };
26097687d0d8SRobert Mustacchi 
26104a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dlf_sts[] = {
26117687d0d8SRobert Mustacchi 	{ 0, 0, "rsfc", "Remote Scaled Flow Control", PRDV_STRVAL,
26127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
26137687d0d8SRobert Mustacchi 	{ 31, 31, "valid", "Remote Data Link Feature Valid", PRDV_STRVAL,
26147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "invalid", "valid" } } },
26157687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26167687d0d8SRobert Mustacchi };
26177687d0d8SRobert Mustacchi 
26184a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_dlf[] = {
26197687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
26207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
26217687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "Data Link Feature Capabilities",
26227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dlf_cap },
26237687d0d8SRobert Mustacchi 	{ 0x8, 4, "sts", "Data Link Feature Status",
26247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dlf_sts },
26257687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26267687d0d8SRobert Mustacchi };
26277687d0d8SRobert Mustacchi 
26287687d0d8SRobert Mustacchi /*
26297687d0d8SRobert Mustacchi  * 16.0 GT/s cap
26307687d0d8SRobert Mustacchi  */
26314a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_16g_cap[] = {
26327687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26337687d0d8SRobert Mustacchi };
26347687d0d8SRobert Mustacchi 
26354a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_16g_ctl[] = {
26367687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26377687d0d8SRobert Mustacchi };
26387687d0d8SRobert Mustacchi 
26394a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_16g_sts[] = {
26407687d0d8SRobert Mustacchi 	{ 0, 0, "eqcomp", "Equalization 16.0 GT/s Complete", PRDV_STRVAL,
26417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26427687d0d8SRobert Mustacchi 	{ 1, 1, "eqp1", "Equalization 16.0 GT/s Phase 1", PRDV_STRVAL,
26437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26447687d0d8SRobert Mustacchi 	{ 2, 2, "eqp2", "Equalization 16.0 GT/s Phase 2", PRDV_STRVAL,
26457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26467687d0d8SRobert Mustacchi 	{ 3, 3, "eqp3", "Equalization 16.0 GT/s Phase 3", PRDV_STRVAL,
26477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
26487687d0d8SRobert Mustacchi 	{ 4, 4, "req", "Link Equalization Request 16.0 GT/s", PRDV_HEX },
26497687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26507687d0d8SRobert Mustacchi };
26517687d0d8SRobert Mustacchi 
26524a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_16g_eq[] = {
26537687d0d8SRobert Mustacchi 	{ 0, 3, "dstxpre", "Downstream Port 16.0 GT/s Transmitter Preset",
26547687d0d8SRobert Mustacchi 	    PRDV_HEX },
26557687d0d8SRobert Mustacchi 	{ 4, 7, "ustxpre", "Upstream Port 16.0 GT/s Transmitter Preset",
26567687d0d8SRobert Mustacchi 	    PRDV_HEX },
26577687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
26587687d0d8SRobert Mustacchi };
26597687d0d8SRobert Mustacchi 
26607687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_16geq(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)26617687d0d8SRobert Mustacchi pcieadm_cfgspace_print_16geq(pcieadm_cfgspace_walk_t *walkp,
26624a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
26637687d0d8SRobert Mustacchi {
26647687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
26657687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
2666c3e0a189SRobert Mustacchi 		    "Physical Layer 16.0 GT/s cap");
26677687d0d8SRobert Mustacchi 		return;
26687687d0d8SRobert Mustacchi 	}
26697687d0d8SRobert Mustacchi 
26707687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
26717687d0d8SRobert Mustacchi 		char eqshort[32], eqhuman[128];
26727687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
26737687d0d8SRobert Mustacchi 
26747687d0d8SRobert Mustacchi 		(void) snprintf(eqshort, sizeof (eqshort), "lane%u", i);
26757687d0d8SRobert Mustacchi 		(void) snprintf(eqhuman, sizeof (eqhuman), "Lane %u EQ Control",
26767687d0d8SRobert Mustacchi 		    i);
26777687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 1;
26787687d0d8SRobert Mustacchi 		p.pcp_len = 1;
26797687d0d8SRobert Mustacchi 		p.pcp_short = eqshort;
26807687d0d8SRobert Mustacchi 		p.pcp_human = eqhuman;
26817687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
26827687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_16g_eq;
26837687d0d8SRobert Mustacchi 
26847687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
26857687d0d8SRobert Mustacchi 	}
26867687d0d8SRobert Mustacchi }
26877687d0d8SRobert Mustacchi 
26884a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_16g[] = {
26897687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
26907687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
26917687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "16.0 GT/s Capabilities",
26927687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_cap },
26937687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl", "16.0 GT/s Control",
26947687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_ctl },
26957687d0d8SRobert Mustacchi 	{ 0xc, 4, "sts", "16.0 GT/s Status",
26967687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_16g_sts },
26977687d0d8SRobert Mustacchi 	{ 0x10, 4, "ldpmis", "16.0 GT/s Local Data Parity Mismatch",
26987687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
26997687d0d8SRobert Mustacchi 	{ 0x14, 4, "frpmis", "16.0 GT/s First Retimer Data Parity Mismatch",
27007687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
27017687d0d8SRobert Mustacchi 	{ 0x18, 4, "srpmis", "16.0 GT/s Second Retimer Data Parity Mismatch",
27027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
27037687d0d8SRobert Mustacchi 	{ 0x1c, 4, "rsvd", "16.0 GT/s Second Retimer Data Parity Mismatch",
27047687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
27057687d0d8SRobert Mustacchi 	{ 0x20, 1, "eqctl", "16.0 GT/s EQ Control",
27067687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_16geq },
27077687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27087687d0d8SRobert Mustacchi };
27097687d0d8SRobert Mustacchi 
27107687d0d8SRobert Mustacchi /*
27117687d0d8SRobert Mustacchi  * Receiver Margining
27127687d0d8SRobert Mustacchi  */
27134a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_margin_cap[] = {
27147687d0d8SRobert Mustacchi 	{ 0, 0, "sw", "Margining uses Driver Software", PRDV_STRVAL,
27157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
27167687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27177687d0d8SRobert Mustacchi };
27187687d0d8SRobert Mustacchi 
27194a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_margin_sts[] = {
27207687d0d8SRobert Mustacchi 	{ 0, 0, "ready", "Margining Ready", PRDV_STRVAL,
27217687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
27227687d0d8SRobert Mustacchi 	{ 1, 1, "sw", "Margining Software Ready", PRDV_STRVAL,
27237687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
27247687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27257687d0d8SRobert Mustacchi };
27267687d0d8SRobert Mustacchi 
27274a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_margin_lane[] = {
27287687d0d8SRobert Mustacchi 	{ 0, 2, "rxno", "Receiver Number", PRDV_HEX },
27297687d0d8SRobert Mustacchi 	{ 3, 5, "type", "Margin Type", PRDV_HEX },
27307687d0d8SRobert Mustacchi 	{ 6, 6, "model", "Usage Model", PRDV_HEX },
27317687d0d8SRobert Mustacchi 	{ 8, 15, "payload", "Margin Payload", PRDV_HEX },
27327687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27337687d0d8SRobert Mustacchi };
27347687d0d8SRobert Mustacchi 
27357687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_margin(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)27367687d0d8SRobert Mustacchi pcieadm_cfgspace_print_margin(pcieadm_cfgspace_walk_t *walkp,
27374a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
27387687d0d8SRobert Mustacchi {
27397687d0d8SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
27407687d0d8SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
27417687d0d8SRobert Mustacchi 		    "lane margining capability");
27427687d0d8SRobert Mustacchi 		return;
27437687d0d8SRobert Mustacchi 	}
27447687d0d8SRobert Mustacchi 
27457687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
27467687d0d8SRobert Mustacchi 		char mshort[32], mhuman[128];
27477687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
27487687d0d8SRobert Mustacchi 
27497687d0d8SRobert Mustacchi 		(void) snprintf(mshort, sizeof (mshort), "lane%uctl", i);
27507687d0d8SRobert Mustacchi 		(void) snprintf(mhuman, sizeof (mhuman), "Lane %u Margining "
27517687d0d8SRobert Mustacchi 		    "Control", i);
27527687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
27537687d0d8SRobert Mustacchi 		p.pcp_len = 2;
27547687d0d8SRobert Mustacchi 		p.pcp_short = mshort;
27557687d0d8SRobert Mustacchi 		p.pcp_human = mhuman;
27567687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
27577687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_margin_lane;
27587687d0d8SRobert Mustacchi 
27597687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
27607687d0d8SRobert Mustacchi 
27617687d0d8SRobert Mustacchi 		(void) snprintf(mshort, sizeof (mshort), "lane%usts", i);
27627687d0d8SRobert Mustacchi 		(void) snprintf(mhuman, sizeof (mhuman), "Lane %u Margining "
27637687d0d8SRobert Mustacchi 		    "Status", i);
27647687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + 2 + i * 4;
27657687d0d8SRobert Mustacchi 		p.pcp_len = 2;
27667687d0d8SRobert Mustacchi 		p.pcp_short = mshort;
27677687d0d8SRobert Mustacchi 		p.pcp_human = mhuman;
27687687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
27697687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_margin_lane;
27707687d0d8SRobert Mustacchi 
27717687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
27727687d0d8SRobert Mustacchi 	}
27737687d0d8SRobert Mustacchi }
27747687d0d8SRobert Mustacchi 
27754a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_margin[] = {
27767687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
27777687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
27787687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "Margining Port Capabilities",
27797687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_margin_cap },
27807687d0d8SRobert Mustacchi 	{ 0x6, 2, "sts", "Margining Port Status",
27817687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_margin_sts },
27827687d0d8SRobert Mustacchi 	{ 0x8, 4, "lane", "Margining Lane", pcieadm_cfgspace_print_margin },
27837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
27847687d0d8SRobert Mustacchi };
27857687d0d8SRobert Mustacchi 
27867687d0d8SRobert Mustacchi /*
27877687d0d8SRobert Mustacchi  * Serial Number Capability
27887687d0d8SRobert Mustacchi  */
27897687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_sn(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)27907687d0d8SRobert Mustacchi pcieadm_cfgspace_print_sn(pcieadm_cfgspace_walk_t *walkp,
27914a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
27927687d0d8SRobert Mustacchi {
27937687d0d8SRobert Mustacchi 	char sn[64];
27947687d0d8SRobert Mustacchi 	uint16_t off = walkp->pcw_capoff + print->pcp_off;
27957687d0d8SRobert Mustacchi 
27967687d0d8SRobert Mustacchi 	(void) snprintf(sn, sizeof (sn),
27977687d0d8SRobert Mustacchi 	    "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
27987687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 7], walkp->pcw_data->pcb_u8[off + 6],
27997687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 5], walkp->pcw_data->pcb_u8[off + 4],
28007687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 3], walkp->pcw_data->pcb_u8[off + 2],
28017687d0d8SRobert Mustacchi 	    walkp->pcw_data->pcb_u8[off + 1], walkp->pcw_data->pcb_u8[off]);
28027687d0d8SRobert Mustacchi 
28037687d0d8SRobert Mustacchi 	pcieadm_cfgspace_puts(walkp, print, sn);
28047687d0d8SRobert Mustacchi }
28057687d0d8SRobert Mustacchi 
28064a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_sn[] = {
28077687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
28087687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
28097687d0d8SRobert Mustacchi 	{ 0x4, 8, "sn", "Serial Number", pcieadm_cfgspace_print_sn },
28107687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28117687d0d8SRobert Mustacchi };
28127687d0d8SRobert Mustacchi 
28137687d0d8SRobert Mustacchi /*
28147687d0d8SRobert Mustacchi  * TLP Processing Hints (TPH)
28157687d0d8SRobert Mustacchi  */
28164a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_tph_cap[] = {
28177687d0d8SRobert Mustacchi 	{ 0, 0, "nost", "No ST Mode", PRDV_STRVAL,
28187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
28197687d0d8SRobert Mustacchi 	{ 1, 1, "ivec", "Interrupt Vector Mode", PRDV_STRVAL,
28207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
28217687d0d8SRobert Mustacchi 	{ 2, 2, "dev", "Device Specific Mode", PRDV_STRVAL,
28227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
28237687d0d8SRobert Mustacchi 	{ 8, 8, "exttph", "Extended TPH Requester", PRDV_STRVAL,
28247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
28257687d0d8SRobert Mustacchi 	{ 9, 10, "loc", "ST Table Location", PRDV_STRVAL,
28267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Not Present",
28277687d0d8SRobert Mustacchi 	    "In Capability Structure", "MSI-X" } } },
28287687d0d8SRobert Mustacchi 	{ 16, 26, "size", "ST Table Size", PRDV_HEX, { .prdv_hex = { 0, 1 } } },
28297687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28307687d0d8SRobert Mustacchi };
28317687d0d8SRobert Mustacchi 
28324a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_tph_ctl[] = {
28337687d0d8SRobert Mustacchi 	{ 0, 2, "mode", "ST Mode Select", PRDV_STRVAL,
28347687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "No ST", "Interrupt Vector",
28357687d0d8SRobert Mustacchi 	    "Device Specific" } } },
28367687d0d8SRobert Mustacchi 	{ 8, 9, "en", "TPH Requester", PRDV_STRVAL,
28377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Not Permitted", "TPH", NULL,
28387687d0d8SRobert Mustacchi 	    "TPH and Extended TPH" } } },
28397687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28407687d0d8SRobert Mustacchi };
28417687d0d8SRobert Mustacchi 
28424a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_tph_st[] = {
28437687d0d8SRobert Mustacchi 	{ 0, 7, "low", "ST Lower", PRDV_HEX },
28447687d0d8SRobert Mustacchi 	{ 8, 15, "up", "ST Upper", PRDV_HEX },
28457687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28467687d0d8SRobert Mustacchi };
28477687d0d8SRobert Mustacchi 
28487687d0d8SRobert Mustacchi /*
28497687d0d8SRobert Mustacchi  * The TPH ST table is only conditionally present in the capability. So we need
28507687d0d8SRobert Mustacchi  * to read the TPH capability register and then check if the table location and
28517687d0d8SRobert Mustacchi  * size are set here.
28527687d0d8SRobert Mustacchi  */
28537687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_tphst(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)28547687d0d8SRobert Mustacchi pcieadm_cfgspace_print_tphst(pcieadm_cfgspace_walk_t *walkp,
28554a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
28567687d0d8SRobert Mustacchi {
28577687d0d8SRobert Mustacchi 	uint_t nents;
28587687d0d8SRobert Mustacchi 	uint32_t tphcap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
28597687d0d8SRobert Mustacchi 
28604a8bbc0bSRobert Mustacchi 	if (bitx32(tphcap, 10, 9) != 1) {
28617687d0d8SRobert Mustacchi 		return;
28627687d0d8SRobert Mustacchi 	}
28637687d0d8SRobert Mustacchi 
28644a8bbc0bSRobert Mustacchi 	nents = bitx32(tphcap, 26, 16) + 1;
28657687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < nents; i++) {
28667687d0d8SRobert Mustacchi 		char tshort[32], thuman[128];
28677687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
28687687d0d8SRobert Mustacchi 
28697687d0d8SRobert Mustacchi 		(void) snprintf(tshort, sizeof (tshort), "st%u", i);
28707687d0d8SRobert Mustacchi 		(void) snprintf(thuman, sizeof (thuman), "ST Table %u",
28717687d0d8SRobert Mustacchi 		    i);
28727687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 2;
28737687d0d8SRobert Mustacchi 		p.pcp_len = 2;
28747687d0d8SRobert Mustacchi 		p.pcp_short = tshort;
28757687d0d8SRobert Mustacchi 		p.pcp_human = thuman;
28767687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
28777687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_tph_st;
28787687d0d8SRobert Mustacchi 
28797687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
28807687d0d8SRobert Mustacchi 	}
28817687d0d8SRobert Mustacchi }
28827687d0d8SRobert Mustacchi 
28834a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_tph[] = {
28847687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
28857687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
28867687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "TPH Requester Capability",
28877687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_tph_cap },
28887687d0d8SRobert Mustacchi 	{ 0x8, 4, "ctl", "TPH Requester Control",
28897687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_tph_ctl },
28907687d0d8SRobert Mustacchi 	{ 0xc, 2, "table", "ST Table", pcieadm_cfgspace_print_tphst },
28917687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
28927687d0d8SRobert Mustacchi };
28937687d0d8SRobert Mustacchi 
28947687d0d8SRobert Mustacchi /*
28957687d0d8SRobert Mustacchi  * SR-IOV
28967687d0d8SRobert Mustacchi  */
28974a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sriov_cap[] = {
28987687d0d8SRobert Mustacchi 	{ 0, 0, "migration", "Migration", PRDV_STRVAL,
28997687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
29007687d0d8SRobert Mustacchi 	{ 1, 1, "ari", "ARI Capable Hierarchy Preserved", PRDV_STRVAL,
29017687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unpreserved", "preserved" } } },
29027687d0d8SRobert Mustacchi 	{ 2, 2, "vf10b", "VF 10-bit Tag Requester", PRDV_STRVAL,
29037687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unpreserved", "preserved" } } },
29047687d0d8SRobert Mustacchi 	{ 21, 31, "inum", "VF Migration Interrupt Message Number", PRDV_HEX },
29057687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29067687d0d8SRobert Mustacchi };
29077687d0d8SRobert Mustacchi 
29084a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sriov_ctl[] = {
29097687d0d8SRobert Mustacchi 	{ 0, 0, "vf", "VF", PRDV_STRVAL,
29107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29117687d0d8SRobert Mustacchi 	{ 1, 1, "vfm", "VF Migration", PRDV_STRVAL,
29127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29137687d0d8SRobert Mustacchi 	{ 2, 2, "vfmi", "VF Migration Interrupt", PRDV_STRVAL,
29147687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29157687d0d8SRobert Mustacchi 	{ 3, 3, "ari", "ARI Capable Hierarchy", PRDV_STRVAL,
29167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29177687d0d8SRobert Mustacchi 	{ 4, 4, "vf10b", "VF 10-bit Tag Requester", PRDV_STRVAL,
29187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29197687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29207687d0d8SRobert Mustacchi };
29217687d0d8SRobert Mustacchi 
29224a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sriov_sts[] = {
29237687d0d8SRobert Mustacchi 	{ 0, 0, "vfm", "VF Migration", PRDV_STRVAL,
29247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "none", "requested" } } },
29257687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29267687d0d8SRobert Mustacchi };
29277687d0d8SRobert Mustacchi 
29284a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sriov_pgsup[] = {
29297687d0d8SRobert Mustacchi 	{ 0, 31, "pgsz", "Supported Page Sizes", PRDV_BITFIELD,
29307687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4 KB", "8 KB", "16 KB", "32 KB",
29317687d0d8SRobert Mustacchi 	    "64 KB", "128 KB", "256 KB", "512 KB", "1 MB", "2 MB", "4 MB",
29327687d0d8SRobert Mustacchi 	    "8 MB", "16 MB", "32 MB", "64 MB", "128 MB", "256 MB", "512 MB",
29337687d0d8SRobert Mustacchi 	    "1 GB", "2 GB", "4 GB", "8 GB", "16 GB", "32 GB", "64 GB",
29347687d0d8SRobert Mustacchi 	    "128 GB", "256 GB", "512 GB", "1 TB", "2 TB", "4 TB", "8 TB" } } },
29357687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29367687d0d8SRobert Mustacchi };
29377687d0d8SRobert Mustacchi 
29384a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sriov_pgen[] = {
29397687d0d8SRobert Mustacchi 	{ 0, 31, "pgsz", "System Page Sizes", PRDV_BITFIELD,
29407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "4 KB", "8 KB", "16 KB", "32 KB",
29417687d0d8SRobert Mustacchi 	    "64 KB", "128 KB", "256 KB", "512 KB", "1 MB", "2 MB", "4 MB",
29427687d0d8SRobert Mustacchi 	    "8 MB", "16 MB", "32 MB", "64 MB", "128 MB", "256 MB", "512 MB",
29437687d0d8SRobert Mustacchi 	    "1 GB", "2 GB", "4 GB", "8 GB", "16 GB", "32 GB", "64 GB",
29447687d0d8SRobert Mustacchi 	    "128 GB", "256 GB", "512 GB", "1 TB", "2 TB", "4 TB", "8 TB" } } },
29457687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29467687d0d8SRobert Mustacchi };
29477687d0d8SRobert Mustacchi 
29484a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_sriov_mig[] = {
29497687d0d8SRobert Mustacchi 	{ 0, 2, "bir", "VF Migration State BIR", PRDV_STRVAL,
29507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3",
29517687d0d8SRobert Mustacchi 	    "BAR 4", "BAR 5" } } },
29527687d0d8SRobert Mustacchi 	{ 3, 31, "offset", "VF Migration State Offset", PRDV_HEX,
29537687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 3 } } },
29547687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29557687d0d8SRobert Mustacchi };
29567687d0d8SRobert Mustacchi 
29574a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_sriov[] = {
29587687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
29597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
29607687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "SR-IOV Capabilities",
29617687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_cap },
29627687d0d8SRobert Mustacchi 	{ 0x8, 2, "ctl", "SR-IOV Control",
29637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_ctl },
29647687d0d8SRobert Mustacchi 	{ 0xa, 2, "sts", "SR-IOV Status",
29657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_sts },
29667687d0d8SRobert Mustacchi 	{ 0xc, 2, "initvfs", "Initial VFs", pcieadm_cfgspace_print_hex },
29677687d0d8SRobert Mustacchi 	{ 0xe, 2, "totvfs", "Total VFs", pcieadm_cfgspace_print_hex },
29687687d0d8SRobert Mustacchi 	{ 0x10, 2, "numvfs", "Number VFs", pcieadm_cfgspace_print_hex },
29697687d0d8SRobert Mustacchi 	{ 0x12, 1, "dep", "Function Dependency Link",
29707687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
29717687d0d8SRobert Mustacchi 	{ 0x14, 2, "offset", "First VF Offset", pcieadm_cfgspace_print_hex },
29727687d0d8SRobert Mustacchi 	{ 0x16, 2, "stride", "VF Stride", pcieadm_cfgspace_print_hex },
29737687d0d8SRobert Mustacchi 	{ 0x1a, 2, "devid", "VF Device ID", pcieadm_cfgspace_print_hex },
29747687d0d8SRobert Mustacchi 	{ 0x1c, 4, "pgsz", "Supported Page Sizes",
29757687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_pgsup },
29767687d0d8SRobert Mustacchi 	{ 0x20, 4, "pgsz", "System Page Sizes",
29777687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_pgen },
29787687d0d8SRobert Mustacchi 	{ 0x24, 24, "vfbar", "Virtual Base Address Register",
29797687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_bars },
29807687d0d8SRobert Mustacchi 	{ 0x3c, 4, "migration", "VF Migration State Array",
29817687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_sriov_mig },
29827687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
29837687d0d8SRobert Mustacchi };
29847687d0d8SRobert Mustacchi 
29857687d0d8SRobert Mustacchi /*
29867687d0d8SRobert Mustacchi  * PCI-X
29877687d0d8SRobert Mustacchi  */
29884a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcix_dev_ctl[] = {
29897687d0d8SRobert Mustacchi 	{ 0, 0, "dper", "Data Parity Error Recovery", PRDV_STRVAL,
29907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29917687d0d8SRobert Mustacchi 	{ 1, 1, "ro", "Relaxed Ordering", PRDV_STRVAL,
29927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
29937687d0d8SRobert Mustacchi 	{ 2, 3, "maxread", "Maximum Memory Read Byte Count", PRDV_STRVAL,
29947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "512 bytes", "1024 bytes",
29951bcd6a1aSRobert Mustacchi 	    "2048 bytes", "4096 bytes" } } },
29967687d0d8SRobert Mustacchi 	{ 4, 6, "maxsplit", "Maximum Outstanding Split Transactions",
29977687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "1", "2", "3", "4", "8",
29987687d0d8SRobert Mustacchi 	    "12", "16", "32" } } },
29997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30007687d0d8SRobert Mustacchi };
30017687d0d8SRobert Mustacchi 
30024a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcix_dev_sts[] = {
30037687d0d8SRobert Mustacchi 	{ 0, 2, "func", "Function Number", PRDV_HEX },
30047687d0d8SRobert Mustacchi 	{ 3, 7, "dev", "Device Number", PRDV_HEX },
30057687d0d8SRobert Mustacchi 	{ 8, 15, "bus", "Bus Number", PRDV_HEX },
30067687d0d8SRobert Mustacchi 	{ 16, 16, "64bit", "64-bit Device", PRDV_STRVAL,
30077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
30087687d0d8SRobert Mustacchi 	    "supported" } } },
30097687d0d8SRobert Mustacchi 	{ 17, 17, "133mhz", "133 MHz Capable", PRDV_STRVAL,
30107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
30117687d0d8SRobert Mustacchi 	    "supported" } } },
30127687d0d8SRobert Mustacchi 	{ 18, 18, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
30137687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30147687d0d8SRobert Mustacchi 	{ 19, 19, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
30157687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30167687d0d8SRobert Mustacchi 	{ 20, 20, "complex", "Device Complexity", PRDV_STRVAL,
30177687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "simple", "bridge" } } },
30187687d0d8SRobert Mustacchi 	{ 21, 22, "maxread", "Designed Maximum Memory Read Byte Count",
30197687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "512 bytes",
30201bcd6a1aSRobert Mustacchi 	    "1024 bytes", "2048 bytes", "4096 bytes" } } },
30217687d0d8SRobert Mustacchi 	{ 23, 25, "maxsplit", "Designed Maximum Outstanding Split Transactions",
30227687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "1", "2", "3", "4", "8",
30237687d0d8SRobert Mustacchi 	    "12", "16", "32" } } },
30247687d0d8SRobert Mustacchi 	{ 26, 28, "maxcread", "Designed Maximum Cumulative Read Size",
30257687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "8/1KB", "16/2KB",
30267687d0d8SRobert Mustacchi 	    "32/4KB", "64/8KB", "128/16KB", "256/32KB", "512/64KB",
30277687d0d8SRobert Mustacchi 	    "1024/128KB" } } },
30287687d0d8SRobert Mustacchi 	{ 29, 29, "rxspcoer", "Received Split Completion Error Message",
30297687d0d8SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "no", "yes" } } },
30307687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30317687d0d8SRobert Mustacchi };
30327687d0d8SRobert Mustacchi 
30334a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcix_sec_sts[] = {
30347687d0d8SRobert Mustacchi 	{ 0, 0, "64bit", "64-bit Device", PRDV_STRVAL,
30357687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
30367687d0d8SRobert Mustacchi 	    "supported" } } },
30377687d0d8SRobert Mustacchi 	{ 1, 1, "133mhz", "133 MHz Capable", PRDV_STRVAL,
30387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
30397687d0d8SRobert Mustacchi 	    "supported" } } },
30407687d0d8SRobert Mustacchi 	{ 2, 2, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
30417687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30427687d0d8SRobert Mustacchi 	{ 3, 3, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
30437687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30447687d0d8SRobert Mustacchi 	{ 4, 4, "spcoor", "Split Completion Overrun", PRDV_STRVAL,
30457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30467687d0d8SRobert Mustacchi 	{ 5, 5, "sprde", "Split Request Delayed", PRDV_STRVAL,
30477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30487687d0d8SRobert Mustacchi 	{ 6, 8, "freq", "Secondary Clock Frequency", PRDV_STRVAL,
30497687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "conventional", "66 MHz", "100 Mhz",
30507687d0d8SRobert Mustacchi 	    "133 MHz" } } },
30517687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30527687d0d8SRobert Mustacchi };
30537687d0d8SRobert Mustacchi 
30544a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcix_bridge_sts[] = {
30557687d0d8SRobert Mustacchi 	{ 0, 2, "func", "Function Number", PRDV_HEX },
30567687d0d8SRobert Mustacchi 	{ 3, 7, "dev", "Device Number", PRDV_HEX },
30577687d0d8SRobert Mustacchi 	{ 8, 15, "bus", "Bus Number", PRDV_HEX },
30587687d0d8SRobert Mustacchi 	{ 16, 16, "64bit", "64-bit Device", PRDV_STRVAL,
30597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (32-bit)",
30607687d0d8SRobert Mustacchi 	    "supported" } } },
30617687d0d8SRobert Mustacchi 	{ 17, 17, "133mhz", "133 MHz Capable", PRDV_STRVAL,
30627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported (66 MHz)",
30637687d0d8SRobert Mustacchi 	    "supported" } } },
30647687d0d8SRobert Mustacchi 	{ 18, 18, "spcodis", "Split Completion Discarded", PRDV_STRVAL,
30657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30667687d0d8SRobert Mustacchi 	{ 19, 19, "unspco", "Unexpected Split Completion", PRDV_STRVAL,
30677687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30687687d0d8SRobert Mustacchi 	{ 20, 20, "spcoor", "Split Completion Overrun", PRDV_STRVAL,
30697687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30707687d0d8SRobert Mustacchi 	{ 21, 21, "sprde", "Split Request Delayed", PRDV_STRVAL,
30717687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
30727687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30737687d0d8SRobert Mustacchi };
30747687d0d8SRobert Mustacchi 
30754a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pcix_bridge_split[] = {
30767687d0d8SRobert Mustacchi 	{ 0, 15, "cap", "Split Transaction Capacity", PRDV_HEX },
30777687d0d8SRobert Mustacchi 	{ 16, 31, "limit", "Split Transaction Commitment Limit", PRDV_HEX },
30787687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30797687d0d8SRobert Mustacchi };
30807687d0d8SRobert Mustacchi 
30814a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcix_dev[] = {
30827687d0d8SRobert Mustacchi 	{ 0x2, 2, "ctl", "PCI-X Command",
30837687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_dev_ctl },
30847687d0d8SRobert Mustacchi 	{ 0x4, 4, "sts", "PCI-X Status",
30857687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_dev_sts },
30867687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30877687d0d8SRobert Mustacchi };
30887687d0d8SRobert Mustacchi 
30894a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pcix_bridge[] = {
30907687d0d8SRobert Mustacchi 	{ 0x2, 2, "secsts", "PCI-X Secondary Status",
30917687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_sec_sts },
30927687d0d8SRobert Mustacchi 	{ 0x4, 4, "sts", "PCI-X Bridge Status",
30937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_sts },
30947687d0d8SRobert Mustacchi 	{ 0x8, 4, "ussplit", "Upstream Split Transaction",
30957687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_split },
30967687d0d8SRobert Mustacchi 	{ 0x8, 4, "dssplit", "Downstream Split Transaction",
30977687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcix_bridge_split },
30987687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
30997687d0d8SRobert Mustacchi };
31007687d0d8SRobert Mustacchi 
31017687d0d8SRobert Mustacchi /*
31027687d0d8SRobert Mustacchi  * Dynamic Power Allocation
31037687d0d8SRobert Mustacchi  */
31044a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dpa_cap[] = {
31057687d0d8SRobert Mustacchi 	{ 0, 4, "substates", "Substate Max", PRDV_HEX,
31067687d0d8SRobert Mustacchi 	    { .prdv_hex = { 0, 1 } } },
31077687d0d8SRobert Mustacchi 	{ 8, 9, "tlu", "Transition Latency Unit", PRDV_STRVAL,
31087687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 ms", "10 ms", "100 ms" } } },
31097687d0d8SRobert Mustacchi 	{ 12, 13, "pas", "Power Allocation Scale", PRDV_STRVAL,
31107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "10.0x", "1.0x", "0.1x",
31117687d0d8SRobert Mustacchi 	    "0.01x" } } },
31127687d0d8SRobert Mustacchi 	{ 16, 23, "tlv0", "Transition Latency Value 0", PRDV_HEX },
31137687d0d8SRobert Mustacchi 	{ 24, 31, "tlv0", "Transition Latency Value 1", PRDV_HEX },
31147687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31157687d0d8SRobert Mustacchi };
31167687d0d8SRobert Mustacchi 
31174a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dpa_sts[] = {
31187687d0d8SRobert Mustacchi 	{ 0, 4, "substate", "Substate Status", PRDV_HEX },
31197687d0d8SRobert Mustacchi 	{ 8, 8, "ctlen", "Substate Control Enabled", PRDV_STRVAL,
31207687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
31217687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31227687d0d8SRobert Mustacchi };
31237687d0d8SRobert Mustacchi 
31244a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dpa_ctl[] = {
31257687d0d8SRobert Mustacchi 	{ 0, 4, "substate", "Substate Control", PRDV_HEX },
31267687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31277687d0d8SRobert Mustacchi };
31287687d0d8SRobert Mustacchi 
31294a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_dpa[] = {
31307687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
31317687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
31327687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "DPA Capability",
31337687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_cap },
31347687d0d8SRobert Mustacchi 	{ 0x8, 4, "lat", "DPA Latency Indicator", pcieadm_cfgspace_print_hex },
31357687d0d8SRobert Mustacchi 	{ 0xc, 2, "sts", "DPA Status",
31367687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_sts },
31377687d0d8SRobert Mustacchi 	{ 0xe, 2, "sts", "DPA Control",
31387687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpa_ctl },
31397687d0d8SRobert Mustacchi 	{ 0x10, 1, "paa", "DPA Power Allocation Array",
31407687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpa_paa },
31417687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31427687d0d8SRobert Mustacchi };
31437687d0d8SRobert Mustacchi 
31447687d0d8SRobert Mustacchi /*
31457687d0d8SRobert Mustacchi  * Power Budgeting
31467687d0d8SRobert Mustacchi  */
31474a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_powbudg_data[] = {
31487687d0d8SRobert Mustacchi 	{ 0, 7, "base", "Base Power", PRDV_HEX },
31497687d0d8SRobert Mustacchi 	{ 8, 9, "scale", "Data Scale", PRDV_STRVAL,
31507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1.0x", "0.1x", "0.01x",
31517687d0d8SRobert Mustacchi 	    "0.001x" } } },
31527687d0d8SRobert Mustacchi 	{ 10, 12, "pmsub", "PM Substate", PRDV_STRVAL,
31537687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Default", "Device Specific",
31547687d0d8SRobert Mustacchi 	    "Device Specific", "Device Specific", "Device Specific",
31557687d0d8SRobert Mustacchi 	    "Device Specific", "Device Specific", "Device Specific" } } },
31567687d0d8SRobert Mustacchi 	{ 13, 14, "pmstate", "PM State", PRDV_STRVAL,
31577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "D0", "D1", "D2", "D3" } } },
31587687d0d8SRobert Mustacchi 	{ 15, 17, "type", "Type", PRDV_STRVAL,
31597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PME Aux", "Axiliary", "Idle",
31607687d0d8SRobert Mustacchi 	    "Sustained", "Sustained - EPRS", "Maximum - EPRS", NULL,
31617687d0d8SRobert Mustacchi 	    "Maximum" } } },
31627687d0d8SRobert Mustacchi 	{ 18, 20, "rail", "Power Rail", PRDV_STRVAL,
31637687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Power (12V)", "Power (3.3V)",
31647687d0d8SRobert Mustacchi 	    "Power (1.5V or 1.8V)", NULL, NULL, NULL, NULL, "Thermal" } } },
31657687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31667687d0d8SRobert Mustacchi };
31677687d0d8SRobert Mustacchi 
31684a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_powbudg_cap[] = {
31697687d0d8SRobert Mustacchi 	{ 0, 0, "sa", "System Allocated", PRDV_STRVAL,
31707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
31717687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31727687d0d8SRobert Mustacchi };
31737687d0d8SRobert Mustacchi 
31747687d0d8SRobert Mustacchi 
31754a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_powbudg[] = {
31767687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
31777687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
31787687d0d8SRobert Mustacchi 	{ 0x4, 1, "sel", "Data Select", pcieadm_cfgspace_print_hex },
31797687d0d8SRobert Mustacchi 	{ 0x8, 4, "data", "Data Regiser", pcieadm_cfgspace_print_regdef,
31807687d0d8SRobert Mustacchi 	    pcieadm_regdef_powbudg_data },
31817687d0d8SRobert Mustacchi 	{ 0xc, 0x1, "cap", "Power Budget Capability",
31827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_powbudg_cap },
31837687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
31847687d0d8SRobert Mustacchi };
31857687d0d8SRobert Mustacchi 
31867687d0d8SRobert Mustacchi /*
31877687d0d8SRobert Mustacchi  * Precision Time Management
31887687d0d8SRobert Mustacchi  */
31894a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ptm_cap[] = {
31907687d0d8SRobert Mustacchi 	{ 0, 0, "req", "PTM Requester", PRDV_STRVAL,
31917687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31927687d0d8SRobert Mustacchi 	{ 1, 1, "resp", "PTM Responder", PRDV_STRVAL,
31937687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31947687d0d8SRobert Mustacchi 	{ 2, 2, "root", "PTM Root", PRDV_STRVAL,
31957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31967687d0d8SRobert Mustacchi 	{ 3, 3, "eptm", "ePTM", PRDV_STRVAL,
31977687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
31987687d0d8SRobert Mustacchi 	{ 8, 15, "gran", "Local Clock Granularity", PRDV_HEX },
31997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32007687d0d8SRobert Mustacchi };
32017687d0d8SRobert Mustacchi 
32024a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ptm_ctl[] = {
32037687d0d8SRobert Mustacchi 	{ 0, 0, "en", "PTM Enable", PRDV_STRVAL,
32047687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
32057687d0d8SRobert Mustacchi 	{ 1, 1, "root", "Root Select", PRDV_STRVAL,
32067687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
32077687d0d8SRobert Mustacchi 	{ 8, 15, "gran", "Effective Granularity", PRDV_HEX },
32087687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32097687d0d8SRobert Mustacchi };
32107687d0d8SRobert Mustacchi 
32114a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_info_ptm[] = {
32127687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
32137687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
32147687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap", "PTM Capability",
32157687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ptm_cap },
32167687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap", "PTM Control",
32177687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ptm_ctl },
32187687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32197687d0d8SRobert Mustacchi };
32207687d0d8SRobert Mustacchi 
32217687d0d8SRobert Mustacchi /*
32227687d0d8SRobert Mustacchi  * Address Translation Services (ATS)
32237687d0d8SRobert Mustacchi  */
32244a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ats_cap[] = {
32257687d0d8SRobert Mustacchi 	{ 0, 4, "invqd", "Invalidate Queue Depth", PRDV_HEX },
32267687d0d8SRobert Mustacchi 	{ 5, 5, "pgalign", "Page Aligned Request", PRDV_STRVAL,
32277687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
32287687d0d8SRobert Mustacchi 	{ 6, 6, "glbinv", "Global Invalidate", PRDV_STRVAL,
32297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32307687d0d8SRobert Mustacchi 	{ 7, 7, "relo", "Relaxed Ordering", PRDV_STRVAL,
32317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
32327687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32337687d0d8SRobert Mustacchi };
32347687d0d8SRobert Mustacchi 
32354a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ats_ctl[] = {
32367687d0d8SRobert Mustacchi 	{ 0, 4, "stu", "Smallest Translation Unit", PRDV_HEX },
32377687d0d8SRobert Mustacchi 	{ 15, 15, "en", "Enable", PRDV_STRVAL,
32387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
32397687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32407687d0d8SRobert Mustacchi };
32417687d0d8SRobert Mustacchi 
32424a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ats[] = {
32437687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
32447687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
32457687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "ATS Capability",
32467687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ats_cap },
32477687d0d8SRobert Mustacchi 	{ 0x6, 2, "cap", "ATS Control",
32487687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ats_ctl },
32497687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32507687d0d8SRobert Mustacchi };
32517687d0d8SRobert Mustacchi 
32527687d0d8SRobert Mustacchi /*
32537687d0d8SRobert Mustacchi  * Page Request
32547687d0d8SRobert Mustacchi  */
32554a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pgreq_ctl[] = {
32567687d0d8SRobert Mustacchi 	{ 0, 0, "en", "Enable", PRDV_STRVAL,
32577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
32587687d0d8SRobert Mustacchi 	{ 1, 1, "reset", "Reset", PRDV_HEX },
32597687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32607687d0d8SRobert Mustacchi };
32617687d0d8SRobert Mustacchi 
32624a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_pgreq_sts[] = {
32637687d0d8SRobert Mustacchi 	{ 0, 0, "rf", "Response Failure", PRDV_STRVAL,
32647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
32657687d0d8SRobert Mustacchi 	{ 1, 1, "uprgi", "Unexpected Page Request Group Index", PRDV_STRVAL,
32667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
32677687d0d8SRobert Mustacchi 	{ 8, 8, "stopped", "Stopped", PRDV_STRVAL,
32687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
32697687d0d8SRobert Mustacchi 	{ 15, 15, "prgrpreq", "PRG Response PASID", PRDV_STRVAL,
32707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
32717687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32727687d0d8SRobert Mustacchi };
32737687d0d8SRobert Mustacchi 
32744a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_pgreq[] = {
32757687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
32767687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
32777687d0d8SRobert Mustacchi 	{ 0x4, 2, "ctl", "Page Request Control",
32787687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pgreq_ctl },
32797687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "Page Request Status",
32807687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pgreq_sts },
32817687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap", "Outstanding Page Request Capacity",
32827687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
32837687d0d8SRobert Mustacchi 	{ 0xc, 4, "alloc", "Outstanding Page Request Allocation",
32847687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
32857687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32867687d0d8SRobert Mustacchi };
32877687d0d8SRobert Mustacchi 
32887687d0d8SRobert Mustacchi /*
32897687d0d8SRobert Mustacchi  * NULL Capability
32907687d0d8SRobert Mustacchi  */
32914a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_null[] = {
32927687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
32937687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
32947687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
32957687d0d8SRobert Mustacchi };
32967687d0d8SRobert Mustacchi 
32977687d0d8SRobert Mustacchi /*
32987687d0d8SRobert Mustacchi  * Downstream Port Containment
32997687d0d8SRobert Mustacchi  */
33004a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dpc_cap[] = {
33017687d0d8SRobert Mustacchi 	{ 0, 4, "inum", "DPC Interrupt Message Number", PRDV_HEX },
33027687d0d8SRobert Mustacchi 	{ 5, 5, "rpext", "Root Port Extensions", PRDV_STRVAL,
33037687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
33047687d0d8SRobert Mustacchi 	{ 6, 6, "ptlpeb", "Poisoned TLP Egress Blocking", PRDV_STRVAL,
33057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
33067687d0d8SRobert Mustacchi 	{ 7, 7, "swtrig", "Software Triggering", PRDV_STRVAL,
33077687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
33087687d0d8SRobert Mustacchi 	{ 8, 11, "logsz", "RP PIO Log Size", PRDV_HEX },
33097687d0d8SRobert Mustacchi 	{ 12, 12, "errcorr", "DL_Active ERR_COR Signaling", PRDV_STRVAL,
33107687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
33117687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
33127687d0d8SRobert Mustacchi };
33137687d0d8SRobert Mustacchi 
33144a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dpc_ctl[] = {
33157687d0d8SRobert Mustacchi 	{ 0, 1, "trigger", "DPC Trigger", PRDV_STRVAL,
33167687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled, fatal",
33177687d0d8SRobert Mustacchi 	    "enabled, non-fatal" } } },
33187687d0d8SRobert Mustacchi 	{ 2, 2, "comp", "Completion Control", PRDV_STRVAL,
33197687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Completer Abort",
33207687d0d8SRobert Mustacchi 	    "Unsupported Request" } } },
33217687d0d8SRobert Mustacchi 	{ 3, 3, "intr", "Interrupt",
33227687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33237687d0d8SRobert Mustacchi 	{ 4, 4, "errcor", "ERR_COR",
33247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33257687d0d8SRobert Mustacchi 	{ 5, 5, "ptlpeb", "Poisoned TLP Egress Blocking", PRDV_STRVAL,
33267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33277687d0d8SRobert Mustacchi 	{ 6, 6, "swtrig", "Software Trigger", PRDV_HEX },
33287687d0d8SRobert Mustacchi 	{ 7, 7, "corerr", "DL_Active ERR_COR",
33297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33307687d0d8SRobert Mustacchi 	{ 8, 8, "sigsfw", "SIG_SFW",
33317687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
33327687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
33337687d0d8SRobert Mustacchi };
33347687d0d8SRobert Mustacchi 
33354a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dpc_sts[] = {
33367687d0d8SRobert Mustacchi 	{ 0, 0, "trigger", "Trigger Status", PRDV_STRVAL,
33377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not triggered", "triggered" } } },
33387687d0d8SRobert Mustacchi 	{ 1, 2, "reason", "Trigger Reason", PRDV_STRVAL,
33397687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unmasked uncorrectable",
33407687d0d8SRobert Mustacchi 	    "ERR_NONFATAL received", "ERR_FATAL received",
33417687d0d8SRobert Mustacchi 	    "see extension" } } },
33427687d0d8SRobert Mustacchi 	{ 3, 3, "istatus", "Interrupt Status", PRDV_HEX },
33437687d0d8SRobert Mustacchi 	{ 4, 4, "rpbusy", "RP Busy", PRDV_STRVAL,
33447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
33457687d0d8SRobert Mustacchi 	{ 5, 6, "extreason", "Trigger Reason Extension", PRDV_STRVAL,
33467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "RP PIO", "Software Trigger" } } },
33477687d0d8SRobert Mustacchi 	{ 8, 12, "feptr", "RP PIO, First Error Pointer", PRDV_HEX },
33487687d0d8SRobert Mustacchi 	{ 13, 13, "sigsfw", "SIG_SFW Status", PRDV_HEX },
33497687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
33507687d0d8SRobert Mustacchi };
33517687d0d8SRobert Mustacchi 
33524a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_dpc_rppio_bits[] = {
33537687d0d8SRobert Mustacchi 	{ 0, 0, "cfgur", "Configuration Request UR Completion", PRDV_HEX },
33547687d0d8SRobert Mustacchi 	{ 1, 1, "cfgca", "Configuration Request CA Completion", PRDV_HEX },
33557687d0d8SRobert Mustacchi 	{ 2, 2, "cfgcto", "Configuration Request Completion Timeout",
33567687d0d8SRobert Mustacchi 	    PRDV_HEX },
33577687d0d8SRobert Mustacchi 	{ 8, 8, "iour", "I/O UR Completion", PRDV_HEX },
33587687d0d8SRobert Mustacchi 	{ 9, 9, "ioca", "I/O CA Completion", PRDV_HEX },
33597687d0d8SRobert Mustacchi 	{ 10, 10, "iocto", "I/O Completion Timeout", PRDV_HEX },
33607687d0d8SRobert Mustacchi 	{ 8, 8, "memur", "Memory UR Completion", PRDV_HEX },
33617687d0d8SRobert Mustacchi 	{ 9, 9, "memca", "Memory CA Completion", PRDV_HEX },
33627687d0d8SRobert Mustacchi 	{ 10, 10, "memcto", "Memory Completion Timeout", PRDV_HEX },
33637687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
33647687d0d8SRobert Mustacchi };
33657687d0d8SRobert Mustacchi 
33667687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_dpc_rppio(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)33677687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_rppio(pcieadm_cfgspace_walk_t *walkp,
33684a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
33697687d0d8SRobert Mustacchi {
33707687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
33717687d0d8SRobert Mustacchi 
33724a8bbc0bSRobert Mustacchi 	if (bitx32(cap, 5, 5) == 0) {
33737687d0d8SRobert Mustacchi 		return;
33747687d0d8SRobert Mustacchi 	}
33757687d0d8SRobert Mustacchi 
33767687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_regdef(walkp, print, arg);
33777687d0d8SRobert Mustacchi }
33787687d0d8SRobert Mustacchi 
33797687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_dpc_piohead(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)33807687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_piohead(pcieadm_cfgspace_walk_t *walkp,
33814a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
33827687d0d8SRobert Mustacchi {
33837687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
33844a8bbc0bSRobert Mustacchi 	uint32_t nwords = bitx32(cap, 11, 8);
33857687d0d8SRobert Mustacchi 
33864a8bbc0bSRobert Mustacchi 	if (bitx32(cap, 5, 5) == 0 || nwords < 4) {
33877687d0d8SRobert Mustacchi 		return;
33887687d0d8SRobert Mustacchi 	}
33897687d0d8SRobert Mustacchi 
33907687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, NULL);
33917687d0d8SRobert Mustacchi }
33927687d0d8SRobert Mustacchi 
33937687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_dpc_impspec(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)33947687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_impspec(pcieadm_cfgspace_walk_t *walkp,
33954a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
33967687d0d8SRobert Mustacchi {
33977687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
33984a8bbc0bSRobert Mustacchi 	uint32_t nwords = bitx32(cap, 11, 8);
33997687d0d8SRobert Mustacchi 
34004a8bbc0bSRobert Mustacchi 	if (bitx32(cap, 5, 5) == 0 || nwords < 5) {
34017687d0d8SRobert Mustacchi 		return;
34027687d0d8SRobert Mustacchi 	}
34037687d0d8SRobert Mustacchi 
34047687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, NULL);
34057687d0d8SRobert Mustacchi }
34067687d0d8SRobert Mustacchi 
34077687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_dpc_tlplog(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)34087687d0d8SRobert Mustacchi pcieadm_cfgspace_print_dpc_tlplog(pcieadm_cfgspace_walk_t *walkp,
34094a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
34107687d0d8SRobert Mustacchi {
34117687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
34124a8bbc0bSRobert Mustacchi 	int32_t nwords = (int32_t)bitx32(cap, 11, 8);
34137687d0d8SRobert Mustacchi 
34144a8bbc0bSRobert Mustacchi 	if (nwords == 0 || bitx32(cap, 5, 5) == 0) {
34157687d0d8SRobert Mustacchi 		return;
34167687d0d8SRobert Mustacchi 	}
34177687d0d8SRobert Mustacchi 
34187687d0d8SRobert Mustacchi 	if (nwords <= 9) {
34197687d0d8SRobert Mustacchi 		nwords -= 5;
34207687d0d8SRobert Mustacchi 	} else {
34217687d0d8SRobert Mustacchi 		nwords -= 4;
34227687d0d8SRobert Mustacchi 	}
34237687d0d8SRobert Mustacchi 
34247687d0d8SRobert Mustacchi 	for (int32_t i = 0; i < nwords; i++) {
34257687d0d8SRobert Mustacchi 		char tlpshort[32], tlphuman[128];
34267687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
34277687d0d8SRobert Mustacchi 
34287687d0d8SRobert Mustacchi 		(void) snprintf(tlpshort, sizeof (tlpshort), "%s%u",
34297687d0d8SRobert Mustacchi 		    print->pcp_short, i);
34307687d0d8SRobert Mustacchi 		(void) snprintf(tlphuman, sizeof (tlphuman), "%s %u",
34317687d0d8SRobert Mustacchi 		    print->pcp_human, i);
34327687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 4;
34337687d0d8SRobert Mustacchi 		p.pcp_len = 4;
34347687d0d8SRobert Mustacchi 		p.pcp_short = tlpshort;
34357687d0d8SRobert Mustacchi 		p.pcp_human = tlphuman;
34367687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_hex;
34377687d0d8SRobert Mustacchi 		p.pcp_arg = NULL;
34387687d0d8SRobert Mustacchi 
34397687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
34407687d0d8SRobert Mustacchi 	}
34417687d0d8SRobert Mustacchi }
34427687d0d8SRobert Mustacchi 
34434a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_dpc[] = {
34447687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
34457687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
34467687d0d8SRobert Mustacchi 	{ 0x4, 2, "cap", "DPC Capability",
34477687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_cap },
34487687d0d8SRobert Mustacchi 	{ 0x6, 2, "ctl", "DPC Control",
34497687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_ctl },
34507687d0d8SRobert Mustacchi 	{ 0x8, 2, "sts", "DPC Status",
34517687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_dpc_sts },
34527687d0d8SRobert Mustacchi 	{ 0xa, 2, "srcid", "DPC Error Source ID",
34537687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
34547687d0d8SRobert Mustacchi 	{ 0x10, 4, "rppiosts", "RP PIO Status",
34557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34567687d0d8SRobert Mustacchi 	{ 0x14, 4, "rppiomask", "RP PIO Mask ID",
34577687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34587687d0d8SRobert Mustacchi 	{ 0x14, 4, "rppiosev", "RP PIO Severity",
34597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34607687d0d8SRobert Mustacchi 	{ 0x18, 4, "rppiose", "RP PIO SysError",
34617687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34627687d0d8SRobert Mustacchi 	{ 0x1c, 4, "rppioex", "RP PIO Exception",
34637687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_rppio, pcieadm_regdef_dpc_rppio_bits },
34647687d0d8SRobert Mustacchi 	{ 0x20, 4, "rppiohl0", "RP PIO Header Log 0",
34657687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34667687d0d8SRobert Mustacchi 	{ 0x24, 4, "rppiohl1", "RP PIO Header Log 1",
34677687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34687687d0d8SRobert Mustacchi 	{ 0x28, 4, "rppiohl2", "RP PIO Header Log 2",
34697687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34707687d0d8SRobert Mustacchi 	{ 0x2c, 4, "rppiohl3", "RP PIO Header Log 3",
34717687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_piohead },
34727687d0d8SRobert Mustacchi 	{ 0x30, 4, "impspec", "RP PIO ImpSpec Log",
34737687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_impspec },
34747687d0d8SRobert Mustacchi 	{ 0x34, 16, "tlplog", "RP PIO TLP Prefix Log",
34757687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_dpc_tlplog },
34767687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
34777687d0d8SRobert Mustacchi };
34787687d0d8SRobert Mustacchi 
34797687d0d8SRobert Mustacchi /*
34807687d0d8SRobert Mustacchi  * Virtual Channel Capability
34817687d0d8SRobert Mustacchi  */
34824a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vc_cap1[] = {
34837687d0d8SRobert Mustacchi 	{ 0, 2, "count", "Extended VC Count", PRDV_HEX },
34847687d0d8SRobert Mustacchi 	{ 4, 6, "lpcount", "Low Priority Extended VC Count", PRDV_HEX },
34857687d0d8SRobert Mustacchi 	{ 8, 9, "refclk", "Reference Clock", PRDV_STRVAL,
34867687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "100ns" } } },
34877687d0d8SRobert Mustacchi 	{ 10, 11, "patsz", "Port Arbitration Table Size", PRDV_STRVAL,
34887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "1 bit", "2 bits", "4 bits",
34897687d0d8SRobert Mustacchi 	    "8 bits" } } },
34907687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
34917687d0d8SRobert Mustacchi };
34927687d0d8SRobert Mustacchi 
34934a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vc_cap2[] = {
34947687d0d8SRobert Mustacchi 	{ 0, 7, "arbcap", "VC Arbitration Capability", PRDV_BITFIELD,
34957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
34967687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
34977687d0d8SRobert Mustacchi 	    "128 phase weighted round robin" } } },
34987687d0d8SRobert Mustacchi 	{ 24, 31, "offset", "VC Arbitration Table Offset", PRDV_HEX },
34997687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35007687d0d8SRobert Mustacchi };
35017687d0d8SRobert Mustacchi 
35024a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vc_ctl[] = {
35037687d0d8SRobert Mustacchi 	{ 0, 0, "loadtbl", "Load VC Arbitration Table", PRDV_HEX },
35047687d0d8SRobert Mustacchi 	{ 1, 3, "arbtype", "VC Arbitration Select", PRDV_STRVAL,
35057687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
35067687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
35077687d0d8SRobert Mustacchi 	    "128 phase weighted round robin" } } },
35087687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35097687d0d8SRobert Mustacchi };
35107687d0d8SRobert Mustacchi 
35114a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vc_sts[] = {
35127687d0d8SRobert Mustacchi 	{ 0, 0, "table", "VC Arbitration Table Status", PRDV_HEX },
35137687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35147687d0d8SRobert Mustacchi };
35157687d0d8SRobert Mustacchi 
35164a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vc_rsrccap[] = {
35177687d0d8SRobert Mustacchi 	{ 0, 7, "arbcap", "Port Arbitration Capability", PRDV_BITFIELD,
35187687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
35197687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
35207687d0d8SRobert Mustacchi 	    "128 phase weighted round robin",
35217687d0d8SRobert Mustacchi 	    "128 phase time-based weighted round robin",
35227687d0d8SRobert Mustacchi 	    "256 phase weighted round robin" } } },
35237687d0d8SRobert Mustacchi 	{ 14, 14, "aps", "Advanced Packet Switching", PRDV_STRVAL,
35247687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
35257687d0d8SRobert Mustacchi 	{ 15, 15, "rstx", "Reject Snoop Transactions", PRDV_STRVAL,
35267687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
35277687d0d8SRobert Mustacchi 	{ 16, 22, "nslots", "Maximum Time Slots", PRDV_HEX,
35287687d0d8SRobert Mustacchi 	    { .prdv_hex = { 0, 1 } } },
35297687d0d8SRobert Mustacchi 	{ 24, 31, "offset", "VC Arbitration Table Offset", PRDV_HEX },
35307687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35317687d0d8SRobert Mustacchi };
35327687d0d8SRobert Mustacchi 
35334a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vc_rsrcctl[] = {
35347687d0d8SRobert Mustacchi 	{ 0, 7, "tcmap", "TC/VC Map", PRDV_HEX },
35357687d0d8SRobert Mustacchi 	{ 16, 16, "loadtbl", "Load VC Arbitration Table", PRDV_HEX },
35367687d0d8SRobert Mustacchi 	{ 17, 19, "arbtype", "Port Arbitration Select", PRDV_STRVAL,
35377687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "hardware fixed",
35387687d0d8SRobert Mustacchi 	    "32 phase weighted round robin", "64 phase weighted round robin",
35397687d0d8SRobert Mustacchi 	    "128 phase weighted round robin",
35407687d0d8SRobert Mustacchi 	    "128 phase time-based weighted round robin",
35417687d0d8SRobert Mustacchi 	    "256 phase weighted round robin" } } },
35427687d0d8SRobert Mustacchi 	{ 24, 26, "vcid", "VC ID", PRDV_HEX },
35437687d0d8SRobert Mustacchi 	{ 31, 31, "en", "VC Enable",
35447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
35457687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35467687d0d8SRobert Mustacchi };
35477687d0d8SRobert Mustacchi 
35484a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_vc_rsrcsts[] = {
35497687d0d8SRobert Mustacchi 	{ 0, 0, "table", "Port Arbitration Table Status", PRDV_HEX },
35507687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
35517687d0d8SRobert Mustacchi };
35527687d0d8SRobert Mustacchi 
35537687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_vc_rsrc(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)35547687d0d8SRobert Mustacchi pcieadm_cfgspace_print_vc_rsrc(pcieadm_cfgspace_walk_t *walkp,
35554a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
35567687d0d8SRobert Mustacchi {
35577687d0d8SRobert Mustacchi 	uint32_t cap = walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + 4) / 4];
35584a8bbc0bSRobert Mustacchi 	uint32_t nents = bitx32(cap, 2, 0) + 1;
35597687d0d8SRobert Mustacchi 
35607687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < nents; i++) {
35617687d0d8SRobert Mustacchi 		char vcshort[32], vchuman[128];
35627687d0d8SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
35637687d0d8SRobert Mustacchi 
35647687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrccap%u", i);
35657687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
35667687d0d8SRobert Mustacchi 		    "Capability", i);
35677687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10;
35687687d0d8SRobert Mustacchi 		p.pcp_len = 4;
35697687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
35707687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
35717687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
35727687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrccap;
35737687d0d8SRobert Mustacchi 
35747687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
35757687d0d8SRobert Mustacchi 
35767687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrcctl%u", i);
35777687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
35787687d0d8SRobert Mustacchi 		    "Control", i);
35797687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10 + 4;
35807687d0d8SRobert Mustacchi 		p.pcp_len = 4;
35817687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
35827687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
35837687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
35847687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrcctl;
35857687d0d8SRobert Mustacchi 
35867687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
35877687d0d8SRobert Mustacchi 
35887687d0d8SRobert Mustacchi 		(void) snprintf(vcshort, sizeof (vcshort), "rsrcsts%u", i);
35897687d0d8SRobert Mustacchi 		(void) snprintf(vchuman, sizeof (vchuman), "VC Resource %u "
35907687d0d8SRobert Mustacchi 		    "Status", i);
35917687d0d8SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 0x10 + 0xa;
35927687d0d8SRobert Mustacchi 		p.pcp_len = 2;
35937687d0d8SRobert Mustacchi 		p.pcp_short = vcshort;
35947687d0d8SRobert Mustacchi 		p.pcp_human = vchuman;
35957687d0d8SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
35967687d0d8SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_vc_rsrcsts;
35977687d0d8SRobert Mustacchi 
35987687d0d8SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
35997687d0d8SRobert Mustacchi 	}
36007687d0d8SRobert Mustacchi }
36017687d0d8SRobert Mustacchi 
36024a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_vc[] = {
36037687d0d8SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
36047687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
36057687d0d8SRobert Mustacchi 	{ 0x4, 4, "cap1", "Port VC Capability 1",
36067687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_cap1 },
36077687d0d8SRobert Mustacchi 	{ 0x8, 4, "cap2", "Port VC Capability 2",
36087687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_cap2 },
36097687d0d8SRobert Mustacchi 	{ 0xc, 2, "ctl", "Port VC Control",
36107687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_ctl },
36117687d0d8SRobert Mustacchi 	{ 0xe, 2, "sts", "Port VC Status",
36127687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_vc_sts },
36137687d0d8SRobert Mustacchi 	{ 0x10, 12, "vcrec", "VC Resource", pcieadm_cfgspace_print_vc_rsrc },
36147687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36157687d0d8SRobert Mustacchi };
36167687d0d8SRobert Mustacchi 
36177687d0d8SRobert Mustacchi /*
36187687d0d8SRobert Mustacchi  * HyperTransport
36197687d0d8SRobert Mustacchi  */
36204a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ht_intr[] = {
36217687d0d8SRobert Mustacchi 	{ 0x2, 1, "index", "Interrupt Discovery Index",
36227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
36237687d0d8SRobert Mustacchi 	{ 0x4, 4, "dataport", "Interrupt Dataport",
36247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
36257687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36267687d0d8SRobert Mustacchi };
36277687d0d8SRobert Mustacchi 
36284a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_command_pri[] = {
36297687d0d8SRobert Mustacchi 	{ 0, 4, "unitid", "Base Unit ID", PRDV_HEX },
36307687d0d8SRobert Mustacchi 	{ 5, 9, "count", "Unit Count", PRDV_HEX },
36317687d0d8SRobert Mustacchi 	{ 10, 10, "host", "Master Host", PRDV_HEX },
36327687d0d8SRobert Mustacchi 	{ 11, 11, "dir", "Default Direction", PRDV_STRVAL,
36337687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "towards host",
36347687d0d8SRobert Mustacchi 	    "away from host" } } },
36357687d0d8SRobert Mustacchi 	{ 12, 12, "drop", "Drop on Uninitialized Link", PRDV_HEX },
36367687d0d8SRobert Mustacchi 	{ 13, 15, "cap", "Capability ID", PRDV_HEX },
36377687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36387687d0d8SRobert Mustacchi };
36397687d0d8SRobert Mustacchi 
36404a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_command_sec[] = {
36417687d0d8SRobert Mustacchi 	{ 0, 0, "reset", "Warm Reset", PRDV_HEX },
36427687d0d8SRobert Mustacchi 	{ 1, 1, "de", "Double Ended", PRDV_HEX },
36437687d0d8SRobert Mustacchi 	{ 2, 6, "devno", "Device Number", PRDV_HEX },
36447687d0d8SRobert Mustacchi 	{ 7, 7, "chain", "Chain Side", PRDV_STRVAL,
36457687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "from host", "from chain" } } },
36467687d0d8SRobert Mustacchi 	{ 8, 8, "hide", "Host Hide", PRDV_STRVAL,
36477687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "visible", "hidden" } } },
36487687d0d8SRobert Mustacchi 	{ 10, 10, "target", "Act as Target", PRDV_HEX },
36497687d0d8SRobert Mustacchi 	{ 11, 11, "eocerr", "Host Inbound End of Chain Error", PRDV_HEX },
36507687d0d8SRobert Mustacchi 	{ 12, 12, "drop", "Drop on Uninitialized Link", PRDV_HEX },
36517687d0d8SRobert Mustacchi 	{ 13, 15, "cap", "Capability ID", PRDV_HEX },
36527687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36537687d0d8SRobert Mustacchi };
36547687d0d8SRobert Mustacchi 
36554a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_linkctl[] = {
36567687d0d8SRobert Mustacchi 	{ 0, 0, "srcid", "Source ID", PRDV_STRVAL,
36577687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36587687d0d8SRobert Mustacchi 	{ 1, 1, "cfl", "CRC Flood", PRDV_STRVAL,
36597687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36607687d0d8SRobert Mustacchi 	{ 2, 2, "cst", "CRC Start Test", PRDV_HEX },
36617687d0d8SRobert Mustacchi 	{ 3, 3, "cfer", "CRC Force Error", PRDV_STRVAL,
36627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36637687d0d8SRobert Mustacchi 	{ 4, 4, "linkfail", "Link Failure", PRDV_HEX },
36647687d0d8SRobert Mustacchi 	{ 5, 5, "initcmp", "Initialization Complete", PRDV_HEX },
36657687d0d8SRobert Mustacchi 	{ 6, 6, "eoc", "End of Chain", PRDV_HEX },
36667687d0d8SRobert Mustacchi 	{ 7, 7, "txoff", "Transmitter Off", PRDV_STRVAL,
36677687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "transmitter on",
36687687d0d8SRobert Mustacchi 	    "transmitter off" } } },
36697687d0d8SRobert Mustacchi 	{ 8, 11, "crcerr", "CRC Error", PRDV_HEX },
36707687d0d8SRobert Mustacchi 	{ 12, 12, "isoc", "Isochronous Flow Control", PRDV_STRVAL,
36717687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36727687d0d8SRobert Mustacchi 	{ 13, 13, "ls", "LDTSTOP# Tristate", PRDV_STRVAL,
36737687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36747687d0d8SRobert Mustacchi 	{ 14, 14, "extctl", "Extended CTL Time", PRDV_HEX },
36757687d0d8SRobert Mustacchi 	{ 15, 15, "64b", "64-bit Addressing", PRDV_STRVAL,
36767687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36777687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
36787687d0d8SRobert Mustacchi };
36797687d0d8SRobert Mustacchi 
36804a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_linkcfg[] = {
36817687d0d8SRobert Mustacchi 	{ 0, 2, "maxin", "Maximum Link Width In", PRDV_STRVAL,
36827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36837687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36847687d0d8SRobert Mustacchi 	{ 3, 3, "dwfcinsup", "Doubleword Flow Control In", PRDV_STRVAL,
36857687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
36867687d0d8SRobert Mustacchi 	{ 4, 6, "maxout", "Maximum Link Width Out", PRDV_STRVAL,
36877687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36887687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36897687d0d8SRobert Mustacchi 	{ 7, 7, "dwfcoutsup", "Doubleword Flow Control Out", PRDV_STRVAL,
36907687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
36917687d0d8SRobert Mustacchi 	{ 8, 10, "linkin", "Link Width In", PRDV_STRVAL,
36927687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36937687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36947687d0d8SRobert Mustacchi 	{ 11, 11, "dwfcin", "Doubleword Flow Control In", PRDV_STRVAL,
36957687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
36967687d0d8SRobert Mustacchi 	{ 12, 14, "linkout", "Link Width Out", PRDV_STRVAL,
36977687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "8 bits", "16 bits", NULL, "32 bits",
36987687d0d8SRobert Mustacchi 	    "2 bits", "4 bits", NULL, "not connected" } } },
36997687d0d8SRobert Mustacchi 	{ 15, 15, "dwfcout", "Doubleword Flow Control Out", PRDV_STRVAL,
37007687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37017687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37027687d0d8SRobert Mustacchi };
37037687d0d8SRobert Mustacchi 
37044a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_rev[] = {
37057687d0d8SRobert Mustacchi 	{ 0, 4, "minor", "Minor Revision", PRDV_HEX },
37067687d0d8SRobert Mustacchi 	{ 5, 7, "major", "Major Revision", PRDV_HEX },
37077687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37087687d0d8SRobert Mustacchi };
37097687d0d8SRobert Mustacchi 
37104a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_linkfreq[] = {
37117687d0d8SRobert Mustacchi 	{ 0, 4, "freq", "Link Frequency", PRDV_STRVAL,
37127687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "200 MHz", "300 MHz", "400 MHz",
37137687d0d8SRobert Mustacchi 	    "500 MHz", "600 MHz", "800 MHz", "1000 MHz", "1200 MHz", "1400 MHz",
37147687d0d8SRobert Mustacchi 	    "1600 MHz", "1800 MHz", "2000 MHz", "2200 MHz", "2400 MHz",
37157687d0d8SRobert Mustacchi 	    "2600 MHz", "Vendor Specfic" } } },
37167687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37177687d0d8SRobert Mustacchi };
37187687d0d8SRobert Mustacchi 
37194a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_linkerr[] = {
37207687d0d8SRobert Mustacchi 	{ 4, 4, "prot", "Protocol Error", PRDV_HEX },
37217687d0d8SRobert Mustacchi 	{ 5, 5, "over", "Overflow Error", PRDV_HEX },
37227687d0d8SRobert Mustacchi 	{ 6, 6, "eoc", "End of Chain Error", PRDV_HEX },
37237687d0d8SRobert Mustacchi 	{ 7, 7, "ctl", "CTL Timeout", PRDV_HEX },
37247687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37257687d0d8SRobert Mustacchi };
37267687d0d8SRobert Mustacchi 
37274a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_linkcap[] = {
37287687d0d8SRobert Mustacchi 	{ 0, 15, "freq", "Link Frequency", PRDV_BITFIELD,
37297687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "200 MHz", "300 MHz", "400 MHz",
37307687d0d8SRobert Mustacchi 	    "500 MHz", "600 MHz", "800 MHz", "1000 MHz", "1200 MHz", "1400 MHz",
37317687d0d8SRobert Mustacchi 	    "1600 MHz", "1800 MHz", "2000 MHz", "2200 MHz", "2400 MHz",
37327687d0d8SRobert Mustacchi 	    "2600 MHz", "Vendor Specfic" } } },
37337687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37347687d0d8SRobert Mustacchi };
37357687d0d8SRobert Mustacchi 
37364a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_feature[] = {
37377687d0d8SRobert Mustacchi 	{ 0, 0, "isofc", "Isochronous Flow Control", PRDV_STRVAL,
37387687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37397687d0d8SRobert Mustacchi 	{ 1, 1, "ls", "LDTSTOP#", PRDV_STRVAL,
37407687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37417687d0d8SRobert Mustacchi 	{ 2, 2, "crct", "CRC Test Mode", PRDV_STRVAL,
37427687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37437687d0d8SRobert Mustacchi 	{ 3, 3, "ectl", "Extended CTL Time", PRDV_STRVAL,
37447687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
37457687d0d8SRobert Mustacchi 	{ 4, 4, "64b", "64-bit Addressing", PRDV_STRVAL,
37467687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37477687d0d8SRobert Mustacchi 	{ 5, 5, "unitid", "UnitID Reorder", PRDV_STRVAL,
37487687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
37497687d0d8SRobert Mustacchi 	{ 6, 6, "srcid", "Source Identification Extension", PRDV_STRVAL,
37507687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "not required", "required" } } },
37517687d0d8SRobert Mustacchi 	{ 8, 8, "extreg", "Extended Register Set", PRDV_STRVAL,
37527687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
37537687d0d8SRobert Mustacchi 	{ 9, 9, "uscfg", "Upstream Configuration", PRDV_STRVAL,
37547687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37557687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37567687d0d8SRobert Mustacchi };
37577687d0d8SRobert Mustacchi 
37584a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_error[] = {
37597687d0d8SRobert Mustacchi 	{ 0, 0, "protfl", "Protocol Error Flood", PRDV_STRVAL,
37607687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37617687d0d8SRobert Mustacchi 	{ 1, 1, "ovfl", "Overflow Error Flood", PRDV_STRVAL,
37627687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37637687d0d8SRobert Mustacchi 	{ 2, 2, "protf", "Protocol Error Fatal", PRDV_STRVAL,
37647687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37657687d0d8SRobert Mustacchi 	{ 3, 3, "ovf", "Overflow Error Fatal", PRDV_STRVAL,
37667687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37677687d0d8SRobert Mustacchi 	{ 4, 4, "eocf", "End of Chain Fatal Error", PRDV_STRVAL,
37687687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37697687d0d8SRobert Mustacchi 	{ 5, 5, "respf", "Response Error Fatal", PRDV_STRVAL,
37707687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37717687d0d8SRobert Mustacchi 	{ 6, 6, "crcf", "CRC Error Fatal", PRDV_STRVAL,
37727687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37737687d0d8SRobert Mustacchi 	{ 7, 7, "sysf", "System Error Fatal", PRDV_STRVAL,
37747687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37757687d0d8SRobert Mustacchi 	{ 8, 8, "chain", "Chain Fail", PRDV_HEX },
37767687d0d8SRobert Mustacchi 	{ 9, 9, "resp", "Response Error", PRDV_HEX },
37777687d0d8SRobert Mustacchi 	{ 10, 10, "protnf", "Protocol Error Non-Fatal", PRDV_STRVAL,
37787687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37797687d0d8SRobert Mustacchi 	{ 11, 11, "ovfnf", "Overflow Error Non-Fatal", PRDV_STRVAL,
37807687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37817687d0d8SRobert Mustacchi 	{ 12, 12, "eocnf", "End of Chain Error Non-Fatal", PRDV_STRVAL,
37827687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37837687d0d8SRobert Mustacchi 	{ 13, 13, "respnf", "Response Error Non-Fatal", PRDV_STRVAL,
37847687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37857687d0d8SRobert Mustacchi 	{ 14, 14, "crcnf", "CRC Error Non-Fatal", PRDV_STRVAL,
37867687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37877687d0d8SRobert Mustacchi 	{ 15, 15, "sysnf", "System Error Non-Fatal", PRDV_STRVAL,
37887687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
37897687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37907687d0d8SRobert Mustacchi };
37917687d0d8SRobert Mustacchi 
37924a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_memory[] = {
37937687d0d8SRobert Mustacchi 	{ 0, 8, "base", "Memory Base Upper 8 Bits", PRDV_HEX,
37947687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 32 } } },
37957687d0d8SRobert Mustacchi 	{ 9, 15, "limit", "Memory Limit Upper 8 Bits", PRDV_HEX,
37967687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_hex = { 32 } } },
37977687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
37987687d0d8SRobert Mustacchi };
37997687d0d8SRobert Mustacchi 
38004a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ht_pri[] = {
38017687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
38027687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_command_pri },
38037687d0d8SRobert Mustacchi 	{ 0x4, 2, "linkctl0", "Link Control 0",
38047687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
38057687d0d8SRobert Mustacchi 	{ 0x6, 2, "linkcfg0", "Link Configuration 0",
38067687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
38077687d0d8SRobert Mustacchi 	{ 0x8, 2, "linkctl1", "Link Control 1",
38087687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
38097687d0d8SRobert Mustacchi 	{ 0xa, 2, "linkcfg1", "Link Configuration 1",
38107687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
38117687d0d8SRobert Mustacchi 	{ 0xc, 1, "rev", "Revision",
38127687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_rev },
38137687d0d8SRobert Mustacchi 	{ 0xd, 1, "linkfreq0", "Link Frequency 0",
38147687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
38157687d0d8SRobert Mustacchi 	{ 0xd, 1, "linkerr0", "Link Error 0",
38167687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
38177687d0d8SRobert Mustacchi 	{ 0xe, 2, "linkfcap0", "Link Frequency Cap 0",
38187687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
38197687d0d8SRobert Mustacchi 	{ 0x10, 1, "feature", "Feature Capability",
38207687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_feature },
38217687d0d8SRobert Mustacchi 	{ 0x11, 1, "linkfreq1", "Link Frequency 1",
38227687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
38237687d0d8SRobert Mustacchi 	{ 0x11, 1, "linkerr1", "Link Error 1",
38247687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
38257687d0d8SRobert Mustacchi 	{ 0x12, 2, "linkfcap1", "Link Frequency Cap 1",
38267687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
38277687d0d8SRobert Mustacchi 	{ 0x14, 2, "scratch", "Enumeration Scratchpad",
38287687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
38297687d0d8SRobert Mustacchi 	{ 0x16, 2, "error", "Error Handling",
38307687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_error },
38317687d0d8SRobert Mustacchi 	{ 0x18, 2, "memory", "Memory",
38327687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_memory },
38337687d0d8SRobert Mustacchi 	{ 0x1a, 1, "bus", "Bus Number", pcieadm_cfgspace_print_hex },
38347687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38357687d0d8SRobert Mustacchi };
38367687d0d8SRobert Mustacchi 
38374a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ht_sec[] = {
38387687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
38397687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_command_sec },
38407687d0d8SRobert Mustacchi 	{ 0x4, 2, "linkctl", "Link Control",
38417687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkctl },
38427687d0d8SRobert Mustacchi 	{ 0x6, 2, "linkcfg", "Link Configuration",
38437687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcfg },
38447687d0d8SRobert Mustacchi 	{ 0x8, 1, "rev", "Revision",
38457687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_rev },
38467687d0d8SRobert Mustacchi 	{ 0x9, 1, "linkfreq", "Link Frequency 0",
38477687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkfreq },
38487687d0d8SRobert Mustacchi 	{ 0x9, 1, "linkerr", "Link Error 0",
38497687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkerr },
38507687d0d8SRobert Mustacchi 	{ 0xa, 2, "linkfcap", "Link Frequency Cap 0",
38517687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_linkcap },
38527687d0d8SRobert Mustacchi 	{ 0xc, 2, "feature", "Feature Capability",
38537687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_feature },
38547687d0d8SRobert Mustacchi 	{ 0x10, 2, "scratch", "Enumeration Scratchpad",
38557687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
38567687d0d8SRobert Mustacchi 	{ 0x12, 2, "error", "Error Handling",
38577687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_error },
38587687d0d8SRobert Mustacchi 	{ 0x14, 2, "memory", "Memory",
38597687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_memory },
38607687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38617687d0d8SRobert Mustacchi };
38627687d0d8SRobert Mustacchi 
38634a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ht_msi[] = {
38647687d0d8SRobert Mustacchi 	{ 0, 0, "en", "Enable", PRDV_STRVAL,
38657687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
38667687d0d8SRobert Mustacchi 	{ 1, 1, "fixed", "Fixed", PRDV_STRVAL,
38677687d0d8SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
38687687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38697687d0d8SRobert Mustacchi };
38707687d0d8SRobert Mustacchi 
38717687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_ht_msi_addr(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)38727687d0d8SRobert Mustacchi pcieadm_cfgspace_print_ht_msi_addr(pcieadm_cfgspace_walk_t *walkp,
38734a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
38747687d0d8SRobert Mustacchi {
38757687d0d8SRobert Mustacchi 	uint8_t fixed = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 2];
38767687d0d8SRobert Mustacchi 
38774a8bbc0bSRobert Mustacchi 	if (bitx8(fixed, 1, 1) != 0)
38787687d0d8SRobert Mustacchi 		return;
38797687d0d8SRobert Mustacchi 
38807687d0d8SRobert Mustacchi 	pcieadm_cfgspace_print_hex(walkp, print, arg);
38817687d0d8SRobert Mustacchi }
38827687d0d8SRobert Mustacchi 
38834a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ht_msi[] = {
38847687d0d8SRobert Mustacchi 	{ 0x2, 2, "command", "Command",
38857687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ht_msi },
38867687d0d8SRobert Mustacchi 	{ 0x4, 8, "address", "MSI Address",
38877687d0d8SRobert Mustacchi 	    pcieadm_cfgspace_print_ht_msi_addr },
38887687d0d8SRobert Mustacchi 	{ -1, -1, NULL }
38897687d0d8SRobert Mustacchi };
38907687d0d8SRobert Mustacchi 
38917687d0d8SRobert Mustacchi /*
38927687d0d8SRobert Mustacchi  * Capability related tables
38937687d0d8SRobert Mustacchi  */
38947687d0d8SRobert Mustacchi typedef struct pcieadm_cap_vers {
38957687d0d8SRobert Mustacchi 	uint32_t ppr_vers;
38967687d0d8SRobert Mustacchi 	uint32_t ppr_len;
38974a8bbc0bSRobert Mustacchi 	const pcieadm_cfgspace_print_t *ppr_print;
38987687d0d8SRobert Mustacchi } pcieadm_cap_vers_t;
38997687d0d8SRobert Mustacchi 
39007687d0d8SRobert Mustacchi typedef struct pcieadm_subcap {
39017687d0d8SRobert Mustacchi 	const char *psub_short;
39027687d0d8SRobert Mustacchi 	const char *psub_human;
39037687d0d8SRobert Mustacchi } pcieadm_subcap_t;
39047687d0d8SRobert Mustacchi 
39057687d0d8SRobert Mustacchi typedef struct pcieadm_pci_cap pcieadm_pci_cap_t;
39067687d0d8SRobert Mustacchi 
39077687d0d8SRobert Mustacchi typedef void (*pcieadm_cap_info_f)(pcieadm_cfgspace_walk_t *,
39087687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *, uint32_t, const pcieadm_cap_vers_t **,
39097687d0d8SRobert Mustacchi     uint32_t *, const pcieadm_subcap_t **);
39107687d0d8SRobert Mustacchi 
39117687d0d8SRobert Mustacchi struct pcieadm_pci_cap {
39127687d0d8SRobert Mustacchi 	uint32_t ppc_id;
39137687d0d8SRobert Mustacchi 	const char *ppc_short;
39147687d0d8SRobert Mustacchi 	const char *ppc_human;
39157687d0d8SRobert Mustacchi 	pcieadm_cap_info_f ppc_info;
39164a8bbc0bSRobert Mustacchi 	const pcieadm_cap_vers_t ppc_vers[4];
39177687d0d8SRobert Mustacchi };
39187687d0d8SRobert Mustacchi 
39197687d0d8SRobert Mustacchi /*
39207687d0d8SRobert Mustacchi  * Capability version determinations.
39217687d0d8SRobert Mustacchi  */
39227687d0d8SRobert Mustacchi 
39237687d0d8SRobert Mustacchi static void
pcieadm_cap_info_fixed(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)39247687d0d8SRobert Mustacchi pcieadm_cap_info_fixed(pcieadm_cfgspace_walk_t *walkp,
39257687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
39267687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
39277687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
39287687d0d8SRobert Mustacchi {
39297687d0d8SRobert Mustacchi 	*versp = &cap->ppc_vers[0];
39307687d0d8SRobert Mustacchi 	*lenp = cap->ppc_vers[0].ppr_len;
39317687d0d8SRobert Mustacchi 	*subcap = NULL;
39327687d0d8SRobert Mustacchi }
39337687d0d8SRobert Mustacchi 
39347687d0d8SRobert Mustacchi static void
pcieadm_cap_info_vers(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)39357687d0d8SRobert Mustacchi pcieadm_cap_info_vers(pcieadm_cfgspace_walk_t *walkp,
39367687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
39377687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
39387687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
39397687d0d8SRobert Mustacchi {
39407687d0d8SRobert Mustacchi 	uint8_t vers;
39417687d0d8SRobert Mustacchi 
39427687d0d8SRobert Mustacchi 	*subcap = NULL;
39437687d0d8SRobert Mustacchi 	vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
39447687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < ARRAY_SIZE(cap->ppc_vers); i++) {
39457687d0d8SRobert Mustacchi 		if (vers == cap->ppc_vers[i].ppr_vers &&
39467687d0d8SRobert Mustacchi 		    cap->ppc_vers[i].ppr_vers != 0) {
39477687d0d8SRobert Mustacchi 			*versp = &cap->ppc_vers[i];
39487687d0d8SRobert Mustacchi 			*lenp = cap->ppc_vers[i].ppr_len;
39497687d0d8SRobert Mustacchi 			return;
39507687d0d8SRobert Mustacchi 		}
39517687d0d8SRobert Mustacchi 	}
39527687d0d8SRobert Mustacchi 
39537687d0d8SRobert Mustacchi 	*versp = NULL;
39547687d0d8SRobert Mustacchi 	*lenp = 0;
39557687d0d8SRobert Mustacchi }
39567687d0d8SRobert Mustacchi 
39577687d0d8SRobert Mustacchi /*
39587687d0d8SRobert Mustacchi  * The PCI Power Management capability uses a 3-bit version ID as opposed to the
39597687d0d8SRobert Mustacchi  * standard 4-bit version.
39607687d0d8SRobert Mustacchi  */
39617687d0d8SRobert Mustacchi static void
pcieadm_cap_info_pcipm(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)39627687d0d8SRobert Mustacchi pcieadm_cap_info_pcipm(pcieadm_cfgspace_walk_t *walkp,
39637687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
39647687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
39657687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
39667687d0d8SRobert Mustacchi {
39677687d0d8SRobert Mustacchi 	uint8_t vers;
39687687d0d8SRobert Mustacchi 
39697687d0d8SRobert Mustacchi 	*subcap = NULL;
39707687d0d8SRobert Mustacchi 	vers = walkp->pcw_data->pcb_u8[off + 2] & 0x7;
39717687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < ARRAY_SIZE(cap->ppc_vers); i++) {
39727687d0d8SRobert Mustacchi 		if (vers == cap->ppc_vers[i].ppr_vers) {
39737687d0d8SRobert Mustacchi 			*versp = &cap->ppc_vers[i];
39747687d0d8SRobert Mustacchi 			*lenp = cap->ppc_vers[i].ppr_len;
39757687d0d8SRobert Mustacchi 			return;
39767687d0d8SRobert Mustacchi 		}
39777687d0d8SRobert Mustacchi 	}
39787687d0d8SRobert Mustacchi 
39797687d0d8SRobert Mustacchi 	*versp = NULL;
39807687d0d8SRobert Mustacchi 	*lenp = 0;
39817687d0d8SRobert Mustacchi }
39827687d0d8SRobert Mustacchi 
39837687d0d8SRobert Mustacchi /*
3984bc729d49SRobert Mustacchi  * The PCIe capability underwent a few changes. In version 1 of the capability,
3985bc729d49SRobert Mustacchi  * devices were not required to implement the entire capability. In particular,
3986bc729d49SRobert Mustacchi  * endpoints did not need to implement anything more than the link status
3987bc729d49SRobert Mustacchi  * register. In the v2 capability, this was changed such that all devices had to
3988bc729d49SRobert Mustacchi  * implement the entire capbility, but otherwise hardcode registers to zero. As
3989bc729d49SRobert Mustacchi  * such we get to play guess the length based on the device type.
3990bc729d49SRobert Mustacchi  */
39914a8bbc0bSRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_dev = {
3992bc729d49SRobert Mustacchi 	1, 0x0c, pcieadm_cap_pcie_v1_dev
3993bc729d49SRobert Mustacchi };
3994bc729d49SRobert Mustacchi 
39954a8bbc0bSRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_link = {
3996bc729d49SRobert Mustacchi 	1, 0x14, pcieadm_cap_pcie_v1_link
3997bc729d49SRobert Mustacchi };
3998bc729d49SRobert Mustacchi 
39994a8bbc0bSRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_slot = {
4000bc729d49SRobert Mustacchi 	1, 0x1c, pcieadm_cap_pcie_v1_slot
4001bc729d49SRobert Mustacchi };
4002bc729d49SRobert Mustacchi 
40034a8bbc0bSRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v1_all = {
4004bc729d49SRobert Mustacchi 	1, 0x24, pcieadm_cap_pcie_v1_all
4005bc729d49SRobert Mustacchi };
4006bc729d49SRobert Mustacchi 
40074a8bbc0bSRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_pcie_v2 = {
4008bc729d49SRobert Mustacchi 	2, 0x4c, pcieadm_cap_pcie_v2
4009bc729d49SRobert Mustacchi };
4010bc729d49SRobert Mustacchi 
4011bc729d49SRobert Mustacchi static void
pcieadm_cap_info_pcie(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)4012bc729d49SRobert Mustacchi pcieadm_cap_info_pcie(pcieadm_cfgspace_walk_t *walkp,
4013bc729d49SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
4014bc729d49SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
4015bc729d49SRobert Mustacchi     const pcieadm_subcap_t **subcap)
4016bc729d49SRobert Mustacchi {
4017bc729d49SRobert Mustacchi 	uint8_t vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
4018bc729d49SRobert Mustacchi 	uint16_t pcie = walkp->pcw_data->pcb_u8[off + 2] |
4019bc729d49SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[off + 3] << 8);
4020bc729d49SRobert Mustacchi 
4021bc729d49SRobert Mustacchi 	/*
4022bc729d49SRobert Mustacchi 	 * Version 2 is simple. There's only one thing to do, so we do it. For
4023bc729d49SRobert Mustacchi 	 * version 1 we need to look at the device type.
4024bc729d49SRobert Mustacchi 	 */
4025bc729d49SRobert Mustacchi 	*subcap = NULL;
4026bc729d49SRobert Mustacchi 	if (vers == 2) {
4027bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v2;
4028bc729d49SRobert Mustacchi 		*lenp = (*versp)->ppr_len;
4029bc729d49SRobert Mustacchi 		return;
4030bc729d49SRobert Mustacchi 	} else if (vers != 1) {
4031bc729d49SRobert Mustacchi 		*versp = NULL;
4032bc729d49SRobert Mustacchi 		*lenp = 0;
4033bc729d49SRobert Mustacchi 		return;
4034bc729d49SRobert Mustacchi 	}
4035bc729d49SRobert Mustacchi 
4036bc729d49SRobert Mustacchi 	switch (pcie & PCIE_PCIECAP_DEV_TYPE_MASK) {
4037bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCIE_DEV:
4038bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCI_DEV:
4039bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v1_link;
4040bc729d49SRobert Mustacchi 		break;
4041bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_RC_IEP:
4042bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v1_dev;
4043bc729d49SRobert Mustacchi 		break;
4044bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_UP:
4045bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_DOWN:
4046bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCIE2PCI:
4047bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_PCI2PCIE:
4048bc729d49SRobert Mustacchi 		if ((pcie & PCIE_PCIECAP_SLOT_IMPL) != 0) {
4049bc729d49SRobert Mustacchi 			*versp = &pcieadm_cap_vers_pcie_v1_slot;
4050bc729d49SRobert Mustacchi 		} else {
4051bc729d49SRobert Mustacchi 			*versp = &pcieadm_cap_vers_pcie_v1_link;
4052bc729d49SRobert Mustacchi 		}
4053bc729d49SRobert Mustacchi 		break;
4054bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_ROOT:
4055bc729d49SRobert Mustacchi 	case PCIE_PCIECAP_DEV_TYPE_RC_EC:
4056bc729d49SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcie_v1_all;
4057bc729d49SRobert Mustacchi 		break;
4058bc729d49SRobert Mustacchi 	default:
4059bc729d49SRobert Mustacchi 		*versp = NULL;
4060bc729d49SRobert Mustacchi 		*lenp = 0;
4061bc729d49SRobert Mustacchi 		return;
4062bc729d49SRobert Mustacchi 	}
4063bc729d49SRobert Mustacchi 
4064bc729d49SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
4065bc729d49SRobert Mustacchi }
4066bc729d49SRobert Mustacchi 
4067bc729d49SRobert Mustacchi /*
40687687d0d8SRobert Mustacchi  * The length of the MSI capability depends on bits in its control field. As
40697687d0d8SRobert Mustacchi  * such we use a custom function to extract the length and treat each of these
40707687d0d8SRobert Mustacchi  * variants as thought it were a different version.
40717687d0d8SRobert Mustacchi  */
40727687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32 = {
40737687d0d8SRobert Mustacchi 	0, 0xa, pcieadm_cap_msi_32
40747687d0d8SRobert Mustacchi };
40757687d0d8SRobert Mustacchi 
40767687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32ext = {
40777687d0d8SRobert Mustacchi 	0, 0xc, pcieadm_cap_msi_32ext
40787687d0d8SRobert Mustacchi };
40797687d0d8SRobert Mustacchi 
40807687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64 = {
40817687d0d8SRobert Mustacchi 	0, 0xe, pcieadm_cap_msi_64
40827687d0d8SRobert Mustacchi };
40837687d0d8SRobert Mustacchi 
40847687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64ext = {
40857687d0d8SRobert Mustacchi 	0, 0x10, pcieadm_cap_msi_64ext
40867687d0d8SRobert Mustacchi };
40877687d0d8SRobert Mustacchi 
40887687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_32pvm = {
40897687d0d8SRobert Mustacchi 	0, 0x14, pcieadm_cap_msi_32pvm
40907687d0d8SRobert Mustacchi };
40917687d0d8SRobert Mustacchi 
40927687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_msi_64pvm = {
40937687d0d8SRobert Mustacchi 	0, 0x18, pcieadm_cap_msi_64pvm
40947687d0d8SRobert Mustacchi };
40957687d0d8SRobert Mustacchi 
40967687d0d8SRobert Mustacchi static void
pcieadm_cap_info_msi(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)40977687d0d8SRobert Mustacchi pcieadm_cap_info_msi(pcieadm_cfgspace_walk_t *walkp,
40987687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
40997687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
41007687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
41017687d0d8SRobert Mustacchi {
41027687d0d8SRobert Mustacchi 	uint16_t ctrl;
41037687d0d8SRobert Mustacchi 	boolean_t addr64, pvm, ext;
41047687d0d8SRobert Mustacchi 
41057687d0d8SRobert Mustacchi 	*subcap = NULL;
41067687d0d8SRobert Mustacchi 	ctrl = walkp->pcw_data->pcb_u8[off + 2] |
41077687d0d8SRobert Mustacchi 	    (walkp->pcw_data->pcb_u8[off + 3] << 8);
41087687d0d8SRobert Mustacchi 	if (ctrl == PCI_EINVAL16) {
41097687d0d8SRobert Mustacchi 		warnx("failed to read MSI Message Control register");
41107687d0d8SRobert Mustacchi 		*lenp = 0;
41117687d0d8SRobert Mustacchi 		*versp = NULL;
41127687d0d8SRobert Mustacchi 		return;
41137687d0d8SRobert Mustacchi 	}
41147687d0d8SRobert Mustacchi 
41157687d0d8SRobert Mustacchi 	/*
41167687d0d8SRobert Mustacchi 	 * The MSI capability has three main things that control its size.
41177687d0d8SRobert Mustacchi 	 * 64-bit addressing adds 4 bytes. Per-Vector Masking adds 8 bytes and
41187687d0d8SRobert Mustacchi 	 * causes the Extended data addressing piece to always be present.
41197687d0d8SRobert Mustacchi 	 * Therefore we check first for pvm as it implies evt, effectively.
41207687d0d8SRobert Mustacchi 	 */
41217687d0d8SRobert Mustacchi 	addr64 = (ctrl & PCI_MSI_64BIT_MASK) != 0;
41227687d0d8SRobert Mustacchi 	pvm = (ctrl & PCI_MSI_PVM_MASK) != 0;
41237687d0d8SRobert Mustacchi 	ext = (ctrl & PCI_MSI_EMD_MASK) != 0;
41247687d0d8SRobert Mustacchi 
41257687d0d8SRobert Mustacchi 	if (pvm && addr64) {
41267687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64pvm;
41277687d0d8SRobert Mustacchi 	} else if (pvm) {
41287687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32pvm;
41297687d0d8SRobert Mustacchi 	} else if (addr64 && ext) {
41307687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64ext;
41317687d0d8SRobert Mustacchi 	} else if (addr64) {
41327687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_64;
41337687d0d8SRobert Mustacchi 	} else if (ext) {
41347687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32ext;
41357687d0d8SRobert Mustacchi 	} else {
41367687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_msi_32;
41377687d0d8SRobert Mustacchi 	}
41387687d0d8SRobert Mustacchi 
41397687d0d8SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
41407687d0d8SRobert Mustacchi }
41417687d0d8SRobert Mustacchi 
41427687d0d8SRobert Mustacchi /*
41437687d0d8SRobert Mustacchi  * The AER Capability is technically different for PCIe-PCI bridges. If we find
41447687d0d8SRobert Mustacchi  * that device type here, then we need to use a different version information
41457687d0d8SRobert Mustacchi  * rather than the actual set defined with the device (which have changed over
41467687d0d8SRobert Mustacchi  * time).
41477687d0d8SRobert Mustacchi  */
41487687d0d8SRobert Mustacchi static const pcieadm_cap_vers_t pcieadm_cap_vers_aer_bridge = {
41497687d0d8SRobert Mustacchi 	1, 0x4c, pcieadm_cap_aer_bridge
41507687d0d8SRobert Mustacchi };
41517687d0d8SRobert Mustacchi 
41527687d0d8SRobert Mustacchi static void
pcieadm_cap_info_aer(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)41537687d0d8SRobert Mustacchi pcieadm_cap_info_aer(pcieadm_cfgspace_walk_t *walkp,
41547687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
41557687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
41567687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
41577687d0d8SRobert Mustacchi {
4158bc729d49SRobert Mustacchi 	if (walkp->pcw_pcietype == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
41597687d0d8SRobert Mustacchi 		uint8_t vers;
41607687d0d8SRobert Mustacchi 
41617687d0d8SRobert Mustacchi 		*subcap = NULL;
41627687d0d8SRobert Mustacchi 		vers = walkp->pcw_data->pcb_u8[off + 2] & 0xf;
41637687d0d8SRobert Mustacchi 		if (vers != pcieadm_cap_vers_aer_bridge.ppr_vers) {
41647687d0d8SRobert Mustacchi 			warnx("encountered PCIe to PCI bridge with unknown "
41657687d0d8SRobert Mustacchi 			    "AER capability version: %u", vers);
41667687d0d8SRobert Mustacchi 			*lenp = 0;
41677687d0d8SRobert Mustacchi 			*versp = NULL;
41687687d0d8SRobert Mustacchi 			return;
41697687d0d8SRobert Mustacchi 		}
41707687d0d8SRobert Mustacchi 		*lenp = pcieadm_cap_vers_aer_bridge.ppr_len;
41717687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_aer_bridge;
41727687d0d8SRobert Mustacchi 	}
41737687d0d8SRobert Mustacchi 
41747687d0d8SRobert Mustacchi 	return (pcieadm_cap_info_vers(walkp, cap, off, versp, lenp, subcap));
41757687d0d8SRobert Mustacchi }
41767687d0d8SRobert Mustacchi 
41777687d0d8SRobert Mustacchi /*
41787687d0d8SRobert Mustacchi  * The PCI-X capability varies depending on the header type of the device.
41797687d0d8SRobert Mustacchi  * Therefore we simply use the device type to figure out what to do.
41807687d0d8SRobert Mustacchi  */
41817687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcix_dev = {
41827687d0d8SRobert Mustacchi 	0, 0x8, pcieadm_cap_pcix_dev
41837687d0d8SRobert Mustacchi };
41847687d0d8SRobert Mustacchi 
41857687d0d8SRobert Mustacchi static pcieadm_cap_vers_t pcieadm_cap_vers_pcix_bridge = {
41867687d0d8SRobert Mustacchi 	0, 0x10, pcieadm_cap_pcix_bridge
41877687d0d8SRobert Mustacchi };
41887687d0d8SRobert Mustacchi 
41897687d0d8SRobert Mustacchi static void
pcieadm_cap_info_pcix(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)41907687d0d8SRobert Mustacchi pcieadm_cap_info_pcix(pcieadm_cfgspace_walk_t *walkp,
41917687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
41927687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
41937687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
41947687d0d8SRobert Mustacchi {
41957687d0d8SRobert Mustacchi 
41967687d0d8SRobert Mustacchi 	*subcap = NULL;
41977687d0d8SRobert Mustacchi 	switch (walkp->pcw_dtype) {
41987687d0d8SRobert Mustacchi 	case PCI_HEADER_ZERO:
41997687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcix_dev;
42007687d0d8SRobert Mustacchi 		break;
42017687d0d8SRobert Mustacchi 	case PCI_HEADER_ONE:
42027687d0d8SRobert Mustacchi 		*versp = &pcieadm_cap_vers_pcix_bridge;
42037687d0d8SRobert Mustacchi 		break;
42047687d0d8SRobert Mustacchi 	default:
42057687d0d8SRobert Mustacchi 		warnx("encountered PCI-X capability with unsupported device "
42067687d0d8SRobert Mustacchi 		    "type: 0x%x\n", walkp->pcw_dtype);
42077687d0d8SRobert Mustacchi 		*lenp = 0;
42087687d0d8SRobert Mustacchi 		*versp = NULL;
42097687d0d8SRobert Mustacchi 		return;
42107687d0d8SRobert Mustacchi 	}
42117687d0d8SRobert Mustacchi 
42127687d0d8SRobert Mustacchi 	*lenp = (*versp)->ppr_len;
42137687d0d8SRobert Mustacchi }
42147687d0d8SRobert Mustacchi 
42157687d0d8SRobert Mustacchi typedef struct pcieadm_cap_ht {
42167687d0d8SRobert Mustacchi 	uint32_t pch_capid;
42177687d0d8SRobert Mustacchi 	pcieadm_subcap_t pch_subcap;
42187687d0d8SRobert Mustacchi 	pcieadm_cap_vers_t pch_vers;
42197687d0d8SRobert Mustacchi } pcieadm_cap_ht_t;
42207687d0d8SRobert Mustacchi 
42217687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_cap_pri = {
42227687d0d8SRobert Mustacchi 	0x00, { "pri", "Primary" }, { 0, 0x1c, pcieadm_cap_ht_pri }
42237687d0d8SRobert Mustacchi };
42247687d0d8SRobert Mustacchi 
42257687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_cap_sec = {
42267687d0d8SRobert Mustacchi 	0x01, { "sec", "Secondary" }, { 0, 0x18, pcieadm_cap_ht_sec }
42277687d0d8SRobert Mustacchi };
42287687d0d8SRobert Mustacchi 
42297687d0d8SRobert Mustacchi static pcieadm_cap_ht_t pcieadm_ht_caps[] = {
42307687d0d8SRobert Mustacchi 	{ 0x08, { "switch", "Switch" } },
42317687d0d8SRobert Mustacchi 	{ 0x10, { "intr", "Interrupt Discovery and Configuration" },
42327687d0d8SRobert Mustacchi 	    { 0, 8, pcieadm_cap_ht_intr } },
42337687d0d8SRobert Mustacchi 	{ 0x11, { "rev", "Revision ID" } },
42347687d0d8SRobert Mustacchi 	{ 0x12, { "unitid", "UnitID Clumping" } },
42357687d0d8SRobert Mustacchi 	{ 0x13, { "extcfg", "Extended Configuration Space Access" } },
42367687d0d8SRobert Mustacchi 	{ 0x14, { "addrmap", "Address Mapping" } },
42377687d0d8SRobert Mustacchi 	{ 0x15, { "msi", "MSI Mapping" },
42387687d0d8SRobert Mustacchi 	    { 0, 4, pcieadm_cap_ht_msi } },
42397687d0d8SRobert Mustacchi 	{ 0x16, { "dir", "DirectRoute" } },
42407687d0d8SRobert Mustacchi 	{ 0x17, { "vcset", "VCSet" } },
42417687d0d8SRobert Mustacchi 	{ 0x18, { "retry", "Retry Mode" } },
42427687d0d8SRobert Mustacchi 	{ 0x19, { "x86", "X86 Encoding" } },
42437687d0d8SRobert Mustacchi 	{ 0x1a, { "gen3", "Gen3" } },
42447687d0d8SRobert Mustacchi 	{ 0x1b, { "fle", "Function-Level Extension" } },
42457687d0d8SRobert Mustacchi 	{ 0x1c, { "pm", "Power Management" } },
42467687d0d8SRobert Mustacchi 	{ UINT32_MAX, NULL },
42477687d0d8SRobert Mustacchi };
42487687d0d8SRobert Mustacchi 
42497687d0d8SRobert Mustacchi static void
pcieadm_cap_info_ht(pcieadm_cfgspace_walk_t * walkp,const pcieadm_pci_cap_t * cap,uint32_t off,const pcieadm_cap_vers_t ** versp,uint32_t * lenp,const pcieadm_subcap_t ** subcap)42507687d0d8SRobert Mustacchi pcieadm_cap_info_ht(pcieadm_cfgspace_walk_t *walkp,
42517687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap, uint32_t off,
42527687d0d8SRobert Mustacchi     const pcieadm_cap_vers_t **versp, uint32_t *lenp,
42537687d0d8SRobert Mustacchi     const pcieadm_subcap_t **subcap)
42547687d0d8SRobert Mustacchi {
42557687d0d8SRobert Mustacchi 	uint32_t base = walkp->pcw_data->pcb_u32[off / 4];
42564a8bbc0bSRobert Mustacchi 	uint32_t caplo = bitx32(base, 31, 29);
42577687d0d8SRobert Mustacchi 	pcieadm_cap_ht_t *htcap = NULL;
42587687d0d8SRobert Mustacchi 
42597687d0d8SRobert Mustacchi 	*versp = NULL;
42607687d0d8SRobert Mustacchi 	*lenp = 0;
42617687d0d8SRobert Mustacchi 	*subcap = NULL;
42627687d0d8SRobert Mustacchi 
42637687d0d8SRobert Mustacchi 	if (caplo > 1) {
42644a8bbc0bSRobert Mustacchi 		uint32_t capid = bitx32(base, 31, 27);
42657687d0d8SRobert Mustacchi 
42667687d0d8SRobert Mustacchi 		for (uint32_t i = 0; pcieadm_ht_caps[i].pch_capid != UINT32_MAX;
42677687d0d8SRobert Mustacchi 		    i++) {
42687687d0d8SRobert Mustacchi 			if (capid == pcieadm_ht_caps[i].pch_capid) {
42697687d0d8SRobert Mustacchi 				htcap = &pcieadm_ht_caps[i];
42707687d0d8SRobert Mustacchi 				break;
42717687d0d8SRobert Mustacchi 			}
42727687d0d8SRobert Mustacchi 		}
42737687d0d8SRobert Mustacchi 	} else if (caplo == 0) {
42747687d0d8SRobert Mustacchi 		htcap = &pcieadm_ht_cap_pri;
42757687d0d8SRobert Mustacchi 	} else if (caplo == 1) {
42767687d0d8SRobert Mustacchi 		htcap = &pcieadm_ht_cap_sec;
42777687d0d8SRobert Mustacchi 	}
42787687d0d8SRobert Mustacchi 
42797687d0d8SRobert Mustacchi 	if (htcap == NULL) {
42807687d0d8SRobert Mustacchi 		warnx("encountered unknown HyperTransport Capability 0x%x",
42814a8bbc0bSRobert Mustacchi 		    bitx32(base, 31, 27));
42827687d0d8SRobert Mustacchi 		return;
42837687d0d8SRobert Mustacchi 	}
42847687d0d8SRobert Mustacchi 
42857687d0d8SRobert Mustacchi 	*subcap = &htcap->pch_subcap;
42867687d0d8SRobert Mustacchi 	if (htcap->pch_vers.ppr_print != NULL) {
42877687d0d8SRobert Mustacchi 		*versp = &htcap->pch_vers;
42887687d0d8SRobert Mustacchi 		*lenp = htcap->pch_vers.ppr_len;
42897687d0d8SRobert Mustacchi 	}
42907687d0d8SRobert Mustacchi }
42917687d0d8SRobert Mustacchi 
42924dde95daSRobert Mustacchi /*
42934dde95daSRobert Mustacchi  * Root Complex Link Declaration
42944dde95daSRobert Mustacchi  */
42954a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_rcld_desc[] = {
42964dde95daSRobert Mustacchi 	{ 0, 3, "type", "Element Type", PRDV_STRVAL,
42974dde95daSRobert Mustacchi 	    .prd_val = { .prdv_strval = { "Configuration Space Element",
42984dde95daSRobert Mustacchi 	    "System Egress Port or internal sink",
42994dde95daSRobert Mustacchi 	    "Internal Root Complex Link" } } },
43004dde95daSRobert Mustacchi 	{ 8, 15, "num", "Number of Entries", PRDV_HEX },
43014dde95daSRobert Mustacchi 	{ 16, 23, "id", "Component ID", PRDV_HEX },
43024dde95daSRobert Mustacchi 	{ 24, 31, "port", "Port Number", PRDV_HEX },
43034dde95daSRobert Mustacchi 	{ -1, -1, NULL }
43044dde95daSRobert Mustacchi };
43054dde95daSRobert Mustacchi 
43064a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_rcld_link[] = {
43074dde95daSRobert Mustacchi 	{ 0, 0, "valid", "Link Valid", PRDV_STRVAL,
43084dde95daSRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
43094dde95daSRobert Mustacchi 	{ 1, 1, "type", "Link Type", PRDV_STRVAL,
43104dde95daSRobert Mustacchi 	    .prd_val = { .prdv_strval = { "RCRB", "Configuration Space" } } },
43114dde95daSRobert Mustacchi 	{ 2, 2, "rcrb", "Assosciate RCRB", PRDV_STRVAL,
43124dde95daSRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
43134dde95daSRobert Mustacchi 	{ 16, 23, "tid", "Target Component ID", PRDV_HEX },
43144dde95daSRobert Mustacchi 	{ 24, 31, "tport", "Target Port Number", PRDV_HEX },
43154dde95daSRobert Mustacchi 	{ -1, -1, NULL }
43164dde95daSRobert Mustacchi };
43174dde95daSRobert Mustacchi 
43184dde95daSRobert Mustacchi /*
43194dde95daSRobert Mustacchi  * Print a variable number of Root Complex Links.
43204dde95daSRobert Mustacchi  */
43214dde95daSRobert Mustacchi static void
pcieadm_cfgspace_print_rcld(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)43224dde95daSRobert Mustacchi pcieadm_cfgspace_print_rcld(pcieadm_cfgspace_walk_t *walkp,
43234a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
43244dde95daSRobert Mustacchi {
43254dde95daSRobert Mustacchi 	uint_t nlinks = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 5];
43264dde95daSRobert Mustacchi 
43274dde95daSRobert Mustacchi 	for (uint_t i = 0; i < nlinks; i++) {
43284dde95daSRobert Mustacchi 		char mshort[32], mhuman[128];
43294dde95daSRobert Mustacchi 		pcieadm_cfgspace_print_t p;
43304dde95daSRobert Mustacchi 		uint16_t off = print->pcp_off + i * 0x10;
43314dde95daSRobert Mustacchi 		uint8_t type = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + off];
43324dde95daSRobert Mustacchi 
43334dde95daSRobert Mustacchi 		(void) snprintf(mshort, sizeof (mshort), "link%udesc", i);
43344dde95daSRobert Mustacchi 		(void) snprintf(mhuman, sizeof (mhuman), "Link %u Description");
43354dde95daSRobert Mustacchi 
43364dde95daSRobert Mustacchi 		p.pcp_off = off;
43374dde95daSRobert Mustacchi 		p.pcp_len = 4;
43384dde95daSRobert Mustacchi 		p.pcp_short = mshort;
43394dde95daSRobert Mustacchi 		p.pcp_human = mhuman;
43404dde95daSRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
43414dde95daSRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_rcld_link;
43424dde95daSRobert Mustacchi 
43434dde95daSRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
43444dde95daSRobert Mustacchi 
43454dde95daSRobert Mustacchi 		/*
43464dde95daSRobert Mustacchi 		 * The way that we print the link depends on the actual type of
43474dde95daSRobert Mustacchi 		 * link which is in bit 2 of the link description.
43484dde95daSRobert Mustacchi 		 */
43494dde95daSRobert Mustacchi 		p.pcp_off += 8;
43504dde95daSRobert Mustacchi 
43514dde95daSRobert Mustacchi 		if ((type & (1 << 1)) == 0) {
43524dde95daSRobert Mustacchi 			(void) snprintf(mshort, sizeof (mshort),
43534dde95daSRobert Mustacchi 			    "link%uaddr", i);
43544dde95daSRobert Mustacchi 			(void) snprintf(mhuman, sizeof (mhuman),
43554dde95daSRobert Mustacchi 			    "Link %u Address");
43564dde95daSRobert Mustacchi 			p.pcp_len = 8;
43574dde95daSRobert Mustacchi 			p.pcp_print = pcieadm_cfgspace_print_hex;
43584dde95daSRobert Mustacchi 			p.pcp_arg = NULL;
43594dde95daSRobert Mustacchi 
43604dde95daSRobert Mustacchi 			p.pcp_print(walkp, &p, p.pcp_arg);
43614dde95daSRobert Mustacchi 		} else {
43624dde95daSRobert Mustacchi 			warnx("encountered unsupported RCLD Link Address");
43634dde95daSRobert Mustacchi 		}
43644dde95daSRobert Mustacchi 	}
43654dde95daSRobert Mustacchi }
43664dde95daSRobert Mustacchi 
43674a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_rcld[] = {
43684dde95daSRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
43694dde95daSRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
43704dde95daSRobert Mustacchi 	{ 0x4, 4, "desc", "Self Description",
43714dde95daSRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_rcld_desc },
43724dde95daSRobert Mustacchi 	{ 0x10, 0x10, "link", "Link Entry", pcieadm_cfgspace_print_rcld },
43734dde95daSRobert Mustacchi 	{ -1, -1, NULL }
43744dde95daSRobert Mustacchi };
43754dde95daSRobert Mustacchi 
43764dde95daSRobert Mustacchi 
4377c3e0a189SRobert Mustacchi /*
4378c3e0a189SRobert Mustacchi  * Physical Layer 32.0 GT/s Capability
4379c3e0a189SRobert Mustacchi  */
43804a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_cap[] = {
4381c3e0a189SRobert Mustacchi 	{ 0, 0, "eqbyp", "Equalization Bypass to Highest Rate", PRDV_STRVAL,
4382c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4383c3e0a189SRobert Mustacchi 	{ 1, 1, "noeq", "No Equalization Needed", PRDV_STRVAL,
4384c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4385c3e0a189SRobert Mustacchi 	{ 8, 8, "mts0", "Modified TS Usage Mode 0 - PCI Express", PRDV_STRVAL,
4386c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4387c3e0a189SRobert Mustacchi 	{ 9, 9, "mts1", "Modified TS Usage Mode 1 - Training Set", PRDV_STRVAL,
4388c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4389c3e0a189SRobert Mustacchi 	{ 10, 10, "mts2", "Modified TS Usage Mode 2 - Alternate Protocol",
4390c3e0a189SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "unsupported",
4391c3e0a189SRobert Mustacchi 	    "supported" } } },
4392c3e0a189SRobert Mustacchi 	/*
4393c3e0a189SRobert Mustacchi 	 * Bits 11 to 15 are defined as reserved for future use here as
4394c3e0a189SRobert Mustacchi 	 * read-only bits. Add them here once they have actual definitions.
4395c3e0a189SRobert Mustacchi 	 */
4396c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4397c3e0a189SRobert Mustacchi };
4398c3e0a189SRobert Mustacchi 
43994a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_ctl[] = {
4400c3e0a189SRobert Mustacchi 	{ 0, 0, "eqbyp", "Equalization Bypass to Highest Rate", PRDV_STRVAL,
4401c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
4402c3e0a189SRobert Mustacchi 	{ 1, 1, "noeq", "No Equalization Needed", PRDV_STRVAL,
4403c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "enabled", "disabled" } } },
4404c3e0a189SRobert Mustacchi 	{ 8, 10, "mts", "Modified TS Usage Mode Selected", PRDV_STRVAL,
4405c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PCIe", "training set messages",
4406c3e0a189SRobert Mustacchi 	    "alternate protocol negotiation" } } },
4407c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4408c3e0a189SRobert Mustacchi };
4409c3e0a189SRobert Mustacchi 
44104a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_sts[] = {
4411c3e0a189SRobert Mustacchi 	{ 0, 0, "eqcomp", "Equalization 32.0 GT/s Complete", PRDV_STRVAL,
4412c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
4413c3e0a189SRobert Mustacchi 	{ 1, 1, "eqp1", "Equalization 32.0 GT/s Phase 1", PRDV_STRVAL,
4414c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
4415c3e0a189SRobert Mustacchi 	{ 2, 2, "eqp2", "Equalization 32.0 GT/s Phase 2", PRDV_STRVAL,
4416c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
4417c3e0a189SRobert Mustacchi 	{ 3, 3, "eqp3", "Equalization 32.0 GT/s Phase 3", PRDV_STRVAL,
4418c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "incomplete", "complete" } } },
4419c3e0a189SRobert Mustacchi 	{ 4, 4, "req", "Link Equalization Request 32.0 GT/s", PRDV_HEX },
4420c3e0a189SRobert Mustacchi 	{ 5, 5, "mts", "Modified TS Received", PRDV_STRVAL,
4421c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
4422c3e0a189SRobert Mustacchi 	{ 6, 7, "rxelbc", "Received Enhanced Link Behavior Control",
4423c3e0a189SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = {
4424c3e0a189SRobert Mustacchi 	    "full equalization required", "equalization bypass to highest rate",
4425c3e0a189SRobert Mustacchi 	    "no equalization needed", "modified TS1/TS2 ordered sets" } } },
4426c3e0a189SRobert Mustacchi 	{ 8, 8, "txpre", "Transmitter Precoding", PRDV_STRVAL,
4427c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4428c3e0a189SRobert Mustacchi 	{ 9, 9, "prereq", "Transmitter Precoding Request", PRDV_STRVAL,
4429c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4430c3e0a189SRobert Mustacchi 	{ 10, 10, "noeqrx", "No Equalization Needed Received", PRDV_STRVAL,
4431c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
4432c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4433c3e0a189SRobert Mustacchi };
4434c3e0a189SRobert Mustacchi 
44354a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_rxts1[] = {
4436c3e0a189SRobert Mustacchi 	{ 0, 2, "mts", "Modified TS Usage Mode Selected", PRDV_STRVAL,
4437c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PCIe", "training set messages",
4438c3e0a189SRobert Mustacchi 	    "alternate protocol negotiation" } } },
4439c3e0a189SRobert Mustacchi 	{ 3, 15, "info", "Received Modified TS Information 1", PRDV_HEX },
4440c3e0a189SRobert Mustacchi 	{ 16, 31, "vendor", "Received Modified TS Vendor ID", PRDV_HEX },
4441c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4442c3e0a189SRobert Mustacchi };
4443c3e0a189SRobert Mustacchi 
44444a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_rxts2[] = {
4445c3e0a189SRobert Mustacchi 	{ 0, 23, "info", "Received Modified TS Information 2", PRDV_HEX },
4446c3e0a189SRobert Mustacchi 	{ 24, 25, "apnsts", "Alternate Protocol Negotiation Status",
4447c3e0a189SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "not supported",
4448c3e0a189SRobert Mustacchi 	    "disabled", "failed", "succeeded" } } },
4449c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4450c3e0a189SRobert Mustacchi };
4451c3e0a189SRobert Mustacchi 
44524a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_txts1[] = {
4453c3e0a189SRobert Mustacchi 	{ 0, 2, "mts", "Transmitted Modified TS Usage Mode", PRDV_STRVAL,
4454c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "PCIe", "training set messages",
4455c3e0a189SRobert Mustacchi 	    "alternate protocol negotiation" } } },
4456c3e0a189SRobert Mustacchi 	{ 3, 15, "info", "Transmitted Modified TS Information 1", PRDV_HEX },
4457c3e0a189SRobert Mustacchi 	{ 16, 31, "vendor", "Transmitted Modified TS Vendor ID", PRDV_HEX },
4458c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4459c3e0a189SRobert Mustacchi };
4460c3e0a189SRobert Mustacchi 
44614a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_txts2[] = {
4462c3e0a189SRobert Mustacchi 	{ 0, 23, "info", "Transmitted Modified TS Information 2", PRDV_HEX },
4463c3e0a189SRobert Mustacchi 	{ 24, 25, "apnsts", "Alternate Protocol Negotiation Status",
4464c3e0a189SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "not supported",
4465c3e0a189SRobert Mustacchi 	    "disabled", "failed", "succeeded" } } },
4466c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4467c3e0a189SRobert Mustacchi };
4468c3e0a189SRobert Mustacchi 
44694a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_32g_eq[] = {
4470c3e0a189SRobert Mustacchi 	{ 0, 3, "dstxpre", "Downstream Port 32.0 GT/s Transmitter Preset",
4471c3e0a189SRobert Mustacchi 	    PRDV_HEX },
4472c3e0a189SRobert Mustacchi 	{ 4, 7, "ustxpre", "Upstream Port 32.0 GT/s Transmitter Preset",
4473c3e0a189SRobert Mustacchi 	    PRDV_HEX },
4474c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4475c3e0a189SRobert Mustacchi };
4476c3e0a189SRobert Mustacchi 
4477c3e0a189SRobert Mustacchi static void
pcieadm_cfgspace_print_32geq(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)4478c3e0a189SRobert Mustacchi pcieadm_cfgspace_print_32geq(pcieadm_cfgspace_walk_t *walkp,
44794a8bbc0bSRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
4480c3e0a189SRobert Mustacchi {
4481c3e0a189SRobert Mustacchi 	if (walkp->pcw_nlanes == 0) {
4482c3e0a189SRobert Mustacchi 		warnx("failed to capture lane count, but somehow have "
4483c3e0a189SRobert Mustacchi 		    "Physical Layer 32.0 GT/s cap");
4484c3e0a189SRobert Mustacchi 		return;
4485c3e0a189SRobert Mustacchi 	}
4486c3e0a189SRobert Mustacchi 
4487c3e0a189SRobert Mustacchi 	for (uint_t i = 0; i < walkp->pcw_nlanes; i++) {
4488c3e0a189SRobert Mustacchi 		char eqshort[32], eqhuman[128];
4489c3e0a189SRobert Mustacchi 		pcieadm_cfgspace_print_t p;
4490c3e0a189SRobert Mustacchi 
4491c3e0a189SRobert Mustacchi 		(void) snprintf(eqshort, sizeof (eqshort), "lane%u", i);
4492c3e0a189SRobert Mustacchi 		(void) snprintf(eqhuman, sizeof (eqhuman), "Lane %u EQ Control",
4493c3e0a189SRobert Mustacchi 		    i);
4494c3e0a189SRobert Mustacchi 		p.pcp_off = print->pcp_off + i * 1;
4495c3e0a189SRobert Mustacchi 		p.pcp_len = 1;
4496c3e0a189SRobert Mustacchi 		p.pcp_short = eqshort;
4497c3e0a189SRobert Mustacchi 		p.pcp_human = eqhuman;
4498c3e0a189SRobert Mustacchi 		p.pcp_print = pcieadm_cfgspace_print_regdef;
4499c3e0a189SRobert Mustacchi 		p.pcp_arg = pcieadm_regdef_32g_eq;
4500c3e0a189SRobert Mustacchi 
4501c3e0a189SRobert Mustacchi 		p.pcp_print(walkp, &p, p.pcp_arg);
4502c3e0a189SRobert Mustacchi 	}
4503c3e0a189SRobert Mustacchi }
4504c3e0a189SRobert Mustacchi 
45054a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_32g[] = {
4506c3e0a189SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
4507c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
4508c3e0a189SRobert Mustacchi 	{ 0x4, 4, "cap", "32.0 GT/s Capabilities",
4509c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_32g_cap },
4510c3e0a189SRobert Mustacchi 	{ 0x8, 4, "ctl", "32.0 GT/s Control",
4511c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_32g_ctl },
4512c3e0a189SRobert Mustacchi 	{ 0xc, 4, "sts", "32.0 GT/s Status",
4513c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_32g_sts },
4514c3e0a189SRobert Mustacchi 	{ 0x10, 4, "rxts1", "Received Modified TS Data 1",
4515c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_32g_rxts1 },
4516c3e0a189SRobert Mustacchi 	{ 0x14, 4, "rxts2", "Received Modified TS Data 2",
4517c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_32g_rxts2 },
4518c3e0a189SRobert Mustacchi 	{ 0x18, 4, "txts1", "Transmitted Modified TS Data 1",
4519c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_32g_txts1 },
4520c3e0a189SRobert Mustacchi 	{ 0x1c, 4, "txts2", "Transmitted Modified TS Data 2",
4521c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_32g_txts2 },
4522c3e0a189SRobert Mustacchi 	{ 0x20, 1, "eqctl", "32.0 GT/s EQ Control",
4523c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_32geq },
4524c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4525c3e0a189SRobert Mustacchi };
4526c3e0a189SRobert Mustacchi 
4527c3e0a189SRobert Mustacchi /*
4528c3e0a189SRobert Mustacchi  * Native PCIe Enclosure Management
4529c3e0a189SRobert Mustacchi  */
45304a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_npem_cap[] = {
4531c3e0a189SRobert Mustacchi 	{ 0, 0, "npem", "NPEM", PRDV_STRVAL,
4532c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4533c3e0a189SRobert Mustacchi 	{ 1, 1, "reset", "NPEM Reset", PRDV_STRVAL,
4534c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4535c3e0a189SRobert Mustacchi 	{ 2, 2, "ok", "NPEM OK", PRDV_STRVAL,
4536c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4537c3e0a189SRobert Mustacchi 	{ 3, 3, "loc", "NPEM Locate", PRDV_STRVAL,
4538c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4539c3e0a189SRobert Mustacchi 	{ 4, 4, "fail", "NPEM Fail", PRDV_STRVAL,
4540c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4541c3e0a189SRobert Mustacchi 	{ 5, 5, "rb", "NPEM Rebuild", PRDV_STRVAL,
4542c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4543c3e0a189SRobert Mustacchi 	{ 6, 6, "pfa", "NPEM PFA", PRDV_STRVAL,
4544c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4545c3e0a189SRobert Mustacchi 	{ 7, 7, "hs", "NPEM Hot Spare", PRDV_STRVAL,
4546c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4547c3e0a189SRobert Mustacchi 	{ 8, 8, "crit", "NPEM In a Critical Array", PRDV_STRVAL,
4548c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4549c3e0a189SRobert Mustacchi 	{ 9, 9, "fail", "NPEM In a Failed Array", PRDV_STRVAL,
4550c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4551c3e0a189SRobert Mustacchi 	{ 10, 10, "invdt", "NPEM Invalid Device type", PRDV_STRVAL,
4552c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4553c3e0a189SRobert Mustacchi 	{ 11, 11, "dis", "NPEM Disabled", PRDV_STRVAL,
4554c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4555c3e0a189SRobert Mustacchi 	{ 24, 31, "es", "Enclosure-specific Capabilities", PRDV_HEX },
4556c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4557c3e0a189SRobert Mustacchi };
4558c3e0a189SRobert Mustacchi 
45594a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_npem_ctl[] = {
4560c3e0a189SRobert Mustacchi 	{ 0, 0, "npem", "NPEM", PRDV_STRVAL,
4561c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4562c3e0a189SRobert Mustacchi 	{ 1, 1, "reset", "NPEM Initiate Reset", PRDV_STRVAL,
4563c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4564c3e0a189SRobert Mustacchi 	{ 2, 2, "ok", "NPEM OK", PRDV_STRVAL,
4565c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4566c3e0a189SRobert Mustacchi 	{ 3, 3, "loc", "NPEM Locate", PRDV_STRVAL,
4567c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4568c3e0a189SRobert Mustacchi 	{ 4, 4, "fail", "NPEM Fail", PRDV_STRVAL,
4569c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4570c3e0a189SRobert Mustacchi 	{ 5, 5, "rb", "NPEM Rebuild", PRDV_STRVAL,
4571c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4572c3e0a189SRobert Mustacchi 	{ 6, 6, "pfa", "NPEM PFA", PRDV_STRVAL,
4573c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4574c3e0a189SRobert Mustacchi 	{ 7, 7, "hs", "NPEM Hot Spare", PRDV_STRVAL,
4575c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4576c3e0a189SRobert Mustacchi 	{ 8, 8, "crit", "NPEM In a Critical Array", PRDV_STRVAL,
4577c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4578c3e0a189SRobert Mustacchi 	{ 9, 9, "fail", "NPEM In a Failed Array", PRDV_STRVAL,
4579c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4580c3e0a189SRobert Mustacchi 	{ 10, 10, "invdt", "NPEM Invalid Device type", PRDV_STRVAL,
4581c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4582c3e0a189SRobert Mustacchi 	{ 11, 11, "dis", "NPEM Disabled", PRDV_STRVAL,
4583c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4584c3e0a189SRobert Mustacchi 	{ 24, 31, "es", "Enclosure-specific Control", PRDV_HEX },
4585c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4586c3e0a189SRobert Mustacchi };
4587c3e0a189SRobert Mustacchi 
45884a8bbc0bSRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_npem_sts[] = {
4589c3e0a189SRobert Mustacchi 	{ 0, 0, "ccmplt", "NPEM Command Complete", PRDV_STRVAL,
4590c3e0a189SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "no", "yes" } } },
4591c3e0a189SRobert Mustacchi 	{ 24, 31, "es", "Enclosure-specific Status", PRDV_HEX },
4592c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4593c3e0a189SRobert Mustacchi };
4594c3e0a189SRobert Mustacchi 
45954a8bbc0bSRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_npem[] = {
4596c3e0a189SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
4597c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
4598c3e0a189SRobert Mustacchi 	{ 0x4, 4, "cap", "NPEM Capability",
4599c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_npem_cap },
4600c3e0a189SRobert Mustacchi 	{ 0x8, 4, "ctl", "NPEM Control",
4601c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_npem_ctl },
4602c3e0a189SRobert Mustacchi 	{ 0xc, 4, "sts", "NPEM Status",
4603c3e0a189SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_npem_sts },
4604c3e0a189SRobert Mustacchi 	{ -1, -1, NULL }
4605c3e0a189SRobert Mustacchi };
4606c3e0a189SRobert Mustacchi 
4607459e74f0SRobert Mustacchi /*
4608459e74f0SRobert Mustacchi  * Alternate Protocol Capability
4609459e74f0SRobert Mustacchi  */
4610459e74f0SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ap_cap[] = {
4611459e74f0SRobert Mustacchi 	{ 0, 7, "count", "Alternate Protocol Count", PRDV_HEX },
4612459e74f0SRobert Mustacchi 	{ 8, 8, "sen", "Alternate Protocol Select Enable", PRDV_STRVAL,
4613459e74f0SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "unsupported", "supported" } } },
4614459e74f0SRobert Mustacchi 	{ -1, -1, NULL }
4615459e74f0SRobert Mustacchi };
4616459e74f0SRobert Mustacchi 
4617459e74f0SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ap_ctl[] = {
4618459e74f0SRobert Mustacchi 	{ 0, 7, "index", "Alternate Protocol Index Select", PRDV_HEX },
4619459e74f0SRobert Mustacchi 	{ 8, 8, "apngen", "Alternate Protocol Negotiation Global Enable",
4620459e74f0SRobert Mustacchi 	    PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled",
4621459e74f0SRobert Mustacchi 	    "enabled" } } },
4622459e74f0SRobert Mustacchi 	{ -1, -1, NULL }
4623459e74f0SRobert Mustacchi };
4624459e74f0SRobert Mustacchi 
4625459e74f0SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ap_data1[] = {
4626459e74f0SRobert Mustacchi 	{ 0, 2, "use", "Alternate Protocol Usage Information", PRDV_HEX },
4627459e74f0SRobert Mustacchi 	{ 5, 15, "detail", "Alternate Protocol Details", PRDV_HEX },
4628459e74f0SRobert Mustacchi 	{ 16, 31, "vendor", "Alternate Protocol Vendor ID", PRDV_HEX },
4629459e74f0SRobert Mustacchi 	{ -1, -1, NULL }
4630459e74f0SRobert Mustacchi };
4631459e74f0SRobert Mustacchi 
4632459e74f0SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ap_data2[] = {
4633459e74f0SRobert Mustacchi 	{ 0, 23, "mts2", "Modified TS 2 Information", PRDV_HEX },
4634459e74f0SRobert Mustacchi 	{ -1, -1, NULL }
4635459e74f0SRobert Mustacchi };
4636459e74f0SRobert Mustacchi 
4637459e74f0SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_ap_sen[] = {
4638459e74f0SRobert Mustacchi 	{ 0, 0, "pcie", "Selective Enable Mask - PCIe", PRDV_STRVAL,
4639459e74f0SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "disabled", "enabled" } } },
4640459e74f0SRobert Mustacchi 	{ 1, 31, "other", "Selective Enable Mask - Other", PRDV_HEX },
4641459e74f0SRobert Mustacchi 	{ -1, -1, NULL }
4642459e74f0SRobert Mustacchi };
4643459e74f0SRobert Mustacchi 
4644459e74f0SRobert Mustacchi /*
4645459e74f0SRobert Mustacchi  * The Advanced Protocol Selective Enable Mask register is only present if a bit
4646459e74f0SRobert Mustacchi  * in the capabilities register is present. As such, we need to check if it is
4647459e74f0SRobert Mustacchi  * here before we try to read and print it.
4648459e74f0SRobert Mustacchi  */
4649459e74f0SRobert Mustacchi static void
pcieadm_cfgspace_print_ap_sen(pcieadm_cfgspace_walk_t * walkp,const pcieadm_cfgspace_print_t * print,const void * arg)4650459e74f0SRobert Mustacchi pcieadm_cfgspace_print_ap_sen(pcieadm_cfgspace_walk_t *walkp,
4651459e74f0SRobert Mustacchi     const pcieadm_cfgspace_print_t *print, const void *arg)
4652459e74f0SRobert Mustacchi {
4653459e74f0SRobert Mustacchi 	uint32_t ap_cap = walkp->pcw_data->pcb_u32[walkp->pcw_capoff + 4];
4654459e74f0SRobert Mustacchi 	pcieadm_cfgspace_print_t p;
4655459e74f0SRobert Mustacchi 
4656459e74f0SRobert Mustacchi 	if (bitx32(ap_cap, 8, 8) == 0)
4657459e74f0SRobert Mustacchi 		return;
4658459e74f0SRobert Mustacchi 
4659459e74f0SRobert Mustacchi 	(void) memcpy(&p, print, sizeof (*print));
4660459e74f0SRobert Mustacchi 	p.pcp_print = pcieadm_cfgspace_print_regdef;
4661459e74f0SRobert Mustacchi 	p.pcp_arg = pcieadm_regdef_ap_sen;
4662459e74f0SRobert Mustacchi 
4663459e74f0SRobert Mustacchi 	p.pcp_print(walkp, &p, p.pcp_arg);
4664459e74f0SRobert Mustacchi }
4665459e74f0SRobert Mustacchi 
4666459e74f0SRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_ap[] = {
4667459e74f0SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
4668459e74f0SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
4669459e74f0SRobert Mustacchi 	{ 0x4, 4, "cap", "Alternate Protocol Capabilities",
4670459e74f0SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ap_cap },
4671459e74f0SRobert Mustacchi 	{ 0x8, 4, "ctl", "Alternate Protocol Control",
4672459e74f0SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ap_ctl },
4673459e74f0SRobert Mustacchi 	{ 0xc, 4, "data1", "Alternate Protocol Data 1",
4674459e74f0SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ap_data1 },
4675459e74f0SRobert Mustacchi 	{ 0x10, 4, "data2", "Alternate Protocol Data 2",
4676459e74f0SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_ap_data2 },
4677459e74f0SRobert Mustacchi 	{ 0x14, 4, "sen", "Alternate Protocol Select Enable Mask",
4678459e74f0SRobert Mustacchi 	    pcieadm_cfgspace_print_ap_sen },
4679459e74f0SRobert Mustacchi 	{ -1, -1, NULL }
4680459e74f0SRobert Mustacchi };
4681c3e0a189SRobert Mustacchi 
468262ed5172SRobert Mustacchi /*
468362ed5172SRobert Mustacchi  * Root Complex Event Collector Endpoint Association
468462ed5172SRobert Mustacchi  */
468562ed5172SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_rcecea_bus[] = {
468662ed5172SRobert Mustacchi 	{ 8, 15, "next", "RCEC Next Bus", PRDV_HEX },
468762ed5172SRobert Mustacchi 	{ 16, 23, "last", "RCEC Last Bus", PRDV_HEX },
468862ed5172SRobert Mustacchi 	{ -1, -1, NULL }
468962ed5172SRobert Mustacchi };
469062ed5172SRobert Mustacchi 
469162ed5172SRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_rcecea_v1[] = {
469262ed5172SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
469362ed5172SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
469462ed5172SRobert Mustacchi 	{ 0x4, 4, "bitmap", "Association Bitmap for RCiEPs",
469562ed5172SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
469662ed5172SRobert Mustacchi 	{ -1, -1, NULL }
469762ed5172SRobert Mustacchi };
469862ed5172SRobert Mustacchi 
469962ed5172SRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_rcecea_v2[] = {
470062ed5172SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header",
470162ed5172SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_caphdr },
470262ed5172SRobert Mustacchi 	{ 0x4, 4, "bitmap", "Association Bitmap for RCiEPs",
470362ed5172SRobert Mustacchi 	    pcieadm_cfgspace_print_hex },
470462ed5172SRobert Mustacchi 	{ 0x8, 4, "bus", "RCEC Associated Bus Numbers",
470562ed5172SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_rcecea_bus },
470662ed5172SRobert Mustacchi 	{ -1, -1, NULL }
470762ed5172SRobert Mustacchi };
470862ed5172SRobert Mustacchi 
4709*8a300ed6SRobert Mustacchi /*
4710*8a300ed6SRobert Mustacchi  * Readiness Time Reporting
4711*8a300ed6SRobert Mustacchi  */
4712*8a300ed6SRobert Mustacchi 
4713*8a300ed6SRobert Mustacchi /*
4714*8a300ed6SRobert Mustacchi  * A single readiness time constitutes a 9 bit value and 3 bit scale. The actual
4715*8a300ed6SRobert Mustacchi  * register contains a value in nanosconds which is calculated as value *
4716*8a300ed6SRobert Mustacchi  * 32^scale. We take advantage of the fact that this is a power of 2 and
4717*8a300ed6SRobert Mustacchi  * therefore we can calculate 32^scale by taking advantage that 32 is 2^5 and
4718*8a300ed6SRobert Mustacchi  * that this is really 2^(scale * 5) which becomes a simple bit shift.
4719*8a300ed6SRobert Mustacchi  */
4720*8a300ed6SRobert Mustacchi static void
pcieadm_regdef_print_rtr(pcieadm_cfgspace_walk_t * walkp,const pcieadm_regdef_t * regdef,uint64_t reg)4721*8a300ed6SRobert Mustacchi pcieadm_regdef_print_rtr(pcieadm_cfgspace_walk_t *walkp,
4722*8a300ed6SRobert Mustacchi     const pcieadm_regdef_t *regdef, uint64_t reg)
4723*8a300ed6SRobert Mustacchi {
4724*8a300ed6SRobert Mustacchi 	uint64_t scale = bitx64(reg, 11, 9);
4725*8a300ed6SRobert Mustacchi 	uint64_t time = bitx64(reg, 8, 0);
4726*8a300ed6SRobert Mustacchi 
4727*8a300ed6SRobert Mustacchi 	time *= 1ULL << (scale * 5);
4728*8a300ed6SRobert Mustacchi 	pcieadm_field_printf(walkp, regdef->prd_short, regdef->prd_human,
4729*8a300ed6SRobert Mustacchi 	    reg, "%" PRIu64 " ns\n", time);
4730*8a300ed6SRobert Mustacchi }
4731*8a300ed6SRobert Mustacchi 
4732*8a300ed6SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_rtr1[] = {
4733*8a300ed6SRobert Mustacchi 	{ 0, 11, "reset", "Reset Time", PRDV_CUSTOM,
4734*8a300ed6SRobert Mustacchi 	    .prd_val = { .prdv_func = pcieadm_regdef_print_rtr } },
4735*8a300ed6SRobert Mustacchi 	{ 12, 23, "dlup", "DL_Up Time", PRDV_CUSTOM,
4736*8a300ed6SRobert Mustacchi 	    .prd_val = { .prdv_func = pcieadm_regdef_print_rtr } },
4737*8a300ed6SRobert Mustacchi 	{ 31, 31, "valid", "Valid", PRDV_STRVAL,
4738*8a300ed6SRobert Mustacchi 	    .prd_val = { .prdv_strval = { "invalid", "valid" } } },
4739*8a300ed6SRobert Mustacchi 	{ -1, -1, NULL }
4740*8a300ed6SRobert Mustacchi };
4741*8a300ed6SRobert Mustacchi 
4742*8a300ed6SRobert Mustacchi static const pcieadm_regdef_t pcieadm_regdef_rtr2[] = {
4743*8a300ed6SRobert Mustacchi 	{ 0, 11, "flr", "FLR Time", PRDV_CUSTOM,
4744*8a300ed6SRobert Mustacchi 	    .prd_val = { .prdv_func = pcieadm_regdef_print_rtr } },
4745*8a300ed6SRobert Mustacchi 	{ 12, 23, "d3d0", "D3_HOT to D0 Time", PRDV_CUSTOM,
4746*8a300ed6SRobert Mustacchi 	    .prd_val = { .prdv_func = pcieadm_regdef_print_rtr } },
4747*8a300ed6SRobert Mustacchi 	{ -1, -1, NULL }
4748*8a300ed6SRobert Mustacchi };
4749*8a300ed6SRobert Mustacchi 
4750*8a300ed6SRobert Mustacchi static const pcieadm_cfgspace_print_t pcieadm_cap_rtr[] = {
4751*8a300ed6SRobert Mustacchi 	{ 0x0, 4, "caphdr", "Capability Header", pcieadm_cfgspace_print_regdef,
4752*8a300ed6SRobert Mustacchi 	    pcieadm_regdef_pcie_caphdr },
4753*8a300ed6SRobert Mustacchi 	{ 0x4, 4, "rtr1", "Readiness Time Reporting Register 1",
4754*8a300ed6SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_rtr1 },
4755*8a300ed6SRobert Mustacchi 	{ 0x8, 4, "rtr2", "Readiness Time Reporting Register 2",
4756*8a300ed6SRobert Mustacchi 	    pcieadm_cfgspace_print_regdef, pcieadm_regdef_rtr2 },
4757*8a300ed6SRobert Mustacchi 	{ -1, -1, NULL }
4758*8a300ed6SRobert Mustacchi };
4759*8a300ed6SRobert Mustacchi 
47604a8bbc0bSRobert Mustacchi static const pcieadm_pci_cap_t pcieadm_pci_caps[] = {
47617687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PM, "pcipm", "PCI Power Management",
47627687d0d8SRobert Mustacchi 	    pcieadm_cap_info_pcipm, { { 2, 8, pcieadm_cap_pcipm_v3 },
47637687d0d8SRobert Mustacchi 	    { 3, 8, pcieadm_cap_pcipm_v3 } } },
47647687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_AGP, "agp", "Accelerated Graphics Port" },
47657687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_VPD, "vpd", "Vital Product Data", pcieadm_cap_info_fixed,
47667687d0d8SRobert Mustacchi 	    { { 0, 8, pcieadm_cap_vpd } } },
47677687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SLOT_ID, "slot", "Slot Identification" },
47687687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_MSI, "msi", "Message Signaled Interrupts",
47697687d0d8SRobert Mustacchi 	    pcieadm_cap_info_msi },
47707687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_cPCI_HS, "cpci", "CompactPCI Hot Swap" },
47717687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PCIX, "pcix", "PCI-X", pcieadm_cap_info_pcix },
47727687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_HT, "ht", "HyperTransport", pcieadm_cap_info_ht },
47737687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_VS, "vs", "Vendor Specific", pcieadm_cap_info_fixed,
47747687d0d8SRobert Mustacchi 	    { { 0, 3, pcieadm_cap_vs } } },
47757687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_DEBUG_PORT, "dbg", "Debug Port", pcieadm_cap_info_fixed,
47767687d0d8SRobert Mustacchi 	    { { 0, 4, pcieadm_cap_debug } } },
47777687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_cPCI_CRC, "cpcicrc",
47787687d0d8SRobert Mustacchi 	    "CompactPCI Central Resource Control" },
47797687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_PCI_HOTPLUG, "pcihp", "PCI Hot-Plug" },
47807687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_P2P_SUBSYS, "bdgsub", "PCI Bridge Subsystem Vendor ID",
47817687d0d8SRobert Mustacchi 	    pcieadm_cap_info_fixed, { 0, 8, pcieadm_cap_bridge_subsys } },
47827687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_AGP_8X, "agp8x", "AGP 8x" },
47837687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SECURE_DEV, "secdev", "Secure Device" },
4784bc729d49SRobert Mustacchi 	{ PCI_CAP_ID_PCI_E, "pcie", "PCI Express", pcieadm_cap_info_pcie },
47857687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_MSI_X, "msix", "MSI-X", pcieadm_cap_info_fixed,
47867687d0d8SRobert Mustacchi 	    { { 0, 12, pcieadm_cap_msix } } },
47877687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_SATA, "sata", "Serial ATA Configuration",
47887687d0d8SRobert Mustacchi 	    pcieadm_cap_info_fixed, { { 0, 8, pcieadm_cap_sata } } },
47897687d0d8SRobert Mustacchi 	/*
47907687d0d8SRobert Mustacchi 	 * Note, the AF feature doesn't have a version but encodes a length in
47917687d0d8SRobert Mustacchi 	 * the version field, so we cheat and use that.
47927687d0d8SRobert Mustacchi 	 */
47937687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_FLR, "af", "Advanced Features", pcieadm_cap_info_vers,
47947687d0d8SRobert Mustacchi 	    { { 6, 6, pcieadm_cap_af } } },
47957687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_EA, "ea", "Enhanced Allocation" },
47967687d0d8SRobert Mustacchi 	{ PCI_CAP_ID_FPB, "fpb", "Flattening Portal Bridge" }
47977687d0d8SRobert Mustacchi };
47987687d0d8SRobert Mustacchi 
47994a8bbc0bSRobert Mustacchi static const pcieadm_pci_cap_t pcieadm_pcie_caps[] = {
48007687d0d8SRobert Mustacchi 	{ 0, "null", "NULL Capability", pcieadm_cap_info_fixed,
48017687d0d8SRobert Mustacchi 	    { { 0, 0x4, pcieadm_cap_null } } },
48027687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_AER, "aer", "Advanced Error Reporting",
48037687d0d8SRobert Mustacchi 	    pcieadm_cap_info_aer, { { 1, 0x38, pcieadm_cap_aer_v1 },
48047687d0d8SRobert Mustacchi 	    { 2, 0x48, pcieadm_cap_aer_v2 } } },
48057687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VC, "vc", "Virtual Channel", pcieadm_cap_info_vers,
48067687d0d8SRobert Mustacchi 	    { { 0x1, 0x1c, pcieadm_cap_vc } } },
48077687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SER, "sn", "Serial Number", pcieadm_cap_info_vers,
48087687d0d8SRobert Mustacchi 	    { { 1, 0xc, pcieadm_cap_sn } } },
480966a9cc68SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PWR_BUDGET, "pwrbudg", "Power Budgeting",
48107687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_powbudg } } },
48117687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_LINK_DECL, "rcld",
48124dde95daSRobert Mustacchi 	    "Root Complex Link Declaration",  pcieadm_cap_info_vers,
48134dde95daSRobert Mustacchi 	    { { 1, 0x1c, pcieadm_cap_rcld } } },
48147687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_INT_LINKCTRL, "rcilc",
48157687d0d8SRobert Mustacchi 	    "Root Complex Internal Link Control" },
48167687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RC_EVNT_CEA, "rcecea",
481762ed5172SRobert Mustacchi 	    "Root Complex Event Collector Endpoint Association",
481862ed5172SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_rcecea_v1 },
481962ed5172SRobert Mustacchi 	    { 2, 0xc, pcieadm_cap_rcecea_v2 } } },
48207687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MFVC, "mfvc", "Multi-Function Virtual Channel" },
48217687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VC_WITH_MFVC, "vcwmfvc", "Virtual Channel with MFVC",
48227687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 0x1, 0x1c, pcieadm_cap_vc } } },
48237687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RCRB, "rcrb", "Root Complex Register Block" },
48247687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VS, "vsec", "Vendor Specific Extended Capability",
48257687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_vsec } } },
48267687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_CAC, "cac", "Configuration Access Correlation" },
48277687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ACS, "acs", "Access Control Services",
48287687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_acs } } },
48297687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ARI, "ari", "Alternative Routing-ID Interpretation",
48307687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ari } } },
48317687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_ATS, "ats", "Access Translation Services",
48327687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ats } } },
48337687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SRIOV, "sriov", "Single Root I/O Virtualization",
48347687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x40, pcieadm_cap_sriov } } },
48357687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MRIOV, "mriov", "Multi-Root I/O Virtualization" },
48367687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MULTICAST, "mcast", "Multicast",
48377687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x30, pcieadm_cap_mcast } } },
48387687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PGREQ, "pgreq", "Page Request",
48397687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_pgreq } } },
48407687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_EA, "ea", "Enhanced Allocation" },
48417687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RESIZE_BAR, "rbar", "Resizable Bar" },
48427687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DPA, "dpa", "Dynamic Power Allocation",
48437687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_dpa } } },
48447687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_TPH_REQ, "tph", "TPH Requester",
48457687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_tph } } },
48467687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LTR, "ltr", "Latency Tolerance Reporting",
48477687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_ltr } } },
48487687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PCIE2, "pcie2", "Secondary PCI Express",
48497687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_pcie2 } } },
48507687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PASID, "pasid", "Process Address Space ID",
48517687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x8, pcieadm_cap_pasid } } },
48527687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LNR, "lnr", "LN Requester" },
48537687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DPC, "dpc", "Downstream Port Containment",
48547687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x30, pcieadm_cap_dpc } } },
48557687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_L1PM, "l1pm", "L1 PM Substates",
48567687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_l1pm_v1 },
48577687d0d8SRobert Mustacchi 	    { 2, 0x14, pcieadm_cap_l1pm_v2 } } },
48587687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PTM, "ptm", "Precision Time Management",
48597687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_info_ptm } } },
48607687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FRS, "frs", "FRS Queueing" },
4861*8a300ed6SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_RTR, "rtr", "Readiness Time Reporting",
4862*8a300ed6SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_rtr } } },
48637687d0d8SRobert Mustacchi 	/*
4864e6d654ccSRobert Mustacchi 	 * When we encounter a designated vendor specification, in particular,
48657687d0d8SRobert Mustacchi 	 * for CXL, we'll want to set ppc_subcap so we can use reasonable
48667687d0d8SRobert Mustacchi 	 * filtering.
48677687d0d8SRobert Mustacchi 	 */
48687687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DVS, "dvsec",
48697687d0d8SRobert Mustacchi 	    "Designated Vendor-Specific Extended Capability" },
48707687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_VFRBAR, "vfrbar", "Virtual Function Resizable BAR" },
48717687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DLF, "dlf", "Data Link Feature",
48727687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0xc, pcieadm_cap_dlf } } },
48737687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL16GT, "pl16g", "Physical Layer 16.0 GT/s",
48747687d0d8SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x22, pcieadm_cap_16g } } },
48757687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_LANE_MARGIN, "margin",
48767687d0d8SRobert Mustacchi 	    "Lane Margining at the Receiver", pcieadm_cap_info_vers,
48777687d0d8SRobert Mustacchi 	    { { 1, 0x8, pcieadm_cap_margin } } },
48787687d0d8SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_HIEARCHY_ID, "hierid", "Hierarchy ID" },
4879c3e0a189SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_NPEM, "npem", "Native PCIe Enclosure Management",
4880c3e0a189SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x10, pcieadm_cap_npem } } },
4881c3e0a189SRobert Mustacchi 	/*
4882c3e0a189SRobert Mustacchi 	 * The sizing of the 32.0 GT/s physical layer requires that there's at
4883c3e0a189SRobert Mustacchi 	 * least one lane's worth of information and the device is required to
4884c3e0a189SRobert Mustacchi 	 * pad that out to 4-byte alignment.
4885c3e0a189SRobert Mustacchi 	 */
4886c3e0a189SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL32GT, "pl32g", "Physical Layer 32.0 GT/s",
4887c3e0a189SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x24, pcieadm_cap_32g } } },
4888459e74f0SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_AP, "ap", "Alternative Protocol",
4889459e74f0SRobert Mustacchi 	    pcieadm_cap_info_vers, { { 1, 0x14, pcieadm_cap_ap } } },
489093260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SFI, "sfi", "System Firmware Intermediary" },
489193260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SHDW_FUNC, "sfunc", "Shadow Functions" },
489293260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DOE, "doe", "Data Object Exchange" },
489393260af4SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_DEV3, "dev3", "Device 3" },
4894e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_IDE, "ide", "Integrity and Data Encryption" },
4895e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_PL64GT, "pl64g", "Physical Layer 64.0 GT/s" },
4896e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FLIT_LOG, "fltlog", "Flit Logging" },
4897e6d654ccSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FLIT_PERF, "fltperf",
4898e6d654ccSRobert Mustacchi 	    "Flit Performance Measurement" },
4899ccb3ca45SRobert Mustacchi 	{ PCIE_EXT_CAP_ID_FLIT_ERR, "flterr", "Flit Error Injection" },
4900d7574e9aSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_SVC, "svc", "Streamlined Virtual Channel" },
4901d7574e9aSRobert Mustacchi 	{ PCIE_EXT_CAP_ID_MMIO_RBL, "mrbl", "MMIO Register Block Locator" }
49027687d0d8SRobert Mustacchi };
49037687d0d8SRobert Mustacchi 
49047687d0d8SRobert Mustacchi static const pcieadm_pci_cap_t *
pcieadm_cfgspace_match_cap(uint32_t capid,boolean_t pcie)49057687d0d8SRobert Mustacchi pcieadm_cfgspace_match_cap(uint32_t capid, boolean_t pcie)
49067687d0d8SRobert Mustacchi {
49077687d0d8SRobert Mustacchi 	uint_t ncaps;
49084a8bbc0bSRobert Mustacchi 	const pcieadm_pci_cap_t *caps;
49097687d0d8SRobert Mustacchi 
49107687d0d8SRobert Mustacchi 	if (pcie) {
49117687d0d8SRobert Mustacchi 		ncaps = ARRAY_SIZE(pcieadm_pcie_caps);
49127687d0d8SRobert Mustacchi 		caps = pcieadm_pcie_caps;
49137687d0d8SRobert Mustacchi 	} else {
49147687d0d8SRobert Mustacchi 		ncaps = ARRAY_SIZE(pcieadm_pci_caps);
49157687d0d8SRobert Mustacchi 		caps = pcieadm_pci_caps;
49167687d0d8SRobert Mustacchi 	}
49177687d0d8SRobert Mustacchi 
49187687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < ncaps; i++) {
49197687d0d8SRobert Mustacchi 		if (caps[i].ppc_id == capid) {
49207687d0d8SRobert Mustacchi 			return (&caps[i]);
49217687d0d8SRobert Mustacchi 		}
49227687d0d8SRobert Mustacchi 	}
49237687d0d8SRobert Mustacchi 
49247687d0d8SRobert Mustacchi 	return (NULL);
49257687d0d8SRobert Mustacchi }
49267687d0d8SRobert Mustacchi 
49277687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_print_cap(pcieadm_cfgspace_walk_t * walkp,uint_t capid,const pcieadm_pci_cap_t * cap_info,const pcieadm_cap_vers_t * vers_info,const pcieadm_subcap_t * subcap)49287687d0d8SRobert Mustacchi pcieadm_cfgspace_print_cap(pcieadm_cfgspace_walk_t *walkp, uint_t capid,
49297687d0d8SRobert Mustacchi     const pcieadm_pci_cap_t *cap_info, const pcieadm_cap_vers_t *vers_info,
49307687d0d8SRobert Mustacchi     const pcieadm_subcap_t *subcap)
49317687d0d8SRobert Mustacchi {
49327687d0d8SRobert Mustacchi 	boolean_t filter = B_FALSE;
49337687d0d8SRobert Mustacchi 
49347687d0d8SRobert Mustacchi 	/*
49357687d0d8SRobert Mustacchi 	 * If we don't recognize the capability, print out the ID if we're not
49367687d0d8SRobert Mustacchi 	 * filtering and not in parsable mode.
49377687d0d8SRobert Mustacchi 	 */
49387687d0d8SRobert Mustacchi 	if (cap_info == NULL) {
49397687d0d8SRobert Mustacchi 		if (walkp->pcw_ofmt == NULL &&
49407687d0d8SRobert Mustacchi 		    pcieadm_cfgspace_filter(walkp, NULL)) {
49417687d0d8SRobert Mustacchi 			warnx("encountered unknown capability ID 0x%x "
49427687d0d8SRobert Mustacchi 			    "unable to print or list", capid);
49437687d0d8SRobert Mustacchi 			pcieadm_print("Unknown Capability (0x%x)\n", capid);
49447687d0d8SRobert Mustacchi 		}
49457687d0d8SRobert Mustacchi 		return;
49467687d0d8SRobert Mustacchi 	}
49477687d0d8SRobert Mustacchi 
49487687d0d8SRobert Mustacchi 	/*
49497687d0d8SRobert Mustacchi 	 * Check to see if we should print this and in particular, if there's
49507687d0d8SRobert Mustacchi 	 * both a capability or subcapability, we need to try and match both.
49517687d0d8SRobert Mustacchi 	 * The reason that the calls to check the filters are conditioned on
49527687d0d8SRobert Mustacchi 	 * pcw_ofmt is that when we're in parsable mode, we cannot match a
49537687d0d8SRobert Mustacchi 	 * top-level capability since it's an arbitrary number of fields.
49547687d0d8SRobert Mustacchi 	 */
49557687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt == NULL) {
49567687d0d8SRobert Mustacchi 		filter = pcieadm_cfgspace_filter(walkp, cap_info->ppc_short);
49577687d0d8SRobert Mustacchi 	}
49587687d0d8SRobert Mustacchi 	pcieadm_strfilt_push(walkp, cap_info->ppc_short);
49597687d0d8SRobert Mustacchi 	if (subcap != NULL) {
49607687d0d8SRobert Mustacchi 		if (walkp->pcw_ofmt == NULL) {
49617687d0d8SRobert Mustacchi 			boolean_t subfilt = pcieadm_cfgspace_filter(walkp,
49627687d0d8SRobert Mustacchi 			    subcap->psub_short);
49637687d0d8SRobert Mustacchi 			filter = subfilt || filter;
49647687d0d8SRobert Mustacchi 		}
49657687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(walkp, subcap->psub_short);
49667687d0d8SRobert Mustacchi 	}
49677687d0d8SRobert Mustacchi 
49687687d0d8SRobert Mustacchi 
49697687d0d8SRobert Mustacchi 	if (walkp->pcw_ofmt == NULL && filter) {
49707687d0d8SRobert Mustacchi 		if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
49717687d0d8SRobert Mustacchi 			if (subcap != NULL) {
49727687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability - %s (%s) "
49737687d0d8SRobert Mustacchi 				    "(0x%x)\n", cap_info->ppc_human,
49747687d0d8SRobert Mustacchi 				    subcap->psub_human,
49757687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, capid);
49767687d0d8SRobert Mustacchi 			} else {
49777687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability (%s) (0x%x)\n",
49787687d0d8SRobert Mustacchi 				    cap_info->ppc_human,
49797687d0d8SRobert Mustacchi 				    walkp->pcw_filt->pstr_curgen, capid);
49807687d0d8SRobert Mustacchi 			}
49817687d0d8SRobert Mustacchi 		} else {
49827687d0d8SRobert Mustacchi 			if (subcap != NULL) {
49837687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability - %s (0x%x)\n",
49847687d0d8SRobert Mustacchi 				    cap_info->ppc_human, subcap->psub_human,
49857687d0d8SRobert Mustacchi 				    capid);
49867687d0d8SRobert Mustacchi 			} else {
49877687d0d8SRobert Mustacchi 				pcieadm_print("%s Capability (0x%x)\n",
49887687d0d8SRobert Mustacchi 				    cap_info->ppc_human, capid);
49897687d0d8SRobert Mustacchi 			}
49907687d0d8SRobert Mustacchi 		}
49917687d0d8SRobert Mustacchi 	}
49927687d0d8SRobert Mustacchi 
49937687d0d8SRobert Mustacchi 	if (vers_info != NULL) {
49944a8bbc0bSRobert Mustacchi 		const pcieadm_cfgspace_print_t *print;
49957687d0d8SRobert Mustacchi 
49967687d0d8SRobert Mustacchi 		pcieadm_indent();
49977687d0d8SRobert Mustacchi 		for (print = vers_info->ppr_print;
49987687d0d8SRobert Mustacchi 		    print->pcp_short != NULL; print++) {
49997687d0d8SRobert Mustacchi 			VERIFY3P(print->pcp_print, !=, NULL);
50007687d0d8SRobert Mustacchi 			print->pcp_print(walkp, print,
50017687d0d8SRobert Mustacchi 			    print->pcp_arg);
50027687d0d8SRobert Mustacchi 		}
50037687d0d8SRobert Mustacchi 		pcieadm_deindent();
50047687d0d8SRobert Mustacchi 	} else {
50057687d0d8SRobert Mustacchi 		if (subcap != NULL) {
50067687d0d8SRobert Mustacchi 			warnx("Unable to print or list %s - %s (no support or "
50077687d0d8SRobert Mustacchi 			    "missing version info)", cap_info->ppc_human,
50087687d0d8SRobert Mustacchi 			    subcap->psub_human);
50097687d0d8SRobert Mustacchi 		} else {
50107687d0d8SRobert Mustacchi 			warnx("Unable to print or list %s (no support or "
50117687d0d8SRobert Mustacchi 			    "missing version info)", cap_info->ppc_human);
50127687d0d8SRobert Mustacchi 		}
50137687d0d8SRobert Mustacchi 	}
50147687d0d8SRobert Mustacchi 
50157687d0d8SRobert Mustacchi 	if (subcap != NULL) {
50167687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(walkp);
50177687d0d8SRobert Mustacchi 	}
50187687d0d8SRobert Mustacchi 	pcieadm_strfilt_pop(walkp);
50197687d0d8SRobert Mustacchi }
50207687d0d8SRobert Mustacchi 
50217687d0d8SRobert Mustacchi static void
pcieadm_cfgspace_write(int fd,const uint8_t * source,size_t len)50227687d0d8SRobert Mustacchi pcieadm_cfgspace_write(int fd, const uint8_t *source, size_t len)
50237687d0d8SRobert Mustacchi {
50247687d0d8SRobert Mustacchi 	size_t off = 0;
50257687d0d8SRobert Mustacchi 
50267687d0d8SRobert Mustacchi 	while (len > 0) {
50277687d0d8SRobert Mustacchi 		ssize_t ret = write(fd, source + off, len - off);
50287687d0d8SRobert Mustacchi 		if (ret < 0) {
50297687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to write config space to "
50307687d0d8SRobert Mustacchi 			    "output file");
50317687d0d8SRobert Mustacchi 		}
50327687d0d8SRobert Mustacchi 
50337687d0d8SRobert Mustacchi 		off += ret;
50347687d0d8SRobert Mustacchi 		len -= ret;
50357687d0d8SRobert Mustacchi 	}
50367687d0d8SRobert Mustacchi }
50377687d0d8SRobert Mustacchi 
50387687d0d8SRobert Mustacchi void
pcieadm_cfgspace(pcieadm_t * pcip,pcieadm_cfgspace_op_t op,pcieadm_cfgspace_f readf,int fd,void * readarg,uint_t nfilts,pcieadm_cfgspace_filter_t * filters,pcieadm_cfgspace_flags_t flags,ofmt_handle_t ofmt)50397687d0d8SRobert Mustacchi pcieadm_cfgspace(pcieadm_t *pcip, pcieadm_cfgspace_op_t op,
50407687d0d8SRobert Mustacchi     pcieadm_cfgspace_f readf, int fd, void *readarg, uint_t nfilts,
50417687d0d8SRobert Mustacchi     pcieadm_cfgspace_filter_t *filters, pcieadm_cfgspace_flags_t flags,
50427687d0d8SRobert Mustacchi     ofmt_handle_t ofmt)
50437687d0d8SRobert Mustacchi {
50447687d0d8SRobert Mustacchi 	uint_t type;
50457687d0d8SRobert Mustacchi 	uint16_t cap;
50467687d0d8SRobert Mustacchi 	pcieadm_cfgspace_data_t data;
50477687d0d8SRobert Mustacchi 	pcieadm_cfgspace_walk_t walk;
50487687d0d8SRobert Mustacchi 	const char *headstr, *headshort;
50494a8bbc0bSRobert Mustacchi 	const pcieadm_cfgspace_print_t *header;
50507687d0d8SRobert Mustacchi 	boolean_t capsup = B_FALSE, extcfg = B_FALSE;
50517687d0d8SRobert Mustacchi 	uint_t ncaps;
50527687d0d8SRobert Mustacchi 
50537687d0d8SRobert Mustacchi 	walk.pcw_pcieadm = pcip;
50547687d0d8SRobert Mustacchi 	walk.pcw_op = op;
50557687d0d8SRobert Mustacchi 	walk.pcw_data = &data;
50567687d0d8SRobert Mustacchi 	walk.pcw_outfd = fd;
50577687d0d8SRobert Mustacchi 	walk.pcw_capoff = 0;
50587687d0d8SRobert Mustacchi 	walk.pcw_nlanes = 0;
50597687d0d8SRobert Mustacchi 	walk.pcw_nfilters = nfilts;
50607687d0d8SRobert Mustacchi 	walk.pcw_filters = filters;
50617687d0d8SRobert Mustacchi 	walk.pcw_flags = flags;
50627687d0d8SRobert Mustacchi 	walk.pcw_ofmt = ofmt;
50637687d0d8SRobert Mustacchi 	walk.pcw_filt = NULL;
50647687d0d8SRobert Mustacchi 
50657687d0d8SRobert Mustacchi 	/*
50667687d0d8SRobert Mustacchi 	 * Start by reading all of the basic 40-byte config space header in one
50677687d0d8SRobert Mustacchi 	 * fell swoop.
50687687d0d8SRobert Mustacchi 	 */
50697687d0d8SRobert Mustacchi 	for (uint32_t i = 0; i < PCI_CAP_PTR_OFF / 4; i++) {
50707687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
50717687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
50727687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
50737687d0d8SRobert Mustacchi 		}
50747687d0d8SRobert Mustacchi 	}
50757687d0d8SRobert Mustacchi 	walk.pcw_valid = PCI_CAP_PTR_OFF;
50767687d0d8SRobert Mustacchi 	walk.pcw_caplen = PCI_CAP_PTR_OFF;
50777687d0d8SRobert Mustacchi 
50787687d0d8SRobert Mustacchi 	/*
50797687d0d8SRobert Mustacchi 	 * Grab the information from the header that we need to figure out what
50807687d0d8SRobert Mustacchi 	 * kind of device this is, how to print it, if there are any
50817687d0d8SRobert Mustacchi 	 * capabilities, and go from there.
50827687d0d8SRobert Mustacchi 	 */
50837687d0d8SRobert Mustacchi 	type = data.pcb_u8[PCI_CONF_HEADER] & PCI_HEADER_TYPE_M;
50847687d0d8SRobert Mustacchi 	switch (type) {
50857687d0d8SRobert Mustacchi 	case PCI_HEADER_ZERO:
50867687d0d8SRobert Mustacchi 		headstr = "Type 0 Header";
50877687d0d8SRobert Mustacchi 		headshort = "header0";
50887687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_type0;
50897687d0d8SRobert Mustacchi 		capsup = (data.pcb_u8[PCI_CONF_STAT] & PCI_STAT_CAP) != 0;
50907687d0d8SRobert Mustacchi 		break;
50917687d0d8SRobert Mustacchi 	case PCI_HEADER_ONE:
50927687d0d8SRobert Mustacchi 		headstr = "Type 1 Header";
50937687d0d8SRobert Mustacchi 		headshort = "header1";
50947687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_type1;
50957687d0d8SRobert Mustacchi 		capsup = (data.pcb_u8[PCI_CONF_STAT] & PCI_STAT_CAP) != 0;
50967687d0d8SRobert Mustacchi 		break;
50977687d0d8SRobert Mustacchi 	case PCI_HEADER_TWO:
50987687d0d8SRobert Mustacchi 	default:
50997687d0d8SRobert Mustacchi 		headstr = "Unknown Header";
51007687d0d8SRobert Mustacchi 		headshort = "headerX";
51017687d0d8SRobert Mustacchi 		header = pcieadm_cfgspace_unknown;
51027687d0d8SRobert Mustacchi 		warnx("unsupported PCI header type: 0x%x, output limited to "
51036b1325cfSRobert Mustacchi 		    "data configuration space", type);
51047687d0d8SRobert Mustacchi 	}
51057687d0d8SRobert Mustacchi 
51067687d0d8SRobert Mustacchi 	walk.pcw_dtype = type;
51077687d0d8SRobert Mustacchi 
51087687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
51097687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[0], PCI_CAP_PTR_OFF);
51107687d0d8SRobert Mustacchi 	} else if (op == PCIEADM_CFGSPACE_OP_PRINT) {
51114a8bbc0bSRobert Mustacchi 		const pcieadm_cfgspace_print_t *print;
51127687d0d8SRobert Mustacchi 
51137687d0d8SRobert Mustacchi 		if (walk.pcw_ofmt == NULL &&
51147687d0d8SRobert Mustacchi 		    pcieadm_cfgspace_filter(&walk, headshort)) {
51157687d0d8SRobert Mustacchi 			if ((flags & PCIEADM_CFGSPACE_F_SHORT) != 0) {
51167687d0d8SRobert Mustacchi 				pcieadm_print("Device %s -- %s (%s)\n",
51177687d0d8SRobert Mustacchi 				    pcip->pia_devstr, headstr, headshort);
51187687d0d8SRobert Mustacchi 			} else {
51197687d0d8SRobert Mustacchi 				pcieadm_print("Device %s -- %s\n",
51207687d0d8SRobert Mustacchi 				    pcip->pia_devstr, headstr);
51217687d0d8SRobert Mustacchi 			}
51227687d0d8SRobert Mustacchi 		}
51237687d0d8SRobert Mustacchi 
51247687d0d8SRobert Mustacchi 		pcieadm_strfilt_push(&walk, headshort);
51257687d0d8SRobert Mustacchi 		pcieadm_indent();
51267687d0d8SRobert Mustacchi 		for (print = header; print->pcp_short != NULL; print++) {
51277687d0d8SRobert Mustacchi 			print->pcp_print(&walk, print, print->pcp_arg);
51287687d0d8SRobert Mustacchi 		}
51297687d0d8SRobert Mustacchi 		pcieadm_deindent();
51307687d0d8SRobert Mustacchi 		pcieadm_strfilt_pop(&walk);
51317687d0d8SRobert Mustacchi 	}
51327687d0d8SRobert Mustacchi 
51337687d0d8SRobert Mustacchi 
51347687d0d8SRobert Mustacchi 	if (!capsup) {
51357687d0d8SRobert Mustacchi 		return;
51367687d0d8SRobert Mustacchi 	}
51377687d0d8SRobert Mustacchi 
51387687d0d8SRobert Mustacchi 	for (uint32_t i = PCI_CAP_PTR_OFF / 4; i < PCI_CONF_HDR_SIZE / 4; i++) {
51397687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
51407687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
51417687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
51427687d0d8SRobert Mustacchi 		}
51437687d0d8SRobert Mustacchi 	}
51447687d0d8SRobert Mustacchi 	walk.pcw_valid = PCIE_EXT_CAP;
51457687d0d8SRobert Mustacchi 	VERIFY3P(walk.pcw_filt, ==, NULL);
51467687d0d8SRobert Mustacchi 
51477687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
51487687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[PCI_CAP_PTR_OFF],
51497687d0d8SRobert Mustacchi 		    PCI_CONF_HDR_SIZE - PCI_CAP_PTR_OFF);
51507687d0d8SRobert Mustacchi 	}
51517687d0d8SRobert Mustacchi 
51527687d0d8SRobert Mustacchi 	ncaps = 0;
51537687d0d8SRobert Mustacchi 	cap = data.pcb_u8[PCI_CONF_CAP_PTR];
51547687d0d8SRobert Mustacchi 	while (cap != 0 && cap != PCI_EINVAL8) {
51557687d0d8SRobert Mustacchi 		const pcieadm_pci_cap_t *cap_info;
51567687d0d8SRobert Mustacchi 		const pcieadm_cap_vers_t *vers_info = NULL;
51577687d0d8SRobert Mustacchi 		const pcieadm_subcap_t *subcap = NULL;
51587687d0d8SRobert Mustacchi 		uint8_t cap_id, nextcap;
51597687d0d8SRobert Mustacchi 		uint32_t read_len = 0;
51607687d0d8SRobert Mustacchi 
51617687d0d8SRobert Mustacchi 		/*
51627687d0d8SRobert Mustacchi 		 * The PCI specification requires that the caller mask off the
51637687d0d8SRobert Mustacchi 		 * bottom two bits. Always check for an invalid value (all 1s)
51647687d0d8SRobert Mustacchi 		 * before this.
51657687d0d8SRobert Mustacchi 		 */
51667687d0d8SRobert Mustacchi 		cap &= PCI_CAP_PTR_MASK;
51677687d0d8SRobert Mustacchi 		cap_id = data.pcb_u8[cap + PCI_CAP_ID];
51687687d0d8SRobert Mustacchi 		nextcap = data.pcb_u8[cap + PCI_CAP_NEXT_PTR];
51697687d0d8SRobert Mustacchi 		cap_info = pcieadm_cfgspace_match_cap(cap_id, B_FALSE);
51707687d0d8SRobert Mustacchi 		if (cap_info != NULL && cap_info->ppc_info != NULL) {
51717687d0d8SRobert Mustacchi 			cap_info->ppc_info(&walk, cap_info, cap, &vers_info,
51727687d0d8SRobert Mustacchi 			    &read_len, &subcap);
51737687d0d8SRobert Mustacchi 		}
51747687d0d8SRobert Mustacchi 
51757687d0d8SRobert Mustacchi 		walk.pcw_caplen = read_len;
51767687d0d8SRobert Mustacchi 		walk.pcw_capoff = cap;
51777687d0d8SRobert Mustacchi 
51787687d0d8SRobert Mustacchi 		if (cap_id == PCI_CAP_ID_PCI_E) {
51797687d0d8SRobert Mustacchi 			extcfg = B_TRUE;
51807687d0d8SRobert Mustacchi 			if (walk.pcw_valid != 0) {
51817687d0d8SRobert Mustacchi 				walk.pcw_pcietype = data.pcb_u8[cap +
51827687d0d8SRobert Mustacchi 				    PCIE_PCIECAP] & PCIE_PCIECAP_DEV_TYPE_MASK;
51837687d0d8SRobert Mustacchi 				walk.pcw_nlanes = (data.pcb_u8[cap +
51847687d0d8SRobert Mustacchi 				    PCIE_LINKCAP] & 0xf0) >> 4;
51857687d0d8SRobert Mustacchi 				walk.pcw_nlanes |= (data.pcb_u8[cap +
51867687d0d8SRobert Mustacchi 				    PCIE_LINKCAP + 1] & 0x01) << 4;
51877687d0d8SRobert Mustacchi 			} else {
51887687d0d8SRobert Mustacchi 				walk.pcw_pcietype = UINT_MAX;
51897687d0d8SRobert Mustacchi 			}
51907687d0d8SRobert Mustacchi 		}
51917687d0d8SRobert Mustacchi 
51927687d0d8SRobert Mustacchi 		if (op == PCIEADM_CFGSPACE_OP_PRINT) {
51937687d0d8SRobert Mustacchi 			pcieadm_cfgspace_print_cap(&walk, cap_id, cap_info,
51947687d0d8SRobert Mustacchi 			    vers_info, subcap);
51957687d0d8SRobert Mustacchi 		}
51967687d0d8SRobert Mustacchi 
51977687d0d8SRobert Mustacchi 		cap = nextcap;
51987687d0d8SRobert Mustacchi 		ncaps++;
51997687d0d8SRobert Mustacchi 		if (ncaps >= PCI_CAP_MAX_PTR) {
52007687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "encountered more PCI capabilities "
52017687d0d8SRobert Mustacchi 			    "than fit in configuration space");
52027687d0d8SRobert Mustacchi 		}
52037687d0d8SRobert Mustacchi 	}
52047687d0d8SRobert Mustacchi 
52057687d0d8SRobert Mustacchi 	if (!extcfg) {
52067687d0d8SRobert Mustacchi 		return;
52077687d0d8SRobert Mustacchi 	}
52087687d0d8SRobert Mustacchi 
52097687d0d8SRobert Mustacchi 	for (uint_t i = PCIE_EXT_CAP / 4; i < PCIE_CONF_HDR_SIZE / 4; i++) {
52107687d0d8SRobert Mustacchi 		if (!readf(i * 4, 4, &data.pcb_u32[i], readarg)) {
52117687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "failed to read offset %u from "
52127687d0d8SRobert Mustacchi 			    "configuration space", i * 4);
52137687d0d8SRobert Mustacchi 		}
52147687d0d8SRobert Mustacchi 	}
52157687d0d8SRobert Mustacchi 	walk.pcw_valid = PCIE_CONF_HDR_SIZE;
52167687d0d8SRobert Mustacchi 
52177687d0d8SRobert Mustacchi 	if (op == PCIEADM_CFGSPACE_OP_WRITE) {
52187687d0d8SRobert Mustacchi 		pcieadm_cfgspace_write(fd, &data.pcb_u8[PCIE_EXT_CAP],
52197687d0d8SRobert Mustacchi 		    PCIE_CONF_HDR_SIZE - PCIE_EXT_CAP);
52207687d0d8SRobert Mustacchi 		return;
52217687d0d8SRobert Mustacchi 	}
52227687d0d8SRobert Mustacchi 
52237687d0d8SRobert Mustacchi 	cap = PCIE_EXT_CAP;
52247687d0d8SRobert Mustacchi 	ncaps = 0;
52257687d0d8SRobert Mustacchi 	while (cap != 0 && cap != PCI_EINVAL16) {
52267687d0d8SRobert Mustacchi 		uint16_t cap_id, nextcap;
52277687d0d8SRobert Mustacchi 		const pcieadm_pci_cap_t *cap_info;
52287687d0d8SRobert Mustacchi 		const pcieadm_cap_vers_t *vers_info = NULL;
52297687d0d8SRobert Mustacchi 		const pcieadm_subcap_t *subcap = NULL;
52307687d0d8SRobert Mustacchi 		uint32_t read_len = 0;
52317687d0d8SRobert Mustacchi 
52327687d0d8SRobert Mustacchi 		/*
52337687d0d8SRobert Mustacchi 		 * PCIe has the same masking as PCI. Note, sys/pcie.h currently
52347687d0d8SRobert Mustacchi 		 * has PCIE_EXT_CAP_NEXT_PTR_MASK as 0xfff, instead of the
52357687d0d8SRobert Mustacchi 		 * below. This should be switched to PCIE_EXT_CAP_NEXT_PTR_MASK
52367687d0d8SRobert Mustacchi 		 * when the kernel headers are fixed.
52377687d0d8SRobert Mustacchi 		 */
52387687d0d8SRobert Mustacchi 		cap &= 0xffc;
52397687d0d8SRobert Mustacchi 
52407687d0d8SRobert Mustacchi 		/*
52417687d0d8SRobert Mustacchi 		 * While this seems duplicative of the loop condition, a device
52427687d0d8SRobert Mustacchi 		 * without capabilities indicates it with a zero for the first
52437687d0d8SRobert Mustacchi 		 * cap.
52447687d0d8SRobert Mustacchi 		 */
52457687d0d8SRobert Mustacchi 		if (data.pcb_u32[cap / 4] == 0 ||
52467687d0d8SRobert Mustacchi 		    data.pcb_u32[cap / 4] == PCI_EINVAL32)
52477687d0d8SRobert Mustacchi 			break;
52487687d0d8SRobert Mustacchi 
52497687d0d8SRobert Mustacchi 		cap_id = data.pcb_u32[cap / 4] & PCIE_EXT_CAP_ID_MASK;
52507687d0d8SRobert Mustacchi 		nextcap = (data.pcb_u32[cap / 4] >>
52517687d0d8SRobert Mustacchi 		    PCIE_EXT_CAP_NEXT_PTR_SHIFT) & PCIE_EXT_CAP_NEXT_PTR_MASK;
52527687d0d8SRobert Mustacchi 
52537687d0d8SRobert Mustacchi 		cap_info = pcieadm_cfgspace_match_cap(cap_id, B_TRUE);
52547687d0d8SRobert Mustacchi 		if (cap_info != NULL && cap_info->ppc_info != NULL) {
52557687d0d8SRobert Mustacchi 			cap_info->ppc_info(&walk, cap_info, cap, &vers_info,
52567687d0d8SRobert Mustacchi 			    &read_len, &subcap);
52577687d0d8SRobert Mustacchi 		}
52587687d0d8SRobert Mustacchi 
52597687d0d8SRobert Mustacchi 		walk.pcw_caplen = read_len;
52607687d0d8SRobert Mustacchi 		walk.pcw_capoff = cap;
52617687d0d8SRobert Mustacchi 
52627687d0d8SRobert Mustacchi 		if (op == PCIEADM_CFGSPACE_OP_PRINT) {
52637687d0d8SRobert Mustacchi 			pcieadm_cfgspace_print_cap(&walk, cap_id, cap_info,
52647687d0d8SRobert Mustacchi 			    vers_info, subcap);
52657687d0d8SRobert Mustacchi 		}
52667687d0d8SRobert Mustacchi 
52677687d0d8SRobert Mustacchi 		cap = nextcap;
52687687d0d8SRobert Mustacchi 		ncaps++;
52697687d0d8SRobert Mustacchi 		if (ncaps >= PCIE_EXT_CAP_MAX_PTR) {
52707687d0d8SRobert Mustacchi 			errx(EXIT_FAILURE, "encountered more PCI capabilities "
52717687d0d8SRobert Mustacchi 			    "than fit in configuration space");
52727687d0d8SRobert Mustacchi 		}
52737687d0d8SRobert Mustacchi 	}
52747687d0d8SRobert Mustacchi }
52757687d0d8SRobert Mustacchi 
52767687d0d8SRobert Mustacchi void
pcieadm_show_cfgspace_usage(FILE * f)52777687d0d8SRobert Mustacchi pcieadm_show_cfgspace_usage(FILE *f)
52787687d0d8SRobert Mustacchi {
52797687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tshow-cfgspace\t[-L] [-n] [-H] -d device | -f file "
52807687d0d8SRobert Mustacchi 	    "[filter...]\n");
52817687d0d8SRobert Mustacchi 	(void) fprintf(f, "\tshow-cfgspace\t-p -o field[,...] [-H] -d device | "
52827687d0d8SRobert Mustacchi 	    "-f file [filter...]\n");
52837687d0d8SRobert Mustacchi }
52847687d0d8SRobert Mustacchi 
52857687d0d8SRobert Mustacchi static void
pcieadm_show_cfgspace_help(const char * fmt,...)52867687d0d8SRobert Mustacchi pcieadm_show_cfgspace_help(const char *fmt, ...)
52877687d0d8SRobert Mustacchi {
52887687d0d8SRobert Mustacchi 	if (fmt != NULL) {
52897687d0d8SRobert Mustacchi 		va_list ap;
52907687d0d8SRobert Mustacchi 
52917687d0d8SRobert Mustacchi 		va_start(ap, fmt);
52927687d0d8SRobert Mustacchi 		vwarnx(fmt, ap);
52937687d0d8SRobert Mustacchi 		va_end(ap);
52947687d0d8SRobert Mustacchi 		(void) fprintf(stderr, "\n");
52957687d0d8SRobert Mustacchi 	}
52967687d0d8SRobert Mustacchi 
52977687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "Usage:  %s show-cfgspace [-L] [-n] [-H] -d "
52987687d0d8SRobert Mustacchi 	    "device | -f file [filter...]\n", pcieadm_progname);
52997687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "        %s show-cfgspace -p -o field[,...] "
53007687d0d8SRobert Mustacchi 	    "[-H] -d device | -f file\n\t\t\t      [filter...]\n",
53017687d0d8SRobert Mustacchi 	    pcieadm_progname);
53027687d0d8SRobert Mustacchi 
53037687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "\nPrint and decode PCI configuration space "
53047687d0d8SRobert Mustacchi 	    "data from a device or file. Each\n<filter> selects a given "
53057687d0d8SRobert Mustacchi 	    "capability, sub-capability, register, or field to print.\n\n"
53067687d0d8SRobert Mustacchi 	    "\t-d device\tread data from the specified device (driver instance,"
53077687d0d8SRobert Mustacchi 	    "\n\t\t\t/devices path, or b/d/f)\n"
53087687d0d8SRobert Mustacchi 	    "\t-f file\t\tread data from the specified file\n"
53097687d0d8SRobert Mustacchi 	    "\t-L\t\tlist printable fields\n"
53107687d0d8SRobert Mustacchi 	    "\t-n\t\tshow printable short names\n"
53117687d0d8SRobert Mustacchi 	    "\t-H\t\tomit the column header (for -L and -p)\n"
53127687d0d8SRobert Mustacchi 	    "\t-p\t\tparsable output (requires -o)\n"
531376c08ae9SRobert Mustacchi 	    "\t-o field\toutput fields to print (required for -p)\n\n"
531476c08ae9SRobert Mustacchi 	    "The following fields are supported:\n"
531576c08ae9SRobert Mustacchi 	    "\thuman\t\ta human-readable description of the specific output\n"
531676c08ae9SRobert Mustacchi 	    "\tshort\t\tthe short name of the value used for filters\n"
531776c08ae9SRobert Mustacchi 	    "\tvalue\t\tthe value of a the given capability, register, etc.\n");
53187687d0d8SRobert Mustacchi }
53197687d0d8SRobert Mustacchi 
53207687d0d8SRobert Mustacchi int
pcieadm_show_cfgspace(pcieadm_t * pcip,int argc,char * argv[])53217687d0d8SRobert Mustacchi pcieadm_show_cfgspace(pcieadm_t *pcip, int argc, char *argv[])
53227687d0d8SRobert Mustacchi {
53237687d0d8SRobert Mustacchi 	int c, ret;
53247687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
53257687d0d8SRobert Mustacchi 	void *readarg;
53267687d0d8SRobert Mustacchi 	boolean_t list = B_FALSE, parse = B_FALSE;
53277687d0d8SRobert Mustacchi 	const char *device = NULL, *file = NULL, *fields = NULL;
53287687d0d8SRobert Mustacchi 	uint_t nfilts = 0;
53297687d0d8SRobert Mustacchi 	pcieadm_cfgspace_filter_t *filts = NULL;
53307687d0d8SRobert Mustacchi 	pcieadm_cfgspace_flags_t flags = 0;
53317687d0d8SRobert Mustacchi 	uint_t oflags = 0;
53327687d0d8SRobert Mustacchi 	ofmt_handle_t ofmt = NULL;
53337687d0d8SRobert Mustacchi 
53347687d0d8SRobert Mustacchi 	while ((c = getopt(argc, argv, ":HLd:f:o:np")) != -1) {
53357687d0d8SRobert Mustacchi 		switch (c) {
53367687d0d8SRobert Mustacchi 		case 'd':
53377687d0d8SRobert Mustacchi 			device = optarg;
53387687d0d8SRobert Mustacchi 			break;
53397687d0d8SRobert Mustacchi 		case 'L':
53407687d0d8SRobert Mustacchi 			list = B_TRUE;
53417687d0d8SRobert Mustacchi 			break;
53427687d0d8SRobert Mustacchi 		case 'f':
53437687d0d8SRobert Mustacchi 			file = optarg;
53447687d0d8SRobert Mustacchi 			break;
53457687d0d8SRobert Mustacchi 		case 'p':
53467687d0d8SRobert Mustacchi 			parse = B_TRUE;
53477687d0d8SRobert Mustacchi 			flags |= PCIEADM_CFGSPACE_F_PARSE;
53487687d0d8SRobert Mustacchi 			oflags |= OFMT_PARSABLE;
53497687d0d8SRobert Mustacchi 			break;
53507687d0d8SRobert Mustacchi 		case 'n':
53517687d0d8SRobert Mustacchi 			flags |= PCIEADM_CFGSPACE_F_SHORT;
53527687d0d8SRobert Mustacchi 			break;
53537687d0d8SRobert Mustacchi 		case 'H':
53547687d0d8SRobert Mustacchi 			oflags |= OFMT_NOHEADER;
53557687d0d8SRobert Mustacchi 			break;
53567687d0d8SRobert Mustacchi 		case 'o':
53577687d0d8SRobert Mustacchi 			fields = optarg;
53587687d0d8SRobert Mustacchi 			break;
53597687d0d8SRobert Mustacchi 		case ':':
53607687d0d8SRobert Mustacchi 			pcieadm_show_cfgspace_help("Option -%c requires an "
53617687d0d8SRobert Mustacchi 			    "argument", optopt);
53627687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
53637687d0d8SRobert Mustacchi 		case '?':
53647687d0d8SRobert Mustacchi 		default:
53657687d0d8SRobert Mustacchi 			pcieadm_show_cfgspace_help("unknown option: -%c",
53667687d0d8SRobert Mustacchi 			    optopt);
53677687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
53687687d0d8SRobert Mustacchi 		}
53697687d0d8SRobert Mustacchi 	}
53707687d0d8SRobert Mustacchi 
53717687d0d8SRobert Mustacchi 	argc -= optind;
53727687d0d8SRobert Mustacchi 	argv += optind;
53737687d0d8SRobert Mustacchi 
53747687d0d8SRobert Mustacchi 	if (device == NULL && file == NULL) {
53757687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("one of -d or -f must be specified");
53767687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
53777687d0d8SRobert Mustacchi 	}
53787687d0d8SRobert Mustacchi 
53797687d0d8SRobert Mustacchi 	if (device != NULL && file != NULL) {
53807687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("only one of -d and -f must be "
53817687d0d8SRobert Mustacchi 		    "specified");
53827687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
53837687d0d8SRobert Mustacchi 	}
53847687d0d8SRobert Mustacchi 
53857687d0d8SRobert Mustacchi 	if (parse && fields == NULL) {
53867687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-p requires fields specified with "
53877687d0d8SRobert Mustacchi 		    "-o");
53887687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
53897687d0d8SRobert Mustacchi 	}
53907687d0d8SRobert Mustacchi 
53917687d0d8SRobert Mustacchi 	if (!parse && fields != NULL) {
53927687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-o can only be used with -p");
53937687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
53947687d0d8SRobert Mustacchi 	}
53957687d0d8SRobert Mustacchi 
53967687d0d8SRobert Mustacchi 	if ((oflags & OFMT_NOHEADER) && !(list || parse)) {
53977687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-H must be used with either -L or "
53987687d0d8SRobert Mustacchi 		    "-p");
53997687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
54007687d0d8SRobert Mustacchi 	}
54017687d0d8SRobert Mustacchi 
54027687d0d8SRobert Mustacchi 	if ((flags & PCIEADM_CFGSPACE_F_SHORT) && (list || parse)) {
54037687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-n cannot be used with either -L "
54047687d0d8SRobert Mustacchi 		    "or -p");
54057687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
54067687d0d8SRobert Mustacchi 	}
54077687d0d8SRobert Mustacchi 
54087687d0d8SRobert Mustacchi 	if (list && parse != 0) {
54097687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-L and -p cannot be used together");
54107687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
54117687d0d8SRobert Mustacchi 	}
54127687d0d8SRobert Mustacchi 
54137687d0d8SRobert Mustacchi 	if (list && fields != NULL) {
54147687d0d8SRobert Mustacchi 		pcieadm_show_cfgspace_help("-L and -o cannot be used together");
54157687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
54167687d0d8SRobert Mustacchi 	}
54177687d0d8SRobert Mustacchi 
54187687d0d8SRobert Mustacchi 	if (list) {
54197687d0d8SRobert Mustacchi 		fields = "short,human";
54207687d0d8SRobert Mustacchi 	}
54217687d0d8SRobert Mustacchi 
54227687d0d8SRobert Mustacchi 	if (argc > 0) {
54237687d0d8SRobert Mustacchi 		nfilts = argc;
54247687d0d8SRobert Mustacchi 		filts = calloc(nfilts, sizeof (pcieadm_cfgspace_filter_t));
54257687d0d8SRobert Mustacchi 
54267687d0d8SRobert Mustacchi 		for (int i = 0; i < argc; i++) {
54277687d0d8SRobert Mustacchi 			filts[i].pcf_string = argv[i];
54287687d0d8SRobert Mustacchi 			filts[i].pcf_len = strlen(argv[i]);
54297687d0d8SRobert Mustacchi 		}
54307687d0d8SRobert Mustacchi 	}
54317687d0d8SRobert Mustacchi 
54327687d0d8SRobert Mustacchi 	if (list || parse) {
54337687d0d8SRobert Mustacchi 		ofmt_status_t oferr;
54347687d0d8SRobert Mustacchi 		oferr = ofmt_open(fields, pcieadm_cfgspace_ofmt, oflags, 0,
54357687d0d8SRobert Mustacchi 		    &ofmt);
54367687d0d8SRobert Mustacchi 		ofmt_check(oferr, parse, ofmt, pcieadm_ofmt_errx, warnx);
54377687d0d8SRobert Mustacchi 	}
54387687d0d8SRobert Mustacchi 
54397687d0d8SRobert Mustacchi 	/*
54407687d0d8SRobert Mustacchi 	 * Initialize privileges that we require. For reading from the kernel
54417687d0d8SRobert Mustacchi 	 * we require all privileges. For a file, we just intersect with things
54427687d0d8SRobert Mustacchi 	 * that would allow someone to read from any file.
54437687d0d8SRobert Mustacchi 	 */
54447687d0d8SRobert Mustacchi 	if (device != NULL) {
54457687d0d8SRobert Mustacchi 		/*
54467687d0d8SRobert Mustacchi 		 * We need full privileges if reading from a device,
54477687d0d8SRobert Mustacchi 		 * unfortunately.
54487687d0d8SRobert Mustacchi 		 */
54497687d0d8SRobert Mustacchi 		priv_fillset(pcip->pia_priv_eff);
54507687d0d8SRobert Mustacchi 	} else {
54517687d0d8SRobert Mustacchi 		VERIFY0(priv_addset(pcip->pia_priv_eff, PRIV_FILE_DAC_READ));
54527687d0d8SRobert Mustacchi 		VERIFY0(priv_addset(pcip->pia_priv_eff, PRIV_FILE_DAC_SEARCH));
54537687d0d8SRobert Mustacchi 	}
54547687d0d8SRobert Mustacchi 	pcieadm_init_privs(pcip);
54557687d0d8SRobert Mustacchi 
54567687d0d8SRobert Mustacchi 	if (device != NULL) {
54577687d0d8SRobert Mustacchi 		pcieadm_find_dip(pcip, device);
54587687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_kernel(pcip, &readf, &readarg);
54597687d0d8SRobert Mustacchi 	} else {
54607687d0d8SRobert Mustacchi 		pcip->pia_devstr = file;
54617687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_file(pcip, file, &readf, &readarg);
54627687d0d8SRobert Mustacchi 	}
54637687d0d8SRobert Mustacchi 	pcieadm_cfgspace(pcip, PCIEADM_CFGSPACE_OP_PRINT, readf, -1, readarg,
54647687d0d8SRobert Mustacchi 	    nfilts, filts, flags, ofmt);
54657687d0d8SRobert Mustacchi 	if (device != NULL) {
54667687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_kernel(readarg);
54677687d0d8SRobert Mustacchi 	} else {
54687687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_file(readarg);
54697687d0d8SRobert Mustacchi 	}
54707687d0d8SRobert Mustacchi 
54717687d0d8SRobert Mustacchi 	ofmt_close(ofmt);
54727687d0d8SRobert Mustacchi 	ret = EXIT_SUCCESS;
54737687d0d8SRobert Mustacchi 	for (uint_t i = 0; i < nfilts; i++) {
54747687d0d8SRobert Mustacchi 		if (!filts[i].pcf_used) {
54757687d0d8SRobert Mustacchi 			warnx("filter '%s' did not match any fields",
54767687d0d8SRobert Mustacchi 			    filts[i].pcf_string);
54777687d0d8SRobert Mustacchi 			ret = EXIT_FAILURE;
54787687d0d8SRobert Mustacchi 		}
54797687d0d8SRobert Mustacchi 	}
54807687d0d8SRobert Mustacchi 
54817687d0d8SRobert Mustacchi 	return (ret);
54827687d0d8SRobert Mustacchi }
54837687d0d8SRobert Mustacchi 
54847687d0d8SRobert Mustacchi typedef struct pcieadm_save_cfgspace {
54857687d0d8SRobert Mustacchi 	pcieadm_t *psc_pci;
54867687d0d8SRobert Mustacchi 	int psc_dirfd;
54877687d0d8SRobert Mustacchi 	uint_t psc_nsaved;
54887687d0d8SRobert Mustacchi 	int psc_ret;
54897687d0d8SRobert Mustacchi } pcieadm_save_cfgspace_t;
54907687d0d8SRobert Mustacchi 
54917687d0d8SRobert Mustacchi static int
pcieadm_save_cfgspace_cb(di_node_t devi,void * arg)54927687d0d8SRobert Mustacchi pcieadm_save_cfgspace_cb(di_node_t devi, void *arg)
54937687d0d8SRobert Mustacchi {
54947687d0d8SRobert Mustacchi 	int fd, nregs, *regs;
54957687d0d8SRobert Mustacchi 	pcieadm_save_cfgspace_t *psc = arg;
54967687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
54977687d0d8SRobert Mustacchi 	void *readarg;
54987687d0d8SRobert Mustacchi 	char fname[128];
54997687d0d8SRobert Mustacchi 
55007687d0d8SRobert Mustacchi 	psc->psc_pci->pia_devstr = di_node_name(devi);
55017687d0d8SRobert Mustacchi 	psc->psc_pci->pia_devi = devi;
55027687d0d8SRobert Mustacchi 	psc->psc_pci->pia_nexus = DI_NODE_NIL;
55037687d0d8SRobert Mustacchi 	pcieadm_find_nexus(psc->psc_pci);
55047687d0d8SRobert Mustacchi 	if (psc->psc_pci->pia_nexus == DI_NODE_NIL) {
55057687d0d8SRobert Mustacchi 		warnx("failed to find nexus for %s", di_node_name(devi));
55067687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
55077687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
55087687d0d8SRobert Mustacchi 	}
55097687d0d8SRobert Mustacchi 
55107687d0d8SRobert Mustacchi 	nregs = di_prop_lookup_ints(DDI_DEV_T_ANY, devi, "reg", &regs);
55117687d0d8SRobert Mustacchi 	if (nregs <= 0) {
55127687d0d8SRobert Mustacchi 		warnx("failed to lookup regs array for %s",
55137687d0d8SRobert Mustacchi 		    psc->psc_pci->pia_devstr);
55147687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
55157687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
55167687d0d8SRobert Mustacchi 	}
55177687d0d8SRobert Mustacchi 
55187687d0d8SRobert Mustacchi 	(void) snprintf(fname, sizeof (fname), "%02x-%02x-%02x.pci",
55197687d0d8SRobert Mustacchi 	    PCI_REG_BUS_G(regs[0]), PCI_REG_DEV_G(regs[0]),
55207687d0d8SRobert Mustacchi 	    PCI_REG_FUNC_G(regs[0]));
55217687d0d8SRobert Mustacchi 
5522414dafc0SRobert Mustacchi 	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, psc->psc_pci->pia_priv_eff) !=
5523414dafc0SRobert Mustacchi 	    0) {
5524414dafc0SRobert Mustacchi 		err(EXIT_FAILURE, "failed to raise privileges");
5525414dafc0SRobert Mustacchi 	}
5526414dafc0SRobert Mustacchi 	fd = openat(psc->psc_dirfd, fname, O_WRONLY | O_TRUNC | O_CREAT, 0666);
5527414dafc0SRobert Mustacchi 	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, psc->psc_pci->pia_priv_min) !=
5528414dafc0SRobert Mustacchi 	    0) {
5529414dafc0SRobert Mustacchi 		err(EXIT_FAILURE, "failed to reduce privileges");
5530414dafc0SRobert Mustacchi 	}
5531414dafc0SRobert Mustacchi 
5532414dafc0SRobert Mustacchi 	if (fd < 0) {
55337687d0d8SRobert Mustacchi 		warn("failed to create output file %s", fname);
55347687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
55357687d0d8SRobert Mustacchi 		return (DI_WALK_CONTINUE);
55367687d0d8SRobert Mustacchi 	}
55377687d0d8SRobert Mustacchi 
55387687d0d8SRobert Mustacchi 	pcieadm_init_cfgspace_kernel(psc->psc_pci, &readf, &readarg);
55397687d0d8SRobert Mustacchi 	pcieadm_cfgspace(psc->psc_pci, PCIEADM_CFGSPACE_OP_WRITE, readf, fd,
55407687d0d8SRobert Mustacchi 	    readarg, 0, NULL, 0, NULL);
55417687d0d8SRobert Mustacchi 	pcieadm_fini_cfgspace_kernel(readarg);
55427687d0d8SRobert Mustacchi 
55437687d0d8SRobert Mustacchi 	if (close(fd) != 0) {
55447687d0d8SRobert Mustacchi 		warn("failed to close output fd for %s", fname);
55457687d0d8SRobert Mustacchi 		psc->psc_ret = EXIT_FAILURE;
55467687d0d8SRobert Mustacchi 	} else {
55477687d0d8SRobert Mustacchi 		psc->psc_nsaved++;
55487687d0d8SRobert Mustacchi 	}
55497687d0d8SRobert Mustacchi 
55507687d0d8SRobert Mustacchi 	return (DI_WALK_CONTINUE);
55517687d0d8SRobert Mustacchi }
55527687d0d8SRobert Mustacchi 
55537687d0d8SRobert Mustacchi void
pcieadm_save_cfgspace_usage(FILE * f)55547687d0d8SRobert Mustacchi pcieadm_save_cfgspace_usage(FILE *f)
55557687d0d8SRobert Mustacchi {
5556755ccbcfSRobert Mustacchi 	(void) fprintf(f, "\tsave-cfgspace\t-d device output-file\n");
5557755ccbcfSRobert Mustacchi 	(void) fprintf(f, "\tsave-cfgspace\t-a output-directory\n");
55587687d0d8SRobert Mustacchi }
55597687d0d8SRobert Mustacchi 
55607687d0d8SRobert Mustacchi static void
pcieadm_save_cfgspace_help(const char * fmt,...)55617687d0d8SRobert Mustacchi pcieadm_save_cfgspace_help(const char *fmt, ...)
55627687d0d8SRobert Mustacchi {
55637687d0d8SRobert Mustacchi 	if (fmt != NULL) {
55647687d0d8SRobert Mustacchi 		va_list ap;
55657687d0d8SRobert Mustacchi 
55667687d0d8SRobert Mustacchi 		va_start(ap, fmt);
55677687d0d8SRobert Mustacchi 		vwarnx(fmt, ap);
55687687d0d8SRobert Mustacchi 		va_end(ap);
55697687d0d8SRobert Mustacchi 		(void) fprintf(stderr, "\n");
55707687d0d8SRobert Mustacchi 	}
55717687d0d8SRobert Mustacchi 
55727687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "Usage:  %s save-cfgspace -d device "
55737687d0d8SRobert Mustacchi 	    "output-file\n", pcieadm_progname);
55747687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "        %s save-cfgspace -a "
55757687d0d8SRobert Mustacchi 	    "output-directory\n", pcieadm_progname);
55767687d0d8SRobert Mustacchi 
55777687d0d8SRobert Mustacchi 	(void) fprintf(stderr, "\nSave PCI configuration space data from a "
55787687d0d8SRobert Mustacchi 	    "device to a file or\nsave all devices to a specified directory."
55797687d0d8SRobert Mustacchi 	    "\n\n"
55807687d0d8SRobert Mustacchi 	    "\t-a\t\tsave data from all devices\n"
55817687d0d8SRobert Mustacchi 	    "\t-d device\tread data from the specified device (driver instance,"
55827687d0d8SRobert Mustacchi 	    "\n\t\t\t/devices path, or b/d/f)\n");
55837687d0d8SRobert Mustacchi }
55847687d0d8SRobert Mustacchi 
55857687d0d8SRobert Mustacchi int
pcieadm_save_cfgspace(pcieadm_t * pcip,int argc,char * argv[])55867687d0d8SRobert Mustacchi pcieadm_save_cfgspace(pcieadm_t *pcip, int argc, char *argv[])
55877687d0d8SRobert Mustacchi {
55887687d0d8SRobert Mustacchi 	int c;
55897687d0d8SRobert Mustacchi 	pcieadm_cfgspace_f readf;
55907687d0d8SRobert Mustacchi 	void *readarg;
55917687d0d8SRobert Mustacchi 	const char *device = NULL;
55927687d0d8SRobert Mustacchi 	boolean_t do_all = B_FALSE;
55937687d0d8SRobert Mustacchi 
55947687d0d8SRobert Mustacchi 	while ((c = getopt(argc, argv, ":ad:")) != -1) {
55957687d0d8SRobert Mustacchi 		switch (c) {
55967687d0d8SRobert Mustacchi 		case 'a':
55977687d0d8SRobert Mustacchi 			do_all = B_TRUE;
55987687d0d8SRobert Mustacchi 			break;
55997687d0d8SRobert Mustacchi 		case 'd':
56007687d0d8SRobert Mustacchi 			device = optarg;
56017687d0d8SRobert Mustacchi 			break;
56027687d0d8SRobert Mustacchi 		case ':':
56037687d0d8SRobert Mustacchi 			pcieadm_save_cfgspace_help("Option -%c requires an "
56047687d0d8SRobert Mustacchi 			    "argument", optopt);
56057687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
56067687d0d8SRobert Mustacchi 		case '?':
56077687d0d8SRobert Mustacchi 		default:
56087687d0d8SRobert Mustacchi 			pcieadm_save_cfgspace_help("unknown option: -%c",
56097687d0d8SRobert Mustacchi 			    optopt);
56107687d0d8SRobert Mustacchi 			exit(EXIT_USAGE);
56117687d0d8SRobert Mustacchi 		}
56127687d0d8SRobert Mustacchi 	}
56137687d0d8SRobert Mustacchi 
56147687d0d8SRobert Mustacchi 	argc -= optind;
56157687d0d8SRobert Mustacchi 	argv += optind;
56167687d0d8SRobert Mustacchi 
56177687d0d8SRobert Mustacchi 	if (device == NULL && !do_all) {
56187687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_help("missing required -d option to "
56197687d0d8SRobert Mustacchi 		    "indicate device to dump");
56207687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
56217687d0d8SRobert Mustacchi 	}
56227687d0d8SRobert Mustacchi 
56237687d0d8SRobert Mustacchi 	if (argc != 1) {
56247687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_help("missing required output path");
56257687d0d8SRobert Mustacchi 		exit(EXIT_USAGE);
56267687d0d8SRobert Mustacchi 	}
56277687d0d8SRobert Mustacchi 
56287687d0d8SRobert Mustacchi 	/*
56297687d0d8SRobert Mustacchi 	 * For reading from devices, we need to full privileges, unfortunately.
56307687d0d8SRobert Mustacchi 	 */
56317687d0d8SRobert Mustacchi 	priv_fillset(pcip->pia_priv_eff);
56327687d0d8SRobert Mustacchi 	pcieadm_init_privs(pcip);
56337687d0d8SRobert Mustacchi 
56347687d0d8SRobert Mustacchi 	if (!do_all) {
56357687d0d8SRobert Mustacchi 		int fd;
56367687d0d8SRobert Mustacchi 
56377687d0d8SRobert Mustacchi 		pcieadm_find_dip(pcip, device);
56387687d0d8SRobert Mustacchi 
56397687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_eff) !=
56407687d0d8SRobert Mustacchi 		    0) {
56417687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to raise privileges");
56427687d0d8SRobert Mustacchi 		}
56437687d0d8SRobert Mustacchi 
56447687d0d8SRobert Mustacchi 		if ((fd = open(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666)) <
56457687d0d8SRobert Mustacchi 		    0) {
56467687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to open output file %s",
56477687d0d8SRobert Mustacchi 			    argv[0]);
56487687d0d8SRobert Mustacchi 		}
56497687d0d8SRobert Mustacchi 
56507687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_min) !=
56517687d0d8SRobert Mustacchi 		    0) {
56527687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to reduce privileges");
56537687d0d8SRobert Mustacchi 		}
56547687d0d8SRobert Mustacchi 
56557687d0d8SRobert Mustacchi 		pcieadm_init_cfgspace_kernel(pcip, &readf, &readarg);
56567687d0d8SRobert Mustacchi 		pcieadm_cfgspace(pcip, PCIEADM_CFGSPACE_OP_WRITE, readf, fd,
56577687d0d8SRobert Mustacchi 		    readarg, 0, NULL, 0, NULL);
56587687d0d8SRobert Mustacchi 		pcieadm_fini_cfgspace_kernel(readarg);
56597687d0d8SRobert Mustacchi 
56607687d0d8SRobert Mustacchi 		if (close(fd) != 0) {
56617687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to close output file "
56627687d0d8SRobert Mustacchi 			    "descriptor");
56637687d0d8SRobert Mustacchi 		}
56647687d0d8SRobert Mustacchi 
56657687d0d8SRobert Mustacchi 		return (EXIT_SUCCESS);
56667687d0d8SRobert Mustacchi 	} else {
56677687d0d8SRobert Mustacchi 		pcieadm_save_cfgspace_t psc;
56687687d0d8SRobert Mustacchi 		pcieadm_di_walk_t walk;
56697687d0d8SRobert Mustacchi 
56707687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_eff) !=
56717687d0d8SRobert Mustacchi 		    0) {
56727687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to raise privileges");
56737687d0d8SRobert Mustacchi 		}
56747687d0d8SRobert Mustacchi 
56757687d0d8SRobert Mustacchi 		if ((psc.psc_dirfd = open(argv[0], O_RDONLY | O_DIRECTORY)) <
56767687d0d8SRobert Mustacchi 		    0) {
56777687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to open output directory %s",
56787687d0d8SRobert Mustacchi 			    argv[0]);
56797687d0d8SRobert Mustacchi 		}
56807687d0d8SRobert Mustacchi 
56817687d0d8SRobert Mustacchi 		if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pcip->pia_priv_min) !=
56827687d0d8SRobert Mustacchi 		    0) {
56837687d0d8SRobert Mustacchi 			err(EXIT_FAILURE, "failed to reduce privileges");
56847687d0d8SRobert Mustacchi 		}
56857687d0d8SRobert Mustacchi 
56867687d0d8SRobert Mustacchi 		psc.psc_nsaved = 0;
56877687d0d8SRobert Mustacchi 		psc.psc_ret = EXIT_SUCCESS;
56887687d0d8SRobert Mustacchi 		psc.psc_pci = pcip;
56897687d0d8SRobert Mustacchi 
56907687d0d8SRobert Mustacchi 		walk.pdw_arg = &psc;
56917687d0d8SRobert Mustacchi 		walk.pdw_func = pcieadm_save_cfgspace_cb;
56927687d0d8SRobert Mustacchi 		pcieadm_di_walk(pcip, &walk);
56937687d0d8SRobert Mustacchi 
56947687d0d8SRobert Mustacchi 		VERIFY0(close(psc.psc_dirfd));
56957687d0d8SRobert Mustacchi 
56967687d0d8SRobert Mustacchi 		if (psc.psc_nsaved == 0) {
56977687d0d8SRobert Mustacchi 			warnx("failed to save any PCI devices");
56987687d0d8SRobert Mustacchi 			return (EXIT_FAILURE);
56997687d0d8SRobert Mustacchi 		}
57007687d0d8SRobert Mustacchi 
57017687d0d8SRobert Mustacchi 		pcieadm_print("successfully saved %u devices to %s\n",
57027687d0d8SRobert Mustacchi 		    psc.psc_nsaved, argv[0]);
57037687d0d8SRobert Mustacchi 		return (psc.psc_ret);
57047687d0d8SRobert Mustacchi 	}
57057687d0d8SRobert Mustacchi }
5706