📄 ls-caps.c
字号:
FLAG(w, PCI_EXP_SLTSTA_PRES), FLAG(w, PCI_EXP_SLTSTA_INTERLOCK)); printf("\t\t\tChanged: MRL%c PresDet%c LinkState%c\n", FLAG(w, PCI_EXP_SLTSTA_MRLS), FLAG(w, PCI_EXP_SLTSTA_PRSD), FLAG(w, PCI_EXP_SLTSTA_LLCHG));}static void cap_express_root(struct device *d, int where){ u32 w = get_conf_word(d, where + PCI_EXP_RTCTL); printf("\t\tRootCtl: ErrCorrectable%c ErrNon-Fatal%c ErrFatal%c PMEIntEna%c CRSVisible%c\n", FLAG(w, PCI_EXP_RTCTL_SECEE), FLAG(w, PCI_EXP_RTCTL_SENFEE), FLAG(w, PCI_EXP_RTCTL_SEFEE), FLAG(w, PCI_EXP_RTCTL_PMEIE), FLAG(w, PCI_EXP_RTCTL_CRSVIS)); w = get_conf_word(d, where + PCI_EXP_RTCAP); printf("\t\tRootCap: CRSVisible%c\n", FLAG(w, PCI_EXP_RTCAP_CRSVIS)); w = get_conf_word(d, where + PCI_EXP_RTSTA); printf("\t\tRootSta: PME ReqID %04x, PMEStatus%c PMEPending%c\n", w & PCI_EXP_RTSTA_PME_REQID, FLAG(w, PCI_EXP_RTSTA_PME_STATUS), FLAG(w, PCI_EXP_RTSTA_PME_PENDING));}static const char *cap_express_dev2_timeout_range(int type){ /* Decode Completion Timeout Ranges. */ switch (type) { case 0: return "Not Supported"; case 1: return "Range A"; case 2: return "Range B"; case 3: return "Range AB"; case 6: return "Range BC"; case 7: return "Range ABC"; case 14: return "Range BCD"; case 15: return "Range ABCD"; default: return "Unknown"; }}static const char *cap_express_dev2_timeout_value(int type){ /* Decode Completion Timeout Value. */ switch (type) { case 0: return "50us to 50ms"; case 1: return "50us to 100us"; case 2: return "1ms to 10ms"; case 5: return "16ms to 55ms"; case 6: return "65ms to 210ms"; case 9: return "260ms to 900ms"; case 10: return "1s to 3.5s"; case 13: return "4s to 13s"; case 14: return "17s to 64s"; default: return "Unknown"; }}static void cap_express_dev2(struct device *d, int where, int type){ u32 l; u16 w; l = get_conf_long(d, where + PCI_EXP_DEVCAP2); printf("\t\tDevCap2: Completion Timeout: %s, TimeoutDis%c", cap_express_dev2_timeout_range(PCI_EXP_DEV2_TIMEOUT_RANGE(l)), FLAG(l, PCI_EXP_DEV2_TIMEOUT_DIS)); if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM) printf(" ARIFwd%c\n", FLAG(l, PCI_EXP_DEV2_ARI)); else printf("\n"); w = get_conf_word(d, where + PCI_EXP_DEVCTL2); printf("\t\tDevCtl2: Completion Timeout: %s, TimeoutDis%c", cap_express_dev2_timeout_value(PCI_EXP_DEV2_TIMEOUT_VALUE(w)), FLAG(w, PCI_EXP_DEV2_TIMEOUT_DIS)); if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM) printf(" ARIFwd%c\n", FLAG(w, PCI_EXP_DEV2_ARI)); else printf("\n");}static const char *cap_express_link2_speed(int type){ switch (type) { case 0: /* hardwire to 0 means only the 2.5GT/s is supported */ case 1: return "2.5GT/s"; case 2: return "5GT/s"; default: return "Unknown"; }}static const char *cap_express_link2_deemphasis(int type){ switch (type) { case 0: return "-6dB"; case 1: return "-3.5dB"; default: return "Unknown"; }}static const char *cap_express_link2_transmargin(int type){ switch (type) { case 0: return "Normal Operating Range"; case 1: return "800-1200mV(full-swing)/400-700mV(half-swing)"; case 2: case 3: case 4: case 5: return "200-400mV(full-swing)/100-200mV(half-swing)"; default: return "Unknown"; }}static void cap_express_link2(struct device *d, int where, int type UNUSED){ u16 w; w = get_conf_word(d, where + PCI_EXP_LNKCTL2); printf("\t\tLnkCtl2: Target Link Speed: %s, EnterCompliance%c SpeedDis%c, Selectable De-emphasis: %s\n" "\t\t\t Transmit Margin: %s, EnterModifiedCompliance%c ComplianceSOS%c\n" "\t\t\t Compliance De-emphasis: %s\n", cap_express_link2_speed(PCI_EXP_LNKCTL2_SPEED(w)), FLAG(w, PCI_EXP_LNKCTL2_CMPLNC), FLAG(w, PCI_EXP_LNKCTL2_SPEED_DIS), cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_DEEMPHASIS(w)), cap_express_link2_transmargin(PCI_EXP_LNKCTL2_MARGIN(w)), FLAG(w, PCI_EXP_LNKCTL2_MOD_CMPLNC), FLAG(w, PCI_EXP_LNKCTL2_CMPLNC_SOS), cap_express_link2_deemphasis(PCI_EXP_LNKCTL2_COM_DEEMPHASIS(w))); w = get_conf_word(d, where + PCI_EXP_LNKSTA2); printf("\t\tLnkSta2: Current De-emphasis Level: %s\n", cap_express_link2_deemphasis(PCI_EXP_LINKSTA2_DEEMPHASIS(w)));}static void cap_express_slot2(struct device *d UNUSED, int where UNUSED){ /* No capabilities that require this field in PCIe rev2.0 spec. */}static voidcap_express(struct device *d, int where, int cap){ int type = (cap & PCI_EXP_FLAGS_TYPE) >> 4; int size; int slot = 0; printf("Express "); if (verbose >= 2) printf("(v%d) ", cap & PCI_EXP_FLAGS_VERS); switch (type) { case PCI_EXP_TYPE_ENDPOINT: printf("Endpoint"); break; case PCI_EXP_TYPE_LEG_END: printf("Legacy Endpoint"); break; case PCI_EXP_TYPE_ROOT_PORT: slot = cap & PCI_EXP_FLAGS_SLOT; printf("Root Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT)); break; case PCI_EXP_TYPE_UPSTREAM: printf("Upstream Port"); break; case PCI_EXP_TYPE_DOWNSTREAM: slot = cap & PCI_EXP_FLAGS_SLOT; printf("Downstream Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT)); break; case PCI_EXP_TYPE_PCI_BRIDGE: printf("PCI/PCI-X Bridge"); break; case PCI_EXP_TYPE_PCIE_BRIDGE: printf("PCI/PCI-X to PCI-Express Bridge"); break; case PCI_EXP_TYPE_ROOT_INT_EP: printf("Root Complex Integrated Endpoint"); break; case PCI_EXP_TYPE_ROOT_EC: printf("Root Complex Event Collector"); break; default: printf("Unknown type %d", type); } printf(", MSI %02x\n", (cap & PCI_EXP_FLAGS_IRQ) >> 9); if (verbose < 2) return; size = 16; if (slot) size = 24; if (type == PCI_EXP_TYPE_ROOT_PORT) size = 32; if (!config_fetch(d, where + PCI_EXP_DEVCAP, size)) return; cap_express_dev(d, where, type); cap_express_link(d, where, type); if (slot) cap_express_slot(d, where); if (type == PCI_EXP_TYPE_ROOT_PORT) cap_express_root(d, where); if ((cap & PCI_EXP_FLAGS_VERS) < 2) return; size = 16; if (slot) size = 24; if (!config_fetch(d, where + PCI_EXP_DEVCAP2, size)) return; cap_express_dev2(d, where, type); cap_express_link2(d, where, type); if (slot) cap_express_slot2(d, where);}static voidcap_msix(struct device *d, int where, int cap){ u32 off; printf("MSI-X: Enable%c Mask%c TabSize=%d\n", FLAG(cap, PCI_MSIX_ENABLE), FLAG(cap, PCI_MSIX_MASK), (cap & PCI_MSIX_TABSIZE) + 1); if (verbose < 2 || !config_fetch(d, where + PCI_MSIX_TABLE, 8)) return; off = get_conf_long(d, where + PCI_MSIX_TABLE); printf("\t\tVector table: BAR=%d offset=%08x\n", off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR); off = get_conf_long(d, where + PCI_MSIX_PBA); printf("\t\tPBA: BAR=%d offset=%08x\n", off & PCI_MSIX_BIR, off & ~PCI_MSIX_BIR);}static voidcap_slotid(int cap){ int esr = cap & 0xff; int chs = cap >> 8; printf("Slot ID: %d slots, First%c, chassis %02x\n", esr & PCI_SID_ESR_NSLOTS, FLAG(esr, PCI_SID_ESR_FIC), chs);}static voidcap_ssvid(struct device *d, int where){ u16 subsys_v, subsys_d; char ssnamebuf[256]; if (!config_fetch(d, where, 8)) return; subsys_v = get_conf_word(d, where + PCI_SSVID_VENDOR); subsys_d = get_conf_word(d, where + PCI_SSVID_DEVICE); printf("Subsystem: %s\n", pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, d->dev->vendor_id, d->dev->device_id, subsys_v, subsys_d));}static voidcap_debug_port(int cap){ int bar = cap >> 13; int pos = cap & 0x1fff; printf("Debug port: BAR=%d offset=%04x\n", bar, pos);}voidshow_caps(struct device *d){ int can_have_ext_caps = 0; if (get_conf_word(d, PCI_STATUS) & PCI_STATUS_CAP_LIST) { int where = get_conf_byte(d, PCI_CAPABILITY_LIST) & ~3; byte been_there[256]; memset(been_there, 0, 256); while (where) { int id, next, cap; printf("\tCapabilities: "); if (!config_fetch(d, where, 4)) { puts("<access denied>"); break; } id = get_conf_byte(d, where + PCI_CAP_LIST_ID); next = get_conf_byte(d, where + PCI_CAP_LIST_NEXT) & ~3; cap = get_conf_word(d, where + PCI_CAP_FLAGS); printf("[%02x] ", where); if (been_there[where]++) { printf("<chain looped>\n"); break; } if (id == 0xff) { printf("<chain broken>\n"); break; } switch (id) { case PCI_CAP_ID_PM: cap_pm(d, where, cap); break; case PCI_CAP_ID_AGP: cap_agp(d, where, cap); break; case PCI_CAP_ID_VPD: cap_vpd(d); break; case PCI_CAP_ID_SLOTID: cap_slotid(cap); break; case PCI_CAP_ID_MSI: cap_msi(d, where, cap); break; case PCI_CAP_ID_CHSWP: printf("CompactPCI hot-swap <?>\n"); break; case PCI_CAP_ID_PCIX: cap_pcix(d, where); can_have_ext_caps = 1; break; case PCI_CAP_ID_HT: cap_ht(d, where, cap); break; case PCI_CAP_ID_VNDR: printf("Vendor Specific Information <?>\n"); break; case PCI_CAP_ID_DBG: cap_debug_port(cap); break; case PCI_CAP_ID_CCRC: printf("CompactPCI central resource control <?>\n"); break; case PCI_CAP_ID_HOTPLUG: printf("Hot-plug capable\n"); break; case PCI_CAP_ID_SSVID: cap_ssvid(d, where); break; case PCI_CAP_ID_AGP3: printf("AGP3 <?>\n"); break; case PCI_CAP_ID_SECURE: printf("Secure device <?>\n"); break; case PCI_CAP_ID_EXP: cap_express(d, where, cap); can_have_ext_caps = 1; break; case PCI_CAP_ID_MSIX: cap_msix(d, where, cap); break; case PCI_CAP_ID_SATA: printf("SATA HBA <?>\n"); break; case PCI_CAP_ID_AF: printf("PCIe advanced features <?>\n"); break; default: printf("#%02x [%04x]\n", id, cap); } where = next; } } if (can_have_ext_caps) show_ext_caps(d);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -