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->class_id = PCI_CLASS_BRIDGE_OTHER;
dc->desc = "PM";
dc->no_user = 1;
dc->vmsd = &vmstate_acpi;
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 = {

View File

@ -934,11 +934,9 @@ static int typhoon_pcihost_init(SysBusDevice *dev)
static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = typhoon_pcihost_init;
dc->no_user = 1;
}
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);
k->init = vpb_sic_init;
dc->no_user = 1;
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->vmsd = &mv88w8618_audio_vmsd;
dc->props = mv88w8618_audio_properties;
/* Reason: pointer property "wm8750" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->no_user = 1;
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 = {

View File

@ -632,7 +632,6 @@ static void pl041_device_class_init(ObjectClass *klass, void *data)
k->init = pl041_init;
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->no_user = 1;
dc->reset = pl041_device_reset;
dc->vmsd = &vmstate_pl041;
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->fw_name = "fdc";
dc->no_user = 1;
dc->reset = fdctrl_external_reset_isa;
dc->vmsd = &vmstate_isa_fdc;
dc->props = isa_fdc_properties;

View File

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

View File

@ -43,15 +43,13 @@ static const TypeInfo icc_bus_info = {
static void icc_device_realize(DeviceState *dev, Error **errp)
{
ICCDevice *id = ICC_DEVICE(dev);
ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(id);
ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev);
if (idc->init) {
if (idc->init(id) < 0) {
error_setg(errp, "%s initialization failed.",
object_get_typename(OBJECT(dev)));
}
/* convert to QOM */
if (idc->realize) {
idc->realize(dev, errp);
}
}
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;
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
dc->no_user = 1;
dc->vmsd = &vmstate_pl110;
}

View File

@ -381,7 +381,6 @@ static void pl080_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
dc->no_user = 1;
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->vmsd = &vmstate_dma;
dc->props = sparc32_dma_properties;
/* Reason: pointer property "iommu_opaque" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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;
dc->reset = omap_gpif_reset;
dc->props = omap_gpio_properties;
/* Reason: pointer property "clk" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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;
dc->reset = omap2_gpif_reset;
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 = {

View File

@ -475,6 +475,8 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data)
k->init = omap_i2c_init;
dc->props = omap_i2c_properties;
dc->reset = omap_i2c_reset;
/* Reason: pointer properties "iclk", "fclk" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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->read_data = eeprom_read_data;
dc->props = smbus_eeprom_properties;
/* Reason: pointer property "data" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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->revision = ICH9_A2_SMB_REVISION;
k->class_id = PCI_CLASS_SERIAL_SMBUS;
dc->no_user = 1;
dc->vmsd = &vmstate_ich9_smbus;
dc->desc = "ICH9 SMBUS Bridge";
k->init = ich9_smbus_initfn;
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)

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)));
}
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;
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);
}
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;
s->id = kvm_apic_get_reg(kapic, 0x2) >> 24;
@ -171,8 +171,10 @@ static const MemoryRegionOps kvm_apic_io_ops = {
.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",
APIC_SPACE_SIZE);
@ -185,7 +187,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data)
{
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_tpr = kvm_apic_set_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);
dc->realize = kvmclock_realize;
dc->no_user = 1;
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);
}
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);
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[] = {
@ -144,7 +146,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = kvm_ioapic_init;
k->realize = kvm_ioapic_realize;
k->pre_save = kvm_ioapic_get;
k->post_load = kvm_ioapic_put;
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);
dc->no_user = 1;
dc->reset = vapic_reset;
dc->vmsd = &vmstate_vapic;
dc->realize = vapic_realize;

View File

@ -547,10 +547,15 @@ static void port92_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->no_user = 1;
dc->realize = port92_realizefn;
dc->reset = port92_reset;
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 = {

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->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
}
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->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
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->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
}
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->class_id = PCI_CLASS_STORAGE_IDE;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->no_user = 1;
}
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);
dc->realize = i8042_realizefn;
dc->no_user = 1;
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);
dc->realize = vmmouse_realizefn;
dc->no_user = 1;
dc->reset = vmmouse_reset;
dc->vmsd = &vmstate_vmmouse;
dc->props = vmmouse_properties;
/* Reason: pointer property "ps2_mouse" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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) {
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_update_irq(s);
@ -482,9 +482,9 @@ static void apic_startup(APICCommonState *s, int vector_num)
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);
@ -494,11 +494,11 @@ void apic_sipi(DeviceState *d)
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 trigger_mode)
{
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
APICCommonState *s = APIC_COMMON(dev);
uint32_t deliver_bitmask[MAX_APIC_WORDS];
int dest_shorthand = (s->icr[0] >> 18) & 3;
APICCommonState *apic_iter;
@ -551,9 +551,9 @@ static bool apic_check_pic(APICCommonState *s)
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;
/* 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;
}
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;
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)
{
DeviceState *d;
DeviceState *dev;
APICCommonState *s;
uint32_t val;
int index;
d = cpu_get_current_apic();
if (!d) {
dev = cpu_get_current_apic();
if (!dev) {
return 0;
}
s = DO_UPCAST(APICCommonState, busdev.qdev, d);
s = APIC_COMMON(dev);
index = (addr >> 4) & 0xff;
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)
{
DeviceState *d;
DeviceState *dev;
APICCommonState *s;
int index = (addr >> 4) & 0xff;
if (addr > 0xfff || !index) {
@ -765,11 +765,11 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
return;
}
d = cpu_get_current_apic();
if (!d) {
dev = cpu_get_current_apic();
if (!dev) {
return;
}
s = DO_UPCAST(APICCommonState, busdev.qdev, d);
s = APIC_COMMON(dev);
trace_apic_mem_writel(addr, val);
@ -810,7 +810,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
break;
case 0x30:
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] >> 15) & 1);
break;
@ -871,8 +871,10 @@ static const MemoryRegionOps apic_io_ops = {
.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",
APIC_SPACE_SIZE);
@ -886,7 +888,7 @@ static void apic_class_init(ObjectClass *klass, void *data)
{
APICCommonClass *k = APIC_COMMON_CLASS(klass);
k->init = apic_init;
k->realize = apic_realize;
k->set_base = apic_set_base;
k->set_tpr = apic_set_tpr;
k->get_tpr = apic_get_tpr;

View File

@ -27,21 +27,21 @@
static int apic_irq_delivered;
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);
if (d) {
APICCommonState *s = APIC_COMMON(d);
if (dev) {
APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
info->set_base(s, val);
}
}
uint64_t cpu_get_apic_base(DeviceState *d)
uint64_t cpu_get_apic_base(DeviceState *dev)
{
if (d) {
APICCommonState *s = APIC_COMMON(d);
if (dev) {
APICCommonState *s = APIC_COMMON(dev);
trace_cpu_get_apic_base((uint64_t)s->apicbase);
return s->apicbase;
} 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;
APICCommonClass *info;
if (!d) {
if (!dev) {
return;
}
s = APIC_COMMON(d);
s = APIC_COMMON(dev);
info = APIC_COMMON_GET_CLASS(s);
info->set_tpr(s, val);
}
uint8_t cpu_get_apic_tpr(DeviceState *d)
uint8_t cpu_get_apic_tpr(DeviceState *dev)
{
APICCommonState *s;
APICCommonClass *info;
if (!d) {
if (!dev) {
return 0;
}
s = APIC_COMMON(d);
s = APIC_COMMON(dev);
info = APIC_COMMON_GET_CLASS(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);
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);
s->vapic_paddr = paddr;
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)
{
APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
APICCommonState *s = APIC_COMMON(dev);
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;
}
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);
info->external_nmi(s);
@ -170,9 +170,9 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time)
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;
if (!s) {
@ -203,19 +203,19 @@ void apic_init_reset(DeviceState *d)
s->timer_expiry = -1;
}
void apic_designate_bsp(DeviceState *d)
void apic_designate_bsp(DeviceState *dev)
{
if (d == NULL) {
if (dev == NULL) {
return;
}
APICCommonState *s = APIC_COMMON(d);
APICCommonState *s = APIC_COMMON(dev);
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);
bool bsp;
@ -226,7 +226,7 @@ static void apic_reset_common(DeviceState *d)
s->vapic_paddr = 0;
info->vapic_base_update(s);
apic_init_reset(d);
apic_init_reset(dev);
if (bsp) {
/*
@ -284,7 +284,7 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id)
return 0;
}
static int apic_init_common(ICCDevice *dev)
static void apic_common_realize(DeviceState *dev, Error **errp)
{
APICCommonState *s = APIC_COMMON(dev);
APICCommonClass *info;
@ -293,14 +293,16 @@ static int apic_init_common(ICCDevice *dev)
static bool mmio_registered;
if (apic_no >= MAX_APICS) {
return -1;
error_setg(errp, "%s initialization failed.",
object_get_typename(OBJECT(dev)));
return;
}
s->idx = apic_no++;
info = APIC_COMMON_GET_CLASS(s);
info->init(s);
info->realize(dev, errp);
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);
mmio_registered = true;
}
@ -315,7 +317,6 @@ static int apic_init_common(ICCDevice *dev)
info->enable_tpr_reporting(s, true);
}
return 0;
}
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->reset = apic_reset_common;
dc->no_user = 1;
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 = {
@ -400,9 +405,9 @@ static const TypeInfo apic_common_type = {
.abstract = true,
};
static void register_types(void)
static void apic_common_register_types(void)
{
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);
ARMGICClass *agc = ARM_GIC_CLASS(klass);
dc->no_user = 1;
agc->parent_realize = dc->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->props = arm_gic_common_properties;
dc->vmsd = &vmstate_gic;
dc->no_user = 1;
}
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;
dc->realize = kvm_arm_gic_realize;
dc->reset = kvm_arm_gic_reset;
dc->no_user = 1;
}
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;
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 = {

View File

@ -355,6 +355,8 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
k->init = grlib_irqmp_init;
dc->reset = grlib_irqmp_reset;
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 = {

View File

@ -135,9 +135,15 @@ static void pic_common_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &vmstate_pic_common;
dc->no_user = 1;
dc->props = pic_properties_common;
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 = {

View File

@ -36,6 +36,9 @@
static IOAPICCommonState *ioapics[MAX_IOAPICS];
/* global variable from ioapic_common.c */
extern int ioapic_no;
static void ioapic_service(IOAPICCommonState *s)
{
uint8_t i;
@ -225,14 +228,16 @@ static const MemoryRegionOps ioapic_io_ops = {
.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,
"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)
@ -240,7 +245,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data)
IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = ioapic_init;
k->realize = ioapic_realize;
dc->reset = ioapic_reset_common;
}

View File

@ -23,6 +23,14 @@
#include "hw/i386/ioapic_internal.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)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);
@ -61,7 +69,6 @@ static void ioapic_common_realize(DeviceState *dev, Error **errp)
{
IOAPICCommonState *s = IOAPIC_COMMON(dev);
IOAPICCommonClass *info;
static int ioapic_no;
if (ioapic_no >= 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->init(s, ioapic_no);
info->realize(dev, errp);
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io_memory);
ioapic_no++;
@ -98,7 +105,6 @@ static void ioapic_common_class_init(ObjectClass *klass, void *data)
dc->realize = ioapic_common_realize;
dc->vmsd = &vmstate_ioapic_common;
dc->no_user = 1;
}
static const TypeInfo ioapic_common_type = {
@ -110,9 +116,9 @@ static const TypeInfo ioapic_common_type = {
.abstract = true,
};
static void register_types(void)
static void ioapic_common_register_types(void)
{
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;
dc->reset = omap_inth_reset;
dc->props = omap_intc_properties;
/* Reason: pointer property "clk" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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;
dc->reset = omap_inth_reset;
dc->props = omap2_intc_properties;
/* Reason: pointer property "iclk", "fclk" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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);
k->init = pl190_init;
dc->no_user = 1;
dc->reset = pl190_reset;
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);
dc->fw_name = "isa";
dc->no_user = 1;
}
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;
k->init = ich9_lpc_initfn;
dc->vmsd = &vmstate_ich9_lpc;
dc->no_user = 1;
k->config_write = ich9_lpc_config_write;
dc->desc = "ICH9 LPC bridge";
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8;
k->revision = ICH9_A2_LPC_REVISION;
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 = {

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->class_id = PCI_CLASS_BRIDGE_ISA;
dc->desc = "ISA bridge";
dc->no_user = 1;
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 = {

View File

@ -480,8 +480,12 @@ static void via_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA;
k->revision = 0x40;
dc->desc = "ISA bridge";
dc->no_user = 1;
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 = {

View File

@ -1151,12 +1151,18 @@ static int gt64120_pci_init(PCIDevice *d)
static void gt64120_pci_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = gt64120_pci_init;
k->vendor_id = PCI_VENDOR_ID_MARVELL;
k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X;
k->revision = 0x10;
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 = {

View File

@ -179,7 +179,6 @@ static void l2x0_class_init(ObjectClass *klass, void *data)
k->init = l2x0_priv_init;
dc->vmsd = &vmstate_l2x0;
dc->no_user = 1;
dc->props = l2x0_properties;
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);
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 = {

View File

@ -646,6 +646,8 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
k->init = fs_eth_init;
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 = {

View File

@ -161,6 +161,8 @@ static void lance_class_init(ObjectClass *klass, void *data)
dc->reset = lance_reset;
dc->vmsd = &vmstate_lance;
dc->props = lance_properties;
/* Reason: pointer property "dma" */
dc->cannot_instantiate_with_device_add_yet = true;
}
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);
dc->realize = fw_cfg_realize;
dc->no_user = 1;
dc->reset = fw_cfg_reset;
dc->vmsd = &vmstate_fw_cfg;
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)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = dec_21154_pci_host_init;
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->class_id = PCI_CLASS_BRIDGE_PCI;
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 = {

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)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = pbm_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_SUN;
k->device_id = PCI_DEVICE_ID_SUN_SABRE;
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 = {

View File

@ -806,8 +806,12 @@ static void bonito_class_init(ObjectClass *klass, void *data)
k->revision = 0x01;
k->class_id = PCI_CLASS_BRIDGE_HOST;
dc->desc = "Host bridge";
dc->no_user = 1;
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 = {
@ -819,11 +823,9 @@ static const TypeInfo bonito_info = {
static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = bonito_pcihost_initfn;
dc->no_user = 1;
}
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->revision = 0x00;
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 = {
@ -143,10 +147,8 @@ static const TypeInfo grackle_pci_info = {
static void pci_grackle_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = pci_grackle_init_device;
dc->no_user = 1;
}
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->vmsd = &vmstate_piix3;
dc->no_user = 1,
k->no_hotplug = 1;
k->init = piix3_initfn;
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) */
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
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 = {
@ -659,7 +663,6 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
dc->desc = "ISA bridge";
dc->vmsd = &vmstate_piix3;
dc->no_user = 1;
k->no_hotplug = 1;
k->init = piix3_initfn;
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) */
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0;
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 = {
@ -689,8 +697,12 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
k->revision = 0x02;
k->class_id = PCI_CLASS_BRIDGE_HOST;
dc->desc = "Host bridge";
dc->no_user = 1;
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 = {
@ -727,7 +739,6 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
hc->root_bus_path = i440fx_pcihost_root_bus_path;
dc->realize = i440fx_pcihost_realize;
dc->fw_name = "pci";
dc->no_user = 1;
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->class_id = PCI_CLASS_PROCESSOR_POWERPC;
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 = {

View File

@ -198,7 +198,11 @@ static void raven_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
dc->desc = "PReP Host Bridge - Motorola 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 = {
@ -215,7 +219,6 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->realize = raven_pcihost_realizefn;
dc->fw_name = "pci";
dc->no_user = 1;
}
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->revision = MCH_HOST_BRIDGE_REVISION_DEFAULT;
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 = {

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)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = unin_main_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI;
k->revision = 0x00;
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 = {
@ -369,12 +375,18 @@ static const TypeInfo unin_main_pci_host_info = {
static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = u3_agp_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP;
k->revision = 0x00;
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 = {
@ -387,12 +399,18 @@ static const TypeInfo u3_agp_pci_host_info = {
static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = unin_agp_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP;
k->revision = 0x00;
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 = {
@ -405,12 +423,18 @@ static const TypeInfo unin_agp_pci_host_info = {
static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = unin_internal_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI;
k->revision = 0x00;
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 = {

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)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = versatile_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_XILINX;
k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
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 = {

View File

@ -391,7 +391,7 @@ void pci_bridge_exitfn(PCIDevice *pci_dev)
pci_bridge_region_cleanup(s, s->windows);
memory_region_destroy(&s->address_space_mem);
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->device_id = PCI_DEVICE_ID_IBM_440GX;
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 = {

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)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = spapr_vio_bridge_init;
dc->no_user = 1;
}
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;
dc->props = s390_ipl_properties;
dc->reset = s390_ipl_reset;
dc->no_user = 1;
}
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)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = s390_virtio_bridge_init;
dc->no_user = 1;
}
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)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = virtual_css_bridge_init;
dc->no_user = 1;
}
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;
k->vmsd = &vmstate_pl181;
k->reset = pl181_reset;
k->no_user = 1;
}
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)
{
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = sh_pci_host_init;
k->vendor_id = PCI_VENDOR_ID_HITACHI;
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 = {

View File

@ -274,7 +274,6 @@ static void arm_mptimer_class_init(ObjectClass *klass, void *data)
dc->realize = arm_mptimer_realize;
dc->vmsd = &vmstate_arm_mptimer;
dc->reset = arm_mptimer_reset;
dc->no_user = 1;
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);
dc->realize = hpet_realize;
dc->no_user = 1;
dc->reset = hpet_reset;
dc->vmsd = &vmstate_hpet;
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->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 = {

View File

@ -750,9 +750,10 @@ static void m48t59_isa_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = m48t59_isa_realize;
dc->no_user = 1;
dc->reset = m48t59_reset_isa;
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 = {

View File

@ -899,9 +899,10 @@ static void rtc_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = rtc_realizefn;
dc->no_user = 1;
dc->vmsd = &vmstate_rtc;
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 = {

View File

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

View File

@ -36,8 +36,10 @@ static const MemoryRegionOps xen_apic_io_ops = {
.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,
"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);
k->init = xen_apic_init;
k->realize = xen_apic_realize;
k->set_base = xen_apic_set_base;
k->set_tpr = xen_apic_set_tpr;
k->get_tpr = xen_apic_get_tpr;

View File

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

View File

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

View File

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

View File

@ -97,7 +97,18 @@ typedef struct DeviceClass {
const char *fw_name;
const char *desc;
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 */
void (*reset)(DeviceState *dev);
@ -272,8 +283,6 @@ void qdev_reset_all(DeviceState *dev);
void qbus_reset_all(BusState *bus);
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 */
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_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_PROP(_n, _s, _f, qdev_prop_ptr, void*)
#define DEFINE_PROP_CHR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*)
#define DEFINE_PROP_STRING(_n, _s, _f) \

View File

@ -358,7 +358,8 @@ struct ObjectClass
Type type;
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;
};
@ -535,6 +536,7 @@ struct InterfaceClass
ObjectClass parent_class;
/*< private >*/
ObjectClass *concrete_class;
Type interface_type;
};
#define TYPE_INTERFACE "interface"

View File

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

View File

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

View File

@ -52,6 +52,8 @@ check-unit-y += tests/test-int128$(EXESUF)
gcov-files-test-int128-y =
check-unit-y += tests/test-bitops$(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
@ -138,6 +140,7 @@ test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o
$(test-obj-y): QEMU_INCLUDES += -Itests
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
@ -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-qfloat$(EXESUF): tests/check-qfloat.o libqemuutil.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-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
@ -160,7 +164,7 @@ tests/test-int128$(EXESUF): tests/test-int128.o
tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
hw/core/qdev.o hw/core/qdev-properties.o \
hw/core/irq.o \
qom/object.o qom/container.o qom/qom-qobject.o \
$(qom-core-obj) \
$(test-qapi-obj-y) \
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();
}