📄 lspci.c
字号:
else { mem_base = (mem_base & PCI_MEMORY_RANGE_MASK) << 16; mem_limit = (mem_limit & PCI_MEMORY_RANGE_MASK) << 16; if (mem_base <= mem_limit || verb) printf("\tMemory behind bridge: %08x-%08x\n", mem_base, mem_limit + 0xfffff); } if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) || (pref_type != PCI_PREF_RANGE_TYPE_32 && pref_type != PCI_PREF_RANGE_TYPE_64)) printf("\t!!! Unknown prefetchable memory range types %x/%x\n", pref_base, pref_limit); else { pref_base = (pref_base & PCI_PREF_RANGE_MASK) << 16; pref_limit = (pref_limit & PCI_PREF_RANGE_MASK) << 16; if (pref_base <= pref_limit || verb) { if (pref_type == PCI_PREF_RANGE_TYPE_32) printf("\tPrefetchable memory behind bridge: %08x-%08x\n", pref_base, pref_limit + 0xfffff); else printf("\tPrefetchable memory behind bridge: %08x%08x-%08x%08x\n", get_conf_long(d, PCI_PREF_BASE_UPPER32), pref_base, get_conf_long(d, PCI_PREF_LIMIT_UPPER32), pref_limit + 0xfffff); } } if (verbose > 1) printf("\tSecondary status: 66MHz%c FastB2B%c ParErr%c DEVSEL=%s >TAbort%c <TAbort%c <MAbort%c <SERR%c <PERR%c\n", FLAG(sec_stat, PCI_STATUS_66MHZ), FLAG(sec_stat, PCI_STATUS_FAST_BACK), FLAG(sec_stat, PCI_STATUS_PARITY), ((sec_stat & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" : ((sec_stat & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" : ((sec_stat & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??", FLAG(sec_stat, PCI_STATUS_SIG_TARGET_ABORT), FLAG(sec_stat, PCI_STATUS_REC_TARGET_ABORT), FLAG(sec_stat, PCI_STATUS_REC_MASTER_ABORT), FLAG(sec_stat, PCI_STATUS_SIG_SYSTEM_ERROR), FLAG(sec_stat, PCI_STATUS_DETECTED_PARITY)); show_rom(d, PCI_ROM_ADDRESS1); if (verbose > 1) { printf("\tBridgeCtl: Parity%c SERR%c NoISA%c VGA%c MAbort%c >Reset%c FastB2B%c\n", FLAG(brc, PCI_BRIDGE_CTL_PARITY), FLAG(brc, PCI_BRIDGE_CTL_SERR), FLAG(brc, PCI_BRIDGE_CTL_NO_ISA), FLAG(brc, PCI_BRIDGE_CTL_VGA), FLAG(brc, PCI_BRIDGE_CTL_MASTER_ABORT), FLAG(brc, PCI_BRIDGE_CTL_BUS_RESET), FLAG(brc, PCI_BRIDGE_CTL_FAST_BACK)); printf("\t\tPriDiscTmr%c SecDiscTmr%c DiscTmrStat%c DiscTmrSERREn%c\n", FLAG(brc, PCI_BRIDGE_CTL_PRI_DISCARD_TIMER), FLAG(brc, PCI_BRIDGE_CTL_SEC_DISCARD_TIMER), FLAG(brc, PCI_BRIDGE_CTL_DISCARD_TIMER_STATUS), FLAG(brc, PCI_BRIDGE_CTL_DISCARD_TIMER_SERR_EN)); } show_caps(d);}static voidshow_htype2(struct device *d){ int i; word cmd = get_conf_word(d, PCI_COMMAND); word brc = get_conf_word(d, PCI_CB_BRIDGE_CONTROL); word exca; int verb = verbose > 2; show_bases(d, 1); printf("\tBus: primary=%02x, secondary=%02x, subordinate=%02x, sec-latency=%d\n", get_conf_byte(d, PCI_CB_PRIMARY_BUS), get_conf_byte(d, PCI_CB_CARD_BUS), get_conf_byte(d, PCI_CB_SUBORDINATE_BUS), get_conf_byte(d, PCI_CB_LATENCY_TIMER)); for (i=0; i<2; i++) { int p = 8*i; u32 base = get_conf_long(d, PCI_CB_MEMORY_BASE_0 + p); u32 limit = get_conf_long(d, PCI_CB_MEMORY_LIMIT_0 + p); if (limit > base || verb) printf("\tMemory window %d: %08x-%08x%s%s\n", i, base, limit, (cmd & PCI_COMMAND_MEMORY) ? "" : " [disabled]", (brc & (PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 << i)) ? " (prefetchable)" : ""); } for (i=0; i<2; i++) { int p = 8*i; u32 base = get_conf_long(d, PCI_CB_IO_BASE_0 + p); u32 limit = get_conf_long(d, PCI_CB_IO_LIMIT_0 + p); if (!(base & PCI_IO_RANGE_TYPE_32)) { base &= 0xffff; limit &= 0xffff; } base &= PCI_CB_IO_RANGE_MASK; limit = (limit & PCI_CB_IO_RANGE_MASK) + 3; if (base <= limit || verb) printf("\tI/O window %d: %08x-%08x%s\n", i, base, limit, (cmd & PCI_COMMAND_IO) ? "" : " [disabled]"); } if (get_conf_word(d, PCI_CB_SEC_STATUS) & PCI_STATUS_SIG_SYSTEM_ERROR) printf("\tSecondary status: SERR\n"); if (verbose > 1) printf("\tBridgeCtl: Parity%c SERR%c ISA%c VGA%c MAbort%c >Reset%c 16bInt%c PostWrite%c\n", FLAG(brc, PCI_CB_BRIDGE_CTL_PARITY), FLAG(brc, PCI_CB_BRIDGE_CTL_SERR), FLAG(brc, PCI_CB_BRIDGE_CTL_ISA), FLAG(brc, PCI_CB_BRIDGE_CTL_VGA), FLAG(brc, PCI_CB_BRIDGE_CTL_MASTER_ABORT), FLAG(brc, PCI_CB_BRIDGE_CTL_CB_RESET), FLAG(brc, PCI_CB_BRIDGE_CTL_16BIT_INT), FLAG(brc, PCI_CB_BRIDGE_CTL_POST_WRITES)); if (d->config_cached < 128) { printf("\t<access denied to the rest>\n"); return; } exca = get_conf_word(d, PCI_CB_LEGACY_MODE_BASE); if (exca) printf("\t16-bit legacy interface ports at %04x\n", exca);}static voidshow_verbose(struct device *d){ struct pci_dev *p = d->dev; word status = get_conf_word(d, PCI_STATUS); word cmd = get_conf_word(d, PCI_COMMAND); word class = p->device_class; byte bist = get_conf_byte(d, PCI_BIST); byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f; byte latency = get_conf_byte(d, PCI_LATENCY_TIMER); byte cache_line = get_conf_byte(d, PCI_CACHE_LINE_SIZE); byte max_lat, min_gnt; byte int_pin = get_conf_byte(d, PCI_INTERRUPT_PIN); unsigned int irq = p->irq; show_terse(d); switch (htype) { case PCI_HEADER_TYPE_NORMAL: if (class == PCI_CLASS_BRIDGE_PCI) printf("\t!!! Invalid class %04x for header type %02x\n", class, htype); max_lat = get_conf_byte(d, PCI_MAX_LAT); min_gnt = get_conf_byte(d, PCI_MIN_GNT); break; case PCI_HEADER_TYPE_BRIDGE: if ((class >> 8) != PCI_BASE_CLASS_BRIDGE) printf("\t!!! Invalid class %04x for header type %02x\n", class, htype); irq = int_pin = min_gnt = max_lat = 0; break; case PCI_HEADER_TYPE_CARDBUS: if ((class >> 8) != PCI_BASE_CLASS_BRIDGE) printf("\t!!! Invalid class %04x for header type %02x\n", class, htype); min_gnt = max_lat = 0; break; default: printf("\t!!! Unknown header type %02x\n", htype); return; } if (p->phy_slot) printf("\tPhysical Slot: %s\n", p->phy_slot); if (verbose > 1) { printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c DisINTx%c\n", FLAG(cmd, PCI_COMMAND_IO), FLAG(cmd, PCI_COMMAND_MEMORY), FLAG(cmd, PCI_COMMAND_MASTER), FLAG(cmd, PCI_COMMAND_SPECIAL), FLAG(cmd, PCI_COMMAND_INVALIDATE), FLAG(cmd, PCI_COMMAND_VGA_PALETTE), FLAG(cmd, PCI_COMMAND_PARITY), FLAG(cmd, PCI_COMMAND_WAIT), FLAG(cmd, PCI_COMMAND_SERR), FLAG(cmd, PCI_COMMAND_FAST_BACK), FLAG(cmd, PCI_COMMAND_DISABLE_INTx)); printf("\tStatus: Cap%c 66MHz%c UDF%c FastB2B%c ParErr%c DEVSEL=%s >TAbort%c <TAbort%c <MAbort%c >SERR%c <PERR%c INTx%c\n", FLAG(status, PCI_STATUS_CAP_LIST), FLAG(status, PCI_STATUS_66MHZ), FLAG(status, PCI_STATUS_UDF), FLAG(status, PCI_STATUS_FAST_BACK), FLAG(status, PCI_STATUS_PARITY), ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" : ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" : ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??", FLAG(status, PCI_STATUS_SIG_TARGET_ABORT), FLAG(status, PCI_STATUS_REC_TARGET_ABORT), FLAG(status, PCI_STATUS_REC_MASTER_ABORT), FLAG(status, PCI_STATUS_SIG_SYSTEM_ERROR), FLAG(status, PCI_STATUS_DETECTED_PARITY), FLAG(status, PCI_STATUS_INTx)); if (cmd & PCI_COMMAND_MASTER) { printf("\tLatency: %d", latency); if (min_gnt || max_lat) { printf(" ("); if (min_gnt) printf("%dns min", min_gnt*250); if (min_gnt && max_lat) printf(", "); if (max_lat) printf("%dns max", max_lat*250); putchar(')'); } if (cache_line) printf(", Cache Line Size: %d bytes", cache_line * 4); putchar('\n'); } if (int_pin || irq) printf("\tInterrupt: pin %c routed to IRQ " PCIIRQ_FMT "\n", (int_pin ? 'A' + int_pin - 1 : '?'), irq); } else { printf("\tFlags: "); if (cmd & PCI_COMMAND_MASTER) printf("bus master, "); if (cmd & PCI_COMMAND_VGA_PALETTE) printf("VGA palette snoop, "); if (cmd & PCI_COMMAND_WAIT) printf("stepping, "); if (cmd & PCI_COMMAND_FAST_BACK) printf("fast Back2Back, "); if (status & PCI_STATUS_66MHZ) printf("66MHz, "); if (status & PCI_STATUS_UDF) printf("user-definable features, "); printf("%s devsel", ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_SLOW) ? "slow" : ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_MEDIUM) ? "medium" : ((status & PCI_STATUS_DEVSEL_MASK) == PCI_STATUS_DEVSEL_FAST) ? "fast" : "??"); if (cmd & PCI_COMMAND_MASTER) printf(", latency %d", latency); if (irq) printf(", IRQ " PCIIRQ_FMT, irq); putchar('\n'); } if (bist & PCI_BIST_CAPABLE) { if (bist & PCI_BIST_START) printf("\tBIST is running\n"); else printf("\tBIST result: %02x\n", bist & PCI_BIST_CODE_MASK); } switch (htype) { case PCI_HEADER_TYPE_NORMAL: show_htype0(d); break; case PCI_HEADER_TYPE_BRIDGE: show_htype1(d); break; case PCI_HEADER_TYPE_CARDBUS: show_htype2(d); break; }}/*** Machine-readable dumps ***/static voidshow_hex_dump(struct device *d){ unsigned int i, cnt; cnt = d->config_cached; if (opt_hex >= 3 && config_fetch(d, cnt, 256-cnt)) { cnt = 256; if (opt_hex >= 4 && config_fetch(d, 256, 4096-256)) cnt = 4096; } for (i=0; i<cnt; i++) { if (! (i & 15)) printf("%02x:", i); printf(" %02x", get_conf_byte(d, i)); if ((i & 15) == 15) putchar('\n'); }}static voidprint_shell_escaped(char *c){ printf(" \""); while (*c) { if (*c == '"' || *c == '\\') putchar('\\'); putchar(*c++); } putchar('"');}static voidshow_machine(struct device *d){ struct pci_dev *p = d->dev; int c; word sv_id, sd_id; char classbuf[128], vendbuf[128], devbuf[128], svbuf[128], sdbuf[128]; get_subid(d, &sv_id, &sd_id); if (verbose) { printf((opt_machine >= 2) ? "Slot:\t" : "Device:\t"); show_slot_name(d); putchar('\n'); printf("Class:\t%s\n", pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, p->device_class)); printf("Vendor:\t%s\n", pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id)); printf("Device:\t%s\n", pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id)); if (sv_id && sv_id != 0xffff) { printf("SVendor:\t%s\n", pci_lookup_name(pacc, svbuf, sizeof(svbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR, sv_id)); printf("SDevice:\t%s\n", pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id)); } if (p->phy_slot) printf("PhySlot:\t%s\n", p->phy_slot); if (c = get_conf_byte(d, PCI_REVISION_ID)) printf("Rev:\t%02x\n", c); if (c = get_conf_byte(d, PCI_CLASS_PROG)) printf("ProgIf:\t%02x\n", c); if (opt_kernel) show_kernel_machine(d); } else { show_slot_name(d); print_shell_escaped(pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, p->device_class)); print_shell_escaped(pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id)); print_shell_escaped(pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id)); if (c = get_conf_byte(d, PCI_REVISION_ID)) printf(" -r%02x", c); if (c = get_conf_byte(d, PCI_CLASS_PROG)) printf(" -p%02x", c); if (sv_id && sv_id != 0xffff) { print_shell_escaped(pci_lookup_name(pacc, svbuf, sizeof(svbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR, sv_id)); print_shell_escaped(pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id)); } else printf(" \"\" \"\""); putchar('\n'); }}/*** Main show function ***/voidshow_device(struct device *d){ if (opt_machine) show_machine(d); else { if (verbose) show_verbose(d); else show_terse(d); if (opt_kernel || verbose) show_kernel(d); } if (opt_hex) show_hex_dump(d); if (verbose || opt_hex) putchar('\n');}static voidshow(void){ struct device *d; for (d=first_dev; d; d=d->next) show_device(d);}/* Main */intmain(int argc, char **argv){ int i; char *msg; if (argc == 2 && !strcmp(argv[1], "--version")) { puts("lspci version " PCIUTILS_VERSION); return 0; } pacc = pci_alloc(); pacc->error = die; pci_filter_init(pacc, &filter); while ((i = getopt(argc, argv, options)) != -1) switch (i) { case 'n': pacc->numeric_ids++; break; case 'v': verbose++; break; case 'b': pacc->buscentric = 1; break; case 's': if (msg = pci_filter_parse_slot(&filter, optarg)) die("-s: %s", msg); break; case 'd': if (msg = pci_filter_parse_id(&filter, optarg)) die("-d: %s", msg); break; case 'x': opt_hex++; break; case 't': opt_tree++; break; case 'i': pci_set_name_list_path(pacc, optarg, 0); break; case 'm': opt_machine++; break; case 'p': opt_pcimap = optarg; break;#ifdef PCI_OS_LINUX case 'k': opt_kernel++; break;#endif case 'M': opt_map_mode++; break; case 'D': opt_domains = 2; break;#ifdef PCI_USE_DNS case 'q': opt_query_dns++; break; case 'Q': opt_query_all = 1; break;#else case 'q': case 'Q': die("DNS queries are not available in this version");#endif default: if (parse_generic_option(i, pacc, optarg)) break; bad: fprintf(stderr, help_msg, pacc->id_file_name); return 1; } if (optind < argc) goto bad; if (opt_query_dns) { pacc->id_lookup_mode |= PCI_LOOKUP_NETWORK; if (opt_query_dns > 1) pacc->id_lookup_mode |= PCI_LOOKUP_REFRESH_CACHE; } if (opt_query_all) pacc->id_lookup_mode |= PCI_LOOKUP_NETWORK | PCI_LOOKUP_SKIP_LOCAL; pci_init(pacc); if (opt_map_mode) map_the_bus(); else { scan_devices(); sort_them(); if (opt_tree) show_forest(); else show(); } pci_cleanup(pacc); return (seen_errors ? 2 : 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -