Patchwork [v3,4/9] pci: Replace used bitmap with config byte map

login
register
mail settings
Submitter Alex Williamson
Date Nov. 19, 2010, 11:19 p.m.
Message ID <20101119231941.22162.38903.stgit@s20.home>
Download mbox | patch
Permalink /patch/72333/
State New
Headers show

Comments

Alex Williamson - Nov. 19, 2010, 11:19 p.m.
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@redhat.com>
---

 hw/device-assignment.c |    4 ++--
 hw/pci.c               |   30 +++++++++---------------------
 hw/pci.h               |    8 ++------
 3 files changed, 13 insertions(+), 29 deletions(-)

Patch

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