📄 lspci.c
字号:
((status >> 3) & 0x1f), // dev (status & PCI_PCIX_BRIDGE_STATUS_FUNCTION), // function FLAG(status, PCI_PCIX_BRIDGE_STATUS_64BIT), FLAG(status, PCI_PCIX_BRIDGE_STATUS_133MHZ), FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_DISCARDED), FLAG(status, PCI_PCIX_BRIDGE_STATUS_UNEXPECTED_SC), FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_OVERRUN), FLAG(status, PCI_PCIX_BRIDGE_STATUS_SPLIT_REQUEST_DELAYED)); upstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_UPSTREAM_SPLIT_TRANS_CTRL); printf("\t\t: Upstream: Capacity=%u, Commitment Limit=%u\n", (upstcr & PCI_PCIX_BRIDGE_STR_CAPACITY), (upstcr >> 16) & 0xffff); downstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_DOWNSTREAM_SPLIT_TRANS_CTRL); printf("\t\t: Downstream: Capacity=%u, Commitment Limit=%u\n", (downstcr & PCI_PCIX_BRIDGE_STR_CAPACITY), (downstcr >> 16) & 0xffff);}static voidshow_pcix(struct device *d, int where){ switch (d->dev->hdrtype) { case PCI_HEADER_TYPE_NORMAL: show_pcix_nobridge(d, where); break; case PCI_HEADER_TYPE_BRIDGE: show_pcix_bridge(d, where); break; }}static voidshow_rom(struct device *d){ struct pci_dev *p = d->dev; pciaddr_t rom = p->rom_base_addr; pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->rom_size : 0; if (!rom && !len) return; printf("\tExpansion ROM at "); if (rom & PCI_ROM_ADDRESS_MASK) printf(ADDR_FORMAT, rom & PCI_ROM_ADDRESS_MASK); else printf("<unassigned>"); if (!(rom & PCI_ROM_ADDRESS_ENABLE)) printf(" [disabled]"); show_size(len); putchar('\n');}static voidshow_msi(struct device *d, int where, int cap){ int is64; u32 t; u16 w; printf("Message Signalled Interrupts: 64bit%c Queue=%d/%d Enable%c\n", FLAG(cap, PCI_MSI_FLAGS_64BIT), (cap & PCI_MSI_FLAGS_QSIZE) >> 4, (cap & PCI_MSI_FLAGS_QMASK) >> 1, FLAG(cap, PCI_MSI_FLAGS_ENABLE)); if (verbose < 2) return; is64 = cap & PCI_MSI_FLAGS_64BIT; config_fetch(d, where + PCI_MSI_ADDRESS_LO, (is64 ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32) + 2 - PCI_MSI_ADDRESS_LO); printf("\t\tAddress: "); if (is64) { t = get_conf_long(d, where + PCI_MSI_ADDRESS_HI); w = get_conf_word(d, where + PCI_MSI_DATA_64); printf("%08x", t); } else w = get_conf_word(d, where + PCI_MSI_DATA_32); t = get_conf_long(d, where + PCI_MSI_ADDRESS_LO); printf("%08x Data: %04x\n", t, w);}static voidshow_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 voidshow_caps(struct device *d){ if (get_conf_word(d, PCI_STATUS) & PCI_STATUS_CAP_LIST) { int where = get_conf_byte(d, PCI_CAPABILITY_LIST) & ~3; while (where) { int id, next, cap; printf("\tCapabilities: "); if (!config_fetch(d, where, 4)) { puts("<available only to root>"); 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 (id == 0xff) { printf("<chain broken>\n"); break; } switch (id) { case PCI_CAP_ID_PM: show_pm(d, where, cap); break; case PCI_CAP_ID_AGP: show_agp(d, where, cap); break; case PCI_CAP_ID_VPD: printf("Vital Product Data\n"); break; case PCI_CAP_ID_SLOTID: show_slotid(cap); break; case PCI_CAP_ID_MSI: show_msi(d, where, cap); break; case PCI_CAP_ID_PCIX: show_pcix(d, where); break; default: printf("#%02x [%04x]\n", id, cap); } where = next; } }}static voidshow_htype0(struct device *d){ show_bases(d, 6); show_rom(d); show_caps(d);}static voidshow_htype1(struct device *d){ u32 io_base = get_conf_byte(d, PCI_IO_BASE); u32 io_limit = get_conf_byte(d, PCI_IO_LIMIT); u32 io_type = io_base & PCI_IO_RANGE_TYPE_MASK; u32 mem_base = get_conf_word(d, PCI_MEMORY_BASE); u32 mem_limit = get_conf_word(d, PCI_MEMORY_LIMIT); u32 mem_type = mem_base & PCI_MEMORY_RANGE_TYPE_MASK; u32 pref_base = get_conf_word(d, PCI_PREF_MEMORY_BASE); u32 pref_limit = get_conf_word(d, PCI_PREF_MEMORY_LIMIT); u32 pref_type = pref_base & PCI_PREF_RANGE_TYPE_MASK; word brc = get_conf_word(d, PCI_BRIDGE_CONTROL); int verb = verbose > 2; show_bases(d, 2); printf("\tBus: primary=%02x, secondary=%02x, subordinate=%02x, sec-latency=%d\n", get_conf_byte(d, PCI_PRIMARY_BUS), get_conf_byte(d, PCI_SECONDARY_BUS), get_conf_byte(d, PCI_SUBORDINATE_BUS), get_conf_byte(d, PCI_SEC_LATENCY_TIMER)); if (io_type != (io_limit & PCI_IO_RANGE_TYPE_MASK) || (io_type != PCI_IO_RANGE_TYPE_16 && io_type != PCI_IO_RANGE_TYPE_32)) printf("\t!!! Unknown I/O range types %x/%x\n", io_base, io_limit); else { io_base = (io_base & PCI_IO_RANGE_MASK) << 8; io_limit = (io_limit & PCI_IO_RANGE_MASK) << 8; if (io_type == PCI_IO_RANGE_TYPE_32) { io_base |= (get_conf_word(d, PCI_IO_BASE_UPPER16) << 16); io_limit |= (get_conf_word(d, PCI_IO_LIMIT_UPPER16) << 16); } if (io_base <= io_limit || verb) printf("\tI/O behind bridge: %08x-%08x\n", io_base, io_limit+0xfff); } if (mem_type != (mem_limit & PCI_MEMORY_RANGE_TYPE_MASK) || mem_type) printf("\t!!! Unknown memory range types %x/%x\n", mem_base, mem_limit); 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); } } if (get_conf_word(d, PCI_SEC_STATUS) & PCI_STATUS_SIG_SYSTEM_ERROR) printf("\tSecondary status: SERR\n"); show_rom(d); 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)); 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 = get_conf_word(d, PCI_CB_LEGACY_MODE_BASE); 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 (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 = get_conf_word(d, PCI_CLASS_DEVICE); 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, subsys_d; 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 != PCI_CLASS_BRIDGE_PCI) printf("\t!!! Invalid class %04x for header type %02x\n", class, htype); irq = int_pin = min_gnt = max_lat = 0; subsys_v = subsys_d = 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; 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\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)); printf("\tStatus: Cap%c 66Mhz%c UDF%c FastB2B%c ParErr%c DEVSEL=%s >TAbort%c <TAbort%c <MAbort%c >SERR%c <PERR%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)); 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 %02x", cache_line); putchar('\n'); } if (int_pin || irq) printf("\tInterrupt: pin %c routed to IRQ " IRQ_FORMAT "\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 " IRQ_FORMAT, 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; }}static voidshow_hex_dump(struct device *d){ unsigned int i; for(i=0; i<d->config_cnt; i++) { if (! (i & 15)) printf("%02x:", i); printf(" %02x", get_conf_byte(d, i)); if ((i & 15) == 15) putchar('\n'); }}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: 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("Device:\t%02x:%02x.%x\n", p->bus, p->dev, p->func); printf("Class:\t%s\n", pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, get_conf_word(d, PCI_CLASS_DEVICE), 0, 0, 0)); printf("Vendor:\t%s\n", pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id, 0, 0)); printf("Device:\t%s\n", pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, 0, 0)); if (sv_id && sv_id != 0xffff) { printf("SVendor:\t%s\n", pci_lookup_name(pacc, svbuf, sizeof(svbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id, sv_id, sd_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 { printf("%02x:%02x.%x ", p->bus, p->dev, p->func); printf("\"%s\" \"%s\" \"%s\"", pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, get_conf_word(d, PCI_CLASS_DEVICE), 0, 0, 0), pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id, 0, 0), pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, 0, 0)); 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) printf(" \"%s\" \"%s\"", pci_lookup_name(pacc, svbuf, sizeof(svbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id, sv_id, sd_id), pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id)); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -