qemu-devel.nongnu.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).