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; + + 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; 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);