| /* |
| * This file and its contents are supplied under the terms of the |
| * Common Development and Distribution License ("CDDL"), version 1.0. |
| * You may only use this file in accordance with the terms of version |
| * 1.0 of the CDDL. |
| * |
| * A full copy of the text of the CDDL should have accompanied this |
| * source. A copy of the CDDL is also available via the Internet at |
| * http://www.illumos.org/license/CDDL. |
| */ |
| |
| /* |
| * Copyright 2023 Oxide Computer Company |
| */ |
| |
| /* |
| * This file contains logic to walk and print a large chunk of configuration |
| * space and many of the capabilities. There are multiple sub-commands that |
| * vector into the same logic (e.g. 'save-cfgspace' and 'show-cfgspace'). In |
| * general, there are a few major goals with this bit of code: |
| * |
| * o Every field should strive to be parsable and therefore selectable for |
| * output. This drove the idea that every field has both a short name and a |
| * human name. The short name is a dot-delineated name. When in parsable |
| * mode, the name will always refer to a single field. However, for |
| * convenience for humans, when not trying to be parsable, we show the |
| * parents in the tree. That is if you specify something like |
| * 'pcie.linkcap.maxspeed', in parsable mode you'll only get that; however, |
| * in non-parsable mode, you'll get an indication of the capability and |
| * register that field was in. |
| * |
| * o Related to the above, parsable mode always outputs a raw, uninterpreted |
| * value. This was done on purpose. Some fields require interpreting multiple |
| * registers to have meaning and long strings aren't always the most useful. |
| * |
| * o Every field isn't always pretty printed. This was generally just a |
| * decision based upon the field itself and how much work it'd be to fit it |
| * into the framework we have. In general, the ones we're mostly guilty of |
| * doing this with are related to cases where there's a scaling value in a |
| * subsequent register. If you find yourself wanting this, feel free to add |
| * it. |
| * |
| * o Currently designated vendor-specific capabilities aren't included here (or |
| * any specific vendor-specific capabilities for that matter). If they are |
| * added, they should follow the same angle of using a name to represent a |
| * sub-capability as we did with HyperTransport. |
| */ |
| |
| #include <err.h> |
| #include <strings.h> |
| #include <sys/sysmacros.h> |
| #include <sys/pci.h> |
| #include <sys/pcie.h> |
| #include <sys/debug.h> |
| #include <ofmt.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <sys/bitext.h> |
| |
| #include "pcieadm.h" |
| |
| typedef enum pcieadm_cfgspace_op { |
| PCIEADM_CFGSPACE_OP_PRINT, |
| PCIEADM_CFGSPACE_OP_WRITE |
| } pcieadm_cfgspace_op_t; |
| |
| typedef enum piceadm_cfgspace_flag { |
| PCIEADM_CFGSPACE_F_PARSE = 1 << 0, |
| PCIEADM_CFGSPACE_F_SHORT = 1 << 1, |
| } pcieadm_cfgspace_flags_t; |
| |
| typedef enum pcieadm_cfgspace_otype { |
| PCIEADM_CFGSPACE_OT_SHORT, |
| PCIEADM_CFGSPACE_OT_HUMAN, |
| PCIEADM_CFGSPACE_OT_VALUE |
| } pcieadm_cfgsapce_otype_t; |
| |
| typedef struct pcieadm_cfgspace_ofmt { |
| const char *pco_base; |
| const char *pco_short; |
| const char *pco_human; |
| uint64_t pco_value; |
| const char *pco_strval; |
| } pcieadm_cfgspace_ofmt_t; |
| |
| typedef enum pcieadm_regdef_val { |
| PRDV_STRVAL, |
| PRDV_BITFIELD, |
| PRDV_HEX |
| } pcieadm_regdef_val_t; |
| |
| typedef struct pcieadm_regdef_addend { |
| uint8_t pra_shift; |
| int64_t pra_addend; |
| } pcieadm_regdef_addend_t; |
| |
| typedef struct pcieadm_regdef { |
| uint8_t prd_lowbit; |
| uint8_t prd_hibit; |
| const char *prd_short; |
| const char *prd_human; |
| pcieadm_regdef_val_t prd_valtype; |
| union { |
| /* |
| * Enough space for up to an 8-bit fields worth of values |
| * (though we expect most to be sparse). |
| */ |
| const char *prdv_strval[128]; |
| pcieadm_regdef_addend_t prdv_hex; |
| } prd_val; |
| } pcieadm_regdef_t; |
| |
| typedef struct pcieadm_unitdef { |
| const char *pcd_unit; |
| uint32_t pcd_mult; |
| } pcieadm_unitdef_t; |
| |
| typedef struct pcieadm_strmap { |
| const char *psr_str; |
| uint64_t psr_val; |
| } pcieadm_strmap_t; |
| |
| typedef struct pcieadm_cfgspace_filter { |
| const char *pcf_string; |
| size_t pcf_len; |
| boolean_t pcf_used; |
| } pcieadm_cfgspace_filter_t; |
| |
| typedef struct pcieadm_strfilt { |
| struct pcieadm_strfilt *pstr_next; |
| const char *pstr_str; |
| char pstr_curgen[256]; |
| } pcieadm_strfilt_t; |
| |
| /* |
| * Data is sized to be large enough that we can hold all of PCIe extended |
| * configuration space. |
| */ |
| typedef union pcieadm_cfgspace_data { |
| uint8_t pcb_u8[PCIE_CONF_HDR_SIZE]; |
| uint32_t pcb_u32[PCIE_CONF_HDR_SIZE / 4]; |
| } pcieadm_cfgspace_data_t; |
| |
| typedef struct pcieadm_cfgspace_walk { |
| pcieadm_t *pcw_pcieadm; |
| pcieadm_cfgspace_op_t pcw_op; |
| uint32_t pcw_valid; |
| pcieadm_cfgspace_data_t *pcw_data; |
| uint16_t pcw_capoff; |
| uint32_t pcw_caplen; |
| int pcw_outfd; |
| uint_t pcw_dtype; |
| uint_t pcw_nlanes; |
| uint_t pcw_pcietype; |
| uint_t pcw_nfilters; |
| pcieadm_cfgspace_filter_t *pcw_filters; |
| pcieadm_cfgspace_flags_t pcw_flags; |
| ofmt_handle_t pcw_ofmt; |
| pcieadm_strfilt_t *pcw_filt; |
| } pcieadm_cfgspace_walk_t; |
| |
| void |
| pcieadm_strfilt_pop(pcieadm_cfgspace_walk_t *walkp) |
| { |
| pcieadm_strfilt_t *filt; |
| |
| VERIFY3P(walkp->pcw_filt, !=, NULL); |
| filt = walkp->pcw_filt; |
| walkp->pcw_filt = filt->pstr_next; |
| free(filt); |
| } |
| |
| void |
| pcieadm_strfilt_push(pcieadm_cfgspace_walk_t *walkp, const char *str) |
| { |
| pcieadm_strfilt_t *filt; |
| size_t len; |
| |
| filt = calloc(1, sizeof (*filt)); |
| if (filt == NULL) { |
| errx(EXIT_FAILURE, "failed to allocate memory for string " |
| "filter"); |
| } |
| |
| filt->pstr_str = str; |
| if (walkp->pcw_filt == NULL) { |
| len = strlcat(filt->pstr_curgen, str, |
| sizeof (filt->pstr_curgen)); |
| } else { |
| len = snprintf(filt->pstr_curgen, sizeof (filt->pstr_curgen), |
| "%s.%s", walkp->pcw_filt->pstr_curgen, str); |
| filt->pstr_next = walkp->pcw_filt; |
| } |
| |
| if (len >= sizeof (filt->pstr_curgen)) { |
| errx(EXIT_FAILURE, "overflowed internal string buffer " |
| "appending %s", str); |
| } |
| |
| walkp->pcw_filt = filt; |
| } |
| |
| static boolean_t |
| pcieadm_cfgspace_filter(pcieadm_cfgspace_walk_t *walkp, const char *str) |
| { |
| char buf[1024]; |
| size_t len; |
| |
| if (walkp->pcw_nfilters == 0) { |
| return (B_TRUE); |
| } |
| |
| if (str == NULL) { |
| return (B_FALSE); |
| } |
| |
| if (walkp->pcw_filt != NULL) { |
| len = snprintf(buf, sizeof (buf), "%s.%s", |
| walkp->pcw_filt->pstr_curgen, str); |
| } else { |
| len = snprintf(buf, sizeof (buf), "%s", str); |
| } |
| |
| if (len >= sizeof (buf)) { |
| abort(); |
| } |
| |
| for (uint_t i = 0; i < walkp->pcw_nfilters; i++) { |
| if (strcmp(buf, walkp->pcw_filters[i].pcf_string) == 0) { |
| walkp->pcw_filters[i].pcf_used = B_TRUE; |
| return (B_TRUE); |
| } |
| |
| /* |
| * If we're in non-parsable mode, we want to do a little bit |
| * more in a few cases. We want to make sure that we print the |
| * parents of more-specific entries. That is, if someone |
| * specified 'header.command.serr', then we want to print |
| * 'header', and 'header.command'. Similarly, if someone |
| * specifies an individual field, we want to print all of its |
| * subfields, that is asking for 'header.command', really gets |
| * that and all of 'header.command.*'. |
| */ |
| if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_PARSE) != 0) { |
| continue; |
| } |
| |
| if (len >= walkp->pcw_filters[i].pcf_len) { |
| if (strncmp(buf, walkp->pcw_filters[i].pcf_string, |
| walkp->pcw_filters[i].pcf_len) == 0 && |
| buf[walkp->pcw_filters[i].pcf_len] == '.') { |
| return (B_TRUE); |
| } |
| } else { |
| if (strncmp(buf, walkp->pcw_filters[i].pcf_string, |
| len) == 0 && |
| walkp->pcw_filters[i].pcf_string[len] == '.') { |
| return (B_TRUE); |
| } |
| } |
| } |
| |
| return (B_FALSE); |
| } |
| |
| static boolean_t |
| pcieadm_cfgspace_ofmt_cb(ofmt_arg_t *ofarg, char *buf, uint_t buflen) |
| { |
| pcieadm_cfgspace_ofmt_t *pco = ofarg->ofmt_cbarg; |
| |
| switch (ofarg->ofmt_id) { |
| case PCIEADM_CFGSPACE_OT_SHORT: |
| if (snprintf(buf, buflen, "%s.%s", pco->pco_base, |
| pco->pco_short) >= buflen) { |
| return (B_FALSE); |
| } |
| break; |
| case PCIEADM_CFGSPACE_OT_HUMAN: |
| if (strlcpy(buf, pco->pco_human, buflen) >= buflen) { |
| return (B_FALSE); |
| } |
| break; |
| case PCIEADM_CFGSPACE_OT_VALUE: |
| if (pco->pco_strval != NULL) { |
| if (strlcpy(buf, pco->pco_strval, buflen) >= buflen) { |
| return (B_FALSE); |
| } |
| } else { |
| if (snprintf(buf, buflen, "0x%" PRIx64, |
| pco->pco_value) >= buflen) { |
| return (B_FALSE); |
| } |
| } |
| break; |
| default: |
| abort(); |
| } |
| |
| return (B_TRUE); |
| } |
| |
| |
| static const ofmt_field_t pcieadm_cfgspace_ofmt[] = { |
| { "SHORT", 30, PCIEADM_CFGSPACE_OT_SHORT, pcieadm_cfgspace_ofmt_cb }, |
| { "HUMAN", 30, PCIEADM_CFGSPACE_OT_HUMAN, pcieadm_cfgspace_ofmt_cb }, |
| { "VALUE", 20, PCIEADM_CFGSPACE_OT_VALUE, pcieadm_cfgspace_ofmt_cb }, |
| { NULL, 0, 0, NULL } |
| }; |
| |
| static void |
| pcieadm_cfgspace_print_parse(pcieadm_cfgspace_walk_t *walkp, |
| const char *sname, const char *human, uint64_t value) |
| { |
| pcieadm_cfgspace_ofmt_t pco; |
| |
| VERIFY3P(walkp->pcw_filt, !=, NULL); |
| pco.pco_base = walkp->pcw_filt->pstr_curgen; |
| pco.pco_short = sname; |
| pco.pco_human = human; |
| pco.pco_value = value; |
| pco.pco_strval = NULL; |
| ofmt_print(walkp->pcw_ofmt, &pco); |
| } |
| |
| typedef struct pcieadm_cfgspace_print pcieadm_cfgspace_print_t; |
| typedef void (*pcieadm_cfgspace_print_f)(pcieadm_cfgspace_walk_t *, |
| const pcieadm_cfgspace_print_t *, const void *); |
| |
| struct pcieadm_cfgspace_print { |
| uint8_t pcp_off; |
| uint8_t pcp_len; |
| const char *pcp_short; |
| const char *pcp_human; |
| pcieadm_cfgspace_print_f pcp_print; |
| const void *pcp_arg; |
| }; |
| |
| static void |
| pcieadm_field_printf(pcieadm_cfgspace_walk_t *walkp, const char *shortf, |
| const char *humanf, uint64_t val, const char *fmt, ...) |
| { |
| va_list ap; |
| |
| if (!pcieadm_cfgspace_filter(walkp, shortf)) |
| return; |
| |
| if (walkp->pcw_ofmt != NULL) { |
| pcieadm_cfgspace_print_parse(walkp, shortf, humanf, val); |
| return; |
| } |
| |
| if (walkp->pcw_pcieadm->pia_indent > 0) { |
| (void) printf("%*s", walkp->pcw_pcieadm->pia_indent, ""); |
| } |
| |
| if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) { |
| (void) printf("|--> %s (%s.%s): ", humanf, |
| walkp->pcw_filt->pstr_curgen, shortf); |
| } else { |
| (void) printf("|--> %s: ", humanf); |
| } |
| |
| va_start(ap, fmt); |
| (void) vprintf(fmt, ap); |
| va_end(ap); |
| |
| } |
| |
| static void |
| pcieadm_cfgspace_printf(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, uint64_t val, const char *fmt, ...) |
| { |
| va_list ap; |
| |
| if (!pcieadm_cfgspace_filter(walkp, print->pcp_short)) |
| return; |
| |
| if (walkp->pcw_ofmt != NULL) { |
| pcieadm_cfgspace_print_parse(walkp, print->pcp_short, |
| print->pcp_human, val); |
| return; |
| } |
| |
| if (walkp->pcw_pcieadm->pia_indent > 0) { |
| (void) printf("%*s", walkp->pcw_pcieadm->pia_indent, ""); |
| } |
| |
| if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) { |
| (void) printf("%s (%s.%s): ", print->pcp_human, |
| walkp->pcw_filt->pstr_curgen, print->pcp_short); |
| } else { |
| (void) printf("%s: ", print->pcp_human); |
| } |
| |
| va_start(ap, fmt); |
| (void) vprintf(fmt, ap); |
| va_end(ap); |
| } |
| |
| static void |
| pcieadm_cfgspace_puts(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const char *str) |
| { |
| if (!pcieadm_cfgspace_filter(walkp, print->pcp_short)) |
| return; |
| |
| if (walkp->pcw_ofmt != NULL) { |
| pcieadm_cfgspace_ofmt_t pco; |
| |
| VERIFY3P(walkp->pcw_filt, !=, NULL); |
| pco.pco_base = walkp->pcw_filt->pstr_curgen; |
| pco.pco_short = print->pcp_short; |
| pco.pco_human = print->pcp_human; |
| pco.pco_strval = str; |
| ofmt_print(walkp->pcw_ofmt, &pco); |
| return; |
| } |
| |
| if (walkp->pcw_pcieadm->pia_indent > 0) { |
| (void) printf("%*s", walkp->pcw_pcieadm->pia_indent, ""); |
| } |
| |
| if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != 0) { |
| (void) printf("%s (%s.%s): %s\n", print->pcp_human, |
| walkp->pcw_filt->pstr_curgen, print->pcp_short, str); |
| } else { |
| (void) printf("%s: %s\n", print->pcp_human, str); |
| } |
| } |
| |
| static uint64_t |
| pcieadm_cfgspace_extract(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print) |
| { |
| uint32_t val = 0; |
| |
| VERIFY3U(print->pcp_len, <=, 8); |
| VERIFY3U(print->pcp_off + print->pcp_len + walkp->pcw_capoff, <=, |
| walkp->pcw_valid); |
| for (uint8_t i = print->pcp_len; i > 0; i--) { |
| val <<= 8; |
| val |= walkp->pcw_data->pcb_u8[walkp->pcw_capoff + |
| print->pcp_off + i - 1]; |
| } |
| |
| return (val); |
| } |
| |
| static uint16_t |
| pcieadm_cfgspace_extract_u16(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print) |
| { |
| VERIFY(print->pcp_len == 2); |
| return ((uint16_t)pcieadm_cfgspace_extract(walkp, print)); |
| } |
| |
| static void |
| pcieadm_cfgspace_print_unit(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| const pcieadm_unitdef_t *unit = arg; |
| uint64_t rawval = pcieadm_cfgspace_extract(walkp, print); |
| uint64_t val = rawval; |
| |
| if (unit->pcd_mult > 1) { |
| val *= unit->pcd_mult; |
| } |
| pcieadm_cfgspace_printf(walkp, print, rawval, "0x%" PRIx64 " %s%s\n", |
| val, unit->pcd_unit, val != 1 ? "s" : ""); |
| } |
| |
| static void |
| pcieadm_cfgspace_print_regdef(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| const pcieadm_regdef_t *regdef = arg; |
| uint64_t val = pcieadm_cfgspace_extract(walkp, print); |
| |
| pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val); |
| |
| pcieadm_indent(); |
| pcieadm_strfilt_push(walkp, print->pcp_short); |
| |
| for (regdef = arg; regdef->prd_short != NULL; regdef++) { |
| uint32_t nbits = regdef->prd_hibit - regdef->prd_lowbit + 1UL; |
| uint32_t bitmask = (1UL << nbits) - 1UL; |
| uint64_t regval = (val >> regdef->prd_lowbit) & bitmask; |
| const char *strval; |
| uint64_t actval; |
| |
| if (!pcieadm_cfgspace_filter(walkp, regdef->prd_short)) { |
| continue; |
| } |
| |
| switch (regdef->prd_valtype) { |
| case PRDV_STRVAL: |
| strval = regdef->prd_val.prdv_strval[regval]; |
| if (strval == NULL) { |
| strval = "reserved"; |
| } |
| |
| pcieadm_field_printf(walkp, regdef->prd_short, |
| regdef->prd_human, regval, "%s (0x%" PRIx64 ")\n", |
| strval, regval << regdef->prd_lowbit); |
| break; |
| case PRDV_HEX: |
| actval = regval; |
| if (regdef->prd_val.prdv_hex.pra_shift > 0) { |
| actval <<= regdef->prd_val.prdv_hex.pra_shift; |
| } |
| actval += regdef->prd_val.prdv_hex.pra_addend; |
| |
| pcieadm_field_printf(walkp, regdef->prd_short, |
| regdef->prd_human, regval, "0x% " PRIx64 "\n", |
| actval); |
| break; |
| case PRDV_BITFIELD: |
| pcieadm_field_printf(walkp, regdef->prd_short, |
| regdef->prd_human, regval, "0x%" PRIx64 "\n", |
| regval << regdef->prd_lowbit); |
| |
| if (walkp->pcw_ofmt == NULL) { |
| pcieadm_indent(); |
| for (uint32_t i = 0; i < nbits; i++) { |
| if (((1 << i) & regval) == 0) |
| continue; |
| pcieadm_print("|--> %s (0x%x)\n", |
| regdef->prd_val.prdv_strval[i], |
| 1UL << (i + regdef->prd_lowbit)); |
| } |
| pcieadm_deindent(); |
| } |
| break; |
| } |
| } |
| |
| pcieadm_strfilt_pop(walkp); |
| pcieadm_deindent(); |
| } |
| |
| static void |
| pcieadm_cfgspace_print_strmap(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| const pcieadm_strmap_t *strmap = arg; |
| uint64_t val = pcieadm_cfgspace_extract(walkp, print); |
| const char *str = "reserved"; |
| |
| for (uint_t i = 0; strmap[i].psr_str != NULL; i++) { |
| if (strmap[i].psr_val == val) { |
| str = strmap[i].psr_str; |
| break; |
| } |
| } |
| |
| pcieadm_cfgspace_printf(walkp, print, val, "0x%x -- %s\n", val, str); |
| } |
| |
| static void |
| pcieadm_cfgspace_print_hex(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| uint64_t val = pcieadm_cfgspace_extract(walkp, print); |
| |
| pcieadm_cfgspace_printf(walkp, print, val, "0x%" PRIx64 "\n", val); |
| } |
| |
| static void |
| pcieadm_cfgspace_print_vendor(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| pcidb_vendor_t *vend; |
| uint16_t vid = pcieadm_cfgspace_extract_u16(walkp, print); |
| |
| vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb, vid); |
| if (vend != NULL) { |
| pcieadm_cfgspace_printf(walkp, print, vid, "0x%x -- %s\n", vid, |
| pcidb_vendor_name(vend)); |
| } else { |
| pcieadm_cfgspace_printf(walkp, print, vid, "0x%x\n", vid); |
| } |
| } |
| |
| static void |
| pcieadm_cfgspace_print_device(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| pcidb_device_t *dev; |
| uint16_t did = pcieadm_cfgspace_extract_u16(walkp, print); |
| uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] + |
| (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8); |
| |
| dev = pcidb_lookup_device(walkp->pcw_pcieadm->pia_pcidb, vid, did); |
| if (dev != NULL) { |
| pcieadm_cfgspace_printf(walkp, print, did, "0x%x -- %s\n", did, |
| pcidb_device_name(dev)); |
| } else { |
| pcieadm_cfgspace_printf(walkp, print, did, "0x%x\n", did); |
| } |
| } |
| |
| /* |
| * To print out detailed information about a subsystem vendor or device, we need |
| * all of the information about the vendor and device due to the organization of |
| * the PCI IDs db. |
| */ |
| static void |
| pcieadm_cfgspace_print_subid(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| uint16_t vid = walkp->pcw_data->pcb_u8[PCI_CONF_VENID] + |
| (walkp->pcw_data->pcb_u8[PCI_CONF_VENID + 1] << 8); |
| uint16_t did = walkp->pcw_data->pcb_u8[PCI_CONF_DEVID] + |
| (walkp->pcw_data->pcb_u8[PCI_CONF_DEVID + 1] << 8); |
| uint16_t svid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID] + |
| (walkp->pcw_data->pcb_u8[PCI_CONF_SUBVENID + 1] << 8); |
| uint16_t sdid = walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID] + |
| (walkp->pcw_data->pcb_u8[PCI_CONF_SUBSYSID + 1] << 8); |
| uint16_t val = pcieadm_cfgspace_extract_u16(walkp, print); |
| boolean_t isvendor = print->pcp_off == PCI_CONF_SUBVENID; |
| |
| if (isvendor) { |
| pcidb_vendor_t *vend; |
| vend = pcidb_lookup_vendor(walkp->pcw_pcieadm->pia_pcidb, |
| svid); |
| if (vend != NULL) { |
| pcieadm_cfgspace_printf(walkp, print, val, |
| "0x%x -- %s\n", val, pcidb_vendor_name(vend)); |
| } else { |
| pcieadm_cfgspace_printf(walkp, print, val, |
| "0x%x\n", val); |
| } |
| } else { |
| pcidb_subvd_t *subvd; |
| subvd = pcidb_lookup_subvd(walkp->pcw_pcieadm->pia_pcidb, vid, |
| did, svid, sdid); |
| if (subvd != NULL) { |
| pcieadm_cfgspace_printf(walkp, print, val, |
| "0x%x -- %s\n", val, pcidb_subvd_name(subvd)); |
| } else { |
| pcieadm_cfgspace_printf(walkp, print, val, "0x%x\n", |
| val); |
| } |
| } |
| } |
| |
| /* |
| * The variable natures of BARs is a pain. This makes printing this out and the |
| * fields all a bit gross. |
| */ |
| static void |
| pcieadm_cfgspace_print_bars(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| uint32_t *barp = &walkp->pcw_data->pcb_u32[(walkp->pcw_capoff + |
| print->pcp_off) / 4]; |
| char barname[32]; |
| const char *typestrs[2] = { "Memory Space", "I/O Space" }; |
| |
| for (uint_t i = 0; i < print->pcp_len / 4; i++) { |
| uint_t type; |
| (void) snprintf(barname, sizeof (barname), "%s%u", |
| print->pcp_short, i); |
| |
| type = barp[i] & PCI_BASE_SPACE_M; |
| |
| if (pcieadm_cfgspace_filter(walkp, barname) && |
| walkp->pcw_ofmt == NULL) { |
| if ((walkp->pcw_flags & PCIEADM_CFGSPACE_F_SHORT) != |
| 0) { |
| pcieadm_print("%s %u (%s.%s)\n", |
| print->pcp_human, i, |
| walkp->pcw_filt->pstr_curgen, barname); |
| } else { |
| pcieadm_print("%s %u\n", print->pcp_human, i); |
| } |
| } |
| |
| pcieadm_strfilt_push(walkp, barname); |
| pcieadm_indent(); |
| |
| pcieadm_field_printf(walkp, "space", "Space", type, |
| "%s (0x%x)\n", typestrs[type], type); |
| |
| if (type == PCI_BASE_SPACE_IO) { |
| uint32_t addr = barp[i] & PCI_BASE_IO_ADDR_M; |
| |
| pcieadm_field_printf(walkp, "addr", "Address", addr, |
| "0x%" PRIx32 "\n", addr); |
| } else { |
| uint8_t type, pre; |
| uint64_t addr; |
| const char *locstr; |
| |
| type = barp[i] & PCI_BASE_TYPE_M; |
| pre = barp[i] & PCI_BASE_PREF_M; |
| addr = barp[i] & PCI_BASE_M_ADDR_M; |
| |
| if (type == PCI_BASE_TYPE_ALL) { |
| addr += (uint64_t)barp[i+1] << 32; |
| i++; |
| } |
| |
| pcieadm_field_printf(walkp, "addr", "Address", addr, |
| "0x%" PRIx64 "\n", addr); |
| |
| switch (type) { |
| case PCI_BASE_TYPE_MEM: |
| locstr = "32-bit"; |
| break; |
| case PCI_BASE_TYPE_LOW: |
| locstr = "Sub-1 MiB"; |
| break; |
| case PCI_BASE_TYPE_ALL: |
| locstr = "64-bit"; |
| break; |
| case PCI_BASE_TYPE_RES: |
| default: |
| locstr = "Reserved"; |
| break; |
| } |
| |
| pcieadm_field_printf(walkp, "type", "Memory Type", addr, |
| "%s (0x%x)\n", locstr, type >> 1); |
| pcieadm_field_printf(walkp, "prefetch", "Prefetchable", |
| pre != 0, "%s (0x%x)\n", pre != 0 ? "yes" : "no", |
| pre != 0); |
| } |
| |
| pcieadm_deindent(); |
| pcieadm_strfilt_pop(walkp); |
| } |
| } |
| |
| static void |
| pcieadm_cfgspace_print_ecv(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| uint16_t bitlen, nwords; |
| |
| if (bitx8(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 5, 5) == 0) { |
| return; |
| } |
| |
| bitlen = walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 5]; |
| if (bitlen == 0) { |
| bitlen = 256; |
| } |
| |
| nwords = bitlen / 32; |
| if ((bitlen % 8) != 0) { |
| nwords++; |
| } |
| |
| for (uint16_t i = 0; i < nwords; i++) { |
| char tshort[32], thuman[128]; |
| pcieadm_cfgspace_print_t p; |
| |
| (void) snprintf(tshort, sizeof (tshort), "ecv%u", i); |
| (void) snprintf(thuman, sizeof (thuman), "Egress Control " |
| "Vector %u", i); |
| p.pcp_off = print->pcp_off + i * 4; |
| p.pcp_len = 4; |
| p.pcp_short = tshort; |
| p.pcp_human = thuman; |
| p.pcp_print = pcieadm_cfgspace_print_hex; |
| p.pcp_arg = NULL; |
| |
| p.pcp_print(walkp, &p, p.pcp_arg); |
| } |
| } |
| |
| static void |
| pcieadm_cfgspace_print_dpa_paa(pcieadm_cfgspace_walk_t *walkp, |
| const pcieadm_cfgspace_print_t *print, const void *arg) |
| { |
| uint8_t nents; |
| |
| nents = bitx8(walkp->pcw_data->pcb_u8[walkp->pcw_capoff + 4], 4, 0) + 1; |
| if (nents == 0) { |
| return; |
| } |
| |
| for (uint8_t i = 0; i < nents; i++) { |
| char tshort[32], thuman[128]; |
| pcieadm_cfgspace_print_t p; |
| |
| (void) snprintf(tshort, sizeof (tshort), "%s%u", |
| print->pcp_short, i); |
| (void) snprintf(thuman, sizeof (thuman), "%s %u", |
| print->pcp_human, i); |
| |
| p.pcp_off = print->pcp_off + i; |
| p.pcp_len = 1; |
| p.pcp_short = tshort; |
| p.pcp_human = thuman; |
| p.pcp_print = pcieadm_cfgspace_print_hex; |
| p.pcp_arg = NULL; |
| |
| p.pcp_print(walkp, &p, p.pcp_arg); |
| } |
| } |
| |
| /* |
| * Config Space Header Table Definitions |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_command[] = { |
| { 0, 0, "io", "I/O Space", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 1, "mem", "Memory Space", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 2, 2, "bus", "Bus Master", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 3, 3, "spec", "Special Cycle", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 4, 4, "mwi", "Memory Write and Invalidate", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 5, 5, "vga", "VGA Palette Snoop", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 6, 6, "per", "Parity Error Response", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 7, 7, "idsel", "IDSEL Stepping/Wait Cycle Control", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 8, 8, "serr", "SERR# Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } }, }, |
| { 9, 9, "fbtx", "Fast Back-to-Back Transactions", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } }, }, |
| { 10, 10, "intx", "Interrupt X", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "enabled", "disabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_status[] = { |
| { 0, 0, "imm", "Immediate Readiness", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } }, }, |
| { 3, 3, "istat", "Interrupt Status", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not pending", "pending" } }, }, |
| { 4, 4, "capsup", "Capabilities List", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } }, }, |
| { 5, 5, "66mhz", "66 MHz Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } }, }, |
| { 7, 7, "fbtxcap", "Fast Back-to-Back Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } }, }, |
| { 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no error", "error detected" } }, }, |
| { 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "fast", "medium", "slow", |
| "reserved" } } }, |
| { 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 12, 12, "rta", "Received Target Abort", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 13, 13, "rma", "Received Master Abort", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 14, 14, "sse", "Signaled System Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 15, 15, "dpe", "Detected Parity Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * It might be interesting to translate these into numbers at a future point. |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_class[] = { |
| { 16, 23, "class", "Class Code", PRDV_HEX }, |
| { 7, 15, "sclass", "Sub-Class Code", PRDV_HEX }, |
| { 0, 7, "pi", "Programming Interface", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridge_iobase[] = { |
| { 0, 3, "cap", "Addressing Capability", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } }, |
| { 4, 7, "base", "Base", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 12 } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridge_iolim[] = { |
| { 0, 3, "cap", "Addressing Capability", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "16-bit", "32-bit" } } }, |
| { 4, 7, "limit", "Limit", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 12, 0xfff } } }, |
| { -1, -1, NULL } |
| }; |
| |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridgests[] = { |
| { 5, 5, "66mhz", "66 MHz", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 8, 8, "mdperr", "Master Data Parity Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no error", "error detected" } } }, |
| { 9, 10, "devsel", "DEVSEL# Timing", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "fast", "medium", "slow" } } }, |
| { 11, 11, "sta", "Signaled Target Abort", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no abort", "aborted" } } }, |
| { 12, 12, "rta", "Received Target Abort", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no abort", "aborted" } } }, |
| { 13, 13, "rma", "Received Master Abort", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no abort", "aborted" } } }, |
| { 14, 14, "rsyserr", "Received System Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no error", "error received" } } }, |
| { 15, 15, "dperr", "Detected Parity Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no error", "error detected" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridge_membase[] = { |
| { 4, 16, "base", "Base", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 20 } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridge_memlim[] = { |
| { 4, 16, "limit", "Limit", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 20, 0xfffff } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridge_pfbase[] = { |
| { 0, 3, "cap", "Addressing Capability", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } }, |
| { 4, 16, "base", "Base", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 20 } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridge_pflim[] = { |
| { 0, 3, "cap", "Addressing Capability", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "32-bit", "64-bit" } } }, |
| { 4, 16, "limit", "Limit", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 20, 0xfffff } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bridge_ctl[] = { |
| { 0, 0, "perrresp", "Parity Error Response", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 1, "serr", "SERR#", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 2, 2, "isa", "ISA", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 3, 3, "vga", "VGA", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 4, 4, "vgadec", "VGA 16-bit Decode", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "10-bit", "16-bit" } } }, |
| { 5, 5, "mabort", "Master Abort", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 6, 6, "secrst", "Secondary Bus Reset", PRDV_HEX }, |
| { 7, 7, "fastb2b", "Fast Back-to-Back Transactions", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 8, 8, "pridisc", "Primary Discard Timer", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } }, |
| { 9, 9, "secdisc", "Secondary Discard Timer", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "2^15 cycles", "2^10 cycles" } } }, |
| { 10, 10, "disctimer", "Discard Timer Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 11, 11, "discserr", "Discard Timer SERR#", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static pcieadm_unitdef_t pcieadm_unitdef_cache = { |
| "byte", 4 |
| }; |
| |
| static pcieadm_unitdef_t pcieadm_unitdef_latreg = { "cycle" }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_header[] = { |
| { 0, 6, "layout", "Header Layout", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "Device", "Bridge", "PC Card" } } }, |
| { 7, 7, "mfd", "Multi-Function Device", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_bist[] = { |
| { 0, 3, "code", "Completion Code", PRDV_HEX }, |
| { 6, 6, "start", "Start BIST", PRDV_HEX }, |
| { 7, 7, "cap", "BIST Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_exprom[] = { |
| { 0, 0, "enable", "Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 3, "valsts", "Validation Status", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not supported", "in progress", |
| "valid contents, no trust test performed", |
| "valid and trusted contents", |
| "invalid contents", |
| "valid but untrusted contents", |
| "valid contents with warning, no trust test performed", |
| "valid and trusted contents with warning" } } }, |
| { 4, 7, "valdet", "Validation Details", PRDV_HEX }, |
| { 11, 31, "addr", "Base Address", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 11 } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static pcieadm_strmap_t pcieadm_strmap_ipin[] = { |
| { "none", 0 }, |
| { "INTA", PCI_INTA }, |
| { "INTB", PCI_INTB }, |
| { "INTC", PCI_INTC }, |
| { "INTD", PCI_INTD }, |
| { NULL } |
| }; |
| |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cfgspace_type0[] = { |
| { 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor }, |
| { 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device }, |
| { 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_command }, |
| { 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_status }, |
| { 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex }, |
| { 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_class }, |
| { 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit, |
| &pcieadm_unitdef_cache }, |
| { 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit, |
| &pcieadm_unitdef_latreg }, |
| { 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_header }, |
| { 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_bist }, |
| { 0x10, 24, "bar", "Base Address Register", |
| pcieadm_cfgspace_print_bars }, |
| { 0x28, 4, "cis", "Cardbus CIS Pointer", pcieadm_cfgspace_print_hex }, |
| { 0x2c, 2, "subvid", "Subsystem Vendor ID", |
| pcieadm_cfgspace_print_subid }, |
| { 0x2e, 2, "subdev", "Subsystem Device ID", |
| pcieadm_cfgspace_print_subid }, |
| { 0x30, 4, "rom", "Expansion ROM", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_exprom }, |
| { 0x34, 1, "cap", "Capabilities Pointer", pcieadm_cfgspace_print_hex }, |
| { 0x3c, 1, "iline", "Interrupt Line", pcieadm_cfgspace_print_hex }, |
| { 0x3d, 1, "ipin", "Interrupt Pin", pcieadm_cfgspace_print_strmap, |
| pcieadm_strmap_ipin }, |
| { 0x3e, 1, "gnt", "Min_Gnt", pcieadm_cfgspace_print_hex }, |
| { 0x3f, 1, "lat", "Min_Lat", pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cfgspace_type1[] = { |
| { 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor }, |
| { 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device }, |
| { 0x4, 2, "command", "Command", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_command }, |
| { 0x6, 2, "status", "Status", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_status }, |
| { 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex }, |
| { 0x9, 3, "class", "Class Code", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_class }, |
| { 0xc, 1, "cache", "Cache Line Size", pcieadm_cfgspace_print_unit, |
| &pcieadm_unitdef_cache }, |
| { 0xd, 1, "latency", "Latency Timer", pcieadm_cfgspace_print_unit, |
| &pcieadm_unitdef_latreg }, |
| { 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_header }, |
| { 0xf, 1, "bist", "BIST", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_bist }, |
| { 0x10, 8, "bar", "Base Address Register", |
| pcieadm_cfgspace_print_bars }, |
| { PCI_BCNF_PRIBUS, 1, "pribus", "Primary Bus Number", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_SECBUS, 1, "secbus", "Secondary Bus Number", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_SUBBUS, 1, "subbus", "Subordinate Bus Number", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_LATENCY_TIMER, 1, "latency2", "Secondary Latency timer", |
| pcieadm_cfgspace_print_unit, &pcieadm_unitdef_latreg }, |
| { PCI_BCNF_IO_BASE_LOW, 1, "iobase", "I/O Base Low", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iobase }, |
| { PCI_BCNF_IO_LIMIT_LOW, 1, "iolimit", "I/O Limit Low", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_iolim }, |
| { PCI_BCNF_SEC_STATUS, 2, "status2", "Secondary Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridgests }, |
| { PCI_BCNF_MEM_BASE, 2, "membase", "Memory Base", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_membase }, |
| { PCI_BCNF_MEM_LIMIT, 2, "memlimit", "Memory Limit", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_memlim }, |
| { PCI_BCNF_PF_BASE_LOW, 2, "pfbase", "Prefetchable Memory Base", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pfbase }, |
| { PCI_BCNF_PF_LIMIT_LOW, 2, "pflimit", "Prefetchable Memory Limit", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_pflim }, |
| { PCI_BCNF_PF_BASE_HIGH, 4, "pfbasehi", |
| "Prefetchable Base Upper 32 bits", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_PF_LIMIT_HIGH, 4, "pflimihi", |
| "Prefetchable Limit Upper 32 bits", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_IO_BASE_HI, 2, "iobasehi", "I/O Base Upper 16 bits", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_IO_LIMIT_HI, 2, "iolimithi", "I/O Limit Upper 16 bits", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_CAP_PTR, 1, "cap", "Capabilities Pointer", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_ROM, 4, "rom", "Expansion ROM", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_exprom }, |
| { PCI_BCNF_ILINE, 1, "iline", "Interrupt Line", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_BCNF_IPIN, 1, "ipin", "Interrupt Pin", |
| pcieadm_cfgspace_print_strmap, pcieadm_strmap_ipin }, |
| { PCI_BCNF_BCNTRL, 2, "bctl", "Bridge Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_bridge_ctl }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cfgspace_unknown[] = { |
| { 0x0, 2, "vendor", "Vendor ID", pcieadm_cfgspace_print_vendor }, |
| { 0x2, 2, "device", "Device ID", pcieadm_cfgspace_print_device }, |
| { 0x8, 1, "revision", "Revision ID", pcieadm_cfgspace_print_hex }, |
| { 0xe, 1, "type", "Header Type", pcieadm_cfgspace_print_regdef, |
| pcieadm_regdef_header }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * Power Management Capability Version 3. Note versions two and three seem to be |
| * the same, but are used to indicate compliance to different revisions of the |
| * PCI power management specification. |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_pmcap[] = { |
| { 0, 2, "vers", "Version", PRDV_HEX }, |
| { 3, 3, "clock", "PME Clock", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not required", "required" } } }, |
| { 4, 4, "irrd0", "Immediate Readiness on Return to D0", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 5, 5, "dsi", "Device Specific Initialization", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 6, 8, "auxcur", "Auxiliary Current", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "0", "55 mA", "100 mA", "160 mA", |
| "220 mA", "270 mA", "320 mA", "375 mA" } } }, |
| { 9, 9, "d1", "D1", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 10, 10, "d2", "D2", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 11, 15, "pme", "PME Support", PRDV_BITFIELD, |
| .prd_val = { .prdv_strval = { "D0", "D1", "D2", "D3hot", |
| "D3cold" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_pcipm_v3[] = { |
| { PCI_PMCAP, 2, "pmcap", "Power Management Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pmcap }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * PCI Bridge Subsystem Capability |
| */ |
| static const pcieadm_cfgspace_print_t pcieadm_cap_bridge_subsys[] = { |
| { 0x4, 2, "subvid", "Subsystem Vendor ID", pcieadm_cfgspace_print_hex }, |
| { 0x6, 2, "subdev", "Subsystem Device ID", pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * MSI Capability |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_msictrl[] = { |
| { 0, 0, "enable", "MSI Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 3, "mmsgcap", "Multiple Message Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "1 vector", "2 vectors", |
| "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } }, |
| { 4, 6, "mmsgen", "Multiple Message Enabled", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "1 vector", "2 vectors", |
| "4 vectors", "8 vectors", "16 vectors", "32 vectors" } } }, |
| { 7, 7, "addr64", "64-bit Address Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 8, 8, "pvm", "Per-Vector Masking Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 9, 9, "extmdcap", "Extended Message Data Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 10, 10, "extmden", "extended Message Data Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_msi_32[] = { |
| { PCI_MSI_CTRL, 2, "ctrl", "Message Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl }, |
| { PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_32BIT_DATA, 2, "data", "Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_msi_32ext[] = { |
| { PCI_MSI_CTRL, 2, "ctrl", "Message Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl }, |
| { PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_32BIT_DATA, 2, "data", "Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_msi_32pvm[] = { |
| { PCI_MSI_CTRL, 2, "ctrl", "Message Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl }, |
| { PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_32BIT_DATA, 2, "data", "Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_32BIT_EXTDATA, 2, "extdata", "Extended Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_32BIT_MASK, 4, "mask", "Mask Bits", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_32BIT_PENDING, 4, "pend", "Pending Bits", |
| pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_msi_64[] = { |
| { PCI_MSI_CTRL, 2, "ctrl", "Message Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl }, |
| { PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_DATA, 2, "data", "Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_msi_64ext[] = { |
| { PCI_MSI_CTRL, 2, "ctrl", "Message Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl }, |
| { PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_DATA, 2, "data", "Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_msi_64pvm[] = { |
| { PCI_MSI_CTRL, 2, "ctrl", "Message Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msictrl }, |
| { PCI_MSI_ADDR_OFFSET, 4, "addr", "Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_ADDR, 4, "upadd", "Upper Message Address", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_DATA, 2, "data", "Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_EXTDATA, 2, "extdata", "Extended Message Data", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_MASKBITS, 4, "mask", "Mask Bits", |
| pcieadm_cfgspace_print_hex }, |
| { PCI_MSI_64BIT_PENDING, 4, "pend", "Pending Bits", |
| pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * MSI-X Capability |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_msixctrl[] = { |
| { 0, 10, "size", "Table Size", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 0, 1 } } }, |
| { 14, 14, "mask", "Function Mask", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unmasked", "masked" } } }, |
| { 15, 15, "enable", "MSI-X Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_msixtable[] = { |
| { 0, 2, "bir", "Table BIR", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3", |
| "BAR 4", "BAR 5" } } }, |
| { 3, 31, "offset", "Table Offset", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 3 } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_msixpba[] = { |
| { 0, 2, "bir", "PBA BIR", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "BAR 0", "BAR 1", "BAR 2", "BAR 3", |
| "BAR 4", "BAR 5" } } }, |
| { 3, 31, "offset", "PBA Offset", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 3 } } }, |
| { -1, -1, NULL } |
| }; |
| |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_msix[] = { |
| { PCI_MSIX_CTRL, 2, "ctrl", "Control Register", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixctrl }, |
| { PCI_MSIX_TBL_OFFSET, 4, "table", "Table Offset", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixtable }, |
| { PCI_MSIX_PBA_OFFSET, 4, "pba", "PBA Offset", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_msixpba }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * PCI Express Capability |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_cap[] = { |
| { 0, 3, "vers", "Version", PRDV_HEX }, |
| { 4, 7, "type", "Device/Port Type", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "PCIe Endpoint", |
| "Legacy PCIe Endpoint", NULL, NULL, |
| "Root Port of PCIe Root Complex", |
| "Upstream Port of PCIe Switch", |
| "Downstream Port of PCIe Switch", |
| "PCIe to PCI/PCI-X Bridge", |
| "PCI/PCI-x to PCIe Bridge", |
| "RCiEP", |
| "Root Complex Event Collector" } } }, |
| { 8, 8, "slot", "Slot Implemented", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "No", "Yes" } } }, |
| { 9, 13, "intno", "Interrupt Message Number", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_devcap[] = { |
| { 0, 2, "mps", "Max Payload Size Supported", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "128 bytes", "256 bytes", |
| "512 bytes", "1024 bytes", "2048 bytes", "4096 bytes" } } }, |
| { 3, 4, "pfunc", "Phantom Functions Supported", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "No", "1-bit", "2-bits", |
| "3-bits" } } }, |
| { 5, 5, "exttag", "Extended Tag Field", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "5-bit", "8-bit" } } }, |
| { 6, 8, "l0slat", "L0s Acceptable Latency", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "64 ns", "128 ns", "256 ns", |
| "512 ns", "1 us", "2 us", "4 us", "No limit" } } }, |
| { 9, 11, "l1lat", "L1 Acceptable Latency", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "1 us", "2 us", "4 us", "8 us", |
| "16 us", "32 us", "64 us", "No limit" } } }, |
| { 15, 15, "rber", "Role Based Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 16, 16, "errcor", "ERR_COR Subclass", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 18, 25, "csplv", "Captured Slot Power Limit", PRDV_HEX }, |
| { 26, 27, "cspls", "Captured Slot Power Limit Scale", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "1.0x", "0.1x", "0.01x", |
| "0.001x" } } }, |
| { 28, 28, "flr", "Function Level Reset", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_devctl[] = { |
| { 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 2, 2, "ferr", "Fatal Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 3, 3, "unsupreq", "Unsupported Request Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 4, 4, "relord", "Relaxed Ordering", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 5, 7, "mps", "Max Payload Size", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "128 bytes", "256 bytes", |
| "512 bytes", "1024 bytes", "2048 bytes", "4096 bytes" } } }, |
| { 8, 8, "exttag", "Extended Tag Field", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 9, 9, "pfunc", "Phantom Functions", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 9, 9, "auxpm", "Aux Power PM", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 11, 11, "nosnoop", "No Snoop", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 12, 14, "mrrs", "Max Read Request Size", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "128 bytes", "256 bytes", |
| "512 bytes", "1024 bytes", "2048 bytes", "4096 bytes" } } }, |
| { 15, 15, "bcrflr", "Bridge Configuration Retry / Function Level Reset", |
| PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_devsts[] = { |
| { 0, 0, "corerr", "Correctable Error Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 1, 1, "nferr", "Non-Fatal Error Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 2, 2, "ferr", "Fatal Error Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 3, 3, "unsupreq", "Unsupported Request Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 4, 4, "auxpm", "AUX Power Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 5, 5, "txpend", "Transactions Pending", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 6, 6, "eprd", "Emergency Power Reduction Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_linkcap[] = { |
| { 0, 3, "maxspeed", "Maximum Link Speed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s", |
| "8.0 GT/s", "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } }, |
| { 4, 9, "maxwidth", "Maximum Link Width", PRDV_HEX }, |
| { 10, 11, "aspm", "ASPM Support", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } }, |
| { 12, 14, "l0slat", "L0s Exit Latency", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "<64ns", "64-128ns", "128-256ns", |
| "256-512ns", "512ns-1us", "1-2us", "2-4us", ">4us" } } }, |
| { 15, 17, "l1lat", "L1 Exit Latency", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "<1us", "1-2us", "2-4us", "4-8us", |
| "8-16us", "16-32us" "32-64us", ">64us" } } }, |
| { 18, 18, "clockpm", "Clock Power Management", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 19, 19, "supdown", "Surprise Down Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 20, 20, "dlact", "Data Link Layer Active Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 21, 21, "linkbw", "Link Bandwidth Notification Capability", |
| PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 22, 22, "aspmcomp", "ASPM Optionality Compliance", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not compliant", "compliant" } } }, |
| { 24, 31, "portno", "Port Number", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_linkctl[] = { |
| { 0, 1, "aspmctl", "ASPM Control", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "None", "L0s", "L1", "L0s/L1" } } }, |
| { 3, 3, "rcb", "Read Completion Boundary", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "64 byte", "128 byte" } } }, |
| { 4, 4, "disable", "Link Disable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not force disabled", |
| "force disabled" } } }, |
| { 5, 5, "retrain", "Retrain Link", PRDV_HEX }, |
| { 6, 6, "ccc", "Common Clock Configuration", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "asynchronous", "common" } } }, |
| { 7, 7, "extsync", "Extended Sync", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 8, 8, "clkpm", "Clock Power Management", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 9, 9, "hwawd", "Hardware Autonomous Width", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "enabled", "disabled" } } }, |
| { 10, 10, "linkbwint", "Link Bandwidth Management Interrupt", |
| PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled", |
| "enabled" } } }, |
| { 11, 11, "linkabwint", "Link Autonomous Bandwidth Interrupt", |
| PRDV_STRVAL, .prd_val = { .prdv_strval = { "disabled", |
| "enabled" } } }, |
| { 14, 15, "drs", "DRS Signaling Control", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not reported", "Interrupt enabled", |
| "DRS->FRS enabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_linksts[] = { |
| { 0, 3, "speed", "Link Speed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s", |
| "8.0 GT/s", "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } }, |
| { 4, 9, "width", "Link Width", PRDV_HEX }, |
| { 11, 11, "training", "Link Training", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 12, 12, "slotclk", "Slot Clock Configuration", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "asynchronous", "common" } } }, |
| { 13, 13, "dllact", "Data Link Layer Link Active", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 14, 14, "linkbw", "Link Bandwidth Management Status", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no change", "change occurred" } } }, |
| { 15, 15, "linkabw", "Link Autonomous Bandwidth Status", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no change", "change occurred" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_slotcap[] = { |
| { 0, 0, "attnbtn", "Attention Button Present", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 1, 1, "pwrctrl", "Power Controller Present", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 2, 2, "mrlsen", "MRL Sensor Present", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 3, 3, "attnind", "Attention Indicator Present", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 4, 4, "pwrind", "Power Indicator Present", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 5, 5, "hpsup", "Hot-Plug Surprise", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 6, 6, "hpcap", "Hot-Plug Capable ", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 7, 14, "slotplv", "Slot Power Limit Value", PRDV_HEX }, |
| { 15, 16, "slotpls", "Slot Power Limit Scale", PRDV_HEX }, |
| { 17, 17, "emi", "Electromechanical Interlock Present", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 18, 18, "ncc", "No Command Completed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 19, 31, "slotno", "Physical Slot Number", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_slotctl[] = { |
| { 0, 0, "attnbtn", "Attention Button Pressed Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 1, "pwrflt", "Power Fault Detected Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 2, 2, "mrlchg", "MRL Sensor Changed Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 3, 3, "preschg", "Presence Detect Changed Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 4, 4, "ccmpltint", "Command Complete Interrupt", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 5, 5, "hpi", "Hot Plug Interrupt Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 6, 7, "attnind", "Attention Indicator Control", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } }, |
| { 8, 9, "pwrin", "Power Indicator Control", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { NULL, "on", "blink", "off" } } }, |
| { 10, 10, "pwrctrl", "Power Controller Control", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "power on", "power off" } } }, |
| { 11, 11, "emi", "Electromechanical Interlock Control", PRDV_HEX }, |
| { 12, 12, "dll", "Data Link Layer State Changed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 13, 13, "autopowdis", "Auto Slot Power Limit", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "enabled", "disabled" } } }, |
| { 14, 14, "ibpddis", "In-Band PD", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "enabled", "disabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_slotsts[] = { |
| { 0, 0, "attnbtn", "Attention Button Pressed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 1, 1, "pwrflt", "Power Fault Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 2, 2, "mrlchg", "MRL Sensor Changed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 3, 3, "preschg", "Presence Detect Changed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 4, 4, "ccmplt", "Command Complete", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 5, 5, "mrlsen", "MRL Sensor State", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "closed", "open" } } }, |
| { 6, 6, "presdet", "Presence Detect State", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not present", "present" } } }, |
| { 7, 7, "emi", "Electromechanical Interlock", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disengaged", "engaged" } } }, |
| { 8, 8, "dll", "Data Link Layer State Changed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_rootcap[] = { |
| { 0, 0, "syscorerr", "System Error on Correctable Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 1, "sysnonftl", "System Error on Non-Fatal Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 2, 2, "sysfatal", "System Error on Fatal Error", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 3, 3, "pmeie", "PME Interrupt", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 4, 4, "crssw", "CRS Software Visibility", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_rootctl[] = { |
| { 0, 0, "crssw", "CRS Software Visibility", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_rootsts[] = { |
| { 0, 15, "pmereqid", "PME Requester ID", PRDV_HEX }, |
| { 16, 16, "pmests", "PME Status", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "deasserted", "asserted" } } }, |
| { 17, 17, "pmepend", "PME Pending", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_devcap2[] = { |
| { 0, 3, "cmpto", "Completion Timeout Ranges Supported", PRDV_BITFIELD, |
| .prd_val = { .prdv_strval = { "50us-10ms", "10ms-250ms", |
| "250ms-4s", "4s-64s" } } }, |
| { 4, 4, "cmptodis", "Completion Timeout Disable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 6, 6, "atomroute", "AtomicOp Routing", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 7, 7, "atom32", "32-bit AtomicOp Completer", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 8, 8, "atom64", "64-bit AtomicOp Completer", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 9, 9, "cas128", "128-bit CAS Completer", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 10, 10, "norelord", "No Ro-enabld PR-PR Passing", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 11, 11, "ltr", "LTR Mechanism", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 12, 13, "tph", "TPH Completer", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "TPH supported", |
| NULL, "TPH and Extended TPH supported" } } }, |
| { 14, 15, "lncls", "LN System CLS", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", |
| "LN with 64-byte cachelines", "LN with 128-byte cachelines" } } }, |
| { 16, 16, "tag10comp", "10-bit Tag Completer", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 17, 17, "tag10req", "10-bit Tag Requester", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 18, 19, "obff", "OBFF", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "Message Signaling", |
| "WAKE# Signaling", "WAKE# and Message Signaling" } } }, |
| { 20, 20, "extfmt", "Extended Fmt Field Supported", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 21, 21, "eetlp", "End-End TLP Prefix Supported", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 22, 23, "maxeetlp", "Max End-End TLP Prefixes", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "4", "1", "2", "3" } } }, |
| { 24, 25, "empr", "Emergency Power Reduction", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", |
| "supported, device-specific", |
| "supported, from factor or device-specific" } } }, |
| { 21, 21, "emprinit", |
| "Emergency Power Reduction Initialization Required", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 31, 31, "frs", "Function Readiness Status", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_devctl2[] = { |
| { 0, 3, "cmpto", "Completion Timeout", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "50us-50ms", "50us-100us", |
| "1ms-10ms", NULL, NULL, "16ms-55ms", "65ms-210ms", NULL, NULL, |
| "260ms-900ms", "1s-3.5s", NULL, NULL, "4s-13s", "17s-64s" } } }, |
| { 4, 4, "cmptodis", "Completion Timeout Disabled", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not disabled", "disabled" } } }, |
| { 5, 5, "ari", "ARI Forwarding", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 6, 6, "atomreq", "AtomicOp Requester", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 7, 7, "atomblock", "AtomicOp Egress Blocking", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unblocked", "blocked" } } }, |
| { 8, 8, "idoreq", "ID-Based Ordering Request", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 9, 9, "idocomp", "ID-Based Ordering Completion", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 10, 10, "ltr", "LTR Mechanism", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 11, 11, "empowred", "Emergency Power Reduction", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not requested", "requested" } } }, |
| { 12, 12, "tag10req", "10-bit Tag Requester", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 13, 14, "obff", "OBFF", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "message signaling - A", |
| "message signaling - B", "WAKE# signaling" } } }, |
| { 15, 15, "eetlpblk", "End-End TLP Prefix Blocking", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unblocked", "blocked" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_devsts2[] = { |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_linkcap2[] = { |
| { 1, 7, "supspeeds", "Supported Link Speeds", PRDV_BITFIELD, |
| .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s", |
| "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } }, |
| { 8, 8, "crosslink", "Crosslink", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 9, 15, "skposgen", "Lower SKP OS Generation Supported Speeds Vector", |
| PRDV_BITFIELD, |
| .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s", |
| "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } }, |
| { 16, 22, "skposrecv", "Lower SKP OS Reception Supported Speeds Vector", |
| PRDV_BITFIELD, |
| .prd_val = { .prdv_strval = { "2.5 GT/s", "5.0 GT/s", "8.0 GT/s", |
| "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } }, |
| { 23, 23, "retimedet", "Retimer Presence Detect Supported", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 24, 24, "retime2det", "Two Retimers Presence Detect Supported", |
| PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 31, 31, "drs", "Device Readiness Status", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_linkctl2[] = { |
| { 0, 3, "targspeed", "Target Link Speed", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { NULL, "2.5 GT/s", "5.0 GT/s", |
| "8.0 GT/s", "16.0 GT/s", "32.0 GT/s", "64.0 GT/s" } } }, |
| { 4, 4, "comp", "Enter Compliance", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 5, 5, "hwautosp", "Hardware Autonomous Speed Disable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not disabled", "disabled" } } }, |
| { 6, 6, "seldeemph", "Selectable De-emphasis", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } }, |
| { 7, 9, "txmarg", "TX Margin", PRDV_HEX }, |
| { 10, 10, "modcomp", "Enter Modified Compliance", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 11, 11, "compsos", "Compliance SOS", |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 12, 15, "compemph", "Compliance Preset/De-emphasis", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_linksts2[] = { |
| { 0, 0, "curdeemph", "Current De-emphasis Level", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "-6 dB", "-3.5 dB" } } }, |
| { 1, 1, "eq8comp", "Equalization 8.0 GT/s Complete", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 2, 2, "eq8p1comp", "Equalization 8.0 GT/s Phase 1", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } }, |
| { 3, 3, "eq8p2comp", "Equalization 8.0 GT/s Phase 2", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } }, |
| { 4, 4, "eq8p3comp", "Equalization 8.0 GT/s Phase 3", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsuccessful", "successful" } } }, |
| { 5, 5, "linkeq8req", "Link Equalization Request 8.0 GT/s", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "not requested", "requested" } } }, |
| { 6, 6, "retimedet", "Retimer Presence Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 7, 7, "retime2det", "Two Retimers Presence Detected", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { 8, 9, "crosslink", "Crosslink Resolution", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "upstream port", |
| "downstream port", "incomplete" } } }, |
| { 12, 14, "dscomppres", "Downstream Component Presence", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "link down - undetermined", |
| "link down - not present", "link down - present", NULL, |
| "link up - present", "link up - present and DRS" } } }, |
| { 15, 15, "drsrx", "DRS Message Received", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "no", "yes" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_slotcap2[] = { |
| { 0, 0, "ibpddis", "In-Band PD Disable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_slotctl2[] = { |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_slotsts2[] = { |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_dev[] = { |
| { PCIE_PCIECAP, 2, "cap", "Capability Register", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap }, |
| { PCIE_DEVCAP, 4, "devcap", "Device Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap }, |
| { PCIE_DEVSTS, 2, "devsts", "Device Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_link[] = { |
| { PCIE_PCIECAP, 2, "cap", "Capability Register", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap }, |
| { PCIE_DEVCAP, 4, "devcap", "Device Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap }, |
| { PCIE_DEVSTS, 2, "devsts", "Device Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts }, |
| { PCIE_LINKCAP, 4, "linkcap", "Link Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap }, |
| { PCIE_LINKCTL, 2, "linkctl", "Link Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl }, |
| { PCIE_LINKSTS, 2, "linksts", "Link Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_slot[] = { |
| { PCIE_PCIECAP, 2, "cap", "Capability Register", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap }, |
| { PCIE_DEVCAP, 4, "devcap", "Device Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap }, |
| { PCIE_DEVSTS, 2, "devsts", "Device Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts }, |
| { PCIE_LINKCAP, 4, "linkcap", "Link Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap }, |
| { PCIE_LINKCTL, 2, "linkctl", "Link Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl }, |
| { PCIE_LINKSTS, 2, "linksts", "Link Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts }, |
| { PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap }, |
| { PCIE_SLOTCTL, 2, "slotctl", "Slot Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl }, |
| { PCIE_SLOTSTS, 2, "slotsts", "Slot Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts }, |
| { -1, -1, NULL } |
| }; |
| |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v1_all[] = { |
| { PCIE_PCIECAP, 2, "cap", "Capability Register", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap }, |
| { PCIE_DEVCAP, 4, "devcap", "Device Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap }, |
| { PCIE_DEVSTS, 2, "devsts", "Device Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts }, |
| { PCIE_LINKCAP, 4, "linkcap", "Link Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap }, |
| { PCIE_LINKCTL, 2, "linkctl", "Link Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl }, |
| { PCIE_LINKSTS, 2, "linksts", "Link Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts }, |
| { PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap }, |
| { PCIE_SLOTCTL, 2, "slotctl", "Slot Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl }, |
| { PCIE_SLOTSTS, 2, "slotsts", "Slot Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts }, |
| { PCIE_ROOTCTL, 2, "rootctl", "Root control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl }, |
| { PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap }, |
| { PCIE_ROOTSTS, 4, "rootsts", "Root Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_pcie_v2[] = { |
| { PCIE_PCIECAP, 2, "cap", "Capability Register", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_cap }, |
| { PCIE_DEVCAP, 4, "devcap", "Device Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap }, |
| { PCIE_DEVCTL, 2, "devctl", "Device Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl }, |
| { PCIE_DEVSTS, 2, "devsts", "Device Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts }, |
| { PCIE_LINKCAP, 4, "linkcap", "Link Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap }, |
| { PCIE_LINKCTL, 2, "linkctl", "Link Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl }, |
| { PCIE_LINKSTS, 2, "linksts", "Link Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts }, |
| { PCIE_SLOTCAP, 4, "slotcap", "Slot Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap }, |
| { PCIE_SLOTCTL, 2, "slotctl", "Slot Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl }, |
| { PCIE_SLOTSTS, 2, "slotsts", "Slot Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts }, |
| { PCIE_ROOTCTL, 2, "rootctl", "Root Control", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootctl }, |
| { PCIE_ROOTCAP, 2, "rootcap", "Root Capabilities", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootcap }, |
| { PCIE_ROOTSTS, 4, "rootsts", "Root Status", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_rootsts }, |
| { PCIE_DEVCAP2, 4, "devcap2", "Device Capabilities 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devcap2 }, |
| { PCIE_DEVCTL2, 2, "devctl2", "Device Control 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devctl2 }, |
| { PCIE_DEVSTS2, 2, "devsts2", "Device Status 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_devsts2 }, |
| { PCIE_LINKCAP2, 4, "linkcap2", "Link Capabilities 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkcap2 }, |
| { PCIE_LINKCTL2, 2, "linkctl2", "Link Control 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linkctl2 }, |
| { PCIE_LINKSTS2, 2, "linksts2", "Link Status 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_linksts2 }, |
| { PCIE_SLOTCAP2, 4, "slotcap2", "Slot Capabilities 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotcap2 }, |
| { PCIE_SLOTCTL2, 2, "slotctl2", "Slot Control 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotctl2 }, |
| { PCIE_SLOTSTS2, 2, "slotsts2", "Slot Status 2", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_pcie_slotsts2 }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * PCIe Extended Capability Header |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_pcie_caphdr[] = { |
| { 0, 15, "capid", "Capability ID", PRDV_HEX }, |
| { 16, 19, "version", "Capability Version", PRDV_HEX }, |
| { 20, 32, "offset", "Next Capability Offset", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * VPD Capability |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_vpd_addr[] = { |
| { 0, 14, "addr", "VPD Address", PRDV_HEX }, |
| { 15, 15, "flag", "Flag", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_vpd[] = { |
| { 0x2, 2, "addr", "VPD Address Register", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_vpd_addr }, |
| { 0x4, 4, "data", "VPD Data", pcieadm_cfgspace_print_hex }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * SATA Capability per AHCI 1.3.1 |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_sata_cr0[] = { |
| { 0, 3, "minrev", "Minor Revision", PRDV_HEX }, |
| { 4, 7, "majrev", "Major Revision", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_sata_cr1[] = { |
| { 0, 3, "bar", "BAR Location", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 2 } } }, |
| { 4, 23, "offset", "BAR Offset", PRDV_HEX, |
| .prd_val = { .prdv_hex = { 2 } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_sata[] = { |
| { 0x2, 2, "satacr0", "SATA Capability Register 0", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr0 }, |
| { 0x4, 4, "satacr1", "SATA Capability Register 1", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_sata_cr1 }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * Debug Capability per EHCI |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_debug[] = { |
| { 0, 12, "offset", "BAR Offset", PRDV_HEX }, |
| { 13, 15, "bar", "BAR Location ", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { NULL, "BAR 0", "BAR 1", "BAR 2", |
| "BAR 3", "BAR 4", "BAR 5" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_cfgspace_print_t pcieadm_cap_debug[] = { |
| { 0x2, 2, "port", "Debug Port", |
| pcieadm_cfgspace_print_regdef, pcieadm_regdef_debug }, |
| { -1, -1, NULL } |
| }; |
| |
| /* |
| * AER Capability |
| */ |
| static const pcieadm_regdef_t pcieadm_regdef_aer_ue[] = { |
| { 4, 4, "dlp", "Data Link Protocol Error", PRDV_HEX }, |
| { 5, 5, "sde", "Surprise Down Error", PRDV_HEX }, |
| { 12, 12, "ptlp", "Poisoned TLP Received", PRDV_HEX }, |
| { 13, 13, "fcp", "Flow Control Protocol Error", PRDV_HEX }, |
| { 14, 14, "cto", "Completion Timeout", PRDV_HEX }, |
| { 15, 15, "cab", "Completion Abort", PRDV_HEX }, |
| { 16, 16, "unco", "Unexpected Completion", PRDV_HEX }, |
| { 17, 17, "rxov", "Receiver Overflow", PRDV_HEX }, |
| { 18, 18, "maltlp", "Malformed TLP", PRDV_HEX }, |
| { 19, 19, "ecrc", "ECRC Error", PRDV_HEX }, |
| { 20, 20, "usuprx", "Unsupported Request Error", PRDV_HEX }, |
| { 21, 21, "acs", "ACS Violation", PRDV_HEX }, |
| { 22, 22, "ueint", "Uncorrectable Internal Error", PRDV_HEX }, |
| { 23, 23, "mcbtlp", "MC Blocked TLP", PRDV_HEX }, |
| { 24, 24, "atoomeb", "AtomicOp Egress Blocked", PRDV_HEX }, |
| { 25, 25, "tlppb", "TLP Prefix Blocked Error", PRDV_HEX }, |
| { 26, 26, "ptlpeb", "Poisoned TLP Egress Blocked", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_aer_ce[] = { |
| { 0, 0, "rxerr", "Receiver Error", PRDV_HEX }, |
| { 6, 6, "badtlp", "Bad TLP", PRDV_HEX }, |
| { 7, 7, "baddllp", "Bad DLLP", PRDV_HEX }, |
| { 8, 8, "replayro", "REPLAY_NUM Rollover", PRDV_HEX }, |
| { 12, 12, "rtto", "Replay timer Timeout", PRDV_HEX }, |
| { 13, 13, "advnfe", "Advisory Non-Fatal Error", PRDV_HEX }, |
| { 14, 14, "ceint", "Correctable Internal Error", PRDV_HEX }, |
| { 15, 15, "headlov", "Header Log Overflow", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_aer_ctrl[] = { |
| { 0, 4, "feptr", "First Error Pointer", PRDV_HEX }, |
| { 5, 5, "ecgencap", "ECRC Generation Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 6, 6, "ecgenen", "ECRC Generation Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 7, 7, "ecchkcap", "ECRC Check Capable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "unsupported", "supported" } } }, |
| { 8, 8, "ecchken", "ECRC Check Enable", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_aer_rootcom[] = { |
| { 0, 0, "corerr", "Correctable Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 1, 1, "nferr", "Non-Fatal Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { 2, 2, "faterr", "Fatal Error Reporting", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "disabled", "enabled" } } }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_aer_rootsts[] = { |
| { 0, 0, "errcor", "ERR_COR Received", PRDV_HEX }, |
| { 1, 1, "merrcor", "Multiple ERR_COR Received", PRDV_HEX }, |
| { 2, 2, "errfnf", "ERR_FATAL/NONFATAL Received", PRDV_HEX }, |
| { 3, 3, "merrfnf", "Multiple ERR_FATAL/NONFATAL Received", PRDV_HEX }, |
| { 4, 4, "fuefat", "First Uncorrectable Fatal", PRDV_HEX }, |
| { 5, 5, "nferrrx", "Non-Fatal Error Messages Received", PRDV_HEX }, |
| { 6, 6, "faterrx", "Fatal Error Messages Received", PRDV_HEX }, |
| { 7, 8, "errcorsc", "ERR_COR Subclass", PRDV_STRVAL, |
| .prd_val = { .prdv_strval = { "ECS Legacy", "ECS SIG_SFW", |
| "ECS SIG_OS", "ECS Extended" } } }, |
| { 27, 31, "inum", "Advanced Error Interrupt Message", PRDV_HEX }, |
| { -1, -1, NULL } |
| }; |
| |
| static const pcieadm_regdef_t pcieadm_regdef_aer_esi[] = { |
| { 0, 15, "errcorr", "ERR_COR Source", PRDV_HEX },
|