All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls
@ 2012-10-03 17:48 Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 1/6] qdev: split up header so it can be used in cpu.h Eduardo Habkost
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Eduardo Habkost @ 2012-10-03 17:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Igor Mammedov

Summary:
 - Object properties are registered by the classes' instance_init()
   functions
 - qdev_prop_set_globals() needs all properties to be registered before being
   called.
 - Hence, qdev_prop_set_globals() can't be called from device_initfn().

Reference:
  http://article.gmane.org/gmane.comp.emulators.qemu/173753

This series is a larger than the single-patch suggestion sent by Igor (URL
above), just because I wanted to include a unit test for the new code. To do
that, I pulled the qdev-split code sent previously to the list, so a qdev unit
test could be written without pulling too many dependencies.

Patches 1-3 are just code movement, patch 3 adds the qdev unit test, patches 5-6
finally introduce post_init(), and move the qdev_prop_set_globals() call to
post_init().

Anthony Liguori (1):
  qdev: split up header so it can be used in cpu.h

Eduardo Habkost (4):
  qdev: separate core from the code used only by qemu-system-*
  tests: unit tests for qdev global-properties handling
  qom: introduce post_init() function
  qdev: set globals on post_init() function

Igor Mammedov (1):
  qapi-types.h doesn't really need to include qemu-common.h

 hw/Makefile.objs               |   1 +
 hw/irq.h                       |   2 +
 hw/mc146818rtc.c               |   1 +
 hw/qdev-addr.c                 |   1 +
 hw/qdev-core.h                 | 240 ++++++++++++++++++++++++++
 hw/qdev-monitor.h              |  16 ++
 hw/qdev-properties-system.c    | 329 ++++++++++++++++++++++++++++++++++++
 hw/qdev-properties.c           | 321 +----------------------------------
 hw/qdev-properties.h           | 131 +++++++++++++++
 hw/qdev-system.c               |  93 +++++++++++
 hw/qdev.c                      | 102 +----------
 hw/qdev.h                      | 371 +----------------------------------------
 include/qemu/object.h          |   3 +
 qom/object.c                   |  14 ++
 scripts/qapi-types.py          |   3 +-
 tests/Makefile                 |   6 +
 tests/fake-qdev.c              |  52 ++++++
 tests/test-qdev-global-props.c | 178 ++++++++++++++++++++
 18 files changed, 1083 insertions(+), 781 deletions(-)
 create mode 100644 hw/qdev-core.h
 create mode 100644 hw/qdev-monitor.h
 create mode 100644 hw/qdev-properties-system.c
 create mode 100644 hw/qdev-properties.h
 create mode 100644 hw/qdev-system.c
 create mode 100644 tests/fake-qdev.c
 create mode 100644 tests/test-qdev-global-props.c

-- 
1.7.11.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 1/6] qdev: split up header so it can be used in cpu.h
  2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
@ 2012-10-03 17:48 ` Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 2/6] qapi-types.h doesn't really need to include qemu-common.h Eduardo Habkost
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2012-10-03 17:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Igor Mammedov

From: Anthony Liguori <aliguori@us.ibm.com>

Header file dependency is a frickin' nightmare right now.  cpu.h tends to get
included in our 'include everything' header files but qdev also needs to include
those headers mainly for qdev-properties since it knows about CharDriverState
and friends.

We can solve this for now by splitting out qdev.h along the same lines that we
previously split the C file.  Then cpu.h just needs to include qdev-core.h

[ehabkost: re-add DEFINE_PROP_PCI_HOST_DEVADDR, that was removed on the
 original patch (by mistake, I guess)]
[ehabkost: kill qdev_prop_set_vlan() declaration]

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/irq.h             |   2 +
 hw/mc146818rtc.c     |   1 +
 hw/qdev-addr.c       |   1 +
 hw/qdev-core.h       | 240 +++++++++++++++++++++++++++++++++
 hw/qdev-monitor.h    |  16 +++
 hw/qdev-properties.c |   1 +
 hw/qdev-properties.h | 130 ++++++++++++++++++
 hw/qdev.c            |   1 +
 hw/qdev.h            | 371 +--------------------------------------------------
 9 files changed, 396 insertions(+), 367 deletions(-)
 create mode 100644 hw/qdev-core.h
 create mode 100644 hw/qdev-monitor.h
 create mode 100644 hw/qdev-properties.h

diff --git a/hw/irq.h b/hw/irq.h
index 56c55f0..1339a3a 100644
--- a/hw/irq.h
+++ b/hw/irq.h
@@ -3,6 +3,8 @@
 
 /* Generic IRQ/GPIO pin infrastructure.  */
 
+typedef struct IRQState *qemu_irq;
+
 typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
 
 void qemu_set_irq(qemu_irq irq, int level);
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index d63554f..1718a57 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -25,6 +25,7 @@
 #include "qemu-timer.h"
 #include "sysemu.h"
 #include "mc146818rtc.h"
+#include "qapi/qapi-visit-core.h"
 
 #ifdef TARGET_I386
 #include "apic.h"
diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index b711b6b..5b5d38f 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -1,6 +1,7 @@
 #include "qdev.h"
 #include "qdev-addr.h"
 #include "targphys.h"
+#include "qapi/qapi-visit-core.h"
 
 /* --- target physical address --- */
 
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
new file mode 100644
index 0000000..ca205fc
--- /dev/null
+++ b/hw/qdev-core.h
@@ -0,0 +1,240 @@
+#ifndef QDEV_CORE_H
+#define QDEV_CORE_H
+
+#include "qemu-queue.h"
+#include "qemu-option.h"
+#include "qemu/object.h"
+#include "hw/irq.h"
+#include "error.h"
+
+typedef struct Property Property;
+
+typedef struct PropertyInfo PropertyInfo;
+
+typedef struct CompatProperty CompatProperty;
+
+typedef struct BusState BusState;
+
+typedef struct BusClass BusClass;
+
+enum DevState {
+    DEV_STATE_CREATED = 1,
+    DEV_STATE_INITIALIZED,
+};
+
+enum {
+    DEV_NVECTORS_UNSPECIFIED = -1,
+};
+
+#define TYPE_DEVICE "device"
+#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE)
+#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
+#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
+
+typedef int (*qdev_initfn)(DeviceState *dev);
+typedef int (*qdev_event)(DeviceState *dev);
+typedef void (*qdev_resetfn)(DeviceState *dev);
+
+struct VMStateDescription;
+
+typedef struct DeviceClass {
+    ObjectClass parent_class;
+
+    const char *fw_name;
+    const char *desc;
+    Property *props;
+    int no_user;
+
+    /* callbacks */
+    void (*reset)(DeviceState *dev);
+
+    /* device state */
+    const struct VMStateDescription *vmsd;
+
+    /* Private to qdev / bus.  */
+    qdev_initfn init;
+    qdev_event unplug;
+    qdev_event exit;
+    const char *bus_type;
+} DeviceClass;
+
+/* This structure should not be accessed directly.  We declare it here
+   so that it can be embedded in individual device state structures.  */
+struct DeviceState {
+    Object parent_obj;
+
+    const char *id;
+    enum DevState state;
+    struct QemuOpts *opts;
+    int hotplugged;
+    BusState *parent_bus;
+    int num_gpio_out;
+    qemu_irq *gpio_out;
+    int num_gpio_in;
+    qemu_irq *gpio_in;
+    QLIST_HEAD(, BusState) child_bus;
+    int num_child_bus;
+    int instance_id_alias;
+    int alias_required_for_version;
+};
+
+/*
+ * This callback is used to create Open Firmware device path in accordance with
+ * OF spec http://forthworks.com/standards/of1275.pdf. Indicidual bus bindings
+ * can be found here http://playground.sun.com/1275/bindings/.
+ */
+
+#define TYPE_BUS "bus"
+#define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS)
+#define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS)
+#define BUS_GET_CLASS(obj) OBJECT_GET_CLASS(BusClass, (obj), TYPE_BUS)
+
+struct BusClass {
+    ObjectClass parent_class;
+
+    /* FIXME first arg should be BusState */
+    void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
+    char *(*get_dev_path)(DeviceState *dev);
+    char *(*get_fw_dev_path)(DeviceState *dev);
+    int (*reset)(BusState *bus);
+};
+
+typedef struct BusChild {
+    DeviceState *child;
+    int index;
+    QTAILQ_ENTRY(BusChild) sibling;
+} BusChild;
+
+/**
+ * BusState:
+ * @qom_allocated: Indicates whether the object was allocated by QOM.
+ * @glib_allocated: Indicates whether the object was initialized in-place
+ * yet is expected to be freed with g_free().
+ */
+struct BusState {
+    Object obj;
+    DeviceState *parent;
+    const char *name;
+    int allow_hotplug;
+    bool qom_allocated;
+    bool glib_allocated;
+    int max_index;
+    QTAILQ_HEAD(ChildrenHead, BusChild) children;
+    QLIST_ENTRY(BusState) sibling;
+};
+
+struct Property {
+    const char   *name;
+    PropertyInfo *info;
+    int          offset;
+    uint8_t      bitnr;
+    uint8_t      qtype;
+    int64_t      defval;
+};
+
+struct PropertyInfo {
+    const char *name;
+    const char *legacy_name;
+    const char **enum_table;
+    int (*parse)(DeviceState *dev, Property *prop, const char *str);
+    int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
+    ObjectPropertyAccessor *get;
+    ObjectPropertyAccessor *set;
+    ObjectPropertyRelease *release;
+};
+
+typedef struct GlobalProperty {
+    const char *driver;
+    const char *property;
+    const char *value;
+    QTAILQ_ENTRY(GlobalProperty) next;
+} GlobalProperty;
+
+/*** Board API.  This should go away once we have a machine config file.  ***/
+
+DeviceState *qdev_create(BusState *bus, const char *name);
+DeviceState *qdev_try_create(BusState *bus, const char *name);
+bool qdev_exists(const char *name);
+int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT;
+void qdev_init_nofail(DeviceState *dev);
+void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
+                                 int required_for_version);
+void qdev_unplug(DeviceState *dev, Error **errp);
+void qdev_free(DeviceState *dev);
+int qdev_simple_unplug_cb(DeviceState *dev);
+void qdev_machine_creation_done(void);
+bool qdev_machine_modified(void);
+
+qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
+void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
+
+BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
+
+/*** Device API.  ***/
+
+/* Register device properties.  */
+/* GPIO inputs also double as IRQ sinks.  */
+void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
+void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
+
+BusState *qdev_get_parent_bus(DeviceState *dev);
+
+/*** BUS API. ***/
+
+DeviceState *qdev_find_recursive(BusState *bus, const char *id);
+
+/* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */
+typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
+typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
+
+void qbus_create_inplace(BusState *bus, const char *typename,
+                         DeviceState *parent, const char *name);
+BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
+/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
+ *         < 0 if either devfn or busfn terminate walk somewhere in cursion,
+ *           0 otherwise. */
+int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
+                       qbus_walkerfn *busfn, void *opaque);
+int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
+                       qbus_walkerfn *busfn, void *opaque);
+void qdev_reset_all(DeviceState *dev);
+void qbus_reset_all_fn(void *opaque);
+
+void qbus_free(BusState *bus);
+
+#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
+
+/* This should go away once we get rid of the NULL bus hack */
+BusState *sysbus_get_default(void);
+
+char *qdev_get_fw_dev_path(DeviceState *dev);
+
+/**
+ * @qdev_machine_init
+ *
+ * Initialize platform devices before machine init.  This is a hack until full
+ * support for composition is added.
+ */
+void qdev_machine_init(void);
+
+/**
+ * @device_reset
+ *
+ * Reset a single device (by calling the reset method).
+ */
+void device_reset(DeviceState *dev);
+
+const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev);
+
+const char *qdev_fw_name(DeviceState *dev);
+
+Object *qdev_get_machine(void);
+
+/* FIXME: make this a link<> */
+void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
+
+extern int qdev_hotplug;
+
+char *qdev_get_dev_path(DeviceState *dev);
+
+#endif
diff --git a/hw/qdev-monitor.h b/hw/qdev-monitor.h
new file mode 100644
index 0000000..220ceba
--- /dev/null
+++ b/hw/qdev-monitor.h
@@ -0,0 +1,16 @@
+#ifndef QEMU_QDEV_MONITOR_H
+#define QEMU_QDEV_MONITOR_H
+
+#include "qdev-core.h"
+#include "monitor.h"
+
+/*** monitor commands ***/
+
+void do_info_qtree(Monitor *mon);
+void do_info_qdm(Monitor *mon);
+int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
+int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
+int qdev_device_help(QemuOpts *opts);
+DeviceState *qdev_device_add(QemuOpts *opts);
+
+#endif
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 8aca0d4..81d901c 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -4,6 +4,7 @@
 #include "blockdev.h"
 #include "hw/block-common.h"
 #include "net/hub.h"
+#include "qapi/qapi-visit-core.h"
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 {
diff --git a/hw/qdev-properties.h b/hw/qdev-properties.h
new file mode 100644
index 0000000..5b046ab
--- /dev/null
+++ b/hw/qdev-properties.h
@@ -0,0 +1,130 @@
+#ifndef QEMU_QDEV_PROPERTIES_H
+#define QEMU_QDEV_PROPERTIES_H
+
+#include "qdev-core.h"
+
+/*** qdev-properties.c ***/
+
+extern PropertyInfo qdev_prop_bit;
+extern PropertyInfo qdev_prop_uint8;
+extern PropertyInfo qdev_prop_uint16;
+extern PropertyInfo qdev_prop_uint32;
+extern PropertyInfo qdev_prop_int32;
+extern PropertyInfo qdev_prop_uint64;
+extern PropertyInfo qdev_prop_hex8;
+extern PropertyInfo qdev_prop_hex32;
+extern PropertyInfo qdev_prop_hex64;
+extern PropertyInfo qdev_prop_string;
+extern PropertyInfo qdev_prop_chr;
+extern PropertyInfo qdev_prop_ptr;
+extern PropertyInfo qdev_prop_macaddr;
+extern PropertyInfo qdev_prop_losttickpolicy;
+extern PropertyInfo qdev_prop_bios_chs_trans;
+extern PropertyInfo qdev_prop_drive;
+extern PropertyInfo qdev_prop_netdev;
+extern PropertyInfo qdev_prop_vlan;
+extern PropertyInfo qdev_prop_pci_devfn;
+extern PropertyInfo qdev_prop_blocksize;
+extern PropertyInfo qdev_prop_pci_host_devaddr;
+
+#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
+        .name      = (_name),                                    \
+        .info      = &(_prop),                                   \
+        .offset    = offsetof(_state, _field)                    \
+            + type_check(_type,typeof_field(_state, _field)),    \
+        }
+#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
+        .name      = (_name),                                           \
+        .info      = &(_prop),                                          \
+        .offset    = offsetof(_state, _field)                           \
+            + type_check(_type,typeof_field(_state, _field)),           \
+        .qtype     = QTYPE_QINT,                                        \
+        .defval    = (_type)_defval,                                    \
+        }
+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
+        .name      = (_name),                                    \
+        .info      = &(qdev_prop_bit),                           \
+        .bitnr    = (_bit),                                      \
+        .offset    = offsetof(_state, _field)                    \
+            + type_check(uint32_t,typeof_field(_state, _field)), \
+        .qtype     = QTYPE_QBOOL,                                \
+        .defval    = (bool)_defval,                              \
+        }
+
+#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
+#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
+#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
+#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
+#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
+#define DEFINE_PROP_HEX8(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
+#define DEFINE_PROP_HEX32(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
+#define DEFINE_PROP_HEX64(_n, _s, _f, _d)                       \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
+#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
+
+#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)             \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
+#define DEFINE_PROP_NETDEV(_n, _s, _f)             \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*)
+#define DEFINE_PROP_VLAN(_n, _s, _f)             \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*)
+#define DEFINE_PROP_DRIVE(_n, _s, _f) \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
+#define DEFINE_PROP_MACADDR(_n, _s, _f)         \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
+#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
+                        LostTickPolicy)
+#define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
+#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
+#define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
+    DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
+
+#define DEFINE_PROP_END_OF_LIST()               \
+    {}
+
+/* Set properties between creation and init.  */
+void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
+int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
+void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
+void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
+void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
+void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value);
+void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value);
+void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
+void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value);
+void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value);
+void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value);
+int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
+void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
+void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
+void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
+/* FIXME: Remove opaque pointer properties.  */
+void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
+
+void qdev_prop_register_global_list(GlobalProperty *props);
+void qdev_prop_set_globals(DeviceState *dev);
+void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+                                    Property *prop, const char *value);
+
+/**
+ * @qdev_property_add_static - add a @Property to a device referencing a
+ * field in a struct.
+ */
+void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
+
+#endif
diff --git a/hw/qdev.c b/hw/qdev.c
index b5a52ac..d0775f6 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -29,6 +29,7 @@
 #include "qdev.h"
 #include "sysemu.h"
 #include "error.h"
+#include "qapi/qapi-visit-core.h"
 
 int qdev_hotplug = 0;
 static bool qdev_hot_added = false;
diff --git a/hw/qdev.h b/hw/qdev.h
index d699194..365b8d6 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -1,372 +1,9 @@
 #ifndef QDEV_H
 #define QDEV_H
 
-#include "hw.h"
-#include "qemu-queue.h"
-#include "qemu-char.h"
-#include "qemu-option.h"
-#include "qapi/qapi-visit-core.h"
-#include "qemu/object.h"
-#include "error.h"
-
-typedef struct Property Property;
-
-typedef struct PropertyInfo PropertyInfo;
-
-typedef struct CompatProperty CompatProperty;
-
-typedef struct BusState BusState;
-
-typedef struct BusClass BusClass;
-
-enum DevState {
-    DEV_STATE_CREATED = 1,
-    DEV_STATE_INITIALIZED,
-};
-
-enum {
-    DEV_NVECTORS_UNSPECIFIED = -1,
-};
-
-#define TYPE_DEVICE "device"
-#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE)
-#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
-#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
-
-typedef int (*qdev_initfn)(DeviceState *dev);
-typedef int (*qdev_event)(DeviceState *dev);
-typedef void (*qdev_resetfn)(DeviceState *dev);
-
-typedef struct DeviceClass {
-    ObjectClass parent_class;
-
-    const char *fw_name;
-    const char *desc;
-    Property *props;
-    int no_user;
-
-    /* callbacks */
-    void (*reset)(DeviceState *dev);
-
-    /* device state */
-    const VMStateDescription *vmsd;
-
-    /* Private to qdev / bus.  */
-    qdev_initfn init;
-    qdev_event unplug;
-    qdev_event exit;
-    const char *bus_type;
-} DeviceClass;
-
-/* This structure should not be accessed directly.  We declare it here
-   so that it can be embedded in individual device state structures.  */
-struct DeviceState {
-    Object parent_obj;
-
-    const char *id;
-    enum DevState state;
-    QemuOpts *opts;
-    int hotplugged;
-    BusState *parent_bus;
-    int num_gpio_out;
-    qemu_irq *gpio_out;
-    int num_gpio_in;
-    qemu_irq *gpio_in;
-    QLIST_HEAD(, BusState) child_bus;
-    int num_child_bus;
-    int instance_id_alias;
-    int alias_required_for_version;
-};
-
-#define TYPE_BUS "bus"
-#define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS)
-#define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS)
-#define BUS_GET_CLASS(obj) OBJECT_GET_CLASS(BusClass, (obj), TYPE_BUS)
-
-struct BusClass {
-    ObjectClass parent_class;
-
-    /* FIXME first arg should be BusState */
-    void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
-    char *(*get_dev_path)(DeviceState *dev);
-    /*
-     * This callback is used to create Open Firmware device path in accordance
-     * with OF spec http://forthworks.com/standards/of1275.pdf. Individual bus
-     * bindings can be found at http://playground.sun.com/1275/bindings/.
-     */
-    char *(*get_fw_dev_path)(DeviceState *dev);
-    int (*reset)(BusState *bus);
-};
-
-typedef struct BusChild {
-    DeviceState *child;
-    int index;
-    QTAILQ_ENTRY(BusChild) sibling;
-} BusChild;
-
-/**
- * BusState:
- * @qom_allocated: Indicates whether the object was allocated by QOM.
- * @glib_allocated: Indicates whether the object was initialized in-place
- * yet is expected to be freed with g_free().
- */
-struct BusState {
-    Object obj;
-    DeviceState *parent;
-    const char *name;
-    int allow_hotplug;
-    bool qom_allocated;
-    bool glib_allocated;
-    int max_index;
-    QTAILQ_HEAD(ChildrenHead, BusChild) children;
-    QLIST_ENTRY(BusState) sibling;
-};
-
-struct Property {
-    const char   *name;
-    PropertyInfo *info;
-    int          offset;
-    uint8_t      bitnr;
-    uint8_t      qtype;
-    int64_t      defval;
-};
-
-struct PropertyInfo {
-    const char *name;
-    const char *legacy_name;
-    const char **enum_table;
-    int (*parse)(DeviceState *dev, Property *prop, const char *str);
-    int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
-    ObjectPropertyAccessor *get;
-    ObjectPropertyAccessor *set;
-    ObjectPropertyRelease *release;
-};
-
-typedef struct GlobalProperty {
-    const char *driver;
-    const char *property;
-    const char *value;
-    QTAILQ_ENTRY(GlobalProperty) next;
-} GlobalProperty;
-
-/*** Board API.  This should go away once we have a machine config file.  ***/
-
-DeviceState *qdev_create(BusState *bus, const char *name);
-DeviceState *qdev_try_create(BusState *bus, const char *name);
-bool qdev_exists(const char *name);
-int qdev_device_help(QemuOpts *opts);
-DeviceState *qdev_device_add(QemuOpts *opts);
-int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT;
-void qdev_init_nofail(DeviceState *dev);
-void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
-                                 int required_for_version);
-void qdev_unplug(DeviceState *dev, Error **errp);
-void qdev_free(DeviceState *dev);
-int qdev_simple_unplug_cb(DeviceState *dev);
-void qdev_machine_creation_done(void);
-bool qdev_machine_modified(void);
-
-qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
-void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
-
-BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
-
-/*** Device API.  ***/
-
-/* Register device properties.  */
-/* GPIO inputs also double as IRQ sinks.  */
-void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
-void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
-
-BusState *qdev_get_parent_bus(DeviceState *dev);
-
-/*** BUS API. ***/
-
-DeviceState *qdev_find_recursive(BusState *bus, const char *id);
-
-/* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */
-typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
-typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
-
-void qbus_create_inplace(BusState *bus, const char *typename,
-                         DeviceState *parent, const char *name);
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
-/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
- *         < 0 if either devfn or busfn terminate walk somewhere in cursion,
- *           0 otherwise. */
-int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
-                       qbus_walkerfn *busfn, void *opaque);
-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
-                       qbus_walkerfn *busfn, void *opaque);
-void qdev_reset_all(DeviceState *dev);
-void qbus_reset_all_fn(void *opaque);
-
-void qbus_free(BusState *bus);
-
-#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
-
-/* This should go away once we get rid of the NULL bus hack */
-BusState *sysbus_get_default(void);
-
-/*** monitor commands ***/
-
-void do_info_qtree(Monitor *mon);
-void do_info_qdm(Monitor *mon);
-int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
-int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
-
-/*** qdev-properties.c ***/
-
-extern PropertyInfo qdev_prop_bit;
-extern PropertyInfo qdev_prop_uint8;
-extern PropertyInfo qdev_prop_uint16;
-extern PropertyInfo qdev_prop_uint32;
-extern PropertyInfo qdev_prop_int32;
-extern PropertyInfo qdev_prop_uint64;
-extern PropertyInfo qdev_prop_hex8;
-extern PropertyInfo qdev_prop_hex32;
-extern PropertyInfo qdev_prop_hex64;
-extern PropertyInfo qdev_prop_string;
-extern PropertyInfo qdev_prop_chr;
-extern PropertyInfo qdev_prop_ptr;
-extern PropertyInfo qdev_prop_macaddr;
-extern PropertyInfo qdev_prop_losttickpolicy;
-extern PropertyInfo qdev_prop_bios_chs_trans;
-extern PropertyInfo qdev_prop_drive;
-extern PropertyInfo qdev_prop_netdev;
-extern PropertyInfo qdev_prop_vlan;
-extern PropertyInfo qdev_prop_pci_devfn;
-extern PropertyInfo qdev_prop_blocksize;
-extern PropertyInfo qdev_prop_pci_host_devaddr;
-
-#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
-        .name      = (_name),                                    \
-        .info      = &(_prop),                                   \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(_type,typeof_field(_state, _field)),    \
-        }
-#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
-        .name      = (_name),                                           \
-        .info      = &(_prop),                                          \
-        .offset    = offsetof(_state, _field)                           \
-            + type_check(_type,typeof_field(_state, _field)),           \
-        .qtype     = QTYPE_QINT,                                        \
-        .defval    = (_type)_defval,                                    \
-        }
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
-        .name      = (_name),                                    \
-        .info      = &(qdev_prop_bit),                           \
-        .bitnr    = (_bit),                                      \
-        .offset    = offsetof(_state, _field)                    \
-            + type_check(uint32_t,typeof_field(_state, _field)), \
-        .qtype     = QTYPE_QBOOL,                                \
-        .defval    = (bool)_defval,                              \
-        }
-
-#define DEFINE_PROP_UINT8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
-#define DEFINE_PROP_UINT16(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
-#define DEFINE_PROP_UINT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
-#define DEFINE_PROP_INT32(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
-#define DEFINE_PROP_UINT64(_n, _s, _f, _d)                      \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
-#define DEFINE_PROP_HEX8(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
-#define DEFINE_PROP_HEX32(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
-#define DEFINE_PROP_HEX64(_n, _s, _f, _d)                       \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
-#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)                   \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
-
-#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)             \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
-#define DEFINE_PROP_NETDEV(_n, _s, _f)             \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*)
-#define DEFINE_PROP_VLAN(_n, _s, _f)             \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*)
-#define DEFINE_PROP_DRIVE(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
-#define DEFINE_PROP_MACADDR(_n, _s, _f)         \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
-#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
-                        LostTickPolicy)
-#define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
-#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \
-    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
-#define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
-    DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
-
-#define DEFINE_PROP_END_OF_LIST()               \
-    {}
-
-/* Set properties between creation and init.  */
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
-int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
-void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
-void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
-void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
-void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value);
-void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value);
-void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
-void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value);
-void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value);
-void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value);
-int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
-void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
-void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
-void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
-/* FIXME: Remove opaque pointer properties.  */
-void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
-
-void qdev_prop_register_global_list(GlobalProperty *props);
-void qdev_prop_set_globals(DeviceState *dev);
-void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
-                                    Property *prop, const char *value);
-
-char *qdev_get_fw_dev_path(DeviceState *dev);
-
-/**
- * @qdev_property_add_static - add a @Property to a device referencing a
- * field in a struct.
- */
-void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
-
-/**
- * @qdev_machine_init
- *
- * Initialize platform devices before machine init.  This is a hack until full
- * support for composition is added.
- */
-void qdev_machine_init(void);
-
-/**
- * @device_reset
- *
- * Reset a single device (by calling the reset method).
- */
-void device_reset(DeviceState *dev);
-
-const VMStateDescription *qdev_get_vmsd(DeviceState *dev);
-
-const char *qdev_fw_name(DeviceState *dev);
-
-Object *qdev_get_machine(void);
-
-/* FIXME: make this a link<> */
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
-
-extern int qdev_hotplug;
-
-char *qdev_get_dev_path(DeviceState *dev);
+#include "hw/hw.h"
+#include "qdev-core.h"
+#include "qdev-properties.h"
+#include "qdev-monitor.h"
 
 #endif
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 2/6] qapi-types.h doesn't really need to include qemu-common.h
  2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 1/6] qdev: split up header so it can be used in cpu.h Eduardo Habkost
@ 2012-10-03 17:48 ` Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 3/6] qdev: separate core from the code used only by qemu-system-* Eduardo Habkost
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2012-10-03 17:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Igor Mammedov

From: Igor Mammedov <imammedo@redhat.com>

needed to prevent build breakage when CPU becomes a child of DeviceState

[ehabkost: include <stdbool.h> too]

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 scripts/qapi-types.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 49ef569..6e0e6ba 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -273,7 +273,8 @@ fdecl.write(mcgen('''
 #ifndef %(guard)s
 #define %(guard)s
 
-#include "qemu-common.h"
+#include <stdbool.h>
+#include <stdint.h>
 
 ''',
                   guard=guardname(h_file)))
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 3/6] qdev: separate core from the code used only by qemu-system-*
  2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 1/6] qdev: split up header so it can be used in cpu.h Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 2/6] qapi-types.h doesn't really need to include qemu-common.h Eduardo Habkost
@ 2012-10-03 17:48 ` Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 4/6] tests: unit tests for qdev global-properties handling Eduardo Habkost
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2012-10-03 17:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Igor Mammedov

This change should help on two things:
 - Allowing DeviceState to be used by *-user;
 - Writing qdev unit tests without pulling too many dependencies.

Note that there are two parts that depend on code compiled only on
qemu-system-*, but are still inside qdev.c:
 - vmstate handling
 - reset function registration.

Those two parts will need to be handled somehow (by being moved outside
of qdev-core, or compiled out, or by adding equivalent implementations
to *-user), to allow the qdev core to be used by *-user.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/Makefile.objs            |   1 +
 hw/qdev-properties-system.c | 329 ++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev-properties.c        | 320 +-----------------------------------------
 hw/qdev-properties.h        |   1 +
 hw/qdev-system.c            |  93 +++++++++++++
 hw/qdev.c                   |  92 -------------
 6 files changed, 425 insertions(+), 411 deletions(-)
 create mode 100644 hw/qdev-properties-system.c
 create mode 100644 hw/qdev-system.c

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index ecdbe44..030cb2d 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -179,6 +179,7 @@ common-obj-y += bt.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o
 common-obj-y += bt-hci-csr.o
 common-obj-y += msmouse.o ps2.o
 common-obj-y += qdev.o qdev-properties.o qdev-monitor.o
+common-obj-y += qdev-system.o qdev-properties-system.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
 
 # xen backend driver support
diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c
new file mode 100644
index 0000000..c42e656
--- /dev/null
+++ b/hw/qdev-properties-system.c
@@ -0,0 +1,329 @@
+#include "net.h"
+#include "qdev.h"
+#include "qerror.h"
+#include "blockdev.h"
+#include "hw/block-common.h"
+#include "net/hub.h"
+#include "qapi/qapi-visit-core.h"
+
+static void get_pointer(Object *obj, Visitor *v, Property *prop,
+                        const char *(*print)(void *ptr),
+                        const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    void **ptr = qdev_get_prop_ptr(dev, prop);
+    char *p;
+
+    p = (char *) (*ptr ? print(*ptr) : "");
+    visit_type_str(v, &p, name, errp);
+}
+
+static void set_pointer(Object *obj, Visitor *v, Property *prop,
+                        int (*parse)(DeviceState *dev, const char *str,
+                                     void **ptr),
+                        const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Error *local_err = NULL;
+    void **ptr = qdev_get_prop_ptr(dev, prop);
+    char *str;
+    int ret;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_str(v, &str, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (!*str) {
+        g_free(str);
+        *ptr = NULL;
+        return;
+    }
+    ret = parse(dev, str, ptr);
+    error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
+    g_free(str);
+}
+
+
+/* --- drive --- */
+
+static int parse_drive(DeviceState *dev, const char *str, void **ptr)
+{
+    BlockDriverState *bs;
+
+    bs = bdrv_find(str);
+    if (bs == NULL)
+        return -ENOENT;
+    if (bdrv_attach_dev(bs, dev) < 0)
+        return -EEXIST;
+    *ptr = bs;
+    return 0;
+}
+
+static void release_drive(Object *obj, const char *name, void *opaque)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (*ptr) {
+        bdrv_detach_dev(*ptr, dev);
+        blockdev_auto_del(*ptr);
+    }
+}
+
+static const char *print_drive(void *ptr)
+{
+    return bdrv_get_device_name(ptr);
+}
+
+static void get_drive(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    get_pointer(obj, v, opaque, print_drive, name, errp);
+}
+
+static void set_drive(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    set_pointer(obj, v, opaque, parse_drive, name, errp);
+}
+
+PropertyInfo qdev_prop_drive = {
+    .name  = "drive",
+    .get   = get_drive,
+    .set   = set_drive,
+    .release = release_drive,
+};
+
+/* --- character device --- */
+
+static int parse_chr(DeviceState *dev, const char *str, void **ptr)
+{
+    CharDriverState *chr = qemu_chr_find(str);
+    if (chr == NULL) {
+        return -ENOENT;
+    }
+    if (chr->avail_connections < 1) {
+        return -EEXIST;
+    }
+    *ptr = chr;
+    --chr->avail_connections;
+    return 0;
+}
+
+static void release_chr(Object *obj, const char *name, void *opaque)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (*ptr) {
+        qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
+    }
+}
+
+
+static const char *print_chr(void *ptr)
+{
+    CharDriverState *chr = ptr;
+
+    return chr->label ? chr->label : "";
+}
+
+static void get_chr(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    get_pointer(obj, v, opaque, print_chr, name, errp);
+}
+
+static void set_chr(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    set_pointer(obj, v, opaque, parse_chr, name, errp);
+}
+
+PropertyInfo qdev_prop_chr = {
+    .name  = "chr",
+    .get   = get_chr,
+    .set   = set_chr,
+    .release = release_chr,
+};
+
+/* --- netdev device --- */
+
+static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
+{
+    NetClientState *netdev = qemu_find_netdev(str);
+
+    if (netdev == NULL) {
+        return -ENOENT;
+    }
+    if (netdev->peer) {
+        return -EEXIST;
+    }
+    *ptr = netdev;
+    return 0;
+}
+
+static const char *print_netdev(void *ptr)
+{
+    NetClientState *netdev = ptr;
+
+    return netdev->name ? netdev->name : "";
+}
+
+static void get_netdev(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    get_pointer(obj, v, opaque, print_netdev, name, errp);
+}
+
+static void set_netdev(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    set_pointer(obj, v, opaque, parse_netdev, name, errp);
+}
+
+PropertyInfo qdev_prop_netdev = {
+    .name  = "netdev",
+    .get   = get_netdev,
+    .set   = set_netdev,
+};
+
+/* --- vlan --- */
+
+static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (*ptr) {
+        int id;
+        if (!net_hub_id_for_client(*ptr, &id)) {
+            return snprintf(dest, len, "%d", id);
+        }
+    }
+
+    return snprintf(dest, len, "<null>");
+}
+
+static void get_vlan(Object *obj, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+    int32_t id = -1;
+
+    if (*ptr) {
+        int hub_id;
+        if (!net_hub_id_for_client(*ptr, &hub_id)) {
+            id = hub_id;
+        }
+    }
+
+    visit_type_int32(v, &id, name, errp);
+}
+
+static void set_vlan(Object *obj, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int32_t id;
+    NetClientState *hubport;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int32(v, &id, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (id == -1) {
+        *ptr = NULL;
+        return;
+    }
+
+    hubport = net_hub_port_find(id);
+    if (!hubport) {
+        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+                  name, prop->info->name);
+        return;
+    }
+    *ptr = hubport;
+}
+
+PropertyInfo qdev_prop_vlan = {
+    .name  = "vlan",
+    .print = print_vlan,
+    .get   = get_vlan,
+    .set   = set_vlan,
+};
+
+
+int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
+{
+    Error *errp = NULL;
+    const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
+    object_property_set_str(OBJECT(dev), bdrv_name,
+                            name, &errp);
+    if (errp) {
+        qerror_report_err(errp);
+        error_free(errp);
+        return -1;
+    }
+    return 0;
+}
+
+void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
+{
+    if (qdev_prop_set_drive(dev, name, value) < 0) {
+        exit(1);
+    }
+}
+
+void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
+{
+    Error *errp = NULL;
+    assert(!value || value->label);
+    object_property_set_str(OBJECT(dev),
+                            value ? value->label : "", name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value)
+{
+    Error *errp = NULL;
+    assert(!value || value->name);
+    object_property_set_str(OBJECT(dev),
+                            value ? value->name : "", name, &errp);
+    assert_no_error(errp);
+}
+
+static int qdev_add_one_global(QemuOpts *opts, void *opaque)
+{
+    GlobalProperty *g;
+
+    g = g_malloc0(sizeof(*g));
+    g->driver   = qemu_opt_get(opts, "driver");
+    g->property = qemu_opt_get(opts, "property");
+    g->value    = qemu_opt_get(opts, "value");
+    qdev_prop_register_global(g);
+    return 0;
+}
+
+void qemu_add_globals(void)
+{
+    qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
+}
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 81d901c..917d986 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -13,49 +13,6 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
     return ptr;
 }
 
-static void get_pointer(Object *obj, Visitor *v, Property *prop,
-                        const char *(*print)(void *ptr),
-                        const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    void **ptr = qdev_get_prop_ptr(dev, prop);
-    char *p;
-
-    p = (char *) (*ptr ? print(*ptr) : "");
-    visit_type_str(v, &p, name, errp);
-}
-
-static void set_pointer(Object *obj, Visitor *v, Property *prop,
-                        int (*parse)(DeviceState *dev, const char *str,
-                                     void **ptr),
-                        const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Error *local_err = NULL;
-    void **ptr = qdev_get_prop_ptr(dev, prop);
-    char *str;
-    int ret;
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_str(v, &str, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if (!*str) {
-        g_free(str);
-        *ptr = NULL;
-        return;
-    }
-    ret = parse(dev, str, ptr);
-    error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
-    g_free(str);
-}
-
 static void get_enum(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
@@ -476,227 +433,6 @@ PropertyInfo qdev_prop_string = {
     .set   = set_string,
 };
 
-/* --- drive --- */
-
-static int parse_drive(DeviceState *dev, const char *str, void **ptr)
-{
-    BlockDriverState *bs;
-
-    bs = bdrv_find(str);
-    if (bs == NULL)
-        return -ENOENT;
-    if (bdrv_attach_dev(bs, dev) < 0)
-        return -EEXIST;
-    *ptr = bs;
-    return 0;
-}
-
-static void release_drive(Object *obj, const char *name, void *opaque)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (*ptr) {
-        bdrv_detach_dev(*ptr, dev);
-        blockdev_auto_del(*ptr);
-    }
-}
-
-static const char *print_drive(void *ptr)
-{
-    return bdrv_get_device_name(ptr);
-}
-
-static void get_drive(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    get_pointer(obj, v, opaque, print_drive, name, errp);
-}
-
-static void set_drive(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    set_pointer(obj, v, opaque, parse_drive, name, errp);
-}
-
-PropertyInfo qdev_prop_drive = {
-    .name  = "drive",
-    .get   = get_drive,
-    .set   = set_drive,
-    .release = release_drive,
-};
-
-/* --- character device --- */
-
-static int parse_chr(DeviceState *dev, const char *str, void **ptr)
-{
-    CharDriverState *chr = qemu_chr_find(str);
-    if (chr == NULL) {
-        return -ENOENT;
-    }
-    if (chr->avail_connections < 1) {
-        return -EEXIST;
-    }
-    *ptr = chr;
-    --chr->avail_connections;
-    return 0;
-}
-
-static void release_chr(Object *obj, const char *name, void *opaque)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (*ptr) {
-        qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
-    }
-}
-
-
-static const char *print_chr(void *ptr)
-{
-    CharDriverState *chr = ptr;
-
-    return chr->label ? chr->label : "";
-}
-
-static void get_chr(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    get_pointer(obj, v, opaque, print_chr, name, errp);
-}
-
-static void set_chr(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    set_pointer(obj, v, opaque, parse_chr, name, errp);
-}
-
-PropertyInfo qdev_prop_chr = {
-    .name  = "chr",
-    .get   = get_chr,
-    .set   = set_chr,
-    .release = release_chr,
-};
-
-/* --- netdev device --- */
-
-static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
-{
-    NetClientState *netdev = qemu_find_netdev(str);
-
-    if (netdev == NULL) {
-        return -ENOENT;
-    }
-    if (netdev->peer) {
-        return -EEXIST;
-    }
-    *ptr = netdev;
-    return 0;
-}
-
-static const char *print_netdev(void *ptr)
-{
-    NetClientState *netdev = ptr;
-
-    return netdev->name ? netdev->name : "";
-}
-
-static void get_netdev(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    get_pointer(obj, v, opaque, print_netdev, name, errp);
-}
-
-static void set_netdev(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    set_pointer(obj, v, opaque, parse_netdev, name, errp);
-}
-
-PropertyInfo qdev_prop_netdev = {
-    .name  = "netdev",
-    .get   = get_netdev,
-    .set   = set_netdev,
-};
-
-/* --- vlan --- */
-
-static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (*ptr) {
-        int id;
-        if (!net_hub_id_for_client(*ptr, &id)) {
-            return snprintf(dest, len, "%d", id);
-        }
-    }
-
-    return snprintf(dest, len, "<null>");
-}
-
-static void get_vlan(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
-    int32_t id = -1;
-
-    if (*ptr) {
-        int hub_id;
-        if (!net_hub_id_for_client(*ptr, &hub_id)) {
-            id = hub_id;
-        }
-    }
-
-    visit_type_int32(v, &id, name, errp);
-}
-
-static void set_vlan(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    NetClientState **ptr = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    int32_t id;
-    NetClientState *hubport;
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_int32(v, &id, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if (id == -1) {
-        *ptr = NULL;
-        return;
-    }
-
-    hubport = net_hub_port_find(id);
-    if (!hubport) {
-        error_set(errp, QERR_INVALID_PARAMETER_VALUE,
-                  name, prop->info->name);
-        return;
-    }
-    *ptr = hubport;
-}
-
-PropertyInfo qdev_prop_vlan = {
-    .name  = "vlan",
-    .print = print_vlan,
-    .get   = get_vlan,
-    .set   = set_vlan,
-};
-
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
@@ -1158,44 +894,6 @@ void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
     assert_no_error(errp);
 }
 
-int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
-{
-    Error *errp = NULL;
-    const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
-    object_property_set_str(OBJECT(dev), bdrv_name,
-                            name, &errp);
-    if (errp) {
-        qerror_report_err(errp);
-        error_free(errp);
-        return -1;
-    }
-    return 0;
-}
-
-void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value)
-{
-    if (qdev_prop_set_drive(dev, name, value) < 0) {
-        exit(1);
-    }
-}
-void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
-{
-    Error *errp = NULL;
-    assert(!value || value->label);
-    object_property_set_str(OBJECT(dev),
-                            value ? value->label : "", name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value)
-{
-    Error *errp = NULL;
-    assert(!value || value->name);
-    object_property_set_str(OBJECT(dev),
-                            value ? value->name : "", name, &errp);
-    assert_no_error(errp);
-}
-
 void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
 {
     Error *errp = NULL;
@@ -1231,7 +929,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
 
 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
 
-static void qdev_prop_register_global(GlobalProperty *prop)
+void qdev_prop_register_global(GlobalProperty *prop)
 {
     QTAILQ_INSERT_TAIL(&global_props, prop, next);
 }
@@ -1263,19 +961,3 @@ void qdev_prop_set_globals(DeviceState *dev)
     } while (class);
 }
 
-static int qdev_add_one_global(QemuOpts *opts, void *opaque)
-{
-    GlobalProperty *g;
-
-    g = g_malloc0(sizeof(*g));
-    g->driver   = qemu_opt_get(opts, "driver");
-    g->property = qemu_opt_get(opts, "property");
-    g->value    = qemu_opt_get(opts, "value");
-    qdev_prop_register_global(g);
-    return 0;
-}
-
-void qemu_add_globals(void)
-{
-    qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0);
-}
diff --git a/hw/qdev-properties.h b/hw/qdev-properties.h
index 5b046ab..ddcf774 100644
--- a/hw/qdev-properties.h
+++ b/hw/qdev-properties.h
@@ -116,6 +116,7 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 /* FIXME: Remove opaque pointer properties.  */
 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
 
+void qdev_prop_register_global(GlobalProperty *prop);
 void qdev_prop_register_global_list(GlobalProperty *props);
 void qdev_prop_set_globals(DeviceState *dev);
 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
diff --git a/hw/qdev-system.c b/hw/qdev-system.c
new file mode 100644
index 0000000..4891d2f
--- /dev/null
+++ b/hw/qdev-system.c
@@ -0,0 +1,93 @@
+#include "net.h"
+#include "qdev.h"
+
+void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
+{
+    assert(dev->num_gpio_in == 0);
+    dev->num_gpio_in = n;
+    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
+}
+
+void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
+{
+    assert(dev->num_gpio_out == 0);
+    dev->num_gpio_out = n;
+    dev->gpio_out = pins;
+}
+
+qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
+{
+    assert(n >= 0 && n < dev->num_gpio_in);
+    return dev->gpio_in[n];
+}
+
+void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
+{
+    assert(n >= 0 && n < dev->num_gpio_out);
+    dev->gpio_out[n] = pin;
+}
+
+void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
+{
+    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
+    if (nd->netdev)
+        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
+    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
+        object_property_find(OBJECT(dev), "vectors", NULL)) {
+        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
+    }
+    nd->instantiated = 1;
+}
+
+BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
+{
+    BusState *bus;
+
+    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+        if (strcmp(name, bus->name) == 0) {
+            return bus;
+        }
+    }
+    return NULL;
+}
+
+/* Create a new device.  This only initializes the device state structure
+   and allows properties to be set.  qdev_init should be called to
+   initialize the actual device emulation.  */
+DeviceState *qdev_create(BusState *bus, const char *name)
+{
+    DeviceState *dev;
+
+    dev = qdev_try_create(bus, name);
+    if (!dev) {
+        if (bus) {
+            hw_error("Unknown device '%s' for bus '%s'\n", name,
+                     object_get_typename(OBJECT(bus)));
+        } else {
+            hw_error("Unknown device '%s' for default sysbus\n", name);
+        }
+    }
+
+    return dev;
+}
+
+DeviceState *qdev_try_create(BusState *bus, const char *type)
+{
+    DeviceState *dev;
+
+    if (object_class_by_name(type) == NULL) {
+        return NULL;
+    }
+    dev = DEVICE(object_new(type));
+    if (!dev) {
+        return NULL;
+    }
+
+    if (!bus) {
+        bus = sysbus_get_default();
+    }
+
+    qdev_set_parent_bus(dev, bus);
+
+    return dev;
+}
diff --git a/hw/qdev.c b/hw/qdev.c
index d0775f6..9e73655 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -25,7 +25,6 @@
    inherit from a particular bus (e.g. PCI or I2C) rather than
    this API directly.  */
 
-#include "net.h"
 #include "qdev.h"
 #include "sysemu.h"
 #include "error.h"
@@ -105,47 +104,6 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
     bus_add_child(bus, dev);
 }
 
-/* Create a new device.  This only initializes the device state structure
-   and allows properties to be set.  qdev_init should be called to
-   initialize the actual device emulation.  */
-DeviceState *qdev_create(BusState *bus, const char *name)
-{
-    DeviceState *dev;
-
-    dev = qdev_try_create(bus, name);
-    if (!dev) {
-        if (bus) {
-            hw_error("Unknown device '%s' for bus '%s'\n", name,
-                     object_get_typename(OBJECT(bus)));
-        } else {
-            hw_error("Unknown device '%s' for default sysbus\n", name);
-        }
-    }
-
-    return dev;
-}
-
-DeviceState *qdev_try_create(BusState *bus, const char *type)
-{
-    DeviceState *dev;
-
-    if (object_class_by_name(type) == NULL) {
-        return NULL;
-    }
-    dev = DEVICE(object_new(type));
-    if (!dev) {
-        return NULL;
-    }
-
-    if (!bus) {
-        bus = sysbus_get_default();
-    }
-
-    qdev_set_parent_bus(dev, bus);
-
-    return dev;
-}
-
 /* Initialize a device.  Device properties should be set before calling
    this function.  IRQs and MMIO regions should be connected/mapped after
    calling this function.
@@ -290,56 +248,6 @@ BusState *qdev_get_parent_bus(DeviceState *dev)
     return dev->parent_bus;
 }
 
-void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
-{
-    assert(dev->num_gpio_in == 0);
-    dev->num_gpio_in = n;
-    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
-}
-
-void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
-{
-    assert(dev->num_gpio_out == 0);
-    dev->num_gpio_out = n;
-    dev->gpio_out = pins;
-}
-
-qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
-{
-    assert(n >= 0 && n < dev->num_gpio_in);
-    return dev->gpio_in[n];
-}
-
-void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
-{
-    assert(n >= 0 && n < dev->num_gpio_out);
-    dev->gpio_out[n] = pin;
-}
-
-void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
-{
-    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
-    if (nd->netdev)
-        qdev_prop_set_netdev(dev, "netdev", nd->netdev);
-    if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
-        object_property_find(OBJECT(dev), "vectors", NULL)) {
-        qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
-    }
-    nd->instantiated = 1;
-}
-
-BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
-{
-    BusState *bus;
-
-    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
-        if (strcmp(name, bus->name) == 0) {
-            return bus;
-        }
-    }
-    return NULL;
-}
-
 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
                        qbus_walkerfn *busfn, void *opaque)
 {
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 4/6] tests: unit tests for qdev global-properties handling
  2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
                   ` (2 preceding siblings ...)
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 3/6] qdev: separate core from the code used only by qemu-system-* Eduardo Habkost
@ 2012-10-03 17:48 ` Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 5/6] qom: introduce post_init() function Eduardo Habkost
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2012-10-03 17:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Igor Mammedov

This tests the qdev global-properties handling code.

A fake-qdev.c module was added with some stub functions, to keep
dependencies under control.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 tests/Makefile                |   6 +++
 tests/fake-qdev.c             |  52 ++++++++++++++++++++
 tests/test-qdev-global-prop.c | 109 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 167 insertions(+)
 create mode 100644 tests/fake-qdev.c
 create mode 100644 tests/test-qdev-global-prop.c

diff --git a/tests/Makefile b/tests/Makefile
index 26a67ce..2433be7 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -15,6 +15,7 @@ check-unit-y += tests/test-string-output-visitor$(EXESUF)
 check-unit-y += tests/test-coroutine$(EXESUF)
 check-unit-y += tests/test-visitor-serialization$(EXESUF)
 check-unit-y += tests/test-iov$(EXESUF)
+check-unit-y += tests/test-qdev-global-prop$(EXESUF)
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
@@ -50,6 +51,11 @@ tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o $(tools-obj-y)
 tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) $(tools-obj-y)
 tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y)
 tests/test-iov$(EXESUF): tests/test-iov.o iov.o
+tests/test-qdev-global-prop$(EXESUF): tests/test-qdev-global-prop.o \
+	hw/qdev.o hw/qdev-properties.o \
+	$(test-qapi-obj-y) $(qom-obj-y) \
+	qemu-option.o \
+	tests/fake-qdev.o
 
 tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
diff --git a/tests/fake-qdev.c b/tests/fake-qdev.c
new file mode 100644
index 0000000..bdbbc6e
--- /dev/null
+++ b/tests/fake-qdev.c
@@ -0,0 +1,52 @@
+/* Fake implementations of functions that are not essential for qdev testing,
+ * but are required by the qdev core code.
+ *
+ * Copyright (c) 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/qdev-core.h"
+#include "hw/hw.h"
+
+BusState *sysbus_get_default(void)
+{
+    return NULL;
+}
+
+void qemu_register_reset(QEMUResetHandler *func, void *opaque)
+{
+}
+
+void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
+{
+}
+
+int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
+                                   const VMStateDescription *vmsd,
+                                   void *base, int alias_id,
+                                   int required_for_version)
+{
+    return 0;
+}
+
+void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
+                        void *opaque)
+{
+}
diff --git a/tests/test-qdev-global-prop.c b/tests/test-qdev-global-prop.c
new file mode 100644
index 0000000..4c50156
--- /dev/null
+++ b/tests/test-qdev-global-prop.c
@@ -0,0 +1,109 @@
+/*
+ *  Test code for qdev global-properties handling
+ *
+ *  Copyright (c) 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <glib.h>
+#include <stdint.h>
+
+#include "hw/qdev.h"
+
+
+#define TYPE_STATIC_PROPS "static_prop_type"
+#define STATIC_TYPE(obj) \
+     OBJECT_CHECK(MyType, (obj), TYPE_STATIC_PROPS)
+
+#define PROP_DEFAULT 100
+
+typedef struct MyType {
+    DeviceState parent_obj;
+
+    uint32_t prop1, prop2, prop3;
+} MyType;
+
+static Property static_props[] = {
+    DEFINE_PROP_UINT32("prop1", MyType, prop1, PROP_DEFAULT),
+    DEFINE_PROP_UINT32("prop2", MyType, prop2, PROP_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static int mytype_init(DeviceState *dev)
+{
+    return 0;
+}
+
+static void static_prop_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->props = static_props;
+    dc->init = mytype_init;
+}
+
+static TypeInfo static_prop_type = {
+    .name = TYPE_STATIC_PROPS,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .class_init = static_prop_class_init,
+};
+
+/* Test simple static property setting to default value */
+static void test_static_prop(void)
+{
+    MyType *mt;
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
+}
+
+/* Test setting of static property using global properties */
+static void test_static_globalprop(void)
+{
+    MyType *mt;
+    GlobalProperty props[] = {
+        {TYPE_STATIC_PROPS, "prop1", "200"},
+        {}
+    };
+    qdev_prop_register_global_list(props);
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 200);
+    g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
+}
+
+int main(int argc, char **argv)
+{
+    module_call_init(MODULE_INIT_QOM);
+    type_register_static(&static_prop_type);
+
+    g_test_init(&argc, &argv, NULL);
+
+    g_test_add_func("/qdev/properties/static/default", test_static_prop);
+    g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
+
+    g_test_run();
+
+    return 0;
+}
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 5/6] qom: introduce post_init() function
  2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
                   ` (3 preceding siblings ...)
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 4/6] tests: unit tests for qdev global-properties handling Eduardo Habkost
@ 2012-10-03 17:48 ` Eduardo Habkost
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 6/6] qdev: set globals on " Eduardo Habkost
  2013-07-09 14:32 ` [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Andreas Färber
  6 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2012-10-03 17:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Igor Mammedov

This will allow classes to specify a function to be called after all
instance_init() functions were called.

This will be used by DeviceState to call qdev_prop_set_globals() at the
right moment.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qemu/object.h |  3 +++
 qom/object.c          | 14 ++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index cc75fee..ca7e38b 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -276,6 +276,8 @@ struct Object
  * @instance_init: This function is called to initialize an object.  The parent
  *   class will have already been initialized so the type is only responsible
  *   for initializing its own members.
+ * @instance_post_init: This function is called to finish initialization of
+ *   an object, after all instance_init functions were called.
  * @instance_finalize: This function is called during object destruction.  This
  *   is called before the parent @instance_finalize function has been called.
  *   An object should only free the members that are unique to its type in this
@@ -311,6 +313,7 @@ struct TypeInfo
 
     size_t instance_size;
     void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
     void (*instance_finalize)(Object *obj);
 
     bool abstract;
diff --git a/qom/object.c b/qom/object.c
index e3e9242..eed5e05 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -49,6 +49,7 @@ struct TypeImpl
     void *class_data;
 
     void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
     void (*instance_finalize)(Object *obj);
 
     bool abstract;
@@ -109,6 +110,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
     ti->class_data = info->class_data;
 
     ti->instance_init = info->instance_init;
+    ti->instance_post_init = info->instance_post_init;
     ti->instance_finalize = info->instance_finalize;
 
     ti->abstract = info->abstract;
@@ -295,6 +297,17 @@ static void object_init_with_type(Object *obj, TypeImpl *ti)
     }
 }
 
+static void object_post_init_with_type(Object *obj, TypeImpl *ti)
+{
+    if (ti->instance_post_init) {
+        ti->instance_post_init(obj);
+    }
+
+    if (type_has_parent(ti)) {
+        object_post_init_with_type(obj, type_get_parent(ti));
+    }
+}
+
 void object_initialize_with_type(void *data, TypeImpl *type)
 {
     Object *obj = data;
@@ -309,6 +322,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
     obj->class = type->class;
     QTAILQ_INIT(&obj->properties);
     object_init_with_type(obj, type);
+    object_post_init_with_type(obj, type);
 }
 
 void object_initialize(void *data, const char *typename)
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 6/6] qdev: set globals on post_init() function
  2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
                   ` (4 preceding siblings ...)
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 5/6] qom: introduce post_init() function Eduardo Habkost
@ 2012-10-03 17:48 ` Eduardo Habkost
  2013-07-09 14:32 ` [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Andreas Färber
  6 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2012-10-03 17:48 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Igor Mammedov

This way, properties registerd in the instance_init() function of
children classes will be handled properly by qdev_prop_set_globals(),
too.

Includes a new unit test for the new functionality.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/qdev.c                      |   9 ++-
 tests/Makefile                 |   4 +-
 tests/test-qdev-global-prop.c  | 109 -------------------------
 tests/test-qdev-global-props.c | 178 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 187 insertions(+), 113 deletions(-)
 delete mode 100644 tests/test-qdev-global-prop.c
 create mode 100644 tests/test-qdev-global-props.c

diff --git a/hw/qdev.c b/hw/qdev.c
index 9e73655..68c5ccb 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -591,12 +591,16 @@ static void device_initfn(Object *obj)
         }
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
-    qdev_prop_set_globals(dev);
-
     object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
                              (Object **)&dev->parent_bus, NULL);
 }
 
+static void device_post_init(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    qdev_prop_set_globals(dev);
+}
+
 /* Unlink device from bus and free the structure.  */
 static void device_finalize(Object *obj)
 {
@@ -659,6 +663,7 @@ static TypeInfo device_type_info = {
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(DeviceState),
     .instance_init = device_initfn,
+    .instance_post_init = device_post_init,
     .instance_finalize = device_finalize,
     .class_base_init = device_class_base_init,
     .abstract = true,
diff --git a/tests/Makefile b/tests/Makefile
index 2433be7..9f86162 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -15,7 +15,7 @@ check-unit-y += tests/test-string-output-visitor$(EXESUF)
 check-unit-y += tests/test-coroutine$(EXESUF)
 check-unit-y += tests/test-visitor-serialization$(EXESUF)
 check-unit-y += tests/test-iov$(EXESUF)
-check-unit-y += tests/test-qdev-global-prop$(EXESUF)
+check-unit-y += tests/test-qdev-global-props$(EXESUF)
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
@@ -51,7 +51,7 @@ tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o $(tools-obj-y)
 tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) $(tools-obj-y)
 tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y)
 tests/test-iov$(EXESUF): tests/test-iov.o iov.o
-tests/test-qdev-global-prop$(EXESUF): tests/test-qdev-global-prop.o \
+tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
 	hw/qdev.o hw/qdev-properties.o \
 	$(test-qapi-obj-y) $(qom-obj-y) \
 	qemu-option.o \
diff --git a/tests/test-qdev-global-prop.c b/tests/test-qdev-global-prop.c
deleted file mode 100644
index 4c50156..0000000
--- a/tests/test-qdev-global-prop.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  Test code for qdev global-properties handling
- *
- *  Copyright (c) 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <glib.h>
-#include <stdint.h>
-
-#include "hw/qdev.h"
-
-
-#define TYPE_STATIC_PROPS "static_prop_type"
-#define STATIC_TYPE(obj) \
-     OBJECT_CHECK(MyType, (obj), TYPE_STATIC_PROPS)
-
-#define PROP_DEFAULT 100
-
-typedef struct MyType {
-    DeviceState parent_obj;
-
-    uint32_t prop1, prop2, prop3;
-} MyType;
-
-static Property static_props[] = {
-    DEFINE_PROP_UINT32("prop1", MyType, prop1, PROP_DEFAULT),
-    DEFINE_PROP_UINT32("prop2", MyType, prop2, PROP_DEFAULT),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static int mytype_init(DeviceState *dev)
-{
-    return 0;
-}
-
-static void static_prop_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->props = static_props;
-    dc->init = mytype_init;
-}
-
-static TypeInfo static_prop_type = {
-    .name = TYPE_STATIC_PROPS,
-    .parent = TYPE_DEVICE,
-    .instance_size = sizeof(MyType),
-    .class_init = static_prop_class_init,
-};
-
-/* Test simple static property setting to default value */
-static void test_static_prop(void)
-{
-    MyType *mt;
-
-    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
-    qdev_init_nofail(DEVICE(mt));
-
-    g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
-}
-
-/* Test setting of static property using global properties */
-static void test_static_globalprop(void)
-{
-    MyType *mt;
-    GlobalProperty props[] = {
-        {TYPE_STATIC_PROPS, "prop1", "200"},
-        {}
-    };
-    qdev_prop_register_global_list(props);
-
-    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
-    qdev_init_nofail(DEVICE(mt));
-
-    g_assert_cmpuint(mt->prop1, ==, 200);
-    g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
-}
-
-int main(int argc, char **argv)
-{
-    module_call_init(MODULE_INIT_QOM);
-    type_register_static(&static_prop_type);
-
-    g_test_init(&argc, &argv, NULL);
-
-    g_test_add_func("/qdev/properties/static/default", test_static_prop);
-    g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
-
-    g_test_run();
-
-    return 0;
-}
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
new file mode 100644
index 0000000..29f602c
--- /dev/null
+++ b/tests/test-qdev-global-props.c
@@ -0,0 +1,178 @@
+/*
+ *  Test code for qdev global-properties handling
+ *
+ *  Copyright (c) 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <glib.h>
+#include <stdint.h>
+
+#include "hw/qdev.h"
+#include "qemu/object.h"
+#include "qapi/qapi-visit-core.h"
+
+
+#define TYPE_STATIC_PROPS "static_prop_type"
+#define STATIC_TYPE(obj) \
+     OBJECT_CHECK(MyType, (obj), TYPE_STATIC_PROPS)
+
+#define PROP_DEFAULT 100
+
+typedef struct MyType {
+    DeviceState parent_obj;
+
+    uint32_t prop1, prop2, prop3;
+} MyType;
+
+static Property static_props[] = {
+    DEFINE_PROP_UINT32("prop1", MyType, prop1, PROP_DEFAULT),
+    DEFINE_PROP_UINT32("prop2", MyType, prop2, PROP_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static int mytype_init(DeviceState *dev)
+{
+    return 0;
+}
+
+static void static_prop_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->props = static_props;
+    dc->init = mytype_init;
+}
+
+static TypeInfo static_prop_type = {
+    .name = TYPE_STATIC_PROPS,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .class_init = static_prop_class_init,
+};
+
+/* Test simple static property setting to default value */
+static void test_static_prop(void)
+{
+    MyType *mt;
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
+}
+
+/* Test setting of static property using global properties */
+static void test_static_globalprop(void)
+{
+    MyType *mt;
+    static GlobalProperty props[] = {
+        {TYPE_STATIC_PROPS, "prop1", "200"},
+        {}
+    };
+    qdev_prop_register_global_list(props);
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 200);
+    g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
+}
+
+#define TYPE_DYNAMIC_PROPS "dynamic_prop_type"
+#define DYNAMIC_TYPE(obj) \
+     OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
+
+static void prop1_acessor(Object *obj,
+                          struct Visitor *v,
+                          void *opaque,
+                          const char *name,
+                          struct Error **errp)
+{
+    MyType *mt = DYNAMIC_TYPE(obj);
+    visit_type_uint32(v, &mt->prop1, name, errp);
+}
+
+static void prop2_acessor(Object *obj,
+                          struct Visitor *v,
+                          void *opaque,
+                          const char *name,
+                          struct Error **errp)
+{
+    MyType *mt = DYNAMIC_TYPE(obj);
+    visit_type_uint32(v, &mt->prop2, name, errp);
+}
+
+static void dynamic_instance_init(Object *obj)
+{
+    object_property_add(obj, "prop1", "uint32", prop1_acessor, prop1_acessor,
+                        NULL, NULL, NULL);
+    object_property_add(obj, "prop2", "uint32", prop2_acessor, prop2_acessor,
+                        NULL, NULL, NULL);
+}
+
+static void dynamic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->init = mytype_init;
+}
+
+
+static TypeInfo dynamic_prop_type = {
+    .name = TYPE_DYNAMIC_PROPS,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .instance_init = dynamic_instance_init,
+    .class_init = dynamic_class_init,
+};
+
+/* Test setting of static property using global properties */
+static void test_dynamic_globalprop(void)
+{
+    MyType *mt;
+    static GlobalProperty props[] = {
+        {TYPE_DYNAMIC_PROPS, "prop1", "101"},
+        {TYPE_DYNAMIC_PROPS, "prop2", "102"},
+        {}
+    };
+    qdev_prop_register_global_list(props);
+
+    mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 101);
+    g_assert_cmpuint(mt->prop2, ==, 102);
+}
+
+int main(int argc, char **argv)
+{
+    module_call_init(MODULE_INIT_QOM);
+    type_register_static(&static_prop_type);
+    type_register_static(&dynamic_prop_type);
+
+    g_test_init(&argc, &argv, NULL);
+
+    g_test_add_func("/qdev/properties/static/default", test_static_prop);
+    g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
+    g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop);
+
+    g_test_run();
+
+    return 0;
+}
-- 
1.7.11.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls
  2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
                   ` (5 preceding siblings ...)
  2012-10-03 17:48 ` [Qemu-devel] [PATCH 6/6] qdev: set globals on " Eduardo Habkost
@ 2013-07-09 14:32 ` Andreas Färber
  2013-07-10 20:08   ` [Qemu-devel] [RFC 0/3 v2] " Eduardo Habkost
  6 siblings, 1 reply; 17+ messages in thread
From: Andreas Färber @ 2013-07-09 14:32 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Igor Mammedov, Eduardo Habkost, qemu-devel

Ping for KVM call discussion

Am 03.10.2012 19:48, schrieb Eduardo Habkost:
> Summary:
>  - Object properties are registered by the classes' instance_init()
>    functions
>  - qdev_prop_set_globals() needs all properties to be registered before being
>    called.
>  - Hence, qdev_prop_set_globals() can't be called from device_initfn().
> 
> Reference:
>   http://article.gmane.org/gmane.comp.emulators.qemu/173753
> 
> This series is a larger than the single-patch suggestion sent by Igor (URL
> above), just because I wanted to include a unit test for the new code. To do
> that, I pulled the qdev-split code sent previously to the list, so a qdev unit
> test could be written without pulling too many dependencies.
> 
> Patches 1-3 are just code movement, patch 3 adds the qdev unit test, patches 5-6
> finally introduce post_init(), and move the qdev_prop_set_globals() call to
> post_init().
> 
> Anthony Liguori (1):
>   qdev: split up header so it can be used in cpu.h
> 
> Eduardo Habkost (4):
>   qdev: separate core from the code used only by qemu-system-*
>   tests: unit tests for qdev global-properties handling
>   qom: introduce post_init() function
>   qdev: set globals on post_init() function
> 
> Igor Mammedov (1):
>   qapi-types.h doesn't really need to include qemu-common.h
> 
>  hw/Makefile.objs               |   1 +
>  hw/irq.h                       |   2 +
>  hw/mc146818rtc.c               |   1 +
>  hw/qdev-addr.c                 |   1 +
>  hw/qdev-core.h                 | 240 ++++++++++++++++++++++++++
>  hw/qdev-monitor.h              |  16 ++
>  hw/qdev-properties-system.c    | 329 ++++++++++++++++++++++++++++++++++++
>  hw/qdev-properties.c           | 321 +----------------------------------
>  hw/qdev-properties.h           | 131 +++++++++++++++
>  hw/qdev-system.c               |  93 +++++++++++
>  hw/qdev.c                      | 102 +----------
>  hw/qdev.h                      | 371 +----------------------------------------
>  include/qemu/object.h          |   3 +
>  qom/object.c                   |  14 ++
>  scripts/qapi-types.py          |   3 +-
>  tests/Makefile                 |   6 +
>  tests/fake-qdev.c              |  52 ++++++
>  tests/test-qdev-global-props.c | 178 ++++++++++++++++++++
>  18 files changed, 1083 insertions(+), 781 deletions(-)
>  create mode 100644 hw/qdev-core.h
>  create mode 100644 hw/qdev-monitor.h
>  create mode 100644 hw/qdev-properties-system.c
>  create mode 100644 hw/qdev-properties.h
>  create mode 100644 hw/qdev-system.c
>  create mode 100644 tests/fake-qdev.c
>  create mode 100644 tests/test-qdev-global-props.c
> 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [RFC 0/3 v2] qdev: handle global properties after all instance_init calls
  2013-07-09 14:32 ` [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Andreas Färber
@ 2013-07-10 20:08   ` Eduardo Habkost
  2013-07-10 20:08     ` [Qemu-devel] [RFC 1/3 v2] tests: unit tests for qdev global-properties handling Eduardo Habkost
                       ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Eduardo Habkost @ 2013-07-10 20:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Andreas Färber, Igor Mammedov

Updated version of the series sent in October 2012.

References:
  http://article.gmane.org/gmane.comp.emulators.qemu/173753
    (old discussion)
  http://article.gmane.org/gmane.comp.emulators.qemu/173782
    (previous version of this series)
  http://article.gmane.org/gmane.comp.emulators.kvm.devel/112380
    (Minutes of last call where this was discussed)

Eduardo Habkost (3):
  tests: unit tests for qdev global-properties handling
  qom: introduce post_init() function
  qdev: set globals on post_init() function

 hw/core/qdev.c                 |  10 ++-
 include/qom/object.h           |   3 +
 qom/object.c                   |  14 ++++
 tests/.gitignore               |   1 +
 tests/Makefile                 |   7 ++
 tests/test-qdev-global-props.c | 178 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 tests/test-qdev-global-props.c

-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [RFC 1/3 v2] tests: unit tests for qdev global-properties handling
  2013-07-10 20:08   ` [Qemu-devel] [RFC 0/3 v2] " Eduardo Habkost
@ 2013-07-10 20:08     ` Eduardo Habkost
  2013-07-10 20:08     ` [Qemu-devel] [RFC 2/3 v2] qom: introduce post_init() function Eduardo Habkost
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2013-07-10 20:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Andreas Färber, Igor Mammedov

This tests the qdev global-properties handling code.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 tests/.gitignore               |   1 +
 tests/Makefile                 |   7 +++
 tests/test-qdev-global-props.c | 109 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)
 create mode 100644 tests/test-qdev-global-props.c

diff --git a/tests/.gitignore b/tests/.gitignore
index fb05c2a..3586416 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -18,4 +18,5 @@ test-qmp-marshal.c
 test-thread-pool
 test-x86-cpuid
 test-xbzrle
+test-qdev-global-props
 *-test
diff --git a/tests/Makefile b/tests/Makefile
index 279d5f8..9849441 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -47,6 +47,7 @@ gcov-files-test-mul64-y = util/host-utils.c
 check-unit-y += tests/test-int128$(EXESUF)
 # all code tested by test-int128 is inside int128.h
 gcov-files-test-int128-y =
+check-unit-y += tests/test-qdev-global-props$(EXESUF)
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
@@ -102,6 +103,12 @@ tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
 tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o xbzrle.o page_cache.o libqemuutil.a
 tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
 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 \
+	$(test-qapi-obj-y) \
+	libqemuutil.a libqemustub.a
 
 tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
new file mode 100644
index 0000000..4c50156
--- /dev/null
+++ b/tests/test-qdev-global-props.c
@@ -0,0 +1,109 @@
+/*
+ *  Test code for qdev global-properties handling
+ *
+ *  Copyright (c) 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <glib.h>
+#include <stdint.h>
+
+#include "hw/qdev.h"
+
+
+#define TYPE_STATIC_PROPS "static_prop_type"
+#define STATIC_TYPE(obj) \
+     OBJECT_CHECK(MyType, (obj), TYPE_STATIC_PROPS)
+
+#define PROP_DEFAULT 100
+
+typedef struct MyType {
+    DeviceState parent_obj;
+
+    uint32_t prop1, prop2, prop3;
+} MyType;
+
+static Property static_props[] = {
+    DEFINE_PROP_UINT32("prop1", MyType, prop1, PROP_DEFAULT),
+    DEFINE_PROP_UINT32("prop2", MyType, prop2, PROP_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static int mytype_init(DeviceState *dev)
+{
+    return 0;
+}
+
+static void static_prop_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->props = static_props;
+    dc->init = mytype_init;
+}
+
+static TypeInfo static_prop_type = {
+    .name = TYPE_STATIC_PROPS,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .class_init = static_prop_class_init,
+};
+
+/* Test simple static property setting to default value */
+static void test_static_prop(void)
+{
+    MyType *mt;
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
+}
+
+/* Test setting of static property using global properties */
+static void test_static_globalprop(void)
+{
+    MyType *mt;
+    GlobalProperty props[] = {
+        {TYPE_STATIC_PROPS, "prop1", "200"},
+        {}
+    };
+    qdev_prop_register_global_list(props);
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 200);
+    g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
+}
+
+int main(int argc, char **argv)
+{
+    module_call_init(MODULE_INIT_QOM);
+    type_register_static(&static_prop_type);
+
+    g_test_init(&argc, &argv, NULL);
+
+    g_test_add_func("/qdev/properties/static/default", test_static_prop);
+    g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
+
+    g_test_run();
+
+    return 0;
+}
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [RFC 2/3 v2] qom: introduce post_init() function
  2013-07-10 20:08   ` [Qemu-devel] [RFC 0/3 v2] " Eduardo Habkost
  2013-07-10 20:08     ` [Qemu-devel] [RFC 1/3 v2] tests: unit tests for qdev global-properties handling Eduardo Habkost
@ 2013-07-10 20:08     ` Eduardo Habkost
  2013-07-11  6:29       ` Igor Mammedov
  2013-07-10 20:08     ` [Qemu-devel] [RFC 3/3 v2] qdev: set globals on " Eduardo Habkost
  2013-07-28 19:44     ` [Qemu-devel] [RFC 0/3 v2] qdev: handle global properties after all instance_init calls Andreas Färber
  3 siblings, 1 reply; 17+ messages in thread
From: Eduardo Habkost @ 2013-07-10 20:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Andreas Färber, Igor Mammedov

This will allow classes to specify a function to be called after all
instance_init() functions were called.

This will be used by DeviceState to call qdev_prop_set_globals() at the
right moment.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 include/qom/object.h |  3 +++
 qom/object.c         | 14 ++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index 23fc048..1a54f64 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -398,6 +398,8 @@ struct Object
  * @instance_init: This function is called to initialize an object.  The parent
  *   class will have already been initialized so the type is only responsible
  *   for initializing its own members.
+ * @instance_post_init: This function is called to finish initialization of
+ *   an object, after all instance_init functions were called.
  * @instance_finalize: This function is called during object destruction.  This
  *   is called before the parent @instance_finalize function has been called.
  *   An object should only free the members that are unique to its type in this
@@ -433,6 +435,7 @@ struct TypeInfo
 
     size_t instance_size;
     void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
     void (*instance_finalize)(Object *obj);
 
     bool abstract;
diff --git a/qom/object.c b/qom/object.c
index b2479d1..74fd241 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -51,6 +51,7 @@ struct TypeImpl
     void *class_data;
 
     void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
     void (*instance_finalize)(Object *obj);
 
     bool abstract;
@@ -111,6 +112,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
     ti->class_data = info->class_data;
 
     ti->instance_init = info->instance_init;
+    ti->instance_post_init = info->instance_post_init;
     ti->instance_finalize = info->instance_finalize;
 
     ti->abstract = info->abstract;
@@ -298,6 +300,17 @@ static void object_init_with_type(Object *obj, TypeImpl *ti)
     }
 }
 
+static void object_post_init_with_type(Object *obj, TypeImpl *ti)
+{
+    if (ti->instance_post_init) {
+        ti->instance_post_init(obj);
+    }
+
+    if (type_has_parent(ti)) {
+        object_post_init_with_type(obj, type_get_parent(ti));
+    }
+}
+
 void object_initialize_with_type(void *data, TypeImpl *type)
 {
     Object *obj = data;
@@ -313,6 +326,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
     object_ref(obj);
     QTAILQ_INIT(&obj->properties);
     object_init_with_type(obj, type);
+    object_post_init_with_type(obj, type);
 }
 
 void object_initialize(void *data, const char *typename)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [RFC 3/3 v2] qdev: set globals on post_init() function
  2013-07-10 20:08   ` [Qemu-devel] [RFC 0/3 v2] " Eduardo Habkost
  2013-07-10 20:08     ` [Qemu-devel] [RFC 1/3 v2] tests: unit tests for qdev global-properties handling Eduardo Habkost
  2013-07-10 20:08     ` [Qemu-devel] [RFC 2/3 v2] qom: introduce post_init() function Eduardo Habkost
@ 2013-07-10 20:08     ` Eduardo Habkost
  2013-07-11  6:48       ` Igor Mammedov
  2013-07-28 19:44     ` [Qemu-devel] [RFC 0/3 v2] qdev: handle global properties after all instance_init calls Andreas Färber
  3 siblings, 1 reply; 17+ messages in thread
From: Eduardo Habkost @ 2013-07-10 20:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Andreas Färber, Igor Mammedov

This way, properties registered in the instance_init() function of
children classes will be handled properly by qdev_prop_set_globals(),
too.

Includes a new unit test for the new functionality.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/core/qdev.c                 | 10 +++++-
 tests/test-qdev-global-props.c | 71 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 9190a7e..e0acb6c 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -752,7 +752,6 @@ static void device_initfn(Object *obj)
         }
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
-    qdev_prop_set_globals(dev, &err);
     if (err != NULL) {
         qerror_report_err(err);
         error_free(err);
@@ -764,6 +763,14 @@ static void device_initfn(Object *obj)
     assert_no_error(err);
 }
 
+static void device_post_init(Object *obj)
+{
+    Error *err = NULL;
+    DeviceState *dev = DEVICE(obj);
+    qdev_prop_set_globals(dev, &err);
+    assert_no_error(err);
+}
+
 /* Unlink device from bus and free the structure.  */
 static void device_finalize(Object *obj)
 {
@@ -853,6 +860,7 @@ static const TypeInfo device_type_info = {
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(DeviceState),
     .instance_init = device_initfn,
+    .instance_post_init = device_post_init,
     .instance_finalize = device_finalize,
     .class_base_init = device_class_base_init,
     .class_init = device_class_init,
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 4c50156..7b5eb88 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -26,6 +26,8 @@
 #include <stdint.h>
 
 #include "hw/qdev.h"
+#include "qemu/object.h"
+#include "qapi-visit.h"
 
 
 #define TYPE_STATIC_PROPS "static_prop_type"
@@ -80,7 +82,7 @@ static void test_static_prop(void)
 static void test_static_globalprop(void)
 {
     MyType *mt;
-    GlobalProperty props[] = {
+    static GlobalProperty props[] = {
         {TYPE_STATIC_PROPS, "prop1", "200"},
         {}
     };
@@ -93,15 +95,82 @@ static void test_static_globalprop(void)
     g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
 }
 
+#define TYPE_DYNAMIC_PROPS "dynamic_prop_type"
+#define DYNAMIC_TYPE(obj) \
+     OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
+
+static void prop1_acessor(Object *obj,
+                          struct Visitor *v,
+                          void *opaque,
+                          const char *name,
+                          struct Error **errp)
+{
+    MyType *mt = DYNAMIC_TYPE(obj);
+    visit_type_uint32(v, &mt->prop1, name, errp);
+}
+
+static void prop2_acessor(Object *obj,
+                          struct Visitor *v,
+                          void *opaque,
+                          const char *name,
+                          struct Error **errp)
+{
+    MyType *mt = DYNAMIC_TYPE(obj);
+    visit_type_uint32(v, &mt->prop2, name, errp);
+}
+
+static void dynamic_instance_init(Object *obj)
+{
+    object_property_add(obj, "prop1", "uint32", prop1_acessor, prop1_acessor,
+                        NULL, NULL, NULL);
+    object_property_add(obj, "prop2", "uint32", prop2_acessor, prop2_acessor,
+                        NULL, NULL, NULL);
+}
+
+static void dynamic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->init = mytype_init;
+}
+
+
+static TypeInfo dynamic_prop_type = {
+    .name = TYPE_DYNAMIC_PROPS,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .instance_init = dynamic_instance_init,
+    .class_init = dynamic_class_init,
+};
+
+/* Test setting of static property using global properties */
+static void test_dynamic_globalprop(void)
+{
+    MyType *mt;
+    static GlobalProperty props[] = {
+        {TYPE_DYNAMIC_PROPS, "prop1", "101"},
+        {TYPE_DYNAMIC_PROPS, "prop2", "102"},
+        {}
+    };
+    qdev_prop_register_global_list(props);
+
+    mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 101);
+    g_assert_cmpuint(mt->prop2, ==, 102);
+}
+
 int main(int argc, char **argv)
 {
     module_call_init(MODULE_INIT_QOM);
     type_register_static(&static_prop_type);
+    type_register_static(&dynamic_prop_type);
 
     g_test_init(&argc, &argv, NULL);
 
     g_test_add_func("/qdev/properties/static/default", test_static_prop);
     g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
+    g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop);
 
     g_test_run();
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [RFC 2/3 v2] qom: introduce post_init() function
  2013-07-10 20:08     ` [Qemu-devel] [RFC 2/3 v2] qom: introduce post_init() function Eduardo Habkost
@ 2013-07-11  6:29       ` Igor Mammedov
  2013-07-12  0:29         ` Eduardo Habkost
  0 siblings, 1 reply; 17+ messages in thread
From: Igor Mammedov @ 2013-07-11  6:29 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Andreas Färber

On Wed, 10 Jul 2013 17:08:41 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> This will allow classes to specify a function to be called after all
> instance_init() functions were called.
> 
> This will be used by DeviceState to call qdev_prop_set_globals() at the
> right moment.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  include/qom/object.h |  3 +++
>  qom/object.c         | 14 ++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/include/qom/object.h b/include/qom/object.h
> index 23fc048..1a54f64 100644
> --- a/include/qom/object.h
> +++ b/include/qom/object.h
> @@ -398,6 +398,8 @@ struct Object
>   * @instance_init: This function is called to initialize an object.  The parent
>   *   class will have already been initialized so the type is only responsible
>   *   for initializing its own members.
> + * @instance_post_init: This function is called to finish initialization of
> + *   an object, after all instance_init functions were called.
>   * @instance_finalize: This function is called during object destruction.  This
>   *   is called before the parent @instance_finalize function has been called.
>   *   An object should only free the members that are unique to its type in this
> @@ -433,6 +435,7 @@ struct TypeInfo
[...]
>  
> +static void object_post_init_with_type(Object *obj, TypeImpl *ti)
> +{
> +    if (ti->instance_post_init) {
> +        ti->instance_post_init(obj);
> +    }
> +
> +    if (type_has_parent(ti)) {
> +        object_post_init_with_type(obj, type_get_parent(ti));
> +    }
Is there  a reason why post init called in opposite order than
instance_init() ?

> +}
> +
>  void object_initialize_with_type(void *data, TypeImpl *type)
>  {
>      Object *obj = data;
> @@ -313,6 +326,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
>      object_ref(obj);
>      QTAILQ_INIT(&obj->properties);
>      object_init_with_type(obj, type);
> +    object_post_init_with_type(obj, type);
>  }
>  
>  void object_initialize(void *data, const char *typename)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [RFC 3/3 v2] qdev: set globals on post_init() function
  2013-07-10 20:08     ` [Qemu-devel] [RFC 3/3 v2] qdev: set globals on " Eduardo Habkost
@ 2013-07-11  6:48       ` Igor Mammedov
  2013-07-12 14:57         ` Eduardo Habkost
  0 siblings, 1 reply; 17+ messages in thread
From: Igor Mammedov @ 2013-07-11  6:48 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Andreas Färber

On Wed, 10 Jul 2013 17:08:42 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> This way, properties registered in the instance_init() function of
> children classes will be handled properly by qdev_prop_set_globals(),
> too.
> 
> Includes a new unit test for the new functionality.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  hw/core/qdev.c                 | 10 +++++-
>  tests/test-qdev-global-props.c | 71 +++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 79 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 9190a7e..e0acb6c 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -752,7 +752,6 @@ static void device_initfn(Object *obj)
>          }
>          class = object_class_get_parent(class);
>      } while (class != object_class_by_name(TYPE_DEVICE));
> -    qdev_prop_set_globals(dev, &err);
>      if (err != NULL) {
>          qerror_report_err(err);
>          error_free(err);
> @@ -764,6 +763,14 @@ static void device_initfn(Object *obj)
>      assert_no_error(err);
>  }
>  
> +static void device_post_init(Object *obj)
> +{
> +    Error *err = NULL;
> +    DeviceState *dev = DEVICE(obj);
> +    qdev_prop_set_globals(dev, &err);
> +    assert_no_error(err);
> +}
> +
>  /* Unlink device from bus and free the structure.  */
>  static void device_finalize(Object *obj)
>  {
> @@ -853,6 +860,7 @@ static const TypeInfo device_type_info = {
>      .parent = TYPE_OBJECT,
>      .instance_size = sizeof(DeviceState),
>      .instance_init = device_initfn,
> +    .instance_post_init = device_post_init,
>      .instance_finalize = device_finalize,
>      .class_base_init = device_class_base_init,
>      .class_init = device_class_init,
> diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
> index 4c50156..7b5eb88 100644
> --- a/tests/test-qdev-global-props.c
> +++ b/tests/test-qdev-global-props.c
> @@ -26,6 +26,8 @@
>  #include <stdint.h>
>  
>  #include "hw/qdev.h"
> +#include "qemu/object.h"
> +#include "qapi-visit.h"
>  
>  
>  #define TYPE_STATIC_PROPS "static_prop_type"
> @@ -80,7 +82,7 @@ static void test_static_prop(void)
>  static void test_static_globalprop(void)
>  {
>      MyType *mt;
> -    GlobalProperty props[] = {
> +    static GlobalProperty props[] = {
>          {TYPE_STATIC_PROPS, "prop1", "200"},
>          {}
>      };
hunk belongs to the 1st patch?

> @@ -93,15 +95,82 @@ static void test_static_globalprop(void)
>      g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
>  }
>  
> +#define TYPE_DYNAMIC_PROPS "dynamic_prop_type"
> +#define DYNAMIC_TYPE(obj) \
> +     OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
> +
> +static void prop1_acessor(Object *obj,
> +                          struct Visitor *v,
> +                          void *opaque,
> +                          const char *name,
> +                          struct Error **errp)
> +{
> +    MyType *mt = DYNAMIC_TYPE(obj);
> +    visit_type_uint32(v, &mt->prop1, name, errp);
> +}
> +
> +static void prop2_acessor(Object *obj,
> +                          struct Visitor *v,
> +                          void *opaque,
> +                          const char *name,
> +                          struct Error **errp)
> +{
> +    MyType *mt = DYNAMIC_TYPE(obj);
> +    visit_type_uint32(v, &mt->prop2, name, errp);
> +}
> +
> +static void dynamic_instance_init(Object *obj)
> +{
> +    object_property_add(obj, "prop1", "uint32", prop1_acessor, prop1_acessor,
> +                        NULL, NULL, NULL);
> +    object_property_add(obj, "prop2", "uint32", prop2_acessor, prop2_acessor,
> +                        NULL, NULL, NULL);
> +}
> +
> +static void dynamic_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    dc->init = mytype_init;
> +}
> +
> +
> +static TypeInfo dynamic_prop_type = {
> +    .name = TYPE_DYNAMIC_PROPS,
> +    .parent = TYPE_DEVICE,
> +    .instance_size = sizeof(MyType),
> +    .instance_init = dynamic_instance_init,
> +    .class_init = dynamic_class_init,
> +};
> +
> +/* Test setting of static property using global properties */
> +static void test_dynamic_globalprop(void)
> +{
> +    MyType *mt;
> +    static GlobalProperty props[] = {
> +        {TYPE_DYNAMIC_PROPS, "prop1", "101"},
> +        {TYPE_DYNAMIC_PROPS, "prop2", "102"},
> +        {}
> +    };
this list cloud be the same for static and dynamic tests, no need to duplicate

and perhaps one property is enough, like it's done for static one?


> +    qdev_prop_register_global_list(props);
> +
> +    mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
> +    qdev_init_nofail(DEVICE(mt));
> +
> +    g_assert_cmpuint(mt->prop1, ==, 101);
> +    g_assert_cmpuint(mt->prop2, ==, 102);
> +}
> +
>  int main(int argc, char **argv)
>  {
>      module_call_init(MODULE_INIT_QOM);
>      type_register_static(&static_prop_type);
> +    type_register_static(&dynamic_prop_type);
>  
>      g_test_init(&argc, &argv, NULL);
>  
>      g_test_add_func("/qdev/properties/static/default", test_static_prop);
>      g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
> +    g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop);
>  
>      g_test_run();
>  

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [RFC 2/3 v2] qom: introduce post_init() function
  2013-07-11  6:29       ` Igor Mammedov
@ 2013-07-12  0:29         ` Eduardo Habkost
  0 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2013-07-12  0:29 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Andreas Färber

On Thu, Jul 11, 2013 at 08:29:15AM +0200, Igor Mammedov wrote:
> On Wed, 10 Jul 2013 17:08:41 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > This will allow classes to specify a function to be called after all
> > instance_init() functions were called.
> > 
> > This will be used by DeviceState to call qdev_prop_set_globals() at the
> > right moment.
> > 
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  include/qom/object.h |  3 +++
> >  qom/object.c         | 14 ++++++++++++++
> >  2 files changed, 17 insertions(+)
> > 
> > diff --git a/include/qom/object.h b/include/qom/object.h
> > index 23fc048..1a54f64 100644
> > --- a/include/qom/object.h
> > +++ b/include/qom/object.h
> > @@ -398,6 +398,8 @@ struct Object
> >   * @instance_init: This function is called to initialize an object.  The parent
> >   *   class will have already been initialized so the type is only responsible
> >   *   for initializing its own members.
> > + * @instance_post_init: This function is called to finish initialization of
> > + *   an object, after all instance_init functions were called.
> >   * @instance_finalize: This function is called during object destruction.  This
> >   *   is called before the parent @instance_finalize function has been called.
> >   *   An object should only free the members that are unique to its type in this
> > @@ -433,6 +435,7 @@ struct TypeInfo
> [...]
> >  
> > +static void object_post_init_with_type(Object *obj, TypeImpl *ti)
> > +{
> > +    if (ti->instance_post_init) {
> > +        ti->instance_post_init(obj);
> > +    }
> > +
> > +    if (type_has_parent(ti)) {
> > +        object_post_init_with_type(obj, type_get_parent(ti));
> > +    }
> Is there  a reason why post init called in opposite order than
> instance_init() ?

Because it seems more useful: if parent types want to initialize
something before subclasses, they can use instance_init(). If they want
to initialize something _after_ subclasses, then they can use
instance_post_init().

> 
> > +}
> > +
> >  void object_initialize_with_type(void *data, TypeImpl *type)
> >  {
> >      Object *obj = data;
> > @@ -313,6 +326,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
> >      object_ref(obj);
> >      QTAILQ_INIT(&obj->properties);
> >      object_init_with_type(obj, type);
> > +    object_post_init_with_type(obj, type);
> >  }
> >  
> >  void object_initialize(void *data, const char *typename)
> 

-- 
Eduardo

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [RFC 3/3 v2] qdev: set globals on post_init() function
  2013-07-11  6:48       ` Igor Mammedov
@ 2013-07-12 14:57         ` Eduardo Habkost
  0 siblings, 0 replies; 17+ messages in thread
From: Eduardo Habkost @ 2013-07-12 14:57 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Andreas Färber

On Thu, Jul 11, 2013 at 08:48:44AM +0200, Igor Mammedov wrote:
[...]
> >  #define TYPE_STATIC_PROPS "static_prop_type"
> > @@ -80,7 +82,7 @@ static void test_static_prop(void)
> >  static void test_static_globalprop(void)
> >  {
> >      MyType *mt;
> > -    GlobalProperty props[] = {
> > +    static GlobalProperty props[] = {
> >          {TYPE_STATIC_PROPS, "prop1", "200"},
> >          {}
> >      };
> hunk belongs to the 1st patch?

Yes, thanks for noticing.


> 
> > @@ -93,15 +95,82 @@ static void test_static_globalprop(void)
> >      g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
> >  }
> >  
> > +#define TYPE_DYNAMIC_PROPS "dynamic_prop_type"
> > +#define DYNAMIC_TYPE(obj) \
> > +     OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
> > +
> > +static void prop1_acessor(Object *obj,
> > +                          struct Visitor *v,
> > +                          void *opaque,
> > +                          const char *name,
> > +                          struct Error **errp)
> > +{
> > +    MyType *mt = DYNAMIC_TYPE(obj);
> > +    visit_type_uint32(v, &mt->prop1, name, errp);
> > +}
> > +
> > +static void prop2_acessor(Object *obj,
> > +                          struct Visitor *v,
> > +                          void *opaque,
> > +                          const char *name,
> > +                          struct Error **errp)
> > +{
> > +    MyType *mt = DYNAMIC_TYPE(obj);
> > +    visit_type_uint32(v, &mt->prop2, name, errp);
> > +}
> > +
> > +static void dynamic_instance_init(Object *obj)
> > +{
> > +    object_property_add(obj, "prop1", "uint32", prop1_acessor, prop1_acessor,
> > +                        NULL, NULL, NULL);
> > +    object_property_add(obj, "prop2", "uint32", prop2_acessor, prop2_acessor,
> > +                        NULL, NULL, NULL);
> > +}
> > +
> > +static void dynamic_class_init(ObjectClass *klass, void *data)
> > +{
> > +    DeviceClass *dc = DEVICE_CLASS(klass);
> > +    dc->init = mytype_init;
> > +}
> > +
> > +
> > +static TypeInfo dynamic_prop_type = {
> > +    .name = TYPE_DYNAMIC_PROPS,
> > +    .parent = TYPE_DEVICE,
> > +    .instance_size = sizeof(MyType),
> > +    .instance_init = dynamic_instance_init,
> > +    .class_init = dynamic_class_init,
> > +};
> > +
> > +/* Test setting of static property using global properties */
> > +static void test_dynamic_globalprop(void)
> > +{
> > +    MyType *mt;
> > +    static GlobalProperty props[] = {
> > +        {TYPE_DYNAMIC_PROPS, "prop1", "101"},
> > +        {TYPE_DYNAMIC_PROPS, "prop2", "102"},
> > +        {}
> > +    };
> this list cloud be the same for static and dynamic tests, no need to duplicate
> 
> and perhaps one property is enough, like it's done for static one?

I don't know. I like the fact that both test cases are exercising the
property-setting API in different ways and are likely to catch different
types of bugs.


> 
> 
> > +    qdev_prop_register_global_list(props);
> > +
> > +    mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
> > +    qdev_init_nofail(DEVICE(mt));
> > +
> > +    g_assert_cmpuint(mt->prop1, ==, 101);
> > +    g_assert_cmpuint(mt->prop2, ==, 102);
> > +}
> > +
> >  int main(int argc, char **argv)
> >  {
> >      module_call_init(MODULE_INIT_QOM);
> >      type_register_static(&static_prop_type);
> > +    type_register_static(&dynamic_prop_type);
> >  
> >      g_test_init(&argc, &argv, NULL);
> >  
> >      g_test_add_func("/qdev/properties/static/default", test_static_prop);
> >      g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
> > +    g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop);
> >  
> >      g_test_run();
> >  
> 

-- 
Eduardo

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [RFC 0/3 v2] qdev: handle global properties after all instance_init calls
  2013-07-10 20:08   ` [Qemu-devel] [RFC 0/3 v2] " Eduardo Habkost
                       ` (2 preceding siblings ...)
  2013-07-10 20:08     ` [Qemu-devel] [RFC 3/3 v2] qdev: set globals on " Eduardo Habkost
@ 2013-07-28 19:44     ` Andreas Färber
  3 siblings, 0 replies; 17+ messages in thread
From: Andreas Färber @ 2013-07-28 19:44 UTC (permalink / raw)
  To: Eduardo Habkost; +Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Igor Mammedov

Am 10.07.2013 22:08, schrieb Eduardo Habkost:
> Updated version of the series sent in October 2012.
> 
> References:
>   http://article.gmane.org/gmane.comp.emulators.qemu/173753
>     (old discussion)
>   http://article.gmane.org/gmane.comp.emulators.qemu/173782
>     (previous version of this series)
>   http://article.gmane.org/gmane.comp.emulators.kvm.devel/112380
>     (Minutes of last call where this was discussed)
> 
> Eduardo Habkost (3):
>   tests: unit tests for qdev global-properties handling
>   qom: introduce post_init() function
>   qdev: set globals on post_init() function

Thanks, I have applied these with some style, spelling and build fixes
to qom-cpu-next:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu-next

Since Igor and me have agreed to continue work on x86 properties on
qom-cpu-next during Hard Freeze, I do not see a need to merge these
patches Last Minute through qom-next for 1.6. If I'm missing some use
case other than x86 subclasses, please let me know.

Regards,
Andreas

>  hw/core/qdev.c                 |  10 ++-
>  include/qom/object.h           |   3 +
>  qom/object.c                   |  14 ++++
>  tests/.gitignore               |   1 +
>  tests/Makefile                 |   7 ++
>  tests/test-qdev-global-props.c | 178 +++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 212 insertions(+), 1 deletion(-)
>  create mode 100644 tests/test-qdev-global-props.c

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2013-07-28 19:44 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-03 17:48 [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Eduardo Habkost
2012-10-03 17:48 ` [Qemu-devel] [PATCH 1/6] qdev: split up header so it can be used in cpu.h Eduardo Habkost
2012-10-03 17:48 ` [Qemu-devel] [PATCH 2/6] qapi-types.h doesn't really need to include qemu-common.h Eduardo Habkost
2012-10-03 17:48 ` [Qemu-devel] [PATCH 3/6] qdev: separate core from the code used only by qemu-system-* Eduardo Habkost
2012-10-03 17:48 ` [Qemu-devel] [PATCH 4/6] tests: unit tests for qdev global-properties handling Eduardo Habkost
2012-10-03 17:48 ` [Qemu-devel] [PATCH 5/6] qom: introduce post_init() function Eduardo Habkost
2012-10-03 17:48 ` [Qemu-devel] [PATCH 6/6] qdev: set globals on " Eduardo Habkost
2013-07-09 14:32 ` [Qemu-devel] [PATCH 0/6] qdev: handle global properties after all instance_init calls Andreas Färber
2013-07-10 20:08   ` [Qemu-devel] [RFC 0/3 v2] " Eduardo Habkost
2013-07-10 20:08     ` [Qemu-devel] [RFC 1/3 v2] tests: unit tests for qdev global-properties handling Eduardo Habkost
2013-07-10 20:08     ` [Qemu-devel] [RFC 2/3 v2] qom: introduce post_init() function Eduardo Habkost
2013-07-11  6:29       ` Igor Mammedov
2013-07-12  0:29         ` Eduardo Habkost
2013-07-10 20:08     ` [Qemu-devel] [RFC 3/3 v2] qdev: set globals on " Eduardo Habkost
2013-07-11  6:48       ` Igor Mammedov
2013-07-12 14:57         ` Eduardo Habkost
2013-07-28 19:44     ` [Qemu-devel] [RFC 0/3 v2] qdev: handle global properties after all instance_init calls Andreas Färber

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.