📄 lspci.c
字号:
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; word subsys_v = 0, subsys_d = 0; char ssnamebuf[256]; 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); subsys_v = get_conf_word(d, PCI_SUBSYSTEM_VENDOR_ID); subsys_d = get_conf_word(d, PCI_SUBSYSTEM_ID); 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; if (d->config_cached >= 128) { subsys_v = get_conf_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID); subsys_d = get_conf_word(d, PCI_CB_SUBSYSTEM_ID); } break; default: printf("\t!!! Unknown header type %02x\n", htype); return; } if (subsys_v && subsys_v != 0xffff) printf("\tSubsystem: %s\n", pci_lookup_name(pacc, ssnamebuf, sizeof(ssnamebuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, subsys_v, subsys_d)); 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=0, sd_id=0; char classbuf[128], vendbuf[128], devbuf[128], svbuf[128], sdbuf[128]; switch (get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f) { case PCI_HEADER_TYPE_NORMAL: sv_id = get_conf_word(d, PCI_SUBSYSTEM_VENDOR_ID); sd_id = get_conf_word(d, PCI_SUBSYSTEM_ID); break; case PCI_HEADER_TYPE_CARDBUS: if (d->config_cached >= 128) { sv_id = get_conf_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID); sd_id = get_conf_word(d, PCI_CB_SUBSYSTEM_ID); } break; } 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 (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); } 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 ***/static voidshow_device(struct device *d){ if (opt_machine) show_machine(d); else if (verbose) show_verbose(d); else show_terse(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);}/*** Tree output ***/struct bridge { struct bridge *chain; /* Single-linked list of bridges */ struct bridge *next, *child; /* Tree of bridges */ struct bus *first_bus; /* List of buses connected to this bridge */ unsigned int domain; unsigned int primary, secondary, subordinate; /* Bus numbers */ struct device *br_dev;};struct bus { unsigned int domain; unsigned int number; struct bus *sibling; struct device *first_dev, **last_dev;};static struct bridge host_bridge = { NULL, NULL, NULL, NULL, 0, ~0, 0, ~0, NULL };static struct bus *find_bus(struct bridge *b, unsigned int domain, unsigned int n){ struct bus *bus; for(bus=b->first_bus; bus; bus=bus->sibling) if (bus->domain == domain && bus->number == n) break; return bus;}static struct bus *new_bus(struct bridge *b, unsigned int domain, unsigned int n){ struct bus *bus = xmalloc(sizeof(struct bus)); bus->domain = domain; bus->number = n; bus->sibling = b->first_bus; bus->first_dev = NULL; bus->last_dev = &bus->first_dev; b->first_bus = bus; return bus;}static voidinsert_dev(struct device *d, struct bridge *b){ struct pci_dev *p = d->dev; struct bus *bus; if (! (bus = find_bus(b, p->domain, p->bus))) { struct bridge *c; for(c=b->child; c; c=c->next) if (c->domain == p->domain && c->secondary <= p->bus && p->bus <= c->subordinate) { insert_dev(d, c); return; } bus = new_bus(b, p->domain, p->bus); } /* Simple insertion at the end _does_ guarantee the correct order as the * original device list was sorted by (domain, bus, devfn) lexicographically * and all devices on the new list have the same bus number. */ *bus->last_dev = d; bus->last_dev = &d->next; d->next = NULL;}static voidgrow_tree(void){ struct device *d, *d2; struct bridge **last_br, *b; /* Build list of bridges */ last_br = &host_bridge.chain; for(d=first_dev; d; d=d->next) { word class = d->dev->device_class; byte ht = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f; if (class == PCI_CLASS_BRIDGE_PCI && (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS)) { b = xmalloc(sizeof(struct bridge)); b->domain = d->dev->domain; if (ht == PCI_HEADER_TYPE_BRIDGE) { b->primary = get_conf_byte(d, PCI_PRIMARY_BUS); b->secondary = get_conf_byte(d, PCI_SECONDARY_BUS); b->subordinate = get_conf_byte(d, PCI_SUBORDINATE_BUS); } else { b->primary = get_conf_byte(d, PCI_CB_PRIMARY_BUS); b->secondary = get_conf_byte(d, PCI_CB_CARD_BUS); b->subordin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -