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