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