/*
* The PCI Utilities -- List All PCI Devices
*
- * Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ * Copyright (c) 1997--2016 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
"\n"
"Selection of devices:\n"
"-s [[[[<domain>]:]<bus>]:][<slot>][.[<func>]]\tShow only devices in selected slots\n"
-"-d [<vendor>]:[<device>]\t\t\tShow only devices with specified ID's\n"
+"-d [<vendor>]:[<device>][:<class>]\t\tShow only devices with specified ID's\n"
"\n"
"Other options:\n"
"-i <file>\tUse specified ID database instead of %s\n"
d->config_cached += 64;
}
pci_setup_cache(p, d->config, d->config_cached);
- pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_PHYS_SLOT);
+ pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS);
return d;
}
word subsys_v, subsys_d;
char ssnamebuf[256];
+ pci_fill_info(p, PCI_FILL_LABEL);
+
+ if (p->label)
+ printf("\tDeviceName: %s", p->label);
get_subid(d, &subsys_v, &subsys_d);
if (subsys_v && subsys_v != 0xffff)
printf("\tSubsystem: %s\n",
/*** Verbose output ***/
static void
-show_size(pciaddr_t x)
+show_size(u64 x)
{
static const char suffix[][2] = { "", "K", "M", "G", "T" };
unsigned i;
if (!x)
return;
for (i = 0; i < (sizeof(suffix) / sizeof(*suffix) - 1); i++) {
- if (x < 1024)
+ if (x % 1024)
break;
x /= 1024;
}
printf(" [size=%u%s]", (unsigned)x, suffix[i]);
}
+static void
+show_range(char *prefix, u64 base, u64 limit, int is_64bit)
+{
+ if (base > limit)
+ {
+ if (!verbose)
+ return;
+ else if (verbose < 3)
+ {
+ printf("%s: None\n", prefix);
+ return;
+ }
+ }
+
+ printf("%s: ", prefix);
+ if (is_64bit)
+ printf("%016" PCI_U64_FMT_X "-%016" PCI_U64_FMT_X, base, limit);
+ else
+ printf("%08x-%08x", (unsigned) base, (unsigned) limit);
+ if (base <= limit)
+ show_size(limit - base + 1);
+ else
+ printf(" [empty]");
+ putchar('\n');
+}
+
static void
show_bases(struct device *d, int cnt)
{
{
pciaddr_t pos = p->base_addr[i];
pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->size[i] : 0;
+ pciaddr_t ioflg = (p->known_fields & PCI_FILL_IO_FLAGS) ? p->flags[i] : 0;
u32 flg = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i);
if (flg == 0xffffffff)
flg = 0;
printf("\tRegion %d: ", i);
else
putchar('\t');
- if (pos && !flg) /* Reported by the OS, but not by the device */
+ if (ioflg & PCI_IORESOURCE_PCI_EA_BEI)
+ printf("[enhanced] ");
+ else if (pos && !(flg & ((flg & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)))
{
+ /* Reported by the OS, but not by the device */
printf("[virtual] ");
flg = pos;
virtual = 1;
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;
+ pciaddr_t ioflg = (p->known_fields & PCI_FILL_IO_FLAGS) ? p->rom_flags : 0;
u32 flg = get_conf_long(d, reg);
word cmd = get_conf_word(d, PCI_COMMAND);
int virtual = 0;
if (!rom && !flg && !len)
return;
putchar('\t');
- if ((rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK))
+ if (ioflg & PCI_IORESOURCE_PCI_EA_BEI)
+ printf("[enhanced] ");
+ else if ((rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK))
{
printf("[virtual] ");
flg = rom;
u32 pref_type = pref_base & PCI_PREF_RANGE_TYPE_MASK;
word sec_stat = get_conf_word(d, PCI_SEC_STATUS);
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",
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);
+ show_range("\tI/O behind bridge", io_base, io_limit+0xfff, 0);
}
if (mem_type != (mem_limit & PCI_MEMORY_RANGE_TYPE_MASK) ||
{
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);
+ show_range("\tMemory behind bridge", mem_base, mem_limit + 0xfffff, 0);
}
if (pref_type != (pref_limit & PCI_PREF_RANGE_TYPE_MASK) ||
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)
+ u64 pref_base_64 = (pref_base & PCI_PREF_RANGE_MASK) << 16;
+ u64 pref_limit_64 = (pref_limit & PCI_PREF_RANGE_MASK) << 16;
+ if (pref_type == PCI_PREF_RANGE_TYPE_64)
{
- 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);
+ pref_base_64 |= (u64) get_conf_long(d, PCI_PREF_BASE_UPPER32) << 32;
+ pref_limit_64 |= (u64) get_conf_long(d, PCI_PREF_LIMIT_UPPER32) << 32;
}
+ show_range("\tPrefetchable memory behind bridge", pref_base_64, pref_limit_64 + 0xfffff, (pref_type == PCI_PREF_RANGE_TYPE_64));
}
if (verbose > 1)
if (verbose > 1)
{
- printf("\tBridgeCtl: Parity%c SERR%c NoISA%c VGA%c MAbort%c >Reset%c FastB2B%c\n",
+ printf("\tBridgeCtl: Parity%c SERR%c NoISA%c VGA%c VGA16%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_VGA_16BIT),
FLAG(brc, PCI_BRIDGE_CTL_MASTER_ABORT),
FLAG(brc, PCI_BRIDGE_CTL_BUS_RESET),
FLAG(brc, PCI_BRIDGE_CTL_FAST_BACK));
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;
+ unsigned int irq;
show_terse(d);
+ pci_fill_info(p, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES |
+ PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE);
+ irq = p->irq;
+
switch (htype)
{
case PCI_HEADER_TYPE_NORMAL:
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;
+ min_gnt = max_lat = 0;
break;
case PCI_HEADER_TYPE_CARDBUS:
if ((class >> 8) != PCI_BASE_CLASS_BRIDGE)
if (verbose > 1)
{
+ if (p->dt_node)
+ printf("\tDT Node: %s\n", p->dt_node);
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),
if (int_pin || irq)
printf("\tInterrupt: pin %c routed to IRQ " PCIIRQ_FMT "\n",
(int_pin ? 'A' + int_pin - 1 : '?'), irq);
+ if (p->numa_node != -1)
+ printf("\tNUMA node: %d\n", p->numa_node);
}
else
{
+ if (p->dt_node)
+ printf("\tDT Node: %s\n", p->dt_node);
printf("\tFlags: ");
if (cmd & PCI_COMMAND_MASTER)
printf("bus master, ");
printf(", latency %d", latency);
if (irq)
printf(", IRQ " PCIIRQ_FMT, irq);
+ if (p->numa_node != -1)
+ printf(", NUMA node %d", p->numa_node);
putchar('\n');
}
if (verbose)
{
+ pci_fill_info(p, PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE);
printf((opt_machine >= 2) ? "Slot:\t" : "Device:\t");
show_slot_name(d);
putchar('\n');
printf("ProgIf:\t%02x\n", c);
if (opt_kernel)
show_kernel_machine(d);
+ if (p->numa_node != -1)
+ printf("NUMANode:\t%d\n", p->numa_node);
+ if (p->dt_node)
+ printf("DTNode:\t%s\n", p->dt_node);
}
else
{