From: Alex Williamson <alex.williamson@xxxxxxxxxx> Capabilities are allocated in bytes, so we can track both whether a byte is used and by what capability in the same structure. Remove pci_reserve_capability() as there are no users, remove pci_access_cap_config() since it's now a trivial lookup. Signed-off-by: Alex Williamson <alex.williamson@xxxxxxxxxx> Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx> diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 76aacac..a4fad60 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -423,7 +423,7 @@ static void assigned_dev_pci_write_config(PCIDevice *d, uint32_t address, if ((address >= 0x10 && address <= 0x24) || address == 0x30 || address == 0x34 || address == 0x3c || address == 0x3d || - pci_access_cap_config(d, address, len)) { + (address > PCI_CONFIG_HEADER_SIZE && d->config_map[address])) { /* used for update-mappings (BAR emulation) */ pci_default_write_config(d, address, val, len); return; @@ -459,7 +459,7 @@ static uint32_t assigned_dev_pci_read_config(PCIDevice *d, uint32_t address, if (address < 0x4 || (pci_dev->need_emulate_cmd && address == 0x4) || (address >= 0x10 && address <= 0x24) || address == 0x30 || address == 0x34 || address == 0x3c || address == 0x3d || - pci_access_cap_config(d, address, len)) { + (address > PCI_CONFIG_HEADER_SIZE && d->config_map[address])) { val = pci_default_read_config(d, address, len); DEBUG("(%x.%x): address=%04x val=0x%08x len=%d\n", (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len); diff --git a/hw/pci.c b/hw/pci.c index f2896d9..cbe6fb7 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -712,7 +712,7 @@ static void pci_config_alloc(PCIDevice *pci_dev) pci_dev->cmask = qemu_mallocz(config_size); pci_dev->wmask = qemu_mallocz(config_size); pci_dev->w1cmask = qemu_mallocz(config_size); - pci_dev->used = qemu_mallocz(config_size); + pci_dev->config_map = qemu_mallocz(config_size); } static void pci_config_free(PCIDevice *pci_dev) @@ -721,7 +721,7 @@ static void pci_config_free(PCIDevice *pci_dev) qemu_free(pci_dev->cmask); qemu_free(pci_dev->wmask); qemu_free(pci_dev->w1cmask); - qemu_free(pci_dev->used); + qemu_free(pci_dev->config_map); } /* -1 for devfn means auto assign */ @@ -751,6 +751,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, pci_dev->irq_state = 0; pci_config_alloc(pci_dev); + memset(pci_dev->config_map, 0xff, PCI_CONFIG_HEADER_SIZE); + if (!is_bridge) { pci_set_default_subsystem_id(pci_dev); } @@ -1083,21 +1085,13 @@ uint32_t pci_default_read_config(PCIDevice *d, { assert(len == 1 || len == 2 || len == 4); - if (pci_access_cap_config(d, address, len)) { + if (address > PCI_CONFIG_HEADER_SIZE && d->config_map[address]) { return d->cap.config_read(d, address, len); } return pci_read_config(d, address, len); } -int pci_access_cap_config(PCIDevice *pci_dev, uint32_t address, int len) -{ - if (pci_dev->cap.supported && address >= pci_dev->cap.start && - (address + len) < pci_dev->cap.start + pci_dev->cap.length) - return 1; - return 0; -} - uint32_t pci_default_cap_read_config(PCIDevice *pci_dev, uint32_t address, int len) { @@ -1122,7 +1116,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) int i, was_irq_disabled = pci_irq_disabled(d); uint32_t config_size = pci_config_size(d); - if (pci_access_cap_config(d, addr, l)) { + if (addr > PCI_CONFIG_HEADER_SIZE && d->config_map[addr]) { d->cap.config_write(d, addr, val, l); return; } @@ -1789,7 +1783,7 @@ static int pci_find_space(PCIDevice *pdev, uint8_t size) int offset = PCI_CONFIG_HEADER_SIZE; int i; for (i = PCI_CONFIG_HEADER_SIZE; i < config_size; ++i) - if (pdev->used[i]) + if (pdev->config_map[i]) offset = i + 1; else if (i - offset + 1 == size) return offset; @@ -1908,7 +1902,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, config[PCI_CAP_LIST_ID] = cap_id; config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST]; pdev->config[PCI_CAPABILITY_LIST] = offset; - memset(pdev->used + offset, 0xFF, size); + memset(pdev->config_map + offset, cap_id, size); /* Make capability read-only by default */ memset(pdev->wmask + offset, 0, size); /* Check capability by default */ @@ -1933,7 +1927,7 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) memset(pdev->w1cmask + offset, 0, size); /* Clear cmask as device-specific registers can't be checked */ memset(pdev->cmask + offset, 0, size); - memset(pdev->used + offset, 0, size); + memset(pdev->config_map + offset, 0, size); if (!pdev->config[PCI_CAPABILITY_LIST]) { pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST; @@ -1941,12 +1935,6 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) } } -/* Reserve space for capability at a known offset (to call after load). */ -void pci_reserve_capability(PCIDevice *pdev, uint8_t offset, uint8_t size) -{ - memset(pdev->used + offset, 0xff, size); -} - uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id) { return pci_find_capability_list(pdev, cap_id, NULL); diff --git a/hw/pci.h b/hw/pci.h index fafc2bb..bd15b43 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -157,8 +157,8 @@ struct PCIDevice { /* Used to implement RW1C(Write 1 to Clear) bytes */ uint8_t *w1cmask; - /* Used to allocate config space for capabilities. */ - uint8_t *used; + /* Used to allocate config space and track capabilities. */ + uint8_t *config_map; /* the following fields are read only */ PCIBus *bus; @@ -250,8 +250,6 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); -void pci_reserve_capability(PCIDevice *pci_dev, uint8_t offset, uint8_t size); - uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id); uint32_t pci_default_read_config(PCIDevice *d, @@ -264,8 +262,6 @@ uint32_t pci_default_cap_read_config(PCIDevice *pci_dev, uint32_t address, int len); void pci_default_cap_write_config(PCIDevice *pci_dev, uint32_t address, uint32_t val, int len); -int pci_access_cap_config(PCIDevice *pci_dev, uint32_t address, int len); - typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev, int state); -- To unsubscribe from this list: send the line "unsubscribe kvm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html