Loading hw/pci/pci.c +50 −0 Original line number Diff line number Diff line Loading @@ -2257,6 +2257,56 @@ void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque) bus->iommu_opaque = opaque; } static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) { Range *range = opaque; PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); uint16_t cmd = pci_get_word(dev->config + PCI_COMMAND); int r; if (!(cmd & PCI_COMMAND_MEMORY)) { return; } if (pc->is_bridge) { pcibus_t base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); pcibus_t limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); base = MAX(base, 0x1ULL << 32); if (limit >= base) { Range pref_range; pref_range.begin = base; pref_range.end = limit + 1; range_extend(range, &pref_range); } } for (r = 0; r < PCI_NUM_REGIONS; ++r) { PCIIORegion *region = &dev->io_regions[r]; Range region_range; if (!region->size || (region->type & PCI_BASE_ADDRESS_SPACE_IO) || !(region->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) { continue; } region_range.begin = pci_get_quad(dev->config + pci_bar(dev, r)); region_range.end = region_range.begin + region->size; region_range.begin = MAX(region_range.begin, 0x1ULL << 32); if (region_range.end - 1 >= region_range.begin) { range_extend(range, ®ion_range); } } } void pci_bus_get_w64_range(PCIBus *bus, Range *range) { range->begin = range->end = 0; pci_for_each_device_under_bus(bus, pci_dev_get_w64, range); } static const TypeInfo pci_device_type_info = { .name = TYPE_PCI_DEVICE, .parent = TYPE_DEVICE, Loading include/hw/pci/pci.h +1 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,7 @@ const char *pci_root_bus_path(PCIDevice *dev); PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn); int pci_qdev_find_device(const char *id, PCIDevice **pdev); PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root, const char *devaddr); void pci_bus_get_w64_range(PCIBus *bus, Range *range); int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned int *slotp, unsigned int *funcp); Loading Loading
hw/pci/pci.c +50 −0 Original line number Diff line number Diff line Loading @@ -2257,6 +2257,56 @@ void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque) bus->iommu_opaque = opaque; } static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) { Range *range = opaque; PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); uint16_t cmd = pci_get_word(dev->config + PCI_COMMAND); int r; if (!(cmd & PCI_COMMAND_MEMORY)) { return; } if (pc->is_bridge) { pcibus_t base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); pcibus_t limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH); base = MAX(base, 0x1ULL << 32); if (limit >= base) { Range pref_range; pref_range.begin = base; pref_range.end = limit + 1; range_extend(range, &pref_range); } } for (r = 0; r < PCI_NUM_REGIONS; ++r) { PCIIORegion *region = &dev->io_regions[r]; Range region_range; if (!region->size || (region->type & PCI_BASE_ADDRESS_SPACE_IO) || !(region->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) { continue; } region_range.begin = pci_get_quad(dev->config + pci_bar(dev, r)); region_range.end = region_range.begin + region->size; region_range.begin = MAX(region_range.begin, 0x1ULL << 32); if (region_range.end - 1 >= region_range.begin) { range_extend(range, ®ion_range); } } } void pci_bus_get_w64_range(PCIBus *bus, Range *range) { range->begin = range->end = 0; pci_for_each_device_under_bus(bus, pci_dev_get_w64, range); } static const TypeInfo pci_device_type_info = { .name = TYPE_PCI_DEVICE, .parent = TYPE_DEVICE, Loading
include/hw/pci/pci.h +1 −0 Original line number Diff line number Diff line Loading @@ -397,6 +397,7 @@ const char *pci_root_bus_path(PCIDevice *dev); PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn); int pci_qdev_find_device(const char *id, PCIDevice **pdev); PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root, const char *devaddr); void pci_bus_get_w64_range(PCIBus *bus, Range *range); int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned int *slotp, unsigned int *funcp); Loading