#include "hw/loader.h"
#include "qemu/range.h"
#include "qmp-commands.h"
+#include "trace.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "exec/address-spaces.h"
.name = "PCIBUS",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
+ .fields = (VMStateField[]) {
VMSTATE_INT32_EQUAL(nirq, PCIBus),
VMSTATE_VARRAY_INT32(irq_count, PCIBus,
nirq, 0, vmstate_info_int32,
.name = "PCIDevice",
.version_id = 2,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
vmstate_info_pci_config,
.name = "PCIEDevice",
.version_id = 2,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
vmstate_info_pci_config,
* This makes us compatible with old devices
* which never set or clear this bit. */
s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
- vmstate_save_state(f, pci_get_vmstate(s), s);
+ vmstate_save_state(f, pci_get_vmstate(s), s, NULL);
/* Restore the interrupt status bit. */
pci_update_irq_status(s);
}
int dom, bus;
unsigned slot;
- assert(!root->parent_dev);
-
if (!root) {
fprintf(stderr, "No primary PCI bus\n");
return NULL;
}
+ assert(!root->parent_dev);
+
if (!devaddr) {
*devfnp = -1;
return pci_find_bus_nr(root, 0);
pci_config_free(pci_dev);
address_space_destroy(&pci_dev->bus_master_as);
- memory_region_destroy(&pci_dev->bus_master_enable_region);
}
/* -1 for devfn means auto assign */
}
pci_dev->bus = bus;
+ pci_dev->devfn = devfn;
dma_as = pci_device_iommu_address_space(pci_dev);
memory_region_init_alias(&pci_dev->bus_master_enable_region,
address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region,
name);
- pci_dev->devfn = devfn;
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
pci_dev->irq_state = 0;
pci_config_alloc(pci_dev);
/* now do the real mapping */
if (r->addr != PCI_BAR_UNMAPPED) {
+ trace_pci_update_mappings_del(d, pci_bus_num(d->bus),
+ PCI_FUNC(d->devfn),
+ PCI_SLOT(d->devfn),
+ i, r->addr, r->size);
memory_region_del_subregion(r->address_space, r->memory);
}
r->addr = new_addr;
if (r->addr != PCI_BAR_UNMAPPED) {
+ trace_pci_update_mappings_add(d, pci_bus_num(d->bus),
+ PCI_FUNC(d->devfn),
+ PCI_SLOT(d->devfn),
+ i, r->addr, r->size);
memory_region_add_subregion_overlap(r->address_space,
r->addr, r->memory, 1);
}
return le32_to_cpu(val);
}
-void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
+void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int l)
{
int i, was_irq_disabled = pci_irq_disabled(d);
+ uint32_t val = val_in;
for (i = 0; i < l; val >>= 8, ++i) {
uint8_t wmask = d->wmask[addr + i];
& PCI_COMMAND_MASTER);
}
- msi_write_config(d, addr, val, l);
- msix_write_config(d, addr, val, l);
+ msi_write_config(d, addr, val_in, l);
+ msix_write_config(d, addr, val_in, l);
}
/***********************************************************/
pci_dev->romfile = g_strdup(pc->romfile);
is_default_rom = true;
}
- pci_add_option_rom(pci_dev, is_default_rom);
+
+ rc = pci_add_option_rom(pci_dev, is_default_rom);
+ if (rc != 0) {
+ pci_unregister_device(DEVICE(pci_dev));
+ return rc;
+ }
return 0;
}
* for 0.11 compatibility.
*/
int class = pci_get_word(pdev->config + PCI_CLASS_DEVICE);
+
+ /*
+ * Hot-plugged devices can't use the option ROM
+ * if the rom bar is disabled.
+ */
+ if (DEVICE(pdev)->hotplugged) {
+ return -1;
+ }
+
if (class == 0x0300) {
rom_add_vga(pdev->romfile);
} else {
snprintf(name, sizeof(name), "%s.rom", object_get_typename(OBJECT(pdev)));
}
pdev->has_rom = true;
- memory_region_init_ram(&pdev->rom, OBJECT(pdev), name, size);
+ memory_region_init_ram(&pdev->rom, OBJECT(pdev), name, size, &error_abort);
vmstate_register_ram(&pdev->rom, &pdev->qdev);
ptr = memory_region_get_ram_ptr(&pdev->rom);
load_image(path, ptr);
return;
vmstate_unregister_ram(&pdev->rom, &pdev->qdev);
- memory_region_destroy(&pdev->rom);
pdev->has_rom = false;
}
ret = pci_add_capability2(pdev, cap_id, offset, size, &local_err);
if (local_err) {
assert(ret < 0);
- error_report("%s", error_get_pretty(local_err));
- error_free(local_err);
+ error_report_err(local_err);
} else {
/* success implies a positive offset in config space */
assert(ret > 0);