X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lspci.c;h=4e6196e2277332c747d123915011c62098ad6eb0;hb=44c6c7fcfe0f9219447ac78e3f386e3223328149;hp=525bb8234b53f5608e6c45cd97242b19d9b3b305;hpb=e6b0b6e1518dc383de76ce6c0afcb4291a6adfea;p=pciutils.git diff --git a/lspci.c b/lspci.c index 525bb82..4e6196e 100644 --- a/lspci.c +++ b/lspci.c @@ -1,7 +1,7 @@ /* * The PCI Utilities -- List All PCI Devices * - * Copyright (c) 1997--2018 Martin Mares + * Copyright (c) 1997--2020 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -405,72 +405,89 @@ show_bases(struct device *d, int cnt) 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); + u32 hw_lower; + u32 hw_upper = 0; + int broken = 0; + if (flg == 0xffffffff) flg = 0; if (!pos && !flg && !len) continue; + if (verbose > 1) printf("\tRegion %d: ", i); else putchar('\t'); - 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))) + + /* Read address as seen by the hardware */ + if (flg & PCI_BASE_ADDRESS_SPACE_IO) + hw_lower = flg & PCI_BASE_ADDRESS_IO_MASK; + else + { + hw_lower = flg & PCI_BASE_ADDRESS_MEM_MASK; + if ((flg & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) + { + if (i >= cnt - 1) + broken = 1; + else + { + i++; + hw_upper = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i); + } + } + } + + /* Detect virtual regions, which are reported by the OS, but unassigned in the device */ + if (pos && !hw_lower && !hw_upper && !(ioflg & PCI_IORESOURCE_PCI_EA_BEI)) { - /* Reported by the OS, but not by the device */ - printf("[virtual] "); flg = pos; virtual = 1; } + + /* Print base address */ if (flg & PCI_BASE_ADDRESS_SPACE_IO) { pciaddr_t a = pos & PCI_BASE_ADDRESS_IO_MASK; printf("I/O ports at "); if (a || (cmd & PCI_COMMAND_IO)) printf(PCIADDR_PORT_FMT, a); - else if (flg & PCI_BASE_ADDRESS_IO_MASK) + else if (hw_lower) printf(""); else printf(""); - if (!virtual && !(cmd & PCI_COMMAND_IO)) + if (virtual) + printf(" [virtual]"); + else if (!(cmd & PCI_COMMAND_IO)) printf(" [disabled]"); } else { int t = flg & PCI_BASE_ADDRESS_MEM_TYPE_MASK; pciaddr_t a = pos & PCI_ADDR_MEM_MASK; - int done = 0; - u32 z = 0; printf("Memory at "); - if (t == PCI_BASE_ADDRESS_MEM_TYPE_64) - { - if (i >= cnt - 1) - { - printf(""); - done = 1; - } - else - { - i++; - z = get_conf_long(d, PCI_BASE_ADDRESS_0 + 4*i); - } - } - if (!done) - { - if (a) - printf(PCIADDR_T_FMT, a); - else - printf(((flg & PCI_BASE_ADDRESS_MEM_MASK) || z) ? "" : ""); - } + if (broken) + printf(""); + else if (a) + printf(PCIADDR_T_FMT, a); + else if (hw_lower || hw_upper) + printf(""); + else + printf(""); printf(" (%s, %sprefetchable)", (t == PCI_BASE_ADDRESS_MEM_TYPE_32) ? "32-bit" : (t == PCI_BASE_ADDRESS_MEM_TYPE_64) ? "64-bit" : (t == PCI_BASE_ADDRESS_MEM_TYPE_1M) ? "low-1M" : "type 3", (flg & PCI_BASE_ADDRESS_MEM_PREFETCH) ? "" : "non-"); - if (!virtual && !(cmd & PCI_COMMAND_MEMORY)) + if (virtual) + printf(" [virtual]"); + else if (!(cmd & PCI_COMMAND_MEMORY)) printf(" [disabled]"); } + + if (ioflg & PCI_IORESOURCE_PCI_EA_BEI) + printf(" [enhanced]"); + show_size(len); putchar('\n'); } @@ -489,26 +506,32 @@ show_rom(struct device *d, int reg) if (!rom && !flg && !len) return; - putchar('\t'); - if (ioflg & PCI_IORESOURCE_PCI_EA_BEI) - printf("[enhanced] "); - else if ((rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK)) + + if ((rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK) && !(ioflg & PCI_IORESOURCE_PCI_EA_BEI)) { - printf("[virtual] "); flg = rom; virtual = 1; } - printf("Expansion ROM at "); + + printf("\tExpansion ROM at "); if (rom & PCI_ROM_ADDRESS_MASK) printf(PCIADDR_T_FMT, rom & PCI_ROM_ADDRESS_MASK); else if (flg & PCI_ROM_ADDRESS_MASK) printf(""); else printf(""); + + if (virtual) + printf(" [virtual]"); + if (!(flg & PCI_ROM_ADDRESS_ENABLE)) printf(" [disabled]"); else if (!virtual && !(cmd & PCI_COMMAND_MEMORY)) printf(" [disabled by cmd]"); + + if (ioflg & PCI_IORESOURCE_PCI_EA_BEI) + printf(" [enhanced]"); + show_size(len); putchar('\n'); }