QOM infrastructure fixes and device conversions

* QOM interface fixes and unit test
 * Device no_user sanitization and documentation
 * Device error reporting improvement
 * Conversion of APIC, ICC, IOAPIC to QOM realization model
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJSub6FAAoJEPou0S0+fgE/JGcP/RvIMVyldoUN1buS+ynXkNGS
 UXCwnGGwE6dw7V8eTHxgm7vj1SznaIFZd1jxhbU/PSRn7SkLjHhM4Ei5Nu06nsJD
 Dwe22muiGxPIucnwhhuyPni9gP386yR7/4cwqMqvEuB696ZO7tdcMQ4PxwMWW6GN
 8XsgF/3nlNFYTTxkG5KhmqqYEQdoQc5aloR7BZiziNaSIXLgIKAFp/T3vl+cwOyV
 j2N4Wq+egPNA821Y+sb9V8ZDkwQamE4qsSdIvWSaR24vFEQ8D+U6Sll2qkfcKo4H
 dmVu27OYFGJ4hJfyNoJ+7RKF1ET+IcmPW6Hcdri0CZNg5f3rHWur3mvasEMB3I3S
 sSQNfItp2bSj0LlTnOcbjE7kP3DTrunAoQ9TJaHo9N94sjXwr8EnCIwHqOZODZbr
 j07uKaRyQp4BCSQwP5QP4XEirLvzJOYCxCmT9pXELW/DMjgzjl1XgZVtEowvzHx4
 JNoF9mVGjVLDdwb9Tm+nR+9dQsNiGyF7HUYfIf1EwKshp6kwqOmO+YkNKq05kfRN
 0GhQB5exB6xN4zUqZTQ544WxB+hls6bOXpOlbKAEWQWpJ2Gj2hlBYTPCuFMwWrfl
 rH0jhC9zzlNqRyTUN+KZjU3GTa0T6neOSIXtDiS/VXWKDEV35zohYgwdpAfvpse2
 61a4MkgXwy7eqUeZ0Jqu
 =WrhM
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'afaerber/tags/qom-devices-for-anthony' into staging

QOM infrastructure fixes and device conversions

* QOM interface fixes and unit test
* Device no_user sanitization and documentation
* Device error reporting improvement
* Conversion of APIC, ICC, IOAPIC to QOM realization model

# gpg: Signature made Tue 24 Dec 2013 09:04:05 AM PST using RSA key ID 3E7E013F
# gpg: Good signature from "Andreas Färber <afaerber@suse.de>"
# gpg:                 aka "Andreas Färber <afaerber@suse.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 174F 0347 1BCC 221A 6175  6F96 FA2E D12D 3E7E 013F

* afaerber/tags/qom-devices-for-anthony: (24 commits)
  qdev-monitor: Improve error message for -device nonexistant
  ioapic: QOM'ify ioapic
  ioapic: Cleanup for QOM'ification
  icc_bus: QOM'ify ICC
  apic: QOM'ify APIC
  apic: Cleanup for QOM'ification
  qdev: Drop misleading qbus_free() function
  qom: Detect bad reentrance during object_class_foreach()
  tests: Test QOM interface casting
  qom: Do not register interface "types" in the type table and fix names
  qom: Split out object and class caches
  qdev: Document that pointer properties kill device_add
  hw: cannot_instantiate_with_device_add_yet due to pointer props
  qdev-monitor: Avoid device_add crashing on non-device driver name
  qdev: Do not let the user try to device_add when it cannot work
  isa: Clean up use of cannot_instantiate_with_device_add_yet
  vt82c686: Clean up use of cannot_instantiate_with_device_add_yet
  piix3 piix4: Clean up use of cannot_instantiate_with_device_add_yet
  ich9: Document why cannot_instantiate_with_device_add_yet
  pci-host: Consistently set cannot_instantiate_with_device_add_yet
  ...
This commit is contained in:
Anthony Liguori 2014-01-09 11:24:48 -08:00
commit c06f13c6da
84 changed files with 492 additions and 182 deletions

View file

@ -544,9 +544,13 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
k->revision = 0x03; k->revision = 0x03;
k->class_id = PCI_CLASS_BRIDGE_OTHER; k->class_id = PCI_CLASS_BRIDGE_OTHER;
dc->desc = "PM"; dc->desc = "PM";
dc->no_user = 1;
dc->vmsd = &vmstate_acpi; dc->vmsd = &vmstate_acpi;
dc->props = piix4_pm_properties; dc->props = piix4_pm_properties;
/*
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo piix4_pm_info = { static const TypeInfo piix4_pm_info = {

View file

@ -934,11 +934,9 @@ static int typhoon_pcihost_init(SysBusDevice *dev)
static void typhoon_pcihost_class_init(ObjectClass *klass, void *data) static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = typhoon_pcihost_init; k->init = typhoon_pcihost_init;
dc->no_user = 1;
} }
static const TypeInfo typhoon_pcihost_info = { static const TypeInfo typhoon_pcihost_info = {

View file

@ -390,7 +390,6 @@ static void vpb_sic_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = vpb_sic_init; k->init = vpb_sic_init;
dc->no_user = 1;
dc->vmsd = &vmstate_vpb_sic; dc->vmsd = &vmstate_vpb_sic;
} }

View file

@ -288,6 +288,8 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
dc->reset = mv88w8618_audio_reset; dc->reset = mv88w8618_audio_reset;
dc->vmsd = &mv88w8618_audio_vmsd; dc->vmsd = &mv88w8618_audio_vmsd;
dc->props = mv88w8618_audio_properties; dc->props = mv88w8618_audio_properties;
/* Reason: pointer property "wm8750" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo mv88w8618_audio_info = { static const TypeInfo mv88w8618_audio_info = {

View file

@ -192,8 +192,9 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
dc->realize = pcspk_realizefn; dc->realize = pcspk_realizefn;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories); set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->no_user = 1;
dc->props = pcspk_properties; dc->props = pcspk_properties;
/* Reason: pointer property "pit", realize sets global pcspk_state */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo pcspk_info = { static const TypeInfo pcspk_info = {

View file

@ -632,7 +632,6 @@ static void pl041_device_class_init(ObjectClass *klass, void *data)
k->init = pl041_init; k->init = pl041_init;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories); set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->no_user = 1;
dc->reset = pl041_device_reset; dc->reset = pl041_device_reset;
dc->vmsd = &vmstate_pl041; dc->vmsd = &vmstate_pl041;
dc->props = pl041_device_properties; dc->props = pl041_device_properties;

View file

@ -2234,7 +2234,6 @@ static void isabus_fdc_class_init(ObjectClass *klass, void *data)
dc->realize = isabus_fdc_realize; dc->realize = isabus_fdc_realize;
dc->fw_name = "fdc"; dc->fw_name = "fdc";
dc->no_user = 1;
dc->reset = fdctrl_external_reset_isa; dc->reset = fdctrl_external_reset_isa;
dc->vmsd = &vmstate_isa_fdc; dc->vmsd = &vmstate_isa_fdc;
dc->props = isa_fdc_properties; dc->props = isa_fdc_properties;

View file

@ -481,11 +481,6 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
return bus; return bus;
} }
void qbus_free(BusState *bus)
{
object_unparent(OBJECT(bus));
}
static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev) static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
{ {
BusClass *bc = BUS_GET_CLASS(bus); BusClass *bc = BUS_GET_CLASS(bus);
@ -794,7 +789,7 @@ static void device_unparent(Object *obj)
while (dev->num_child_bus) { while (dev->num_child_bus) {
bus = QLIST_FIRST(&dev->child_bus); bus = QLIST_FIRST(&dev->child_bus);
qbus_free(bus); object_unparent(OBJECT(bus));
} }
if (dev->realized) { if (dev->realized) {
object_property_set_bool(obj, false, "realized", NULL); object_property_set_bool(obj, false, "realized", NULL);

View file

@ -257,6 +257,13 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data)
DeviceClass *k = DEVICE_CLASS(klass); DeviceClass *k = DEVICE_CLASS(klass);
k->init = sysbus_device_init; k->init = sysbus_device_init;
k->bus_type = TYPE_SYSTEM_BUS; k->bus_type = TYPE_SYSTEM_BUS;
/*
* device_add plugs devices into suitable bus. For "real" buses,
* that actually connects the device. For sysbus, the connections
* need to be made separately, and device_add can't do that. The
* device would be left unconnected, and could not possibly work.
*/
k->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo sysbus_device_type_info = { static const TypeInfo sysbus_device_type_info = {

View file

@ -43,15 +43,13 @@ static const TypeInfo icc_bus_info = {
static void icc_device_realize(DeviceState *dev, Error **errp) static void icc_device_realize(DeviceState *dev, Error **errp)
{ {
ICCDevice *id = ICC_DEVICE(dev); ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev);
ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(id);
if (idc->init) { /* convert to QOM */
if (idc->init(id) < 0) { if (idc->realize) {
error_setg(errp, "%s initialization failed.", idc->realize(dev, errp);
object_get_typename(OBJECT(dev)));
}
} }
} }
static void icc_device_class_init(ObjectClass *oc, void *data) static void icc_device_class_init(ObjectClass *oc, void *data)

View file

@ -496,7 +496,6 @@ static void pl110_class_init(ObjectClass *klass, void *data)
k->init = pl110_initfn; k->init = pl110_initfn;
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->no_user = 1;
dc->vmsd = &vmstate_pl110; dc->vmsd = &vmstate_pl110;
} }

View file

@ -381,7 +381,6 @@ static void pl080_class_init(ObjectClass *oc, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc);
dc->no_user = 1;
dc->vmsd = &vmstate_pl080; dc->vmsd = &vmstate_pl080;
} }

View file

@ -304,6 +304,8 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data)
dc->reset = dma_reset; dc->reset = dma_reset;
dc->vmsd = &vmstate_dma; dc->vmsd = &vmstate_dma;
dc->props = sparc32_dma_properties; dc->props = sparc32_dma_properties;
/* Reason: pointer property "iommu_opaque" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo sparc32_dma_info = { static const TypeInfo sparc32_dma_info = {

View file

@ -759,6 +759,8 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
k->init = omap_gpio_init; k->init = omap_gpio_init;
dc->reset = omap_gpif_reset; dc->reset = omap_gpif_reset;
dc->props = omap_gpio_properties; dc->props = omap_gpio_properties;
/* Reason: pointer property "clk" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo omap_gpio_info = { static const TypeInfo omap_gpio_info = {
@ -788,6 +790,8 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
k->init = omap2_gpio_init; k->init = omap2_gpio_init;
dc->reset = omap2_gpif_reset; dc->reset = omap2_gpif_reset;
dc->props = omap2_gpio_properties; dc->props = omap2_gpio_properties;
/* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo omap2_gpio_info = { static const TypeInfo omap2_gpio_info = {

View file

@ -475,6 +475,8 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data)
k->init = omap_i2c_init; k->init = omap_i2c_init;
dc->props = omap_i2c_properties; dc->props = omap_i2c_properties;
dc->reset = omap_i2c_reset; dc->reset = omap_i2c_reset;
/* Reason: pointer properties "iclk", "fclk" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo omap_i2c_info = { static const TypeInfo omap_i2c_info = {

View file

@ -121,6 +121,8 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
sc->write_data = eeprom_write_data; sc->write_data = eeprom_write_data;
sc->read_data = eeprom_read_data; sc->read_data = eeprom_read_data;
dc->props = smbus_eeprom_properties; dc->props = smbus_eeprom_properties;
/* Reason: pointer property "data" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo smbus_eeprom_info = { static const TypeInfo smbus_eeprom_info = {

View file

@ -97,11 +97,15 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_ICH9_6; k->device_id = PCI_DEVICE_ID_INTEL_ICH9_6;
k->revision = ICH9_A2_SMB_REVISION; k->revision = ICH9_A2_SMB_REVISION;
k->class_id = PCI_CLASS_SERIAL_SMBUS; k->class_id = PCI_CLASS_SERIAL_SMBUS;
dc->no_user = 1;
dc->vmsd = &vmstate_ich9_smbus; dc->vmsd = &vmstate_ich9_smbus;
dc->desc = "ICH9 SMBUS Bridge"; dc->desc = "ICH9 SMBUS Bridge";
k->init = ich9_smbus_initfn; k->init = ich9_smbus_initfn;
k->config_write = ich9_smbus_write_config; k->config_write = ich9_smbus_write_config;
/*
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base) i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base)

View file

@ -25,9 +25,9 @@ static inline uint32_t kvm_apic_get_reg(struct kvm_lapic_state *kapic,
return *((uint32_t *)(kapic->regs + (reg_id << 4))); return *((uint32_t *)(kapic->regs + (reg_id << 4)));
} }
void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) void kvm_put_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
int i; int i;
memset(kapic, 0, sizeof(*kapic)); memset(kapic, 0, sizeof(*kapic));
@ -51,9 +51,9 @@ void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic)
kvm_apic_set_reg(kapic, 0x3e, s->divide_conf); kvm_apic_set_reg(kapic, 0x3e, s->divide_conf);
} }
void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) void kvm_get_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
int i, v; int i, v;
s->id = kvm_apic_get_reg(kapic, 0x2) >> 24; s->id = kvm_apic_get_reg(kapic, 0x2) >> 24;
@ -171,8 +171,10 @@ static const MemoryRegionOps kvm_apic_io_ops = {
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_NATIVE_ENDIAN,
}; };
static void kvm_apic_init(APICCommonState *s) static void kvm_apic_realize(DeviceState *dev, Error **errp)
{ {
APICCommonState *s = APIC_COMMON(dev);
memory_region_init_io(&s->io_memory, NULL, &kvm_apic_io_ops, s, "kvm-apic-msi", memory_region_init_io(&s->io_memory, NULL, &kvm_apic_io_ops, s, "kvm-apic-msi",
APIC_SPACE_SIZE); APIC_SPACE_SIZE);
@ -185,7 +187,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data)
{ {
APICCommonClass *k = APIC_COMMON_CLASS(klass); APICCommonClass *k = APIC_COMMON_CLASS(klass);
k->init = kvm_apic_init; k->realize = kvm_apic_realize;
k->set_base = kvm_apic_set_base; k->set_base = kvm_apic_set_base;
k->set_tpr = kvm_apic_set_tpr; k->set_tpr = kvm_apic_set_tpr;
k->get_tpr = kvm_apic_get_tpr; k->get_tpr = kvm_apic_get_tpr;

View file

@ -114,7 +114,6 @@ static void kvmclock_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = kvmclock_realize; dc->realize = kvmclock_realize;
dc->no_user = 1;
dc->vmsd = &kvmclock_vmsd; dc->vmsd = &kvmclock_vmsd;
} }

View file

@ -127,11 +127,13 @@ static void kvm_ioapic_set_irq(void *opaque, int irq, int level)
apic_report_irq_delivered(delivered); apic_report_irq_delivered(delivered);
} }
static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no) static void kvm_ioapic_realize(DeviceState *dev, Error **errp)
{ {
IOAPICCommonState *s = IOAPIC_COMMON(dev);
memory_region_init_reservation(&s->io_memory, NULL, "kvm-ioapic", 0x1000); memory_region_init_reservation(&s->io_memory, NULL, "kvm-ioapic", 0x1000);
qdev_init_gpio_in(DEVICE(s), kvm_ioapic_set_irq, IOAPIC_NUM_PINS); qdev_init_gpio_in(dev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS);
} }
static Property kvm_ioapic_properties[] = { static Property kvm_ioapic_properties[] = {
@ -144,7 +146,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
k->init = kvm_ioapic_init; k->realize = kvm_ioapic_realize;
k->pre_save = kvm_ioapic_get; k->pre_save = kvm_ioapic_get;
k->post_load = kvm_ioapic_put; k->post_load = kvm_ioapic_put;
dc->reset = kvm_ioapic_reset; dc->reset = kvm_ioapic_reset;

View file

@ -827,7 +827,6 @@ static void vapic_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->no_user = 1;
dc->reset = vapic_reset; dc->reset = vapic_reset;
dc->vmsd = &vmstate_vapic; dc->vmsd = &vmstate_vapic;
dc->realize = vapic_realize; dc->realize = vapic_realize;

View file

@ -547,10 +547,15 @@ static void port92_class_initfn(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->no_user = 1;
dc->realize = port92_realizefn; dc->realize = port92_realizefn;
dc->reset = port92_reset; dc->reset = port92_reset;
dc->vmsd = &vmstate_port92_isa; dc->vmsd = &vmstate_port92_isa;
/*
* Reason: unlike ordinary ISA devices, this one needs additional
* wiring: its A20 output line needs to be wired up by
* port92_init().
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo port92_info = { static const TypeInfo port92_info = {

View file

@ -248,7 +248,6 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
k->class_id = PCI_CLASS_STORAGE_IDE; k->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
} }
static const TypeInfo piix3_ide_info = { static const TypeInfo piix3_ide_info = {
@ -267,7 +266,6 @@ static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
k->class_id = PCI_CLASS_STORAGE_IDE; k->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
dc->unplug = pci_piix3_xen_ide_unplug; dc->unplug = pci_piix3_xen_ide_unplug;
} }
@ -289,7 +287,6 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_82371AB; k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
k->class_id = PCI_CLASS_STORAGE_IDE; k->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
} }
static const TypeInfo piix4_ide_info = { static const TypeInfo piix4_ide_info = {

View file

@ -225,7 +225,6 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
k->revision = 0x06; k->revision = 0x06;
k->class_id = PCI_CLASS_STORAGE_IDE; k->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
} }
static const TypeInfo via_ide_info = { static const TypeInfo via_ide_info = {

View file

@ -522,7 +522,6 @@ static void i8042_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = i8042_realizefn; dc->realize = i8042_realizefn;
dc->no_user = 1;
dc->vmsd = &vmstate_kbd_isa; dc->vmsd = &vmstate_kbd_isa;
} }

View file

@ -282,10 +282,11 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = vmmouse_realizefn; dc->realize = vmmouse_realizefn;
dc->no_user = 1;
dc->reset = vmmouse_reset; dc->reset = vmmouse_reset;
dc->vmsd = &vmstate_vmmouse; dc->vmsd = &vmstate_vmmouse;
dc->props = vmmouse_properties; dc->props = vmmouse_properties;
/* Reason: pointer property "ps2_mouse" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo vmmouse_info = { static const TypeInfo vmmouse_info = {

View file

@ -171,9 +171,9 @@ static void apic_local_deliver(APICCommonState *s, int vector)
} }
} }
void apic_deliver_pic_intr(DeviceState *d, int level) void apic_deliver_pic_intr(DeviceState *dev, int level)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
if (level) { if (level) {
apic_local_deliver(s, APIC_LVT_LINT0); apic_local_deliver(s, APIC_LVT_LINT0);
@ -376,9 +376,9 @@ static void apic_update_irq(APICCommonState *s)
} }
} }
void apic_poll_irq(DeviceState *d) void apic_poll_irq(DeviceState *dev)
{ {
APICCommonState *s = APIC_COMMON(d); APICCommonState *s = APIC_COMMON(dev);
apic_sync_vapic(s, SYNC_FROM_VAPIC); apic_sync_vapic(s, SYNC_FROM_VAPIC);
apic_update_irq(s); apic_update_irq(s);
@ -482,9 +482,9 @@ static void apic_startup(APICCommonState *s, int vector_num)
cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
} }
void apic_sipi(DeviceState *d) void apic_sipi(DeviceState *dev)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
@ -494,11 +494,11 @@ void apic_sipi(DeviceState *d)
s->wait_for_sipi = 0; s->wait_for_sipi = 0;
} }
static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode, static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode,
uint8_t delivery_mode, uint8_t vector_num, uint8_t delivery_mode, uint8_t vector_num,
uint8_t trigger_mode) uint8_t trigger_mode)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
uint32_t deliver_bitmask[MAX_APIC_WORDS]; uint32_t deliver_bitmask[MAX_APIC_WORDS];
int dest_shorthand = (s->icr[0] >> 18) & 3; int dest_shorthand = (s->icr[0] >> 18) & 3;
APICCommonState *apic_iter; APICCommonState *apic_iter;
@ -551,9 +551,9 @@ static bool apic_check_pic(APICCommonState *s)
return true; return true;
} }
int apic_get_interrupt(DeviceState *d) int apic_get_interrupt(DeviceState *dev)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
int intno; int intno;
/* if the APIC is installed or enabled, we let the 8259 handle the /* if the APIC is installed or enabled, we let the 8259 handle the
@ -585,9 +585,9 @@ int apic_get_interrupt(DeviceState *d)
return intno; return intno;
} }
int apic_accept_pic_intr(DeviceState *d) int apic_accept_pic_intr(DeviceState *dev)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
uint32_t lvt0; uint32_t lvt0;
if (!s) if (!s)
@ -657,16 +657,16 @@ static void apic_mem_writew(void *opaque, hwaddr addr, uint32_t val)
static uint32_t apic_mem_readl(void *opaque, hwaddr addr) static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
{ {
DeviceState *d; DeviceState *dev;
APICCommonState *s; APICCommonState *s;
uint32_t val; uint32_t val;
int index; int index;
d = cpu_get_current_apic(); dev = cpu_get_current_apic();
if (!d) { if (!dev) {
return 0; return 0;
} }
s = DO_UPCAST(APICCommonState, busdev.qdev, d); s = APIC_COMMON(dev);
index = (addr >> 4) & 0xff; index = (addr >> 4) & 0xff;
switch(index) { switch(index) {
@ -752,7 +752,7 @@ static void apic_send_msi(hwaddr addr, uint32_t data)
static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
{ {
DeviceState *d; DeviceState *dev;
APICCommonState *s; APICCommonState *s;
int index = (addr >> 4) & 0xff; int index = (addr >> 4) & 0xff;
if (addr > 0xfff || !index) { if (addr > 0xfff || !index) {
@ -765,11 +765,11 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
return; return;
} }
d = cpu_get_current_apic(); dev = cpu_get_current_apic();
if (!d) { if (!dev) {
return; return;
} }
s = DO_UPCAST(APICCommonState, busdev.qdev, d); s = APIC_COMMON(dev);
trace_apic_mem_writel(addr, val); trace_apic_mem_writel(addr, val);
@ -810,7 +810,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
break; break;
case 0x30: case 0x30:
s->icr[0] = val; s->icr[0] = val;
apic_deliver(d, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, apic_deliver(dev, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
(s->icr[0] >> 8) & 7, (s->icr[0] & 0xff), (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
(s->icr[0] >> 15) & 1); (s->icr[0] >> 15) & 1);
break; break;
@ -871,8 +871,10 @@ static const MemoryRegionOps apic_io_ops = {
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_NATIVE_ENDIAN,
}; };
static void apic_init(APICCommonState *s) static void apic_realize(DeviceState *dev, Error **errp)
{ {
APICCommonState *s = APIC_COMMON(dev);
memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi", memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi",
APIC_SPACE_SIZE); APIC_SPACE_SIZE);
@ -886,7 +888,7 @@ static void apic_class_init(ObjectClass *klass, void *data)
{ {
APICCommonClass *k = APIC_COMMON_CLASS(klass); APICCommonClass *k = APIC_COMMON_CLASS(klass);
k->init = apic_init; k->realize = apic_realize;
k->set_base = apic_set_base; k->set_base = apic_set_base;
k->set_tpr = apic_set_tpr; k->set_tpr = apic_set_tpr;
k->get_tpr = apic_get_tpr; k->get_tpr = apic_get_tpr;

View file

@ -27,21 +27,21 @@
static int apic_irq_delivered; static int apic_irq_delivered;
bool apic_report_tpr_access; bool apic_report_tpr_access;
void cpu_set_apic_base(DeviceState *d, uint64_t val) void cpu_set_apic_base(DeviceState *dev, uint64_t val)
{ {
trace_cpu_set_apic_base(val); trace_cpu_set_apic_base(val);
if (d) { if (dev) {
APICCommonState *s = APIC_COMMON(d); APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info = APIC_COMMON_GET_CLASS(s); APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
info->set_base(s, val); info->set_base(s, val);
} }
} }
uint64_t cpu_get_apic_base(DeviceState *d) uint64_t cpu_get_apic_base(DeviceState *dev)
{ {
if (d) { if (dev) {
APICCommonState *s = APIC_COMMON(d); APICCommonState *s = APIC_COMMON(dev);
trace_cpu_get_apic_base((uint64_t)s->apicbase); trace_cpu_get_apic_base((uint64_t)s->apicbase);
return s->apicbase; return s->apicbase;
} else { } else {
@ -50,39 +50,39 @@ uint64_t cpu_get_apic_base(DeviceState *d)
} }
} }
void cpu_set_apic_tpr(DeviceState *d, uint8_t val) void cpu_set_apic_tpr(DeviceState *dev, uint8_t val)
{ {
APICCommonState *s; APICCommonState *s;
APICCommonClass *info; APICCommonClass *info;
if (!d) { if (!dev) {
return; return;
} }
s = APIC_COMMON(d); s = APIC_COMMON(dev);
info = APIC_COMMON_GET_CLASS(s); info = APIC_COMMON_GET_CLASS(s);
info->set_tpr(s, val); info->set_tpr(s, val);
} }
uint8_t cpu_get_apic_tpr(DeviceState *d) uint8_t cpu_get_apic_tpr(DeviceState *dev)
{ {
APICCommonState *s; APICCommonState *s;
APICCommonClass *info; APICCommonClass *info;
if (!d) { if (!dev) {
return 0; return 0;
} }
s = APIC_COMMON(d); s = APIC_COMMON(dev);
info = APIC_COMMON_GET_CLASS(s); info = APIC_COMMON_GET_CLASS(s);
return info->get_tpr(s); return info->get_tpr(s);
} }
void apic_enable_tpr_access_reporting(DeviceState *d, bool enable) void apic_enable_tpr_access_reporting(DeviceState *dev, bool enable)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info = APIC_COMMON_GET_CLASS(s); APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
apic_report_tpr_access = enable; apic_report_tpr_access = enable;
@ -91,19 +91,19 @@ void apic_enable_tpr_access_reporting(DeviceState *d, bool enable)
} }
} }
void apic_enable_vapic(DeviceState *d, hwaddr paddr) void apic_enable_vapic(DeviceState *dev, hwaddr paddr)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info = APIC_COMMON_GET_CLASS(s); APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
s->vapic_paddr = paddr; s->vapic_paddr = paddr;
info->vapic_base_update(s); info->vapic_base_update(s);
} }
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, void apic_handle_tpr_access_report(DeviceState *dev, target_ulong ip,
TPRAccess access) TPRAccess access)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access); vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access);
} }
@ -129,9 +129,9 @@ int apic_get_irq_delivered(void)
return apic_irq_delivered; return apic_irq_delivered;
} }
void apic_deliver_nmi(DeviceState *d) void apic_deliver_nmi(DeviceState *dev)
{ {
APICCommonState *s = APIC_COMMON(d); APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info = APIC_COMMON_GET_CLASS(s); APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
info->external_nmi(s); info->external_nmi(s);
@ -170,9 +170,9 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time)
return true; return true;
} }
void apic_init_reset(DeviceState *d) void apic_init_reset(DeviceState *dev)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
int i; int i;
if (!s) { if (!s) {
@ -203,19 +203,19 @@ void apic_init_reset(DeviceState *d)
s->timer_expiry = -1; s->timer_expiry = -1;
} }
void apic_designate_bsp(DeviceState *d) void apic_designate_bsp(DeviceState *dev)
{ {
if (d == NULL) { if (dev == NULL) {
return; return;
} }
APICCommonState *s = APIC_COMMON(d); APICCommonState *s = APIC_COMMON(dev);
s->apicbase |= MSR_IA32_APICBASE_BSP; s->apicbase |= MSR_IA32_APICBASE_BSP;
} }
static void apic_reset_common(DeviceState *d) static void apic_reset_common(DeviceState *dev)
{ {
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info = APIC_COMMON_GET_CLASS(s); APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
bool bsp; bool bsp;
@ -226,7 +226,7 @@ static void apic_reset_common(DeviceState *d)
s->vapic_paddr = 0; s->vapic_paddr = 0;
info->vapic_base_update(s); info->vapic_base_update(s);
apic_init_reset(d); apic_init_reset(dev);
if (bsp) { if (bsp) {
/* /*
@ -284,7 +284,7 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
static int apic_init_common(ICCDevice *dev) static void apic_common_realize(DeviceState *dev, Error **errp)
{ {
APICCommonState *s = APIC_COMMON(dev); APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info; APICCommonClass *info;
@ -293,14 +293,16 @@ static int apic_init_common(ICCDevice *dev)
static bool mmio_registered; static bool mmio_registered;
if (apic_no >= MAX_APICS) { if (apic_no >= MAX_APICS) {
return -1; error_setg(errp, "%s initialization failed.",
object_get_typename(OBJECT(dev)));
return;
} }
s->idx = apic_no++; s->idx = apic_no++;
info = APIC_COMMON_GET_CLASS(s); info = APIC_COMMON_GET_CLASS(s);
info->init(s); info->realize(dev, errp);
if (!mmio_registered) { if (!mmio_registered) {
ICCBus *b = ICC_BUS(qdev_get_parent_bus(DEVICE(dev))); ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev));
memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory);
mmio_registered = true; mmio_registered = true;
} }
@ -315,7 +317,6 @@ static int apic_init_common(ICCDevice *dev)
info->enable_tpr_reporting(s, true); info->enable_tpr_reporting(s, true);
} }
return 0;
} }
static void apic_dispatch_pre_save(void *opaque) static void apic_dispatch_pre_save(void *opaque)
@ -386,9 +387,13 @@ static void apic_common_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_apic_common; dc->vmsd = &vmstate_apic_common;
dc->reset = apic_reset_common; dc->reset = apic_reset_common;
dc->no_user = 1;
dc->props = apic_properties_common; dc->props = apic_properties_common;
idc->init = apic_init_common; idc->realize = apic_common_realize;
/*
* Reason: APIC and CPU need to be wired up by
* x86_cpu_apic_create()
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo apic_common_type = { static const TypeInfo apic_common_type = {
@ -400,9 +405,9 @@ static const TypeInfo apic_common_type = {
.abstract = true, .abstract = true,
}; };
static void register_types(void) static void apic_common_register_types(void)
{ {
type_register_static(&apic_common_type); type_register_static(&apic_common_type);
} }
type_init(register_types) type_init(apic_common_register_types)

View file

@ -709,7 +709,6 @@ static void arm_gic_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
ARMGICClass *agc = ARM_GIC_CLASS(klass); ARMGICClass *agc = ARM_GIC_CLASS(klass);
dc->no_user = 1;
agc->parent_realize = dc->realize; agc->parent_realize = dc->realize;
dc->realize = arm_gic_realize; dc->realize = arm_gic_realize;
} }

View file

@ -156,7 +156,6 @@ static void arm_gic_common_class_init(ObjectClass *klass, void *data)
dc->realize = arm_gic_common_realize; dc->realize = arm_gic_common_realize;
dc->props = arm_gic_common_properties; dc->props = arm_gic_common_properties;
dc->vmsd = &vmstate_gic; dc->vmsd = &vmstate_gic;
dc->no_user = 1;
} }
static const TypeInfo arm_gic_common_type = { static const TypeInfo arm_gic_common_type = {

View file

@ -150,7 +150,6 @@ static void kvm_arm_gic_class_init(ObjectClass *klass, void *data)
kgc->parent_reset = dc->reset; kgc->parent_reset = dc->reset;
dc->realize = kvm_arm_gic_realize; dc->realize = kvm_arm_gic_realize;
dc->reset = kvm_arm_gic_reset; dc->reset = kvm_arm_gic_reset;
dc->no_user = 1;
} }
static const TypeInfo kvm_arm_gic_info = { static const TypeInfo kvm_arm_gic_info = {

View file

@ -170,6 +170,10 @@ static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
k->init = etraxfs_pic_init; k->init = etraxfs_pic_init;
dc->props = etraxfs_pic_properties; dc->props = etraxfs_pic_properties;
/*
* Note: pointer property "interrupt_vector" may remain null, thus
* no need for dc->cannot_instantiate_with_device_add_yet = true;
*/
} }
static const TypeInfo etraxfs_pic_info = { static const TypeInfo etraxfs_pic_info = {

View file

@ -355,6 +355,8 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
k->init = grlib_irqmp_init; k->init = grlib_irqmp_init;
dc->reset = grlib_irqmp_reset; dc->reset = grlib_irqmp_reset;
dc->props = grlib_irqmp_properties; dc->props = grlib_irqmp_properties;
/* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo grlib_irqmp_info = { static const TypeInfo grlib_irqmp_info = {

View file

@ -135,9 +135,15 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &vmstate_pic_common; dc->vmsd = &vmstate_pic_common;
dc->no_user = 1;
dc->props = pic_properties_common; dc->props = pic_properties_common;
dc->realize = pic_common_realize; dc->realize = pic_common_realize;
/*
* Reason: unlike ordinary ISA devices, the PICs need additional
* wiring: its IRQ input lines are set up by board code, and the
* wiring of the slave to the master is hard-coded in device model
* code.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo pic_common_type = { static const TypeInfo pic_common_type = {

View file

@ -36,6 +36,9 @@
static IOAPICCommonState *ioapics[MAX_IOAPICS]; static IOAPICCommonState *ioapics[MAX_IOAPICS];
/* global variable from ioapic_common.c */
extern int ioapic_no;
static void ioapic_service(IOAPICCommonState *s) static void ioapic_service(IOAPICCommonState *s)
{ {
uint8_t i; uint8_t i;
@ -225,14 +228,16 @@ static const MemoryRegionOps ioapic_io_ops = {
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_NATIVE_ENDIAN,
}; };
static void ioapic_init(IOAPICCommonState *s, int instance_no) static void ioapic_realize(DeviceState *dev, Error **errp)
{ {
IOAPICCommonState *s = IOAPIC_COMMON(dev);
memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s, memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s,
"ioapic", 0x1000); "ioapic", 0x1000);
qdev_init_gpio_in(DEVICE(s), ioapic_set_irq, IOAPIC_NUM_PINS); qdev_init_gpio_in(dev, ioapic_set_irq, IOAPIC_NUM_PINS);
ioapics[instance_no] = s; ioapics[ioapic_no] = s;
} }
static void ioapic_class_init(ObjectClass *klass, void *data) static void ioapic_class_init(ObjectClass *klass, void *data)
@ -240,7 +245,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data)
IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
k->init = ioapic_init; k->realize = ioapic_realize;
dc->reset = ioapic_reset_common; dc->reset = ioapic_reset_common;
} }

View file

@ -23,6 +23,14 @@
#include "hw/i386/ioapic_internal.h" #include "hw/i386/ioapic_internal.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
/* ioapic_no count start from 0 to MAX_IOAPICS,
* remove as static variable from ioapic_common_init.
* now as a global variable, let child to increase the counter
* then we can drop the 'instance_no' argument
* and convert to our QOM's realize function
*/
int ioapic_no;
void ioapic_reset_common(DeviceState *dev) void ioapic_reset_common(DeviceState *dev)
{ {
IOAPICCommonState *s = IOAPIC_COMMON(dev); IOAPICCommonState *s = IOAPIC_COMMON(dev);
@ -61,7 +69,6 @@ static void ioapic_common_realize(DeviceState *dev, Error **errp)
{ {
IOAPICCommonState *s = IOAPIC_COMMON(dev); IOAPICCommonState *s = IOAPIC_COMMON(dev);
IOAPICCommonClass *info; IOAPICCommonClass *info;
static int ioapic_no;
if (ioapic_no >= MAX_IOAPICS) { if (ioapic_no >= MAX_IOAPICS) {
error_setg(errp, "Only %d ioapics allowed", MAX_IOAPICS); error_setg(errp, "Only %d ioapics allowed", MAX_IOAPICS);
@ -69,7 +76,7 @@ static void ioapic_common_realize(DeviceState *dev, Error **errp)
} }
info = IOAPIC_COMMON_GET_CLASS(s); info = IOAPIC_COMMON_GET_CLASS(s);
info->init(s, ioapic_no); info->realize(dev, errp);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io_memory); sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io_memory);
ioapic_no++; ioapic_no++;
@ -98,7 +105,6 @@ static void ioapic_common_class_init(ObjectClass *klass, void *data)
dc->realize = ioapic_common_realize; dc->realize = ioapic_common_realize;
dc->vmsd = &vmstate_ioapic_common; dc->vmsd = &vmstate_ioapic_common;
dc->no_user = 1;
} }
static const TypeInfo ioapic_common_type = { static const TypeInfo ioapic_common_type = {
@ -110,9 +116,9 @@ static const TypeInfo ioapic_common_type = {
.abstract = true, .abstract = true,
}; };
static void register_types(void) static void ioapic_common_register_types(void)
{ {
type_register_static(&ioapic_common_type); type_register_static(&ioapic_common_type);
} }
type_init(register_types) type_init(ioapic_common_register_types)

View file

@ -392,6 +392,8 @@ static void omap_intc_class_init(ObjectClass *klass, void *data)
k->init = omap_intc_init; k->init = omap_intc_init;
dc->reset = omap_inth_reset; dc->reset = omap_inth_reset;
dc->props = omap_intc_properties; dc->props = omap_intc_properties;
/* Reason: pointer property "clk" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo omap_intc_info = { static const TypeInfo omap_intc_info = {
@ -637,6 +639,8 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data)
k->init = omap2_intc_init; k->init = omap2_intc_init;
dc->reset = omap_inth_reset; dc->reset = omap_inth_reset;
dc->props = omap2_intc_properties; dc->props = omap2_intc_properties;
/* Reason: pointer property "iclk", "fclk" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo omap2_intc_info = { static const TypeInfo omap2_intc_info = {

View file

@ -273,7 +273,6 @@ static void pl190_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = pl190_init; k->init = pl190_init;
dc->no_user = 1;
dc->reset = pl190_reset; dc->reset = pl190_reset;
dc->vmsd = &vmstate_pl190; dc->vmsd = &vmstate_pl190;
} }

View file

@ -197,7 +197,6 @@ static void isabus_bridge_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->fw_name = "isa"; dc->fw_name = "isa";
dc->no_user = 1;
} }
static const TypeInfo isabus_bridge_info = { static const TypeInfo isabus_bridge_info = {

View file

@ -644,14 +644,17 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
dc->reset = ich9_lpc_reset; dc->reset = ich9_lpc_reset;
k->init = ich9_lpc_initfn; k->init = ich9_lpc_initfn;
dc->vmsd = &vmstate_ich9_lpc; dc->vmsd = &vmstate_ich9_lpc;
dc->no_user = 1;
k->config_write = ich9_lpc_config_write; k->config_write = ich9_lpc_config_write;
dc->desc = "ICH9 LPC bridge"; dc->desc = "ICH9 LPC bridge";
k->vendor_id = PCI_VENDOR_ID_INTEL; k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8; k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8;
k->revision = ICH9_A2_LPC_REVISION; k->revision = ICH9_A2_LPC_REVISION;
k->class_id = PCI_CLASS_BRIDGE_ISA; k->class_id = PCI_CLASS_BRIDGE_ISA;
/*
* Reason: part of ICH9 southbridge, needs to be wired up by
* pc_q35_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo ich9_lpc_info = { static const TypeInfo ich9_lpc_info = {

View file

@ -113,8 +113,12 @@ static void piix4_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0; k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
k->class_id = PCI_CLASS_BRIDGE_ISA; k->class_id = PCI_CLASS_BRIDGE_ISA;
dc->desc = "ISA bridge"; dc->desc = "ISA bridge";
dc->no_user = 1;
dc->vmsd = &vmstate_piix4; dc->vmsd = &vmstate_piix4;
/*
* Reason: part of PIIX4 southbridge, needs to be wired up,
* e.g. by mips_malta_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo piix4_info = { static const TypeInfo piix4_info = {

View file

@ -480,8 +480,12 @@ static void via_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA; k->class_id = PCI_CLASS_BRIDGE_ISA;
k->revision = 0x40; k->revision = 0x40;
dc->desc = "ISA bridge"; dc->desc = "ISA bridge";
dc->no_user = 1;
dc->vmsd = &vmstate_via; dc->vmsd = &vmstate_via;
/*
* Reason: part of VIA VT82C686 southbridge, needs to be wired up,
* e.g. by mips_fulong2e_init()
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo via_info = { static const TypeInfo via_info = {

View file

@ -1151,12 +1151,18 @@ static int gt64120_pci_init(PCIDevice *d)
static void gt64120_pci_class_init(ObjectClass *klass, void *data) static void gt64120_pci_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = gt64120_pci_init; k->init = gt64120_pci_init;
k->vendor_id = PCI_VENDOR_ID_MARVELL; k->vendor_id = PCI_VENDOR_ID_MARVELL;
k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X; k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X;
k->revision = 0x10; k->revision = 0x10;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo gt64120_pci_info = { static const TypeInfo gt64120_pci_info = {

View file

@ -179,7 +179,6 @@ static void l2x0_class_init(ObjectClass *klass, void *data)
k->init = l2x0_priv_init; k->init = l2x0_priv_init;
dc->vmsd = &vmstate_l2x0; dc->vmsd = &vmstate_l2x0;
dc->no_user = 1;
dc->props = l2x0_properties; dc->props = l2x0_properties;
dc->reset = l2x0_priv_reset; dc->reset = l2x0_priv_reset;
} }

View file

@ -162,7 +162,8 @@ static void vmport_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = vmport_realizefn; dc->realize = vmport_realizefn;
dc->no_user = 1; /* Reason: realize sets global port_state */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo vmport_info = { static const TypeInfo vmport_info = {

View file

@ -646,6 +646,8 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
k->init = fs_eth_init; k->init = fs_eth_init;
dc->props = etraxfs_eth_properties; dc->props = etraxfs_eth_properties;
/* Reason: pointer properties "dma_out", "dma_in" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo etraxfs_eth_info = { static const TypeInfo etraxfs_eth_info = {

View file

@ -161,6 +161,8 @@ static void lance_class_init(ObjectClass *klass, void *data)
dc->reset = lance_reset; dc->reset = lance_reset;
dc->vmsd = &vmstate_lance; dc->vmsd = &vmstate_lance;
dc->props = lance_properties; dc->props = lance_properties;
/* Reason: pointer property "dma" */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo lance_info = { static const TypeInfo lance_info = {

View file

@ -599,7 +599,6 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = fw_cfg_realize; dc->realize = fw_cfg_realize;
dc->no_user = 1;
dc->reset = fw_cfg_reset; dc->reset = fw_cfg_reset;
dc->vmsd = &vmstate_fw_cfg; dc->vmsd = &vmstate_fw_cfg;
dc->props = fw_cfg_properties; dc->props = fw_cfg_properties;

View file

@ -116,6 +116,7 @@ static int dec_21154_pci_host_init(PCIDevice *d)
static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data) static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = dec_21154_pci_host_init; k->init = dec_21154_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_DEC; k->vendor_id = PCI_VENDOR_ID_DEC;
@ -123,6 +124,11 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
k->revision = 0x02; k->revision = 0x02;
k->class_id = PCI_CLASS_BRIDGE_PCI; k->class_id = PCI_CLASS_BRIDGE_PCI;
k->is_bridge = 1; k->is_bridge = 1;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo dec_21154_pci_host_info = { static const TypeInfo dec_21154_pci_host_info = {

View file

@ -516,11 +516,17 @@ static int pbm_pci_host_init(PCIDevice *d)
static void pbm_pci_host_class_init(ObjectClass *klass, void *data) static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = pbm_pci_host_init; k->init = pbm_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_SUN; k->vendor_id = PCI_VENDOR_ID_SUN;
k->device_id = PCI_DEVICE_ID_SUN_SABRE; k->device_id = PCI_DEVICE_ID_SUN_SABRE;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo pbm_pci_host_info = { static const TypeInfo pbm_pci_host_info = {

View file

@ -806,8 +806,12 @@ static void bonito_class_init(ObjectClass *klass, void *data)
k->revision = 0x01; k->revision = 0x01;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
dc->desc = "Host bridge"; dc->desc = "Host bridge";
dc->no_user = 1;
dc->vmsd = &vmstate_bonito; dc->vmsd = &vmstate_bonito;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo bonito_info = { static const TypeInfo bonito_info = {
@ -819,11 +823,9 @@ static const TypeInfo bonito_info = {
static void bonito_pcihost_class_init(ObjectClass *klass, void *data) static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = bonito_pcihost_initfn; k->init = bonito_pcihost_initfn;
dc->no_user = 1;
} }
static const TypeInfo bonito_pcihost_info = { static const TypeInfo bonito_pcihost_info = {

View file

@ -130,7 +130,11 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106; k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106;
k->revision = 0x00; k->revision = 0x00;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
dc->no_user = 1; /*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo grackle_pci_info = { static const TypeInfo grackle_pci_info = {
@ -143,10 +147,8 @@ static const TypeInfo grackle_pci_info = {
static void pci_grackle_class_init(ObjectClass *klass, void *data) static void pci_grackle_class_init(ObjectClass *klass, void *data)
{ {
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = pci_grackle_init_device; k->init = pci_grackle_init_device;
dc->no_user = 1;
} }
static const TypeInfo grackle_pci_host_info = { static const TypeInfo grackle_pci_host_info = {

View file

@ -635,7 +635,6 @@ static void piix3_class_init(ObjectClass *klass, void *data)
dc->desc = "ISA bridge"; dc->desc = "ISA bridge";
dc->vmsd = &vmstate_piix3; dc->vmsd = &vmstate_piix3;
dc->no_user = 1,
k->no_hotplug = 1; k->no_hotplug = 1;
k->init = piix3_initfn; k->init = piix3_initfn;
k->config_write = piix3_write_config; k->config_write = piix3_write_config;
@ -643,6 +642,11 @@ static void piix3_class_init(ObjectClass *klass, void *data)
/* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
k->class_id = PCI_CLASS_BRIDGE_ISA; k->class_id = PCI_CLASS_BRIDGE_ISA;
/*
* Reason: part of PIIX3 southbridge, needs to be wired up by
* pc_piix.c's pc_init1()
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo piix3_info = { static const TypeInfo piix3_info = {
@ -659,7 +663,6 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
dc->desc = "ISA bridge"; dc->desc = "ISA bridge";
dc->vmsd = &vmstate_piix3; dc->vmsd = &vmstate_piix3;
dc->no_user = 1;
k->no_hotplug = 1; k->no_hotplug = 1;
k->init = piix3_initfn; k->init = piix3_initfn;
k->config_write = piix3_write_config_xen; k->config_write = piix3_write_config_xen;
@ -667,6 +670,11 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
/* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
k->class_id = PCI_CLASS_BRIDGE_ISA; k->class_id = PCI_CLASS_BRIDGE_ISA;
/*
* Reason: part of PIIX3 southbridge, needs to be wired up by
* pc_piix.c's pc_init1()
*/
dc->cannot_instantiate_with_device_add_yet = true;
}; };
static const TypeInfo piix3_xen_info = { static const TypeInfo piix3_xen_info = {
@ -689,8 +697,12 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
k->revision = 0x02; k->revision = 0x02;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
dc->desc = "Host bridge"; dc->desc = "Host bridge";
dc->no_user = 1;
dc->vmsd = &vmstate_i440fx; dc->vmsd = &vmstate_i440fx;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo i440fx_info = { static const TypeInfo i440fx_info = {
@ -727,7 +739,6 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
hc->root_bus_path = i440fx_pcihost_root_bus_path; hc->root_bus_path = i440fx_pcihost_root_bus_path;
dc->realize = i440fx_pcihost_realize; dc->realize = i440fx_pcihost_realize;
dc->fw_name = "pci"; dc->fw_name = "pci";
dc->no_user = 1;
dc->props = i440fx_props; dc->props = i440fx_props;
} }

View file

@ -387,6 +387,11 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_MPC8533E; k->device_id = PCI_DEVICE_ID_MPC8533E;
k->class_id = PCI_CLASS_PROCESSOR_POWERPC; k->class_id = PCI_CLASS_PROCESSOR_POWERPC;
dc->desc = "Host bridge"; dc->desc = "Host bridge";
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo e500_host_bridge_info = { static const TypeInfo e500_host_bridge_info = {

View file

@ -198,7 +198,11 @@ static void raven_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
dc->desc = "PReP Host Bridge - Motorola Raven"; dc->desc = "PReP Host Bridge - Motorola Raven";
dc->vmsd = &vmstate_raven; dc->vmsd = &vmstate_raven;
dc->no_user = 1; /*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo raven_info = { static const TypeInfo raven_info = {
@ -215,7 +219,6 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->realize = raven_pcihost_realizefn; dc->realize = raven_pcihost_realizefn;
dc->fw_name = "pci"; dc->fw_name = "pci";
dc->no_user = 1;
} }
static const TypeInfo raven_pcihost_info = { static const TypeInfo raven_pcihost_info = {

View file

@ -403,6 +403,11 @@ static void mch_class_init(ObjectClass *klass, void *data)
k->device_id = PCI_DEVICE_ID_INTEL_Q35_MCH; k->device_id = PCI_DEVICE_ID_INTEL_Q35_MCH;
k->revision = MCH_HOST_BRIDGE_REVISION_DEFAULT; k->revision = MCH_HOST_BRIDGE_REVISION_DEFAULT;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo mch_info = { static const TypeInfo mch_info = {

View file

@ -351,12 +351,18 @@ static int unin_internal_pci_host_init(PCIDevice *d)
static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = unin_main_pci_host_init; k->init = unin_main_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE; k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI;
k->revision = 0x00; k->revision = 0x00;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo unin_main_pci_host_info = { static const TypeInfo unin_main_pci_host_info = {
@ -369,12 +375,18 @@ static const TypeInfo unin_main_pci_host_info = {
static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data) static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = u3_agp_pci_host_init; k->init = u3_agp_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE; k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP; k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP;
k->revision = 0x00; k->revision = 0x00;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo u3_agp_pci_host_info = { static const TypeInfo u3_agp_pci_host_info = {
@ -387,12 +399,18 @@ static const TypeInfo u3_agp_pci_host_info = {
static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data) static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = unin_agp_pci_host_init; k->init = unin_agp_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE; k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP;
k->revision = 0x00; k->revision = 0x00;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo unin_agp_pci_host_info = { static const TypeInfo unin_agp_pci_host_info = {
@ -405,12 +423,18 @@ static const TypeInfo unin_agp_pci_host_info = {
static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data) static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = unin_internal_pci_host_init; k->init = unin_internal_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE; k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI;
k->revision = 0x00; k->revision = 0x00;
k->class_id = PCI_CLASS_BRIDGE_HOST; k->class_id = PCI_CLASS_BRIDGE_HOST;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo unin_internal_pci_host_info = { static const TypeInfo unin_internal_pci_host_info = {

View file

@ -467,11 +467,17 @@ static int versatile_pci_host_init(PCIDevice *d)
static void versatile_pci_host_class_init(ObjectClass *klass, void *data) static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = versatile_pci_host_init; k->init = versatile_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_XILINX; k->vendor_id = PCI_VENDOR_ID_XILINX;
k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30; k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
k->class_id = PCI_CLASS_PROCESSOR_CO; k->class_id = PCI_CLASS_PROCESSOR_CO;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo versatile_pci_host_info = { static const TypeInfo versatile_pci_host_info = {

View file

@ -391,7 +391,7 @@ void pci_bridge_exitfn(PCIDevice *pci_dev)
pci_bridge_region_cleanup(s, s->windows); pci_bridge_region_cleanup(s, s->windows);
memory_region_destroy(&s->address_space_mem); memory_region_destroy(&s->address_space_mem);
memory_region_destroy(&s->address_space_io); memory_region_destroy(&s->address_space_io);
/* qbus_free() is called automatically during device deletion */ /* object_unparent() is called automatically during device deletion */
} }
/* /*

View file

@ -380,6 +380,11 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_IBM; k->vendor_id = PCI_VENDOR_ID_IBM;
k->device_id = PCI_DEVICE_ID_IBM_440GX; k->device_id = PCI_DEVICE_ID_IBM_440GX;
k->class_id = PCI_CLASS_BRIDGE_OTHER; k->class_id = PCI_CLASS_BRIDGE_OTHER;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo ppc4xx_host_bridge_info = { static const TypeInfo ppc4xx_host_bridge_info = {

View file

@ -528,11 +528,9 @@ static int spapr_vio_bridge_init(SysBusDevice *dev)
static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data) static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = spapr_vio_bridge_init; k->init = spapr_vio_bridge_init;
dc->no_user = 1;
} }
static const TypeInfo spapr_vio_bridge_info = { static const TypeInfo spapr_vio_bridge_info = {

View file

@ -182,7 +182,6 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data)
k->init = s390_ipl_init; k->init = s390_ipl_init;
dc->props = s390_ipl_properties; dc->props = s390_ipl_properties;
dc->reset = s390_ipl_reset; dc->reset = s390_ipl_reset;
dc->no_user = 1;
} }
static const TypeInfo s390_ipl_info = { static const TypeInfo s390_ipl_info = {

View file

@ -676,11 +676,9 @@ static int s390_virtio_bridge_init(SysBusDevice *dev)
static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data) static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = s390_virtio_bridge_init; k->init = s390_virtio_bridge_init;
dc->no_user = 1;
} }
static const TypeInfo s390_virtio_bridge_info = { static const TypeInfo s390_virtio_bridge_info = {

View file

@ -1283,11 +1283,9 @@ static int virtual_css_bridge_init(SysBusDevice *dev)
static void virtual_css_bridge_class_init(ObjectClass *klass, void *data) static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = virtual_css_bridge_init; k->init = virtual_css_bridge_init;
dc->no_user = 1;
} }
static const TypeInfo virtual_css_bridge_info = { static const TypeInfo virtual_css_bridge_info = {

View file

@ -506,7 +506,6 @@ static void pl181_class_init(ObjectClass *klass, void *data)
sdc->init = pl181_init; sdc->init = pl181_init;
k->vmsd = &vmstate_pl181; k->vmsd = &vmstate_pl181;
k->reset = pl181_reset; k->reset = pl181_reset;
k->no_user = 1;
} }
static const TypeInfo pl181_info = { static const TypeInfo pl181_info = {

View file

@ -162,10 +162,16 @@ static int sh_pci_host_init(PCIDevice *d)
static void sh_pci_host_class_init(ObjectClass *klass, void *data) static void sh_pci_host_class_init(ObjectClass *klass, void *data)
{ {
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = sh_pci_host_init; k->init = sh_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_HITACHI; k->vendor_id = PCI_VENDOR_ID_HITACHI;
k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R; k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R;
/*
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo sh_pci_host_info = { static const TypeInfo sh_pci_host_info = {

View file

@ -274,7 +274,6 @@ static void arm_mptimer_class_init(ObjectClass *klass, void *data)
dc->realize = arm_mptimer_realize; dc->realize = arm_mptimer_realize;
dc->vmsd = &vmstate_arm_mptimer; dc->vmsd = &vmstate_arm_mptimer;
dc->reset = arm_mptimer_reset; dc->reset = arm_mptimer_reset;
dc->no_user = 1;
dc->props = arm_mptimer_properties; dc->props = arm_mptimer_properties;
} }

View file

@ -765,7 +765,6 @@ static void hpet_device_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = hpet_realize; dc->realize = hpet_realize;
dc->no_user = 1;
dc->reset = hpet_reset; dc->reset = hpet_reset;
dc->vmsd = &vmstate_hpet; dc->vmsd = &vmstate_hpet;
dc->props = hpet_device_properties; dc->props = hpet_device_properties;

View file

@ -282,7 +282,12 @@ static void pit_common_class_init(ObjectClass *klass, void *data)
dc->realize = pit_common_realize; dc->realize = pit_common_realize;
dc->vmsd = &vmstate_pit_common; dc->vmsd = &vmstate_pit_common;
dc->no_user = 1; /*
* Reason: unlike ordinary ISA devices, the PIT may need to be
* wired to the HPET, and because of that, some wiring is always
* done by board code.
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo pit_common_type = { static const TypeInfo pit_common_type = {

View file

@ -750,9 +750,10 @@ static void m48t59_isa_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = m48t59_isa_realize; dc->realize = m48t59_isa_realize;
dc->no_user = 1;
dc->reset = m48t59_reset_isa; dc->reset = m48t59_reset_isa;
dc->props = m48t59_isa_properties; dc->props = m48t59_isa_properties;
/* Reason: needs to be wired up by m48t59_init_isa() */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo m48t59_isa_info = { static const TypeInfo m48t59_isa_info = {

View file

@ -899,9 +899,10 @@ static void rtc_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = rtc_realizefn; dc->realize = rtc_realizefn;
dc->no_user = 1;
dc->vmsd = &vmstate_rtc; dc->vmsd = &vmstate_rtc;
dc->props = mc146818rtc_properties; dc->props = mc146818rtc_properties;
/* Reason: needs to be wired up by rtc_init() */
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo mc146818rtc_info = { static const TypeInfo mc146818rtc_info = {

View file

@ -251,7 +251,6 @@ static void pl031_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = pl031_init; k->init = pl031_init;
dc->no_user = 1;
dc->vmsd = &vmstate_pl031; dc->vmsd = &vmstate_pl031;
} }

View file

@ -36,8 +36,10 @@ static const MemoryRegionOps xen_apic_io_ops = {
.endianness = DEVICE_NATIVE_ENDIAN, .endianness = DEVICE_NATIVE_ENDIAN,
}; };
static void xen_apic_init(APICCommonState *s) static void xen_apic_realize(DeviceState *dev, Error **errp)
{ {
APICCommonState *s = APIC_COMMON(dev);
memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s, memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s,
"xen-apic-msi", APIC_SPACE_SIZE); "xen-apic-msi", APIC_SPACE_SIZE);
@ -72,7 +74,7 @@ static void xen_apic_class_init(ObjectClass *klass, void *data)
{ {
APICCommonClass *k = APIC_COMMON_CLASS(klass); APICCommonClass *k = APIC_COMMON_CLASS(klass);
k->init = xen_apic_init; k->realize = xen_apic_realize;
k->set_base = xen_apic_set_base; k->set_base = xen_apic_set_base;
k->set_tpr = xen_apic_set_tpr; k->set_tpr = xen_apic_set_tpr;
k->get_tpr = xen_apic_get_tpr; k->get_tpr = xen_apic_get_tpr;

View file

@ -66,7 +66,7 @@ typedef struct ICCDeviceClass {
DeviceClass parent_class; DeviceClass parent_class;
/*< public >*/ /*< public >*/
int (*init)(ICCDevice *dev); /* TODO replace with QOM realize */ DeviceRealize realize;
} ICCDeviceClass; } ICCDeviceClass;
#define TYPE_ICC_DEVICE "icc-device" #define TYPE_ICC_DEVICE "icc-device"

View file

@ -80,7 +80,7 @@ typedef struct APICCommonClass
{ {
ICCDeviceClass parent_class; ICCDeviceClass parent_class;
void (*init)(APICCommonState *s); DeviceRealize realize;
void (*set_base)(APICCommonState *s, uint64_t val); void (*set_base)(APICCommonState *s, uint64_t val);
void (*set_tpr)(APICCommonState *s, uint8_t val); void (*set_tpr)(APICCommonState *s, uint8_t val);
uint8_t (*get_tpr)(APICCommonState *s); uint8_t (*get_tpr)(APICCommonState *s);

View file

@ -83,7 +83,8 @@ typedef struct IOAPICCommonState IOAPICCommonState;
typedef struct IOAPICCommonClass { typedef struct IOAPICCommonClass {
SysBusDeviceClass parent_class; SysBusDeviceClass parent_class;
void (*init)(IOAPICCommonState *s, int instance_no);
DeviceRealize realize;
void (*pre_save)(IOAPICCommonState *s); void (*pre_save)(IOAPICCommonState *s);
void (*post_load)(IOAPICCommonState *s); void (*post_load)(IOAPICCommonState *s);
} IOAPICCommonClass; } IOAPICCommonClass;

View file

@ -97,7 +97,18 @@ typedef struct DeviceClass {
const char *fw_name; const char *fw_name;
const char *desc; const char *desc;
Property *props; Property *props;
int no_user;
/*
* Shall we hide this device model from -device / device_add?
* All devices should support instantiation with device_add, and
* this flag should not exist. But we're not there, yet. Some
* devices fail to instantiate with cryptic error messages.
* Others instantiate, but don't work. Exposing users to such
* behavior would be cruel; this flag serves to protect them. It
* should never be set without a comment explaining why it is set.
* TODO remove once we're there
*/
bool cannot_instantiate_with_device_add_yet;
/* callbacks */ /* callbacks */
void (*reset)(DeviceState *dev); void (*reset)(DeviceState *dev);
@ -272,8 +283,6 @@ void qdev_reset_all(DeviceState *dev);
void qbus_reset_all(BusState *bus); void qbus_reset_all(BusState *bus);
void qbus_reset_all_fn(void *opaque); void qbus_reset_all_fn(void *opaque);
void qbus_free(BusState *bus);
/* This should go away once we get rid of the NULL bus hack */ /* This should go away once we get rid of the NULL bus hack */
BusState *sysbus_get_default(void); BusState *sysbus_get_default(void);

View file

@ -122,8 +122,25 @@ extern PropertyInfo qdev_prop_arraylen;
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
/*
* Please avoid pointer properties. If you must use them, you must
* cover them in their device's class init function as follows:
*
* - If the property must be set, the device cannot be used with
* device_add, so add code like this:
* |* Reason: pointer property "NAME-OF-YOUR-PROP" *|
* DeviceClass *dc = DEVICE_CLASS(class);
* dc->cannot_instantiate_with_device_add_yet = true;
*
* - If the property may safely remain null, document it like this:
* |*
* * Note: pointer property "interrupt_vector" may remain null, thus
* * no need for dc->cannot_instantiate_with_device_add_yet = true;
* *|
*/
#define DEFINE_PROP_PTR(_n, _s, _f) \ #define DEFINE_PROP_PTR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*)
#define DEFINE_PROP_CHR(_n, _s, _f) \ #define DEFINE_PROP_CHR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*) DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*)
#define DEFINE_PROP_STRING(_n, _s, _f) \ #define DEFINE_PROP_STRING(_n, _s, _f) \

View file

@ -358,7 +358,8 @@ struct ObjectClass
Type type; Type type;
GSList *interfaces; GSList *interfaces;
const char *cast_cache[OBJECT_CLASS_CAST_CACHE]; const char *object_cast_cache[OBJECT_CLASS_CAST_CACHE];
const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE];
ObjectUnparent *unparent; ObjectUnparent *unparent;
}; };
@ -535,6 +536,7 @@ struct InterfaceClass
ObjectClass parent_class; ObjectClass parent_class;
/*< private >*/ /*< private >*/
ObjectClass *concrete_class; ObjectClass *concrete_class;
Type interface_type;
}; };
#define TYPE_INTERFACE "interface" #define TYPE_INTERFACE "interface"

View file

@ -87,7 +87,7 @@ static void qdev_print_devinfo(DeviceClass *dc)
if (dc->desc) { if (dc->desc) {
error_printf(", desc \"%s\"", dc->desc); error_printf(", desc \"%s\"", dc->desc);
} }
if (dc->no_user) { if (dc->cannot_instantiate_with_device_add_yet) {
error_printf(", no-user"); error_printf(", no-user");
} }
error_printf("\n"); error_printf("\n");
@ -127,7 +127,8 @@ static void qdev_print_devinfos(bool show_no_user)
if ((i < DEVICE_CATEGORY_MAX if ((i < DEVICE_CATEGORY_MAX
? !test_bit(i, dc->categories) ? !test_bit(i, dc->categories)
: !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX)) : !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX))
|| (!show_no_user && dc->no_user)) { || (!show_no_user
&& dc->cannot_instantiate_with_device_add_yet)) {
continue; continue;
} }
if (!cat_printed) { if (!cat_printed) {
@ -477,8 +478,9 @@ DeviceState *qdev_device_add(QemuOpts *opts)
} }
} }
if (!oc) { if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type"); qerror_report(ERROR_CLASS_GENERIC_ERROR,
"'%s' is not a valid device model name", driver);
return NULL; return NULL;
} }
@ -489,6 +491,11 @@ DeviceState *qdev_device_add(QemuOpts *opts)
} }
dc = DEVICE_CLASS(oc); dc = DEVICE_CLASS(oc);
if (dc->cannot_instantiate_with_device_add_yet) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver",
"pluggable device type");
return NULL;
}
/* find bus */ /* find bus */
path = qemu_opt_get(opts, "bus"); path = qemu_opt_get(opts, "bus");

View file

@ -254,7 +254,11 @@ static void cpu_class_init(ObjectClass *klass, void *data)
k->gdb_read_register = cpu_common_gdb_read_register; k->gdb_read_register = cpu_common_gdb_read_register;
k->gdb_write_register = cpu_common_gdb_write_register; k->gdb_write_register = cpu_common_gdb_write_register;
dc->realize = cpu_common_realizefn; dc->realize = cpu_common_realizefn;
dc->no_user = 1; /*
* Reason: CPUs still need special care by board code: wiring up
* IRQs, adding reset handlers, halting non-first CPUs, ...
*/
dc->cannot_instantiate_with_device_add_yet = true;
} }
static const TypeInfo cpu_type_info = { static const TypeInfo cpu_type_info = {

View file

@ -78,8 +78,11 @@ static GHashTable *type_table_get(void)
return type_table; return type_table;
} }
static bool enumerating_types;
static void type_table_add(TypeImpl *ti) static void type_table_add(TypeImpl *ti)
{ {
assert(!enumerating_types);
g_hash_table_insert(type_table_get(), (void *)ti->name, ti); g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
} }
@ -88,7 +91,7 @@ static TypeImpl *type_table_lookup(const char *name)
return g_hash_table_lookup(type_table_get(), name); return g_hash_table_lookup(type_table_get(), name);
} }
static TypeImpl *type_register_internal(const TypeInfo *info) static TypeImpl *type_new(const TypeInfo *info)
{ {
TypeImpl *ti = g_malloc0(sizeof(*ti)); TypeImpl *ti = g_malloc0(sizeof(*ti));
int i; int i;
@ -122,8 +125,15 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
} }
ti->num_interfaces = i; ti->num_interfaces = i;
type_table_add(ti); return ti;
}
static TypeImpl *type_register_internal(const TypeInfo *info)
{
TypeImpl *ti;
ti = type_new(info);
type_table_add(ti);
return ti; return ti;
} }
@ -206,22 +216,25 @@ static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
static void type_initialize(TypeImpl *ti); static void type_initialize(TypeImpl *ti);
static void type_initialize_interface(TypeImpl *ti, const char *parent) static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type,
TypeImpl *parent_type)
{ {
InterfaceClass *new_iface; InterfaceClass *new_iface;
TypeInfo info = { }; TypeInfo info = { };
TypeImpl *iface_impl; TypeImpl *iface_impl;
info.parent = parent; info.parent = parent_type->name;
info.name = g_strdup_printf("%s::%s", ti->name, info.parent); info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name);
info.abstract = true; info.abstract = true;
iface_impl = type_register(&info); iface_impl = type_new(&info);
iface_impl->parent_type = parent_type;
type_initialize(iface_impl); type_initialize(iface_impl);
g_free((char *)info.name); g_free((char *)info.name);
new_iface = (InterfaceClass *)iface_impl->class; new_iface = (InterfaceClass *)iface_impl->class;
new_iface->concrete_class = ti->class; new_iface->concrete_class = ti->class;
new_iface->interface_type = interface_type;
ti->class->interfaces = g_slist_append(ti->class->interfaces, ti->class->interfaces = g_slist_append(ti->class->interfaces,
iface_impl->class); iface_impl->class);
@ -251,8 +264,10 @@ static void type_initialize(TypeImpl *ti)
ti->class->interfaces = NULL; ti->class->interfaces = NULL;
for (e = parent->class->interfaces; e; e = e->next) { for (e = parent->class->interfaces; e; e = e->next) {
ObjectClass *iface = e->data; InterfaceClass *iface = e->data;
type_initialize_interface(ti, object_class_get_name(iface)); ObjectClass *klass = OBJECT_CLASS(iface);
type_initialize_interface(ti, iface->interface_type, klass->type);
} }
for (i = 0; i < ti->num_interfaces; i++) { for (i = 0; i < ti->num_interfaces; i++) {
@ -269,7 +284,7 @@ static void type_initialize(TypeImpl *ti)
continue; continue;
} }
type_initialize_interface(ti, ti->interfaces[i].typename); type_initialize_interface(ti, t, t);
} }
} }
@ -285,8 +300,6 @@ static void type_initialize(TypeImpl *ti)
if (ti->class_init) { if (ti->class_init) {
ti->class_init(ti->class, ti->class_data); ti->class_init(ti->class, ti->class_data);
} }
} }
static void object_init_with_type(Object *obj, TypeImpl *ti) static void object_init_with_type(Object *obj, TypeImpl *ti)
@ -458,7 +471,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
Object *inst; Object *inst;
for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
if (obj->class->cast_cache[i] == typename) { if (obj->class->object_cast_cache[i] == typename) {
goto out; goto out;
} }
} }
@ -475,9 +488,10 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
if (obj && obj == inst) { if (obj && obj == inst) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
obj->class->cast_cache[i - 1] = obj->class->cast_cache[i]; obj->class->object_cast_cache[i - 1] =
obj->class->object_cast_cache[i];
} }
obj->class->cast_cache[i - 1] = typename; obj->class->object_cast_cache[i - 1] = typename;
} }
out: out:
@ -547,7 +561,7 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
int i; int i;
for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
if (class->cast_cache[i] == typename) { if (class->class_cast_cache[i] == typename) {
ret = class; ret = class;
goto out; goto out;
} }
@ -568,9 +582,9 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
#ifdef CONFIG_QOM_CAST_DEBUG #ifdef CONFIG_QOM_CAST_DEBUG
if (class && ret == class) { if (class && ret == class) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
class->cast_cache[i - 1] = class->cast_cache[i]; class->class_cast_cache[i - 1] = class->class_cast_cache[i];
} }
class->cast_cache[i - 1] = typename; class->class_cast_cache[i - 1] = typename;
} }
out: out:
#endif #endif
@ -659,7 +673,9 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
{ {
OCFData data = { fn, implements_type, include_abstract, opaque }; OCFData data = { fn, implements_type, include_abstract, opaque };
enumerating_types = true;
g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
enumerating_types = false;
} }
int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),

View file

@ -52,6 +52,8 @@ check-unit-y += tests/test-int128$(EXESUF)
gcov-files-test-int128-y = gcov-files-test-int128-y =
check-unit-y += tests/test-bitops$(EXESUF) check-unit-y += tests/test-bitops$(EXESUF)
check-unit-y += tests/test-qdev-global-props$(EXESUF) check-unit-y += tests/test-qdev-global-props$(EXESUF)
check-unit-y += tests/check-qom-interface$(EXESUF)
gcov-files-check-qom-interface-y = qom/object.c
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
@ -138,6 +140,7 @@ test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o
$(test-obj-y): QEMU_INCLUDES += -Itests $(test-obj-y): QEMU_INCLUDES += -Itests
QEMU_CFLAGS += -I$(SRC_PATH)/tests QEMU_CFLAGS += -I$(SRC_PATH)/tests
qom-core-obj = qom/object.o qom/qom-qobject.o qom/container.o
tests/test-x86-cpuid.o: QEMU_INCLUDES += -I$(SRC_PATH)/target-i386 tests/test-x86-cpuid.o: QEMU_INCLUDES += -I$(SRC_PATH)/target-i386
@ -147,6 +150,7 @@ tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a
tests/check-qlist$(EXESUF): tests/check-qlist.o libqemuutil.a tests/check-qlist$(EXESUF): tests/check-qlist.o libqemuutil.a
tests/check-qfloat$(EXESUF): tests/check-qfloat.o libqemuutil.a tests/check-qfloat$(EXESUF): tests/check-qfloat.o libqemuutil.a
tests/check-qjson$(EXESUF): tests/check-qjson.o libqemuutil.a libqemustub.a tests/check-qjson$(EXESUF): tests/check-qjson.o libqemuutil.a libqemustub.a
tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(qom-core-obj) libqemuutil.a
tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil.a libqemustub.a
tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a
tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) libqemuutil.a libqemustub.a
@ -160,7 +164,7 @@ tests/test-int128$(EXESUF): tests/test-int128.o
tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
hw/core/qdev.o hw/core/qdev-properties.o \ hw/core/qdev.o hw/core/qdev-properties.o \
hw/core/irq.o \ hw/core/irq.o \
qom/object.o qom/container.o qom/qom-qobject.o \ $(qom-core-obj) \
$(test-qapi-obj-y) \ $(test-qapi-obj-y) \
libqemuutil.a libqemustub.a libqemuutil.a libqemustub.a

105
tests/check-qom-interface.c Normal file
View file

@ -0,0 +1,105 @@
/*
* QOM interface test.
*
* Copyright (C) 2013 Red Hat Inc.
*
* Authors:
* Igor Mammedov <imammedo@redhat.com>
*
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
* See the COPYING.LIB file in the top-level directory.
*/
#include <glib.h>
#include "qom/object.h"
#include "qemu/module.h"
#define TYPE_TEST_IF "test-interface"
#define TEST_IF_CLASS(klass) \
OBJECT_CLASS_CHECK(TestIfClass, (klass), TYPE_TEST_IF)
#define TEST_IF_GET_CLASS(obj) \
OBJECT_GET_CLASS(TestIfClass, (obj), TYPE_TEST_IF)
#define TEST_IF(obj) \
INTERFACE_CHECK(TestIf, (obj), TYPE_TEST_IF)
typedef struct TestIf {
Object parent_obj;
} TestIf;
typedef struct TestIfClass {
InterfaceClass parent_class;
uint32_t test;
} TestIfClass;
static const TypeInfo test_if_info = {
.name = TYPE_TEST_IF,
.parent = TYPE_INTERFACE,
.class_size = sizeof(TestIfClass),
};
#define PATTERN 0xFAFBFCFD
static void test_class_init(ObjectClass *oc, void *data)
{
TestIfClass *tc = TEST_IF_CLASS(oc);
g_assert(tc);
tc->test = PATTERN;
}
#define TYPE_DIRECT_IMPL "direct-impl"
static const TypeInfo direct_impl_info = {
.name = TYPE_DIRECT_IMPL,
.parent = TYPE_OBJECT,
.class_init = test_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_TEST_IF },
{ }
}
};
#define TYPE_INTERMEDIATE_IMPL "intermediate-impl"
static const TypeInfo intermediate_impl_info = {
.name = TYPE_INTERMEDIATE_IMPL,
.parent = TYPE_DIRECT_IMPL,
};
static void test_interface_impl(const char *type)
{
Object *obj = object_new(type);
TestIf *iobj = TEST_IF(obj);
TestIfClass *ioc = TEST_IF_GET_CLASS(iobj);
g_assert(iobj);
g_assert(ioc->test == PATTERN);
}
static void interface_direct_test(void)
{
test_interface_impl(TYPE_DIRECT_IMPL);
}
static void interface_intermediate_test(void)
{
test_interface_impl(TYPE_INTERMEDIATE_IMPL);
}
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
module_call_init(MODULE_INIT_QOM);
type_register_static(&test_if_info);
type_register_static(&direct_impl_info);
type_register_static(&intermediate_impl_info);
g_test_add_func("/qom/interface/direct_impl", interface_direct_test);
g_test_add_func("/qom/interface/intermediate_impl",
interface_intermediate_test);
return g_test_run();
}