[PATCH v2 4/5] arm/pci: Add pci_find_dev() and pci_bar_addr() functions

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

 



These two functions is a prerequisite for the following
pci-testdev test.

Cc: Thomas Huth <thuth@xxxxxxxxxx>
Cc: Andrew Jones <drjones@xxxxxxxxxx>
Signed-off-by: Alexander Gordeev <agordeev@xxxxxxxxxx>
---
 lib/pci-host-generic.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/lib/pci-host-generic.c b/lib/pci-host-generic.c
index 167d0db..9bbf232 100644
--- a/lib/pci-host-generic.c
+++ b/lib/pci-host-generic.c
@@ -419,6 +419,67 @@ static int pci_bus_scan(struct gen_pci *pci)
 	return nr_dev;
 }
 
+static pcidevaddr_t encode_addr(int bus, int dev, int fn)
+{
+	assert(bus < 256 && dev < 32 && fn < 8);
+	return bus << 16 | dev << 11 | fn;
+}
+
+static void decode_addr(pcidevaddr_t bdf, int *bus, int *dev, int *fn)
+{
+	*bus = (bdf >> 16) & 0xff;
+	*dev = (bdf >> 11) & 0x1f;
+	*fn  = (bdf >>  8) & 0x03;
+}
+
+pcidevaddr_t pci_find_dev(u16 vendor_id, u16 device_id)
+{
+	struct gen_pci *pci = get_pci();
+	int dev;
+
+	if (!pci)
+		return PCIDEVADDR_INVALID;
+
+	for_each_pci_dev(pci, dev) {
+		void *conf = dev_conf(pci, dev);
+
+		if (vendor_id == pci_config_readw(conf, PCI_VENDOR_ID) &&
+		    device_id == pci_config_readw(conf, PCI_DEVICE_ID))
+			return encode_addr(0, dev, 0);
+	}
+
+	return PCIDEVADDR_INVALID;
+}
+
+unsigned long pci_bar_addr(pcidevaddr_t bdf, int bar)
+{
+	struct gen_pci *pci = get_pci();
+	void *conf;
+	struct pci_addr_space *res;
+	pci_res_type_t type;
+	phys_addr_t addr;
+	bool is64;
+	int ret, bus, dev, fn;
+
+	if (!pci)
+		return ~0;
+
+	decode_addr(bdf, &bus, &dev, &fn);
+	assert(!bus && !fn);	/* We support bus 0 and function 0 only */
+
+	conf = dev_conf(pci, dev);
+	ret = pci_config_readb(conf, PCI_HEADER_TYPE);
+	assert(ret == PCI_HEADER_TYPE_NORMAL);
+
+	ret = pci_get_bar(conf, bar, &type, &addr, NULL, &is64);
+	assert(ret);
+
+	res = pci_find_res(pci, type);
+	assert(res);
+
+	return res->cpu_range.start + (addr - res->pci_range.start);
+}
+
 bool pci_probe(void)
 {
 	struct gen_pci *pci = get_pci();
-- 
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



[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