On Thu, Nov 03, 2016 at 05:19:46PM +0100, Alexander Gordeev wrote: > Cc: Thomas Huth <thuth@xxxxxxxxxx> > Cc: Andrew Jones <drjones@xxxxxxxxxx> > Cc: Peter Xu <peterx@xxxxxxxxxx> > Suggested-by: Andrew Jones <drjones@xxxxxxxxxx> > Signed-off-by: Alexander Gordeev <agordeev@xxxxxxxxxx> > --- > lib/pci.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > lib/pci.h | 3 +++ > 2 files changed, 92 insertions(+) Reviewed-by: Andrew Jones <drjones@xxxxxxxxxx> > > diff --git a/lib/pci.c b/lib/pci.c > index 42f47d93abfd..e03c67c1a707 100644 > --- a/lib/pci.c > +++ b/lib/pci.c > @@ -126,3 +126,92 @@ bool pci_bar_is64(pcidevaddr_t dev, int bar_num) > return (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == > PCI_BASE_ADDRESS_MEM_TYPE_64; > } > + > +static void pci_bar_print(pcidevaddr_t dev, int bar_num) > +{ > + phys_addr_t size, start, end; > + uint32_t bar; > + > + size = pci_bar_size(dev, bar_num); > + if (!size) > + return; > + > + bar = pci_bar_get(dev, bar_num); > + start = pci_bar_get_addr(dev, bar_num); > + end = start + size - 1; > + > + if (pci_bar_is64(dev, bar_num)) { > + printf("BAR#%d,%d [%" PRIx64 "-%" PRIx64 " ", > + bar_num, bar_num + 1, start, end); > + } else { > + printf("BAR#%d [%02x-%02x ", > + bar_num, (uint32_t)start, (uint32_t)end); > + } > + > + if (bar & PCI_BASE_ADDRESS_SPACE_IO) { > + printf("PIO"); > + } else { > + printf("MEM"); > + switch (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { > + case PCI_BASE_ADDRESS_MEM_TYPE_32: > + printf("32"); > + break; > + case PCI_BASE_ADDRESS_MEM_TYPE_1M: > + printf("1M"); > + break; > + case PCI_BASE_ADDRESS_MEM_TYPE_64: > + printf("64"); > + break; > + default: > + assert(0); > + } > + } > + > + if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) > + printf("/p"); > + > + printf("]"); > +} > + > +static void pci_dev_print_id(pcidevaddr_t dev) > +{ > + printf("00.%02x.%1x %04x:%04x", dev / 8, dev % 8, > + pci_config_readw(dev, PCI_VENDOR_ID), > + pci_config_readw(dev, PCI_DEVICE_ID)); > +} > + > +static void pci_dev_print(pcidevaddr_t dev) > +{ > + uint8_t header = pci_config_readb(dev, PCI_HEADER_TYPE); > + uint8_t progif = pci_config_readb(dev, PCI_CLASS_PROG); > + uint8_t subclass = pci_config_readb(dev, PCI_CLASS_DEVICE); > + uint8_t class = pci_config_readb(dev, PCI_CLASS_DEVICE + 1); > + int i; > + > + pci_dev_print_id(dev); > + printf(" type %02x progif %02x class %02x subclass %02x\n", > + header, progif, class, subclass); > + > + if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL) > + return; > + > + for (i = 0; i < 6; i++) { > + if (pci_bar_size(dev, i)) { > + printf("\t"); > + pci_bar_print(dev, i); > + printf("\n"); > + } > + if (pci_bar_is64(dev, i)) > + i++; > + } > +} > + > +void pci_print(void) > +{ > + pcidevaddr_t dev; > + > + for (dev = 0; dev < 256; ++dev) { > + if (pci_dev_exists(dev)) > + pci_dev_print(dev); > + } > +} > diff --git a/lib/pci.h b/lib/pci.h > index 1462aa2f0e1a..fc0940adc299 100644 > --- a/lib/pci.h > +++ b/lib/pci.h > @@ -15,6 +15,7 @@ enum { > PCIDEVADDR_INVALID = 0xffff, > }; > > +extern void pci_print(void); > extern bool pci_dev_exists(pcidevaddr_t dev); > extern pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id); > > @@ -57,4 +58,6 @@ struct pci_test_dev_hdr { > uint8_t name[]; > }; > > +#define PCI_HEADER_TYPE_MASK 0x7f > + > #endif /* PCI_H */ > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html