On Fri, Oct 21, 2016 at 06:41:47PM +0200, Andrew Jones wrote: > On Thu, Oct 20, 2016 at 03:10:19PM +0200, Alexander Gordeev wrote: > > Hi Andrew et al, > > > > This is 8th version of PCI support. The only noticeable change since v7 > > is no failure in case no requested memory type is found for a BAR. > > > > Sources are avalable at: > > https://github.com/a-gordeev/kvm-unit-tests.git pci-testdev-v7 > ^^ v8 > > I tested this with/without the attached patch and works for me. > > Thanks, > drew > diff --git a/lib/pci-host-generic.c b/lib/pci-host-generic.c > index 96f4b4b37d34e..04e9681190308 100644 > --- a/lib/pci-host-generic.c > +++ b/lib/pci-host-generic.c > @@ -165,20 +165,35 @@ static struct pci_host_bridge *pci_dt_probe(void) > return host; > } > > -static bool pci_alloc_resource(u64 *addr, u32 bar, u64 size) > +static bool pci_alloc_resource(pcidevaddr_t dev, int bar_num, u64 *addr) > { > struct pci_host_bridge *host = pci_host_bridge; > struct pci_addr_space *as = &host->addr_space[0]; > - u32 mask; > - int i; > + u32 mask, bar; > + u64 size; > + int type, i; To correct this addon patch taking my own output-setting advice, here I should have done *addr = ~0; to make sure it's set before the first possible 'return false' > + > + size = pci_bar_size(dev, bar_num); > + if (!size) > + return false; > + > + bar = pci_bar_get(dev, bar_num); > + type = pci_bar_type(bar); > + if (type & PCI_BASE_ADDRESS_MEM_TYPE_MASK) > + type &= ~PCI_BASE_ADDRESS_MEM_PREFETCH; > > for (i = 0; i < host->nr_addr_spaces; i++) { > - if (as->type == pci_bar_type(bar)) > + if (as->type == type) > break; > as++; > } > if (i >= host->nr_addr_spaces) { > - printf("No PCI resource matching a device found\n"); > + printf("%s: warning: can't satisfy request for ", __func__); > + pci_dev_print_id(dev); > + printf(" "); > + pci_bar_print(dev, bar_num); > + printf("\n"); > + *addr = 0; and the *addr = 0 here should be removed. > return false; > } > > @@ -216,15 +231,9 @@ bool pci_probe(void) > cmd = PCI_COMMAND_SERR; > > for (i = 0; i < 6; i++) { > - u64 addr, size; > - u32 bar; > + u64 addr; > > - size = pci_bar_size(dev, i); > - if (!size) > - continue; > - > - bar = pci_bar_get(dev, i); > - if (pci_alloc_resource(&addr, bar, size)) { > + if (pci_alloc_resource(dev, i, &addr)) { > pci_bar_set_addr(dev, i, addr); > > if (pci_bar_is_memory(dev, i)) > diff --git a/lib/pci.c b/lib/pci.c > index 2dbbba4281442..6bd54cbac1bbd 100644 > --- a/lib/pci.c > +++ b/lib/pci.c > @@ -127,53 +127,31 @@ bool pci_bar_is64(pcidevaddr_t dev, int bar_num) > PCI_BASE_ADDRESS_MEM_TYPE_64; > } > > -static void pci_dev_print(pcidevaddr_t dev) > +void pci_bar_print(pcidevaddr_t dev, int bar_num) > { > - uint16_t vendor_id = pci_config_readw(dev, PCI_VENDOR_ID); > - uint16_t device_id = pci_config_readw(dev, PCI_DEVICE_ID); > - 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; > + phys_addr_t size, start, end; > + uint32_t bar; > > - printf("dev %2d fn %d vendor_id %04x device_id %04x type %02x " > - "progif %02x class %02x subclass %02x\n", > - dev / 8, dev % 8, vendor_id, device_id, header, > - progif, class, subclass); > - > - if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL) > + size = pci_bar_size(dev, bar_num); > + if (!size) > return; > > - for (i = 0; i < 6; i++) { > - phys_addr_t size, start, end; > - uint32_t bar; > - > - size = pci_bar_size(dev, i); > - if (!size) > - continue; > - > - start = pci_bar_get_addr(dev, i); > - end = start + size - 1; > - > - if (pci_bar_is64(dev, i)) { > - printf("\tBAR#%d,%d [%" PRIx64 "-%" PRIx64 " ", > - i, i + 1, start, end); > - i++; > - } else { > - printf("\tBAR#%d [%02x-%02x ", > - i, (uint32_t)start, (uint32_t)end); > - } > - > - bar = pci_bar_get(dev, i); > - > - if (bar & PCI_BASE_ADDRESS_SPACE_IO) { > - printf("PIO]\n"); > - continue; > - } > - > + 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"); > @@ -187,11 +165,44 @@ static void pci_dev_print(pcidevaddr_t dev) > default: > assert(0); > } > + } > > - if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) > - printf("/p"); > + if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) > + printf("/p"); > > - printf("]\n"); > + printf("]"); > +} > + > +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++; > } > } > > diff --git a/lib/pci.h b/lib/pci.h > index 40e11a892783c..30f5381106108 100644 > --- a/lib/pci.h > +++ b/lib/pci.h > @@ -40,6 +40,8 @@ extern uint32_t pci_bar_mask(uint32_t bar); > extern bool pci_bar_is64(pcidevaddr_t dev, int bar_num); > extern bool pci_bar_is_memory(pcidevaddr_t dev, int bar_num); > extern bool pci_bar_is_valid(pcidevaddr_t dev, int bar_num); > +extern void pci_bar_print(pcidevaddr_t dev, int bar_num); > +extern void pci_dev_print_id(pcidevaddr_t dev); > > int pci_testdev(void); > -- 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