Re: [kvm-unit-tests PATCH v8 00/12] PCI bus support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux