summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-10-05 19:05:13 +0200
committerAvi Kivity <avi@redhat.com>2009-10-05 19:05:13 +0200
commit20547a10fa08bcca2d8af387013b9b95427f50df (patch)
tree684be6ca382c793b7bfbfab1082eac01ce896fe1
parentFix old-style function definitions in kvm specific code (diff)
parentpiix_pci: kill PIIX3IrqState (diff)
downloadqemu-kvm-20547a10fa08bcca2d8af387013b9b95427f50df.tar.gz
qemu-kvm-20547a10fa08bcca2d8af387013b9b95427f50df.tar.bz2
qemu-kvm-20547a10fa08bcca2d8af387013b9b95427f50df.zip
Merge commit '7cd9eee0f6fd6953114068dd98d91fca1237880b' into upstream-merge
* commit '7cd9eee0f6fd6953114068dd98d91fca1237880b': piix_pci: kill PIIX3IrqState convert pci bridge to qdev support inplace allocation for pci bus, split irq init. switch ide bus to inplace allocation. switch usb bus to inplace allocation. switch scsi bus to inplace allocation. allow qdev busses allocations be inplace temporary fix for on_vcpu kvm: Fix guest single-stepping gdbstub: x86: Switch 64/32 bit registers dynamically Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--hw/esp.c10
-rw-r--r--hw/ide/internal.h2
-rw-r--r--hw/ide/isa.c24
-rw-r--r--hw/ide/pci.c42
-rw-r--r--hw/ide/qdev.c7
-rw-r--r--hw/lsi53c895a.c12
-rw-r--r--hw/pci.c105
-rw-r--r--hw/pci.h5
-rw-r--r--hw/piix_pci.c39
-rw-r--r--hw/qdev.c15
-rw-r--r--hw/qdev.h3
-rw-r--r--hw/scsi-bus.c9
-rw-r--r--hw/scsi-disk.h4
-rw-r--r--hw/usb-bus.c7
-rw-r--r--hw/usb-msd.c6
-rw-r--r--hw/usb-musb.c6
-rw-r--r--hw/usb-ohci.c6
-rw-r--r--hw/usb-uhci.c6
-rw-r--r--hw/usb.h2
-rw-r--r--kvm-all.c12
20 files changed, 195 insertions, 127 deletions
diff --git a/hw/esp.c b/hw/esp.c
index 9a5a8fbf7..5d8602041 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -63,7 +63,7 @@ struct ESPState {
uint8_t ti_buf[TI_BUFSZ];
uint32_t sense;
uint32_t dma;
- SCSIBus *bus;
+ SCSIBus bus;
SCSIDevice *current_dev;
uint8_t cmdbuf[TI_BUFSZ];
uint32_t cmdlen;
@@ -191,7 +191,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
s->async_len = 0;
}
- if (target >= ESP_MAX_DEVS || !s->bus->devs[target]) {
+ if (target >= ESP_MAX_DEVS || !s->bus.devs[target]) {
// No such drive
s->rregs[ESP_RSTAT] = 0;
s->rregs[ESP_RINTR] = INTR_DC;
@@ -199,7 +199,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
esp_raise_irq(s);
return 0;
}
- s->current_dev = s->bus->devs[target];
+ s->current_dev = s->bus.devs[target];
return dmalen;
}
@@ -672,8 +672,8 @@ static int esp_init1(SysBusDevice *dev)
qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);
- s->bus = scsi_bus_new(&dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
- scsi_bus_legacy_handle_cmdline(s->bus);
+ scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
+ scsi_bus_legacy_handle_cmdline(&s->bus);
return 0;
}
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 9df759d4d..029bf80e5 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -551,7 +551,7 @@ void ide_init2(IDEBus *bus, DriveInfo *hd0, DriveInfo *hd1,
void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
/* hw/ide/qdev.c */
-IDEBus *ide_bus_new(DeviceState *dev);
+void ide_bus_new(IDEBus *idebus, DeviceState *dev);
IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
#endif /* HW_IDE_INTERNAL_H */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index d2fe0c037..3205f40b3 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -37,7 +37,7 @@
typedef struct ISAIDEState {
ISADevice dev;
- IDEBus *bus;
+ IDEBus bus;
uint32_t iobase;
uint32_t iobase2;
uint32_t isairq;
@@ -48,18 +48,18 @@ static void isa_ide_save(QEMUFile* f, void *opaque)
{
ISAIDEState *s = opaque;
- idebus_save(f, s->bus);
- ide_save(f, &s->bus->ifs[0]);
- ide_save(f, &s->bus->ifs[1]);
+ idebus_save(f, &s->bus);
+ ide_save(f, &s->bus.ifs[0]);
+ ide_save(f, &s->bus.ifs[1]);
}
static int isa_ide_load(QEMUFile* f, void *opaque, int version_id)
{
ISAIDEState *s = opaque;
- idebus_load(f, s->bus, version_id);
- ide_load(f, &s->bus->ifs[0], version_id);
- ide_load(f, &s->bus->ifs[1], version_id);
+ idebus_load(f, &s->bus, version_id);
+ ide_load(f, &s->bus.ifs[0], version_id);
+ ide_load(f, &s->bus.ifs[1], version_id);
return 0;
}
@@ -67,10 +67,10 @@ static int isa_ide_initfn(ISADevice *dev)
{
ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
- s->bus = ide_bus_new(&s->dev.qdev);
- ide_init_ioport(s->bus, s->iobase, s->iobase2);
+ ide_bus_new(&s->bus, &s->dev.qdev);
+ ide_init_ioport(&s->bus, s->iobase, s->iobase2);
isa_init_irq(dev, &s->irq, s->isairq);
- ide_init2(s->bus, NULL, NULL, s->irq);
+ ide_init2(&s->bus, NULL, NULL, s->irq);
register_savevm("isa-ide", 0, 3, isa_ide_save, isa_ide_load, s);
return 0;
};
@@ -90,9 +90,9 @@ int isa_ide_init(int iobase, int iobase2, int isairq,
s = DO_UPCAST(ISAIDEState, dev, dev);
if (hd0)
- ide_create_drive(s->bus, 0, hd0);
+ ide_create_drive(&s->bus, 0, hd0);
if (hd1)
- ide_create_drive(s->bus, 1, hd1);
+ ide_create_drive(&s->bus, 1, hd1);
return 0;
}
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 89ecd442e..bddf54194 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -51,7 +51,7 @@
typedef struct PCIIDEState {
PCIDevice dev;
- IDEBus *bus[2];
+ IDEBus bus[2];
BMDMAState bmdma[2];
int type; /* see IDE_TYPE_xxx */
uint32_t secondary;
@@ -66,7 +66,7 @@ static void ide_map(PCIDevice *pci_dev, int region_num,
IDEBus *bus;
if (region_num <= 3) {
- bus = d->bus[(region_num >> 1)];
+ bus = &d->bus[(region_num >> 1)];
if (region_num & 1) {
register_ioport_read(addr + 2, 1, 1, ide_status_read, bus);
register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus);
@@ -252,9 +252,9 @@ static void bmdma_map(PCIDevice *pci_dev, int region_num,
for(i = 0;i < 2; i++) {
BMDMAState *bm = &d->bmdma[i];
- d->bus[i]->bmdma = bm;
+ d->bus[i].bmdma = bm;
bm->pci_dev = DO_UPCAST(PCIIDEState, dev, pci_dev);
- bm->bus = d->bus[i];
+ bm->bus = d->bus+i;
qemu_add_vm_change_state_handler(ide_dma_restart_cb, bm);
register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
@@ -294,13 +294,13 @@ static void pci_ide_save(QEMUFile* f, void *opaque)
/* per IDE interface data */
for(i = 0; i < 2; i++) {
- idebus_save(f, d->bus[i]);
+ idebus_save(f, d->bus+i);
}
/* per IDE drive data */
for(i = 0; i < 2; i++) {
- ide_save(f, &d->bus[i]->ifs[0]);
- ide_save(f, &d->bus[i]->ifs[1]);
+ ide_save(f, &d->bus[i].ifs[0]);
+ ide_save(f, &d->bus[i].ifs[1]);
}
}
@@ -330,13 +330,13 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
/* per IDE interface data */
for(i = 0; i < 2; i++) {
- idebus_load(f, d->bus[i], version_id);
+ idebus_load(f, d->bus+i, version_id);
}
/* per IDE drive data */
for(i = 0; i < 2; i++) {
- ide_load(f, &d->bus[i]->ifs[0], version_id);
- ide_load(f, &d->bus[i]->ifs[1], version_id);
+ ide_load(f, &d->bus[i].ifs[0], version_id);
+ ide_load(f, &d->bus[i].ifs[1], version_id);
}
return 0;
}
@@ -351,7 +351,7 @@ static void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
for (i = 0; i < 4; i++) {
if (hd_table[i] == NULL)
continue;
- ide_create_drive(d->bus[bus[i]], unit[i], hd_table[i]);
+ ide_create_drive(d->bus+bus[i], unit[i], hd_table[i]);
}
}
@@ -427,10 +427,10 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
pci_conf[0x3d] = 0x01; // interrupt on pin 1
irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
- d->bus[0] = ide_bus_new(&d->dev.qdev);
- d->bus[1] = ide_bus_new(&d->dev.qdev);
- ide_init2(d->bus[0], NULL, NULL, irq[0]);
- ide_init2(d->bus[1], NULL, NULL, irq[1]);
+ ide_bus_new(&d->bus[0], &d->dev.qdev);
+ ide_bus_new(&d->bus[1], &d->dev.qdev);
+ ide_init2(&d->bus[0], NULL, NULL, irq[0]);
+ ide_init2(&d->bus[1], NULL, NULL, irq[1]);
register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
qemu_register_reset(cmd646_reset, d);
@@ -482,13 +482,13 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d);
- d->bus[0] = ide_bus_new(&d->dev.qdev);
- d->bus[1] = ide_bus_new(&d->dev.qdev);
- ide_init_ioport(d->bus[0], 0x1f0, 0x3f6);
- ide_init_ioport(d->bus[1], 0x170, 0x376);
+ ide_bus_new(&d->bus[0], &d->dev.qdev);
+ ide_bus_new(&d->bus[1], &d->dev.qdev);
+ ide_init_ioport(&d->bus[0], 0x1f0, 0x3f6);
+ ide_init_ioport(&d->bus[1], 0x170, 0x376);
- ide_init2(d->bus[0], NULL, NULL, isa_reserve_irq(14));
- ide_init2(d->bus[1], NULL, NULL, isa_reserve_irq(15));
+ ide_init2(&d->bus[0], NULL, NULL, isa_reserve_irq(14));
+ ide_init2(&d->bus[1], NULL, NULL, isa_reserve_irq(15));
return 0;
}
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index d467e3ad2..c562bc61a 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -29,12 +29,9 @@ static struct BusInfo ide_bus_info = {
.size = sizeof(IDEBus),
};
-IDEBus *ide_bus_new(DeviceState *dev)
+void ide_bus_new(IDEBus *idebus, DeviceState *dev)
{
- IDEBus *idebus;
-
- idebus = FROM_QBUS(IDEBus, qbus_create(&ide_bus_info, dev, NULL));
- return idebus;
+ qbus_create_inplace(&idebus->qbus, &ide_bus_info, dev, NULL);
}
static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 62bdca803..7c4539179 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -193,7 +193,7 @@ typedef struct {
* 2 if processing DMA from lsi_execute_script.
* 3 if a DMA operation is in progress. */
int waiting;
- SCSIBus *bus;
+ SCSIBus bus;
SCSIDevice *current_dev;
int current_lun;
/* The tag is a combination of the device ID and the SCSI tag. */
@@ -585,7 +585,7 @@ static void lsi_reselect(LSIState *s, uint32_t tag)
id = (tag >> 8) & 0xf;
s->ssid = id | 0x80;
DPRINTF("Reselected target %d\n", id);
- s->current_dev = s->bus->devs[id];
+ s->current_dev = s->bus.devs[id];
s->current_tag = tag;
s->scntl1 |= LSI_SCNTL1_CON;
lsi_set_phase(s, PHASE_MI);
@@ -1041,7 +1041,7 @@ again:
}
s->sstat0 |= LSI_SSTAT0_WOA;
s->scntl1 &= ~LSI_SCNTL1_IARB;
- if (id >= LSI_MAX_DEVS || !s->bus->devs[id]) {
+ if (id >= LSI_MAX_DEVS || !s->bus.devs[id]) {
DPRINTF("Selected absent target %d\n", id);
lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
lsi_disconnect(s);
@@ -1052,7 +1052,7 @@ again:
/* ??? Linux drivers compain when this is set. Maybe
it only applies in low-level mode (unimplemented).
lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */
- s->current_dev = s->bus->devs[id];
+ s->current_dev = s->bus.devs[id];
s->current_tag = id << 8;
s->scntl1 |= LSI_SCNTL1_CON;
if (insn & (1 << 3)) {
@@ -2178,8 +2178,8 @@ static int lsi_scsi_init(PCIDevice *dev)
lsi_soft_reset(s);
- s->bus = scsi_bus_new(&dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete);
- scsi_bus_legacy_handle_cmdline(s->bus);
+ scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete);
+ scsi_bus_legacy_handle_cmdline(&s->bus);
register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s);
return 0;
}
diff --git a/hw/pci.c b/hw/pci.c
index b42b73898..7a4378ef0 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -101,39 +101,60 @@ static void pci_bus_reset(void *opaque)
}
}
-PCIBus *pci_register_bus(DeviceState *parent, const char *name,
- pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *irq_opaque, int devfn_min, int nirq)
+void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+ const char *name, int devfn_min)
{
- PCIBus *bus;
static int nbus = 0;
- bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, parent, name));
- bus->set_irq = set_irq;
- bus->map_irq = map_irq;
- bus->irq_opaque = irq_opaque;
+ qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
bus->devfn_min = devfn_min;
- bus->nirq = nirq;
- bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
bus->next = first_bus;
first_bus = bus;
vmstate_register(nbus++, &vmstate_pcibus, bus);
qemu_register_reset(pci_bus_reset, bus);
+}
+
+PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min)
+{
+ PCIBus *bus;
+
+ bus = qemu_mallocz(sizeof(*bus));
+ bus->qbus.qdev_allocated = 1;
+ pci_bus_new_inplace(bus, parent, name, devfn_min);
return bus;
}
-static PCIBus *pci_register_secondary_bus(PCIDevice *dev,
- pci_map_irq_fn map_irq,
- const char *name)
+void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ void *irq_opaque, int nirq)
+{
+ bus->set_irq = set_irq;
+ bus->map_irq = map_irq;
+ bus->irq_opaque = irq_opaque;
+ bus->nirq = nirq;
+ bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
+}
+
+PCIBus *pci_register_bus(DeviceState *parent, const char *name,
+ pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ void *irq_opaque, int devfn_min, int nirq)
{
PCIBus *bus;
- bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name));
+ bus = pci_bus_new(parent, name, devfn_min);
+ pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
+ return bus;
+}
+
+static void pci_register_secondary_bus(PCIBus *bus,
+ PCIDevice *dev,
+ pci_map_irq_fn map_irq,
+ const char *name)
+{
+ qbus_create_inplace(&bus->qbus, &pci_bus_info, &dev->qdev, name);
bus->map_irq = map_irq;
bus->parent_dev = dev;
bus->next = dev->bus->next;
dev->bus->next = bus;
- return bus;
}
int pci_bus_num(PCIBus *s)
@@ -966,7 +987,9 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
typedef struct {
PCIDevice dev;
- PCIBus *bus;
+ PCIBus bus;
+ uint32_t vid;
+ uint32_t did;
} PCIBridge;
static void pci_bridge_write_config(PCIDevice *d,
@@ -975,7 +998,7 @@ static void pci_bridge_write_config(PCIDevice *d,
PCIBridge *s = (PCIBridge *)d;
pci_default_write_config(d, address, val, len);
- s->bus->bus_num = d->config[PCI_SECONDARY_BUS];
+ s->bus.bus_num = d->config[PCI_SECONDARY_BUS];
}
PCIBus *pci_find_bus(int bus_num)
@@ -998,15 +1021,12 @@ PCIDevice *pci_find_device(int bus_num, int slot, int function)
return bus->devices[PCI_DEVFN(slot, function)];
}
-PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
- pci_map_irq_fn map_irq, const char *name)
+static int pci_bridge_initfn(PCIDevice *dev)
{
- PCIBridge *s;
- s = (PCIBridge *)pci_register_device(bus, name, sizeof(PCIBridge),
- devfn, NULL, pci_bridge_write_config);
+ PCIBridge *s = DO_UPCAST(PCIBridge, dev, dev);
- pci_config_set_vendor_id(s->dev.config, vid);
- pci_config_set_device_id(s->dev.config, did);
+ pci_config_set_vendor_id(s->dev.config, s->vid);
+ pci_config_set_device_id(s->dev.config, s->did);
s->dev.config[0x04] = 0x06; // command = bus master, pci mem
s->dev.config[0x05] = 0x00;
@@ -1019,9 +1039,23 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
s->dev.config[PCI_HEADER_TYPE] =
PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type
s->dev.config[0x1E] = 0xa0; // secondary status
+ return 0;
+}
- s->bus = pci_register_secondary_bus(&s->dev, map_irq, name);
- return s->bus;
+PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
+ pci_map_irq_fn map_irq, const char *name)
+{
+ PCIDevice *dev;
+ PCIBridge *s;
+
+ dev = pci_create_noinit(bus, devfn, "pci-bridge");
+ qdev_prop_set_uint32(&dev->qdev, "vendorid", vid);
+ qdev_prop_set_uint32(&dev->qdev, "deviceid", did);
+ qdev_init(&dev->qdev);
+
+ s = DO_UPCAST(PCIBridge, dev, dev);
+ pci_register_secondary_bus(&s->bus, &s->dev, map_irq, name);
+ return &s->bus;
}
static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
@@ -1213,3 +1247,22 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
r->addr, r->addr + r->size - 1);
}
}
+
+static PCIDeviceInfo bridge_info = {
+ .qdev.name = "pci-bridge",
+ .qdev.size = sizeof(PCIBridge),
+ .init = pci_bridge_initfn,
+ .config_write = pci_bridge_write_config,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_HEX32("vendorid", PCIBridge, vid, 0),
+ DEFINE_PROP_HEX32("deviceid", PCIBridge, did, 0),
+ DEFINE_PROP_END_OF_LIST(),
+ }
+};
+
+static void pci_register_devices(void)
+{
+ pci_qdev_register(&bridge_info);
+}
+
+device_init(pci_register_devices)
diff --git a/hw/pci.h b/hw/pci.h
index 80a803c9e..250b9c197 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -295,6 +295,11 @@ 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);
+void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+ const char *name, int devfn_min);
+PCIBus *pci_bus_new(DeviceState *parent, const char *name, int devfn_min);
+void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ void *irq_opaque, int nirq);
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque, int devfn_min, int nirq);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index ee3f3fffe..b1134333b 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -38,18 +38,14 @@ typedef PCIHostState I440FXState;
typedef struct PIIX3State {
PCIDevice dev;
int pci_irq_levels[4];
-} PIIX3State;
-
-typedef struct PIIX3IrqState {
- PIIX3State *piix3;
qemu_irq *pic;
-} PIIX3IrqState;
+} PIIX3State;
struct PCII440FXState {
PCIDevice dev;
target_phys_addr_t isa_page_descs[384 / 4];
uint8_t smm_enabled;
- PIIX3IrqState *irq_state;
+ PIIX3State *piix3;
};
static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val)
@@ -173,7 +169,7 @@ static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
if (version_id == 2)
for (i = 0; i < 4; i++)
- d->irq_state->piix3->pci_irq_levels[i] = qemu_get_be32(f);
+ d->piix3->pci_irq_levels[i] = qemu_get_be32(f);
return 0;
}
@@ -240,25 +236,26 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
PCIBus *b;
PCIDevice *d;
I440FXState *s;
- PIIX3IrqState *irq_state = qemu_malloc(sizeof(*irq_state));
+ PIIX3State *piix3;
- irq_state->pic = pic;
dev = qdev_create(NULL, "i440FX-pcihost");
s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
- b = pci_register_bus(&s->busdev.qdev, "pci.0",
- piix3_set_irq, pci_slot_get_pirq, irq_state, 0, 4);
+ b = pci_bus_new(&s->busdev.qdev, NULL, 0);
s->bus = b;
qdev_init(dev);
d = pci_create_simple(b, 0, "i440FX");
*pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
- (*pi440fx_state)->irq_state = irq_state;
- irq_state->piix3 = DO_UPCAST(PIIX3State, dev,
+ piix3 = DO_UPCAST(PIIX3State, dev,
pci_create_simple(b, -1, "PIIX3"));
- *piix3_devfn = irq_state->piix3->dev.devfn;
+ piix3->pic = pic;
+ pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);
+ (*pi440fx_state)->piix3 = piix3;
+
+ *piix3_devfn = piix3->dev.devfn;
- piix3_dev = irq_state->piix3;
+ piix3_dev = piix3;
return b;
}
@@ -268,22 +265,22 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *
static void piix3_set_irq(void *opaque, int irq_num, int level)
{
int i, pic_irq, pic_level;
- PIIX3IrqState *irq_state = opaque;
+ PIIX3State *piix3 = opaque;
- irq_state->piix3->pci_irq_levels[irq_num] = level;
+ piix3->pci_irq_levels[irq_num] = level;
/* now we change the pic irq level according to the piix irq mappings */
/* XXX: optimize */
- pic_irq = irq_state->piix3->dev.config[0x60 + irq_num];
+ pic_irq = piix3->dev.config[0x60 + irq_num];
if (pic_irq < 16) {
/* The pic level is the logical OR of all the PCI irqs mapped
to it */
pic_level = 0;
for (i = 0; i < 4; i++) {
- if (pic_irq == irq_state->piix3->dev.config[0x60 + i])
- pic_level |= irq_state->piix3->pci_irq_levels[i];
+ if (pic_irq == piix3->dev.config[0x60 + i])
+ pic_level |= piix3->pci_irq_levels[i];
}
- qemu_set_irq(irq_state->pic[pic_irq], pic_level);
+ qemu_set_irq(piix3->pic[pic_irq], pic_level);
}
}
diff --git a/hw/qdev.c b/hw/qdev.c
index a589d7240..530e67404 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -502,13 +502,12 @@ static BusState *qbus_find(const char *path)
}
}
-BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
+void qbus_create_inplace(BusState *bus, BusInfo *info,
+ DeviceState *parent, const char *name)
{
- BusState *bus;
char *buf;
int i,len;
- bus = qemu_mallocz(info->size);
bus->info = info;
bus->parent = parent;
@@ -537,6 +536,16 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
parent->num_child_bus++;
}
+
+}
+
+BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
+{
+ BusState *bus;
+
+ bus = qemu_mallocz(info->size);
+ bus->qdev_allocated = 1;
+ qbus_create_inplace(bus, info, parent, name);
return bus;
}
diff --git a/hw/qdev.h b/hw/qdev.h
index 0a4d07a29..51d835f61 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -47,6 +47,7 @@ struct BusState {
DeviceState *parent;
BusInfo *info;
const char *name;
+ int qdev_allocated;
QLIST_HEAD(, DeviceState) children;
QLIST_ENTRY(BusState) sibling;
};
@@ -145,6 +146,8 @@ BusState *qdev_get_parent_bus(DeviceState *dev);
/*** BUS API. ***/
+void qbus_create_inplace(BusState *bus, BusInfo *info,
+ DeviceState *parent, const char *name);
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 16afa0532..881e36320 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -15,17 +15,14 @@ static struct BusInfo scsi_bus_info = {
static int next_scsi_bus;
/* Create a scsi bus, and attach devices to it. */
-SCSIBus *scsi_bus_new(DeviceState *host, int tcq, int ndev,
- scsi_completionfn complete)
+void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
+ scsi_completionfn complete)
{
- SCSIBus *bus;
-
- bus = FROM_QBUS(SCSIBus, qbus_create(&scsi_bus_info, host, NULL));
+ qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL);
bus->busnr = next_scsi_bus++;
bus->tcq = tcq;
bus->ndev = ndev;
bus->complete = complete;
- return bus;
}
static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
diff --git a/hw/scsi-disk.h b/hw/scsi-disk.h
index febde44a9..b6b6c1266 100644
--- a/hw/scsi-disk.h
+++ b/hw/scsi-disk.h
@@ -52,8 +52,8 @@ struct SCSIBus {
SCSIDevice *devs[8];
};
-SCSIBus *scsi_bus_new(DeviceState *host, int tcq, int ndev,
- scsi_completionfn complete);
+void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
+ scsi_completionfn complete);
void scsi_qdev_register(SCSIDeviceInfo *info);
static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 03933f12f..2cac1e85b 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -14,16 +14,13 @@ static struct BusInfo usb_bus_info = {
static int next_usb_bus = 0;
static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
-USBBus *usb_bus_new(DeviceState *host)
+void usb_bus_new(USBBus *bus, DeviceState *host)
{
- USBBus *bus;
-
- bus = FROM_QBUS(USBBus, qbus_create(&usb_bus_info, host, NULL));
+ qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL);
bus->busnr = next_usb_bus++;
QTAILQ_INIT(&bus->free);
QTAILQ_INIT(&bus->used);
QTAILQ_INSERT_TAIL(&busses, bus, next);
- return bus;
}
USBBus *usb_bus_find(int busnr)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index aa0ce6a12..6b9c8a5bd 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -45,7 +45,7 @@ typedef struct {
uint32_t data_len;
uint32_t residue;
uint32_t tag;
- SCSIBus *bus;
+ SCSIBus bus;
DriveInfo *dinfo;
SCSIDevice *scsi_dev;
int result;
@@ -527,8 +527,8 @@ static int usb_msd_initfn(USBDevice *dev)
}
s->dev.speed = USB_SPEED_FULL;
- s->bus = scsi_bus_new(&s->dev.qdev, 0, 1, usb_msd_command_complete);
- s->scsi_dev = scsi_bus_legacy_add_drive(s->bus, s->dinfo, 0);
+ scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete);
+ s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->dinfo, 0);
usb_msd_handle_reset(dev);
return 0;
}
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index 9eb0d6361..09ec5a125 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -281,7 +281,7 @@ typedef struct {
struct MUSBState {
qemu_irq *irqs;
- USBBus *bus;
+ USBBus bus;
USBPort port;
int idx;
@@ -331,8 +331,8 @@ struct MUSBState {
s->ep[i].epnum = i;
}
- s->bus = usb_bus_new(NULL /* FIXME */);
- usb_register_port(s->bus, &s->port, s, 0, musb_attach);
+ usb_bus_new(&s->bus, NULL /* FIXME */);
+ usb_register_port(&s->bus, &s->port, s, 0, musb_attach);
return s;
}
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 6e428c4fd..48ccd4933 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -65,7 +65,7 @@ enum ohci_type {
};
typedef struct {
- USBBus *bus;
+ USBBus bus;
qemu_irq irq;
enum ohci_type type;
int mem;
@@ -1690,10 +1690,10 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
ohci->irq = irq;
ohci->type = type;
- ohci->bus = usb_bus_new(dev);
+ usb_bus_new(&ohci->bus, dev);
ohci->num_ports = num_ports;
for (i = 0; i < num_ports; i++) {
- usb_register_port(ohci->bus, &ohci->rhport[i].port, ohci, i, ohci_attach);
+ usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, ohci_attach);
}
ohci->async_td = 0;
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 680741368..a3ed9b282 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -122,7 +122,7 @@ typedef struct UHCIPort {
typedef struct UHCIState {
PCIDevice dev;
- USBBus *bus;
+ USBBus bus;
uint16_t cmd; /* cmd register */
uint16_t status;
uint16_t intr; /* interrupt enable register */
@@ -1083,9 +1083,9 @@ static int usb_uhci_common_initfn(UHCIState *s)
pci_conf[0x3d] = 4; // interrupt pin 3
pci_conf[0x60] = 0x10; // release number
- s->bus = usb_bus_new(&s->dev.qdev);
+ usb_bus_new(&s->bus, &s->dev.qdev);
for(i = 0; i < NB_PORTS; i++) {
- usb_register_port(s->bus, &s->ports[i].port, s, i, uhci_attach);
+ usb_register_port(&s->bus, &s->ports[i].port, s, i, uhci_attach);
}
s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s);
diff --git a/hw/usb.h b/hw/usb.h
index 7c5cf8338..467cddb7b 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -303,7 +303,7 @@ struct USBBus {
QTAILQ_ENTRY(USBBus) next;
};
-USBBus *usb_bus_new(DeviceState *host);
+void usb_bus_new(USBBus *bus, DeviceState *host);
USBBus *usb_bus_find(int busnr);
void usb_qdev_register(USBDeviceInfo *info);
void usb_qdev_register_many(USBDeviceInfo *info);
diff --git a/kvm-all.c b/kvm-all.c
index d45bd46ac..b2651df8d 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -916,11 +916,15 @@ void kvm_setup_guest_memory(void *start, size_t size)
#ifdef KVM_UPSTREAM
static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
{
+#ifdef CONFIG_IOTHREAD
if (env == cpu_single_env) {
func(data);
return;
}
abort();
+#else
+ func(data);
+#endif
}
#endif /* KVM_UPSTREAM */
@@ -952,7 +956,13 @@ struct kvm_set_guest_debug_data {
static void kvm_invoke_set_guest_debug(void *data)
{
struct kvm_set_guest_debug_data *dbg_data = data;
- dbg_data->err = kvm_vcpu_ioctl(dbg_data->env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
+ CPUState *env = dbg_data->env;
+
+ if (env->kvm_state->regs_modified) {
+ kvm_arch_put_registers(env);
+ env->kvm_state->regs_modified = 0;
+ }
+ dbg_data->err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
}
int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)