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