qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 10/12] qdev: use full qdev.h include path on qdev*.c
  2012-10-16  1:57 [Qemu-devel] [PATCH v3 00/12] make CPU child of DeviceState and include qdev core in *-user Igor Mammedov
@ 2012-10-16  1:57 ` Igor Mammedov
  0 siblings, 0 replies; 27+ messages in thread
From: Igor Mammedov @ 2012-10-16  1:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, aliguori, afaerber, ehabkost

From: Eduardo Habkost <ehabkost@redhat.com>

This way, the files can be moved to the qom/ directory as-is.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/qdev-core.c       | 2 +-
 hw/qdev-properties.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/qdev-core.c b/hw/qdev-core.c
index a756e07..fbb7cb5 100644
--- a/hw/qdev-core.c
+++ b/hw/qdev-core.c
@@ -25,7 +25,7 @@
    inherit from a particular bus (e.g. PCI or I2C) rather than
    this API directly.  */
 
-#include "qdev.h"
+#include "hw/qdev.h"
 #include "sysemu.h"
 #include "error.h"
 #include "qapi/qapi-visit-core.h"
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 917d986..2e82cb9 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1,5 +1,5 @@
 #include "net.h"
-#include "qdev.h"
+#include "hw/qdev.h"
 #include "qerror.h"
 #include "blockdev.h"
 #include "hw/block-common.h"
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user
@ 2012-10-16 19:08 Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 01/12] qdev: split up header so it can be used in cpu.h Eduardo Habkost
                   ` (11 more replies)
  0 siblings, 12 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

v2:
  This version removes the CONFIG_USER_ONLY ifdefs, and use weak symbols to move
  the vmstate and qemu_register_reset() handling to qdev-system.c
v3 (submitted by Igor):
  - rebased on top of 8b4a3df (today's master)
  - slight code reshuffling in (see commit's changelog)
     "qdev: separate core from the code used only by qemu-system-*"
     "move qemu_irq typedef out of cpu-common.h"
  - commit messages cleanup
v4:
  - Add GCC_WEAK_DECL to functions that have GCC_WEAK versions
  - Updated the qdev_init_gpio_in() code on qdev-system.c to current version
  - Patch description updates (moved changelog below "---" and/or move info
    about changes made by different authors between SoB lines)

git tree for testing:
  https://github.com/ehabkost/qemu-hacks/tree/cpu_qdev.v4

References to previous versions:
  v3: http://article.gmane.org/gmane.comp.emulators.qemu/175980
  v2: http://article.gmane.org/gmane.comp.emulators.qemu/173909
  v1: http://article.gmane.org/gmane.comp.emulators.qemu/166630

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

Eduardo Habkost (8):
  qdev: separate core from the code used only by qemu-system-*
  qdev: rename qdev.c to qdev-core.c
  qdev-core: isolate vmstate handling into separate functions
  qdev: move vmstate handling to qdev-system.c
  qdev-core: isolate reset register/unregister code
  qdev: move reset register/unregister code to qdev-system.c
  qdev: use full qdev.h include path on qdev*.c
  include core qdev code into *-user, too

Igor Mammedov (3):
  qapi-types.h doesn't really need to include qemu-common.h
  move qemu_irq typedef out of cpu-common.h
  qom: make CPU a child of DeviceState

 Makefile.objs               |    3 +
 hw/Makefile.objs            |    3 +-
 hw/arm-misc.h               |    1 +
 hw/bt.h                     |    2 +
 hw/devices.h                |    2 +
 hw/irq.h                    |    2 +
 hw/mc146818rtc.c            |    1 +
 hw/omap.h                   |    1 +
 hw/qdev-addr.c              |    1 +
 hw/qdev-core.h              |  243 ++++++++
 hw/qdev-monitor.h           |   16 +
 hw/qdev-properties-system.c |  340 ++++++++++++
 hw/qdev-properties.c        | 1280 -------------------------------------------
 hw/qdev-properties.h        |  131 +++++
 hw/qdev-system.c            |  105 ++++
 hw/qdev.c                   |  795 ---------------------------
 hw/qdev.h                   |  370 +------------
 hw/soc_dma.h                |    1 +
 hw/xen.h                    |    1 +
 include/qemu/cpu.h          |    6 +-
 qemu-common.h               |    1 -
 qom/Makefile.objs           |    2 +-
 qom/cpu.c                   |    3 +-
 qom/qdev-core.c             |  727 ++++++++++++++++++++++++
 qom/qdev-properties.c       |  963 ++++++++++++++++++++++++++++++++
 scripts/qapi-types.py       |    3 +-
 26 files changed, 2554 insertions(+), 2449 deletions(-)
 create mode 100644 hw/qdev-core.h
 create mode 100644 hw/qdev-monitor.h
 create mode 100644 hw/qdev-properties-system.c
 delete mode 100644 hw/qdev-properties.c
 create mode 100644 hw/qdev-properties.h
 create mode 100644 hw/qdev-system.c
 delete mode 100644 hw/qdev.c
 create mode 100644 qom/qdev-core.c
 create mode 100644 qom/qdev-properties.c

-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 01/12] qdev: split up header so it can be used in cpu.h
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 02/12] qapi-types.h doesn't really need to include qemu-common.h Eduardo Habkost
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

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

hw/qdev.h is split into following new headers:
    hw/qdev-core.h
    hw/qdev-properties.h
    hw/qdev-monitor.h

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

[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]
[ehabkost: moved get_fw_dev_path() comment to the original location
 (I don't know why it was moved)]
[ehabkost: removed qdev_exists() declaration]
[ehabkost: keep using 'QemuOpts' instead of 'struct QemuOpts', as
 qdev-core.h includes qemu-option.h]

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Yes, there is "changelog" data before the "---" mark, but I believe that
in this case they are important to indicate authorship and the scope of
the Signed-off-by lines (so they need to get into the git commit
message)

Detailed changelog:

Changes v1 (from Anthony) -> v2 (from Eduardo):
 - re-add DEFINE_PROP_PCI_HOST_DEVADDR, that was removed on the original
   patch (by mistake, I guess)
 - kill qdev_prop_set_vlan() declaration

Changes v2 -> v3 (from Eduardo):
 - moved get_fw_dev_path() comment to the original location (I don't
   know why it was moved)
 - removed qdev_exists() declaration
 - keep using 'QemuOpts' instead of 'struct QemuOpts', as qdev-core.h
   includes qemu-option.h

Changes v3 -> v4 (from Eduardo):
 - Edited commit message to include additional information
---
 hw/irq.h             |   2 +
 hw/mc146818rtc.c     |   1 +
 hw/qdev-addr.c       |   1 +
 hw/qdev-core.h       | 238 +++++++++++++++++++++++++++++++++
 hw/qdev-monitor.h    |  16 +++
 hw/qdev-properties.c |   1 +
 hw/qdev-properties.h | 130 ++++++++++++++++++
 hw/qdev.c            |   1 +
 hw/qdev.h            | 370 +--------------------------------------------------
 9 files changed, 394 insertions(+), 366 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 e640c10..610e6b7 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 332a77d..4bf8808 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..fce9e22
--- /dev/null
+++ b/hw/qdev-core.h
@@ -0,0 +1,238 @@
+#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;
+    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);
+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 9b9aba3..7ddcd24 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 c6ac636..365b8d6 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -1,371 +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);
-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.7

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

* [Qemu-devel] [PATCH 02/12] qapi-types.h doesn't really need to include qemu-common.h
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 01/12] qdev: split up header so it can be used in cpu.h Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 03/12] qdev: separate core from the code used only by qemu-system-* Eduardo Habkost
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

From: Igor Mammedov <imammedo@redhat.com>

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

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
[ehabkost: include <stdbool.h> too]
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Yes, there is "changelog" data before the "---" mark, but I believe that
in this case they are important to indicate authorship and the scope of
the Signed-off-by lines (so they need to get into the git commit
message).
---
 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 1b84834..6bc2391 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.7

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

* [Qemu-devel] [PATCH 03/12] qdev: separate core from the code used only by qemu-system-*
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 01/12] qdev: split up header so it can be used in cpu.h Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 02/12] qapi-types.h doesn't really need to include qemu-common.h Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 04/12] qdev: rename qdev.c to qdev-core.c Eduardo Habkost
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

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 be handled later, by moving that code to
qdev-system.c but keeping weak symbols for *-user.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
[imammedo: keep qdev_get_child_bus() in hw/qdev.c]
[imammedo: put qdev_set_nic_properties() in hw/qdev-properties-system.c]
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
[ehabkost: updated the qdev_init_gpio_in() code on qdev-system.c to current
 version]
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Yes, there is "changelog" data before the "---" mark, but I believe that
in this case they are important to indicate authorship and the scope of
the Signed-off-by lines (so they need to get into the git commit
message).
---
 hw/Makefile.objs            |   1 +
 hw/qdev-properties-system.c | 340 ++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev-properties.c        | 320 +----------------------------------------
 hw/qdev-properties.h        |   1 +
 hw/qdev-system.c            |  68 +++++++++
 hw/qdev.c                   |  80 -----------
 6 files changed, 411 insertions(+), 399 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 854faa9..16f23c0 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -181,6 +181,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..e3a21db
--- /dev/null
+++ b/hw/qdev-properties-system.c
@@ -0,0 +1,340 @@
+#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,
+};
+
+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;
+}
+
+/* --- 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..93feaee
--- /dev/null
+++ b/hw/qdev-system.c
@@ -0,0 +1,68 @@
+#include "qdev.h"
+
+void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
+{
+    dev->gpio_in = qemu_extend_irqs(dev->gpio_in, dev->num_gpio_in, handler,
+                                        dev, n);
+    dev->num_gpio_in += 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;
+}
+
+/* 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 7ddcd24..ee19dd5 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"
@@ -99,47 +98,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.
@@ -284,44 +242,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)
-{
-    dev->gpio_in = qemu_extend_irqs(dev->gpio_in, dev->num_gpio_in, handler,
-                                        dev, n);
-    dev->num_gpio_in += 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;
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 04/12] qdev: rename qdev.c to qdev-core.c
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (2 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 03/12] qdev: separate core from the code used only by qemu-system-* Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 05/12] qdev-core: isolate vmstate handling into separate functions Eduardo Habkost
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

Just to make clear that it's the qdev core code, corresponding to
qdev-core.h.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/Makefile.objs |   2 +-
 hw/qdev-core.c   | 716 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.c        | 716 -------------------------------------------------------
 3 files changed, 717 insertions(+), 717 deletions(-)
 create mode 100644 hw/qdev-core.c
 delete mode 100644 hw/qdev.c

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 16f23c0..70f2014 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -180,7 +180,7 @@ common-obj-$(CONFIG_SD) += sd.o
 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-core.o qdev-properties.o qdev-monitor.o
 common-obj-y += qdev-system.o qdev-properties-system.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
 
diff --git a/hw/qdev-core.c b/hw/qdev-core.c
new file mode 100644
index 0000000..ee19dd5
--- /dev/null
+++ b/hw/qdev-core.c
@@ -0,0 +1,716 @@
+/*
+ *  Dynamic device configuration and creation.
+ *
+ *  Copyright (c) 2009 CodeSourcery
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The theory here is that it should be possible to create a machine without
+   knowledge of specific devices.  Historically board init routines have
+   passed a bunch of arguments to each device, requiring the board know
+   exactly which device it is dealing with.  This file provides an abstract
+   API for device configuration and initialization.  Devices will generally
+   inherit from a particular bus (e.g. PCI or I2C) rather than
+   this API directly.  */
+
+#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;
+static bool qdev_hot_removed = false;
+
+const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    return dc->vmsd;
+}
+
+const char *qdev_fw_name(DeviceState *dev)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (dc->fw_name) {
+        return dc->fw_name;
+    }
+
+    return object_get_typename(OBJECT(dev));
+}
+
+static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+                                     Error **errp);
+
+static void bus_remove_child(BusState *bus, DeviceState *child)
+{
+    BusChild *kid;
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        if (kid->child == child) {
+            char name[32];
+
+            snprintf(name, sizeof(name), "child[%d]", kid->index);
+            QTAILQ_REMOVE(&bus->children, kid, sibling);
+            object_property_del(OBJECT(bus), name, NULL);
+            g_free(kid);
+            return;
+        }
+    }
+}
+
+static void bus_add_child(BusState *bus, DeviceState *child)
+{
+    char name[32];
+    BusChild *kid = g_malloc0(sizeof(*kid));
+
+    if (qdev_hotplug) {
+        assert(bus->allow_hotplug);
+    }
+
+    kid->index = bus->max_index++;
+    kid->child = child;
+
+    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
+
+    snprintf(name, sizeof(name), "child[%d]", kid->index);
+    object_property_add_link(OBJECT(bus), name,
+                             object_get_typename(OBJECT(child)),
+                             (Object **)&kid->child,
+                             NULL);
+}
+
+void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+{
+    dev->parent_bus = bus;
+    bus_add_child(bus, 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.
+   On failure, destroy the device and return negative value.
+   Return 0 on success.  */
+int qdev_init(DeviceState *dev)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    int rc;
+
+    assert(dev->state == DEV_STATE_CREATED);
+
+    rc = dc->init(dev);
+    if (rc < 0) {
+        qdev_free(dev);
+        return rc;
+    }
+
+    if (!OBJECT(dev)->parent) {
+        static int unattached_count = 0;
+        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
+
+        object_property_add_child(container_get(qdev_get_machine(),
+                                                "/unattached"),
+                                  name, OBJECT(dev), NULL);
+        g_free(name);
+    }
+
+    if (qdev_get_vmsd(dev)) {
+        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
+                                       dev->instance_id_alias,
+                                       dev->alias_required_for_version);
+    }
+    dev->state = DEV_STATE_INITIALIZED;
+    if (dev->hotplugged) {
+        device_reset(dev);
+    }
+    return 0;
+}
+
+void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
+                                 int required_for_version)
+{
+    assert(dev->state == DEV_STATE_CREATED);
+    dev->instance_id_alias = alias_id;
+    dev->alias_required_for_version = required_for_version;
+}
+
+void qdev_unplug(DeviceState *dev, Error **errp)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (!dev->parent_bus->allow_hotplug) {
+        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
+        return;
+    }
+    assert(dc->unplug != NULL);
+
+    qdev_hot_removed = true;
+
+    if (dc->unplug(dev) < 0) {
+        error_set(errp, QERR_UNDEFINED_ERROR);
+        return;
+    }
+}
+
+static int qdev_reset_one(DeviceState *dev, void *opaque)
+{
+    device_reset(dev);
+
+    return 0;
+}
+
+static int qbus_reset_one(BusState *bus, void *opaque)
+{
+    BusClass *bc = BUS_GET_CLASS(bus);
+    if (bc->reset) {
+        return bc->reset(bus);
+    }
+    return 0;
+}
+
+void qdev_reset_all(DeviceState *dev)
+{
+    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
+}
+
+void qbus_reset_all_fn(void *opaque)
+{
+    BusState *bus = opaque;
+    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
+}
+
+/* can be used as ->unplug() callback for the simple cases */
+int qdev_simple_unplug_cb(DeviceState *dev)
+{
+    /* just zap it */
+    qdev_free(dev);
+    return 0;
+}
+
+
+/* Like qdev_init(), but terminate program via error_report() instead of
+   returning an error value.  This is okay during machine creation.
+   Don't use for hotplug, because there callers need to recover from
+   failure.  Exception: if you know the device's init() callback can't
+   fail, then qdev_init_nofail() can't fail either, and is therefore
+   usable even then.  But relying on the device implementation that
+   way is somewhat unclean, and best avoided.  */
+void qdev_init_nofail(DeviceState *dev)
+{
+    const char *typename = object_get_typename(OBJECT(dev));
+
+    if (qdev_init(dev) < 0) {
+        error_report("Initialization of device %s failed", typename);
+        exit(1);
+    }
+}
+
+/* Unlink device from bus and free the structure.  */
+void qdev_free(DeviceState *dev)
+{
+    object_delete(OBJECT(dev));
+}
+
+void qdev_machine_creation_done(void)
+{
+    /*
+     * ok, initial machine setup is done, starting from now we can
+     * only create hotpluggable devices
+     */
+    qdev_hotplug = 1;
+}
+
+bool qdev_machine_modified(void)
+{
+    return qdev_hot_added || qdev_hot_removed;
+}
+
+BusState *qdev_get_parent_bus(DeviceState *dev)
+{
+    return dev->parent_bus;
+}
+
+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)
+{
+    BusChild *kid;
+    int err;
+
+    if (busfn) {
+        err = busfn(bus, opaque);
+        if (err) {
+            return err;
+        }
+    }
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
+        if (err < 0) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
+                       qbus_walkerfn *busfn, void *opaque)
+{
+    BusState *bus;
+    int err;
+
+    if (devfn) {
+        err = devfn(dev, opaque);
+        if (err) {
+            return err;
+        }
+    }
+
+    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+        err = qbus_walk_children(bus, devfn, busfn, opaque);
+        if (err < 0) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+DeviceState *qdev_find_recursive(BusState *bus, const char *id)
+{
+    BusChild *kid;
+    DeviceState *ret;
+    BusState *child;
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
+
+        if (dev->id && strcmp(dev->id, id) == 0) {
+            return dev;
+        }
+
+        QLIST_FOREACH(child, &dev->child_bus, sibling) {
+            ret = qdev_find_recursive(child, id);
+            if (ret) {
+                return ret;
+            }
+        }
+    }
+    return NULL;
+}
+
+static void qbus_realize(BusState *bus)
+{
+    const char *typename = object_get_typename(OBJECT(bus));
+    char *buf;
+    int i,len;
+
+    if (bus->name) {
+        /* use supplied name */
+    } else if (bus->parent && bus->parent->id) {
+        /* parent device has id -> use it for bus name */
+        len = strlen(bus->parent->id) + 16;
+        buf = g_malloc(len);
+        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
+        bus->name = buf;
+    } else {
+        /* no id -> use lowercase bus type for bus name */
+        len = strlen(typename) + 16;
+        buf = g_malloc(len);
+        len = snprintf(buf, len, "%s.%d", typename,
+                       bus->parent ? bus->parent->num_child_bus : 0);
+        for (i = 0; i < len; i++)
+            buf[i] = qemu_tolower(buf[i]);
+        bus->name = buf;
+    }
+
+    if (bus->parent) {
+        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
+        bus->parent->num_child_bus++;
+        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
+    } else if (bus != sysbus_get_default()) {
+        /* TODO: once all bus devices are qdevified,
+           only reset handler for main_system_bus should be registered here. */
+        qemu_register_reset(qbus_reset_all_fn, bus);
+    }
+}
+
+void qbus_create_inplace(BusState *bus, const char *typename,
+                         DeviceState *parent, const char *name)
+{
+    object_initialize(bus, typename);
+
+    bus->parent = parent;
+    bus->name = name ? g_strdup(name) : NULL;
+    qbus_realize(bus);
+}
+
+BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
+{
+    BusState *bus;
+
+    bus = BUS(object_new(typename));
+    bus->qom_allocated = true;
+
+    bus->parent = parent;
+    bus->name = name ? g_strdup(name) : NULL;
+    qbus_realize(bus);
+
+    return bus;
+}
+
+void qbus_free(BusState *bus)
+{
+    if (bus->qom_allocated) {
+        object_delete(OBJECT(bus));
+    } else {
+        object_finalize(OBJECT(bus));
+        if (bus->glib_allocated) {
+            g_free(bus);
+        }
+    }
+}
+
+static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
+{
+    BusClass *bc = BUS_GET_CLASS(bus);
+
+    if (bc->get_fw_dev_path) {
+        return bc->get_fw_dev_path(dev);
+    }
+
+    return NULL;
+}
+
+static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
+{
+    int l = 0;
+
+    if (dev && dev->parent_bus) {
+        char *d;
+        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
+        d = bus_get_fw_dev_path(dev->parent_bus, dev);
+        if (d) {
+            l += snprintf(p + l, size - l, "%s", d);
+            g_free(d);
+        } else {
+            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
+        }
+    }
+    l += snprintf(p + l , size - l, "/");
+
+    return l;
+}
+
+char* qdev_get_fw_dev_path(DeviceState *dev)
+{
+    char path[128];
+    int l;
+
+    l = qdev_get_fw_dev_path_helper(dev, path, 128);
+
+    path[l-1] = '\0';
+
+    return g_strdup(path);
+}
+
+char *qdev_get_dev_path(DeviceState *dev)
+{
+    BusClass *bc;
+
+    if (!dev || !dev->parent_bus) {
+        return NULL;
+    }
+
+    bc = BUS_GET_CLASS(dev->parent_bus);
+    if (bc->get_dev_path) {
+        return bc->get_dev_path(dev);
+    }
+
+    return NULL;
+}
+
+/**
+ * Legacy property handling
+ */
+
+static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+
+    char buffer[1024];
+    char *ptr = buffer;
+
+    prop->info->print(dev, prop, buffer, sizeof(buffer));
+    visit_type_str(v, &ptr, name, errp);
+}
+
+static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    char *ptr = NULL;
+    int ret;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_str(v, &ptr, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    ret = prop->info->parse(dev, prop, ptr);
+    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
+    g_free(ptr);
+}
+
+/**
+ * @qdev_add_legacy_property - adds a legacy property
+ *
+ * Do not use this is new code!  Properties added through this interface will
+ * be given names and types in the "legacy" namespace.
+ *
+ * Legacy properties are string versions of other OOM properties.  The format
+ * of the string depends on the property type.
+ */
+void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+                              Error **errp)
+{
+    gchar *name, *type;
+
+    /* Register pointer properties as legacy properties */
+    if (!prop->info->print && !prop->info->parse &&
+        (prop->info->set || prop->info->get)) {
+        return;
+    }
+
+    name = g_strdup_printf("legacy-%s", prop->name);
+    type = g_strdup_printf("legacy<%s>",
+                           prop->info->legacy_name ?: prop->info->name);
+
+    object_property_add(OBJECT(dev), name, type,
+                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
+                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
+                        NULL,
+                        prop, errp);
+
+    g_free(type);
+    g_free(name);
+}
+
+/**
+ * @qdev_property_add_static - add a @Property to a device.
+ *
+ * Static properties access data in a struct.  The actual type of the
+ * property and the field depends on the property type.
+ */
+void qdev_property_add_static(DeviceState *dev, Property *prop,
+                              Error **errp)
+{
+    Error *local_err = NULL;
+    Object *obj = OBJECT(dev);
+
+    /*
+     * TODO qdev_prop_ptr does not have getters or setters.  It must
+     * go now that it can be replaced with links.  The test should be
+     * removed along with it: all static properties are read/write.
+     */
+    if (!prop->info->get && !prop->info->set) {
+        return;
+    }
+
+    object_property_add(obj, prop->name, prop->info->name,
+                        prop->info->get, prop->info->set,
+                        prop->info->release,
+                        prop, &local_err);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (prop->qtype == QTYPE_NONE) {
+        return;
+    }
+
+    if (prop->qtype == QTYPE_QBOOL) {
+        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
+    } else if (prop->info->enum_table) {
+        object_property_set_str(obj, prop->info->enum_table[prop->defval],
+                                prop->name, &local_err);
+    } else if (prop->qtype == QTYPE_QINT) {
+        object_property_set_int(obj, prop->defval, prop->name, &local_err);
+    }
+    assert_no_error(local_err);
+}
+
+static void device_initfn(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    ObjectClass *class;
+    Property *prop;
+
+    if (qdev_hotplug) {
+        dev->hotplugged = 1;
+        qdev_hot_added = true;
+    }
+
+    dev->instance_id_alias = -1;
+    dev->state = DEV_STATE_CREATED;
+
+    class = object_get_class(OBJECT(dev));
+    do {
+        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
+            qdev_property_add_legacy(dev, prop, NULL);
+            qdev_property_add_static(dev, prop, NULL);
+        }
+        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);
+}
+
+/* Unlink device from bus and free the structure.  */
+static void device_finalize(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    BusState *bus;
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (dev->state == DEV_STATE_INITIALIZED) {
+        while (dev->num_child_bus) {
+            bus = QLIST_FIRST(&dev->child_bus);
+            qbus_free(bus);
+        }
+        if (qdev_get_vmsd(dev)) {
+            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
+        }
+        if (dc->exit) {
+            dc->exit(dev);
+        }
+        if (dev->opts) {
+            qemu_opts_del(dev->opts);
+        }
+    }
+    if (dev->parent_bus) {
+        bus_remove_child(dev->parent_bus, dev);
+    }
+}
+
+static void device_class_base_init(ObjectClass *class, void *data)
+{
+    DeviceClass *klass = DEVICE_CLASS(class);
+
+    /* We explicitly look up properties in the superclasses,
+     * so do not propagate them to the subclasses.
+     */
+    klass->props = NULL;
+}
+
+void device_reset(DeviceState *dev)
+{
+    DeviceClass *klass = DEVICE_GET_CLASS(dev);
+
+    if (klass->reset) {
+        klass->reset(dev);
+    }
+}
+
+Object *qdev_get_machine(void)
+{
+    static Object *dev;
+
+    if (dev == NULL) {
+        dev = container_get(object_get_root(), "/machine");
+    }
+
+    return dev;
+}
+
+static TypeInfo device_type_info = {
+    .name = TYPE_DEVICE,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(DeviceState),
+    .instance_init = device_initfn,
+    .instance_finalize = device_finalize,
+    .class_base_init = device_class_base_init,
+    .abstract = true,
+    .class_size = sizeof(DeviceClass),
+};
+
+static void qbus_initfn(Object *obj)
+{
+    BusState *bus = BUS(obj);
+
+    QTAILQ_INIT(&bus->children);
+}
+
+static void qbus_finalize(Object *obj)
+{
+    BusState *bus = BUS(obj);
+    BusChild *kid;
+
+    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
+        DeviceState *dev = kid->child;
+        qdev_free(dev);
+    }
+    if (bus->parent) {
+        QLIST_REMOVE(bus, sibling);
+        bus->parent->num_child_bus--;
+    } else {
+        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
+        qemu_unregister_reset(qbus_reset_all_fn, bus);
+    }
+    g_free((char *)bus->name);
+}
+
+static const TypeInfo bus_info = {
+    .name = TYPE_BUS,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(BusState),
+    .abstract = true,
+    .class_size = sizeof(BusClass),
+    .instance_init = qbus_initfn,
+    .instance_finalize = qbus_finalize,
+};
+
+static void qdev_register_types(void)
+{
+    type_register_static(&bus_info);
+    type_register_static(&device_type_info);
+}
+
+type_init(qdev_register_types)
diff --git a/hw/qdev.c b/hw/qdev.c
deleted file mode 100644
index ee19dd5..0000000
--- a/hw/qdev.c
+++ /dev/null
@@ -1,716 +0,0 @@
-/*
- *  Dynamic device configuration and creation.
- *
- *  Copyright (c) 2009 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* The theory here is that it should be possible to create a machine without
-   knowledge of specific devices.  Historically board init routines have
-   passed a bunch of arguments to each device, requiring the board know
-   exactly which device it is dealing with.  This file provides an abstract
-   API for device configuration and initialization.  Devices will generally
-   inherit from a particular bus (e.g. PCI or I2C) rather than
-   this API directly.  */
-
-#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;
-static bool qdev_hot_removed = false;
-
-const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-    return dc->vmsd;
-}
-
-const char *qdev_fw_name(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-    if (dc->fw_name) {
-        return dc->fw_name;
-    }
-
-    return object_get_typename(OBJECT(dev));
-}
-
-static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
-                                     Error **errp);
-
-static void bus_remove_child(BusState *bus, DeviceState *child)
-{
-    BusChild *kid;
-
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        if (kid->child == child) {
-            char name[32];
-
-            snprintf(name, sizeof(name), "child[%d]", kid->index);
-            QTAILQ_REMOVE(&bus->children, kid, sibling);
-            object_property_del(OBJECT(bus), name, NULL);
-            g_free(kid);
-            return;
-        }
-    }
-}
-
-static void bus_add_child(BusState *bus, DeviceState *child)
-{
-    char name[32];
-    BusChild *kid = g_malloc0(sizeof(*kid));
-
-    if (qdev_hotplug) {
-        assert(bus->allow_hotplug);
-    }
-
-    kid->index = bus->max_index++;
-    kid->child = child;
-
-    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
-
-    snprintf(name, sizeof(name), "child[%d]", kid->index);
-    object_property_add_link(OBJECT(bus), name,
-                             object_get_typename(OBJECT(child)),
-                             (Object **)&kid->child,
-                             NULL);
-}
-
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
-{
-    dev->parent_bus = bus;
-    bus_add_child(bus, 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.
-   On failure, destroy the device and return negative value.
-   Return 0 on success.  */
-int qdev_init(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-    int rc;
-
-    assert(dev->state == DEV_STATE_CREATED);
-
-    rc = dc->init(dev);
-    if (rc < 0) {
-        qdev_free(dev);
-        return rc;
-    }
-
-    if (!OBJECT(dev)->parent) {
-        static int unattached_count = 0;
-        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
-
-        object_property_add_child(container_get(qdev_get_machine(),
-                                                "/unattached"),
-                                  name, OBJECT(dev), NULL);
-        g_free(name);
-    }
-
-    if (qdev_get_vmsd(dev)) {
-        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
-                                       dev->instance_id_alias,
-                                       dev->alias_required_for_version);
-    }
-    dev->state = DEV_STATE_INITIALIZED;
-    if (dev->hotplugged) {
-        device_reset(dev);
-    }
-    return 0;
-}
-
-void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
-                                 int required_for_version)
-{
-    assert(dev->state == DEV_STATE_CREATED);
-    dev->instance_id_alias = alias_id;
-    dev->alias_required_for_version = required_for_version;
-}
-
-void qdev_unplug(DeviceState *dev, Error **errp)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-    if (!dev->parent_bus->allow_hotplug) {
-        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
-        return;
-    }
-    assert(dc->unplug != NULL);
-
-    qdev_hot_removed = true;
-
-    if (dc->unplug(dev) < 0) {
-        error_set(errp, QERR_UNDEFINED_ERROR);
-        return;
-    }
-}
-
-static int qdev_reset_one(DeviceState *dev, void *opaque)
-{
-    device_reset(dev);
-
-    return 0;
-}
-
-static int qbus_reset_one(BusState *bus, void *opaque)
-{
-    BusClass *bc = BUS_GET_CLASS(bus);
-    if (bc->reset) {
-        return bc->reset(bus);
-    }
-    return 0;
-}
-
-void qdev_reset_all(DeviceState *dev)
-{
-    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
-}
-
-void qbus_reset_all_fn(void *opaque)
-{
-    BusState *bus = opaque;
-    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
-}
-
-/* can be used as ->unplug() callback for the simple cases */
-int qdev_simple_unplug_cb(DeviceState *dev)
-{
-    /* just zap it */
-    qdev_free(dev);
-    return 0;
-}
-
-
-/* Like qdev_init(), but terminate program via error_report() instead of
-   returning an error value.  This is okay during machine creation.
-   Don't use for hotplug, because there callers need to recover from
-   failure.  Exception: if you know the device's init() callback can't
-   fail, then qdev_init_nofail() can't fail either, and is therefore
-   usable even then.  But relying on the device implementation that
-   way is somewhat unclean, and best avoided.  */
-void qdev_init_nofail(DeviceState *dev)
-{
-    const char *typename = object_get_typename(OBJECT(dev));
-
-    if (qdev_init(dev) < 0) {
-        error_report("Initialization of device %s failed", typename);
-        exit(1);
-    }
-}
-
-/* Unlink device from bus and free the structure.  */
-void qdev_free(DeviceState *dev)
-{
-    object_delete(OBJECT(dev));
-}
-
-void qdev_machine_creation_done(void)
-{
-    /*
-     * ok, initial machine setup is done, starting from now we can
-     * only create hotpluggable devices
-     */
-    qdev_hotplug = 1;
-}
-
-bool qdev_machine_modified(void)
-{
-    return qdev_hot_added || qdev_hot_removed;
-}
-
-BusState *qdev_get_parent_bus(DeviceState *dev)
-{
-    return dev->parent_bus;
-}
-
-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)
-{
-    BusChild *kid;
-    int err;
-
-    if (busfn) {
-        err = busfn(bus, opaque);
-        if (err) {
-            return err;
-        }
-    }
-
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
-        if (err < 0) {
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
-                       qbus_walkerfn *busfn, void *opaque)
-{
-    BusState *bus;
-    int err;
-
-    if (devfn) {
-        err = devfn(dev, opaque);
-        if (err) {
-            return err;
-        }
-    }
-
-    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
-        err = qbus_walk_children(bus, devfn, busfn, opaque);
-        if (err < 0) {
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-DeviceState *qdev_find_recursive(BusState *bus, const char *id)
-{
-    BusChild *kid;
-    DeviceState *ret;
-    BusState *child;
-
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        DeviceState *dev = kid->child;
-
-        if (dev->id && strcmp(dev->id, id) == 0) {
-            return dev;
-        }
-
-        QLIST_FOREACH(child, &dev->child_bus, sibling) {
-            ret = qdev_find_recursive(child, id);
-            if (ret) {
-                return ret;
-            }
-        }
-    }
-    return NULL;
-}
-
-static void qbus_realize(BusState *bus)
-{
-    const char *typename = object_get_typename(OBJECT(bus));
-    char *buf;
-    int i,len;
-
-    if (bus->name) {
-        /* use supplied name */
-    } else if (bus->parent && bus->parent->id) {
-        /* parent device has id -> use it for bus name */
-        len = strlen(bus->parent->id) + 16;
-        buf = g_malloc(len);
-        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
-        bus->name = buf;
-    } else {
-        /* no id -> use lowercase bus type for bus name */
-        len = strlen(typename) + 16;
-        buf = g_malloc(len);
-        len = snprintf(buf, len, "%s.%d", typename,
-                       bus->parent ? bus->parent->num_child_bus : 0);
-        for (i = 0; i < len; i++)
-            buf[i] = qemu_tolower(buf[i]);
-        bus->name = buf;
-    }
-
-    if (bus->parent) {
-        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
-        bus->parent->num_child_bus++;
-        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
-    } else if (bus != sysbus_get_default()) {
-        /* TODO: once all bus devices are qdevified,
-           only reset handler for main_system_bus should be registered here. */
-        qemu_register_reset(qbus_reset_all_fn, bus);
-    }
-}
-
-void qbus_create_inplace(BusState *bus, const char *typename,
-                         DeviceState *parent, const char *name)
-{
-    object_initialize(bus, typename);
-
-    bus->parent = parent;
-    bus->name = name ? g_strdup(name) : NULL;
-    qbus_realize(bus);
-}
-
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
-{
-    BusState *bus;
-
-    bus = BUS(object_new(typename));
-    bus->qom_allocated = true;
-
-    bus->parent = parent;
-    bus->name = name ? g_strdup(name) : NULL;
-    qbus_realize(bus);
-
-    return bus;
-}
-
-void qbus_free(BusState *bus)
-{
-    if (bus->qom_allocated) {
-        object_delete(OBJECT(bus));
-    } else {
-        object_finalize(OBJECT(bus));
-        if (bus->glib_allocated) {
-            g_free(bus);
-        }
-    }
-}
-
-static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
-{
-    BusClass *bc = BUS_GET_CLASS(bus);
-
-    if (bc->get_fw_dev_path) {
-        return bc->get_fw_dev_path(dev);
-    }
-
-    return NULL;
-}
-
-static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
-{
-    int l = 0;
-
-    if (dev && dev->parent_bus) {
-        char *d;
-        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
-        d = bus_get_fw_dev_path(dev->parent_bus, dev);
-        if (d) {
-            l += snprintf(p + l, size - l, "%s", d);
-            g_free(d);
-        } else {
-            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
-        }
-    }
-    l += snprintf(p + l , size - l, "/");
-
-    return l;
-}
-
-char* qdev_get_fw_dev_path(DeviceState *dev)
-{
-    char path[128];
-    int l;
-
-    l = qdev_get_fw_dev_path_helper(dev, path, 128);
-
-    path[l-1] = '\0';
-
-    return g_strdup(path);
-}
-
-char *qdev_get_dev_path(DeviceState *dev)
-{
-    BusClass *bc;
-
-    if (!dev || !dev->parent_bus) {
-        return NULL;
-    }
-
-    bc = BUS_GET_CLASS(dev->parent_bus);
-    if (bc->get_dev_path) {
-        return bc->get_dev_path(dev);
-    }
-
-    return NULL;
-}
-
-/**
- * Legacy property handling
- */
-
-static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
-                                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-
-    char buffer[1024];
-    char *ptr = buffer;
-
-    prop->info->print(dev, prop, buffer, sizeof(buffer));
-    visit_type_str(v, &ptr, name, errp);
-}
-
-static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
-                                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    Error *local_err = NULL;
-    char *ptr = NULL;
-    int ret;
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_str(v, &ptr, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    ret = prop->info->parse(dev, prop, ptr);
-    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
-    g_free(ptr);
-}
-
-/**
- * @qdev_add_legacy_property - adds a legacy property
- *
- * Do not use this is new code!  Properties added through this interface will
- * be given names and types in the "legacy" namespace.
- *
- * Legacy properties are string versions of other OOM properties.  The format
- * of the string depends on the property type.
- */
-void qdev_property_add_legacy(DeviceState *dev, Property *prop,
-                              Error **errp)
-{
-    gchar *name, *type;
-
-    /* Register pointer properties as legacy properties */
-    if (!prop->info->print && !prop->info->parse &&
-        (prop->info->set || prop->info->get)) {
-        return;
-    }
-
-    name = g_strdup_printf("legacy-%s", prop->name);
-    type = g_strdup_printf("legacy<%s>",
-                           prop->info->legacy_name ?: prop->info->name);
-
-    object_property_add(OBJECT(dev), name, type,
-                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
-                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
-                        NULL,
-                        prop, errp);
-
-    g_free(type);
-    g_free(name);
-}
-
-/**
- * @qdev_property_add_static - add a @Property to a device.
- *
- * Static properties access data in a struct.  The actual type of the
- * property and the field depends on the property type.
- */
-void qdev_property_add_static(DeviceState *dev, Property *prop,
-                              Error **errp)
-{
-    Error *local_err = NULL;
-    Object *obj = OBJECT(dev);
-
-    /*
-     * TODO qdev_prop_ptr does not have getters or setters.  It must
-     * go now that it can be replaced with links.  The test should be
-     * removed along with it: all static properties are read/write.
-     */
-    if (!prop->info->get && !prop->info->set) {
-        return;
-    }
-
-    object_property_add(obj, prop->name, prop->info->name,
-                        prop->info->get, prop->info->set,
-                        prop->info->release,
-                        prop, &local_err);
-
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if (prop->qtype == QTYPE_NONE) {
-        return;
-    }
-
-    if (prop->qtype == QTYPE_QBOOL) {
-        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
-    } else if (prop->info->enum_table) {
-        object_property_set_str(obj, prop->info->enum_table[prop->defval],
-                                prop->name, &local_err);
-    } else if (prop->qtype == QTYPE_QINT) {
-        object_property_set_int(obj, prop->defval, prop->name, &local_err);
-    }
-    assert_no_error(local_err);
-}
-
-static void device_initfn(Object *obj)
-{
-    DeviceState *dev = DEVICE(obj);
-    ObjectClass *class;
-    Property *prop;
-
-    if (qdev_hotplug) {
-        dev->hotplugged = 1;
-        qdev_hot_added = true;
-    }
-
-    dev->instance_id_alias = -1;
-    dev->state = DEV_STATE_CREATED;
-
-    class = object_get_class(OBJECT(dev));
-    do {
-        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
-            qdev_property_add_legacy(dev, prop, NULL);
-            qdev_property_add_static(dev, prop, NULL);
-        }
-        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);
-}
-
-/* Unlink device from bus and free the structure.  */
-static void device_finalize(Object *obj)
-{
-    DeviceState *dev = DEVICE(obj);
-    BusState *bus;
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-    if (dev->state == DEV_STATE_INITIALIZED) {
-        while (dev->num_child_bus) {
-            bus = QLIST_FIRST(&dev->child_bus);
-            qbus_free(bus);
-        }
-        if (qdev_get_vmsd(dev)) {
-            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
-        }
-        if (dc->exit) {
-            dc->exit(dev);
-        }
-        if (dev->opts) {
-            qemu_opts_del(dev->opts);
-        }
-    }
-    if (dev->parent_bus) {
-        bus_remove_child(dev->parent_bus, dev);
-    }
-}
-
-static void device_class_base_init(ObjectClass *class, void *data)
-{
-    DeviceClass *klass = DEVICE_CLASS(class);
-
-    /* We explicitly look up properties in the superclasses,
-     * so do not propagate them to the subclasses.
-     */
-    klass->props = NULL;
-}
-
-void device_reset(DeviceState *dev)
-{
-    DeviceClass *klass = DEVICE_GET_CLASS(dev);
-
-    if (klass->reset) {
-        klass->reset(dev);
-    }
-}
-
-Object *qdev_get_machine(void)
-{
-    static Object *dev;
-
-    if (dev == NULL) {
-        dev = container_get(object_get_root(), "/machine");
-    }
-
-    return dev;
-}
-
-static TypeInfo device_type_info = {
-    .name = TYPE_DEVICE,
-    .parent = TYPE_OBJECT,
-    .instance_size = sizeof(DeviceState),
-    .instance_init = device_initfn,
-    .instance_finalize = device_finalize,
-    .class_base_init = device_class_base_init,
-    .abstract = true,
-    .class_size = sizeof(DeviceClass),
-};
-
-static void qbus_initfn(Object *obj)
-{
-    BusState *bus = BUS(obj);
-
-    QTAILQ_INIT(&bus->children);
-}
-
-static void qbus_finalize(Object *obj)
-{
-    BusState *bus = BUS(obj);
-    BusChild *kid;
-
-    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
-        DeviceState *dev = kid->child;
-        qdev_free(dev);
-    }
-    if (bus->parent) {
-        QLIST_REMOVE(bus, sibling);
-        bus->parent->num_child_bus--;
-    } else {
-        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
-        qemu_unregister_reset(qbus_reset_all_fn, bus);
-    }
-    g_free((char *)bus->name);
-}
-
-static const TypeInfo bus_info = {
-    .name = TYPE_BUS,
-    .parent = TYPE_OBJECT,
-    .instance_size = sizeof(BusState),
-    .abstract = true,
-    .class_size = sizeof(BusClass),
-    .instance_init = qbus_initfn,
-    .instance_finalize = qbus_finalize,
-};
-
-static void qdev_register_types(void)
-{
-    type_register_static(&bus_info);
-    type_register_static(&device_type_info);
-}
-
-type_init(qdev_register_types)
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 05/12] qdev-core: isolate vmstate handling into separate functions
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (3 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 04/12] qdev: rename qdev.c to qdev-core.c Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-17 18:06   ` Anthony Liguori
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 06/12] qdev: move vmstate handling to qdev-system.c Eduardo Habkost
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

Those functions will eventually be moved somewhere else, and won't get
included on *-user.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/qdev-core.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/hw/qdev-core.c b/hw/qdev-core.c
index ee19dd5..92c3021 100644
--- a/hw/qdev-core.c
+++ b/hw/qdev-core.c
@@ -40,6 +40,22 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
     return dc->vmsd;
 }
 
+static void qdev_init_vmstate(DeviceState *dev)
+{
+    if (qdev_get_vmsd(dev)) {
+        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
+                                       dev->instance_id_alias,
+                                       dev->alias_required_for_version);
+    }
+}
+
+static void qdev_finalize_vmstate(DeviceState *dev)
+{
+    if (qdev_get_vmsd(dev)) {
+        vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
+    }
+}
+
 const char *qdev_fw_name(DeviceState *dev)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
@@ -126,11 +142,7 @@ int qdev_init(DeviceState *dev)
         g_free(name);
     }
 
-    if (qdev_get_vmsd(dev)) {
-        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
-                                       dev->instance_id_alias,
-                                       dev->alias_required_for_version);
-    }
+    qdev_init_vmstate(dev);
     dev->state = DEV_STATE_INITIALIZED;
     if (dev->hotplugged) {
         device_reset(dev);
@@ -615,9 +627,7 @@ static void device_finalize(Object *obj)
             bus = QLIST_FIRST(&dev->child_bus);
             qbus_free(bus);
         }
-        if (qdev_get_vmsd(dev)) {
-            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
-        }
+        qdev_finalize_vmstate(dev);
         if (dc->exit) {
             dc->exit(dev);
         }
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 06/12] qdev: move vmstate handling to qdev-system.c
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (4 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 05/12] qdev-core: isolate vmstate handling into separate functions Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code Eduardo Habkost
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

Add GCC_WEAK symbols to qdev-core.c, so that qdev-core.o can be used
without qdev-system.o (i.e. by *-user).

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
 - Add GCC_WEAK_DECL to function declarations
---
 hw/qdev-core.c   | 23 +++++++----------------
 hw/qdev-core.h   |  2 ++
 hw/qdev-system.c | 22 ++++++++++++++++++++++
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/hw/qdev-core.c b/hw/qdev-core.c
index 92c3021..af0af52 100644
--- a/hw/qdev-core.c
+++ b/hw/qdev-core.c
@@ -34,26 +34,17 @@ int qdev_hotplug = 0;
 static bool qdev_hot_added = false;
 static bool qdev_hot_removed = false;
 
-const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-    return dc->vmsd;
-}
-
-static void qdev_init_vmstate(DeviceState *dev)
+/* vmstate handling:
+ *
+ * The real implementations are on qdev-system.c. Those are weak symbols
+ * used by *-user.
+ */
+void GCC_WEAK qdev_init_vmstate(DeviceState *dev)
 {
-    if (qdev_get_vmsd(dev)) {
-        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
-                                       dev->instance_id_alias,
-                                       dev->alias_required_for_version);
-    }
 }
 
-static void qdev_finalize_vmstate(DeviceState *dev)
+void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
 {
-    if (qdev_get_vmsd(dev)) {
-        vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
-    }
 }
 
 const char *qdev_fw_name(DeviceState *dev)
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index fce9e22..89c54d5 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -223,6 +223,8 @@ void qdev_machine_init(void);
 void device_reset(DeviceState *dev);
 
 const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev);
+void GCC_WEAK_DECL qdev_init_vmstate(DeviceState *dev);
+void GCC_WEAK_DECL qdev_finalize_vmstate(DeviceState *dev);
 
 const char *qdev_fw_name(DeviceState *dev);
 
diff --git a/hw/qdev-system.c b/hw/qdev-system.c
index 93feaee..0c00ab3 100644
--- a/hw/qdev-system.c
+++ b/hw/qdev-system.c
@@ -66,3 +66,25 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
 
     return dev;
 }
+
+const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    return dc->vmsd;
+}
+
+void qdev_init_vmstate(DeviceState *dev)
+{
+    if (qdev_get_vmsd(dev)) {
+        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
+                                       dev->instance_id_alias,
+                                       dev->alias_required_for_version);
+    }
+}
+
+void qdev_finalize_vmstate(DeviceState *dev)
+{
+    if (qdev_get_vmsd(dev)) {
+        vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
+    }
+}
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (5 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 06/12] qdev: move vmstate handling to qdev-system.c Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-17 18:08   ` Anthony Liguori
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 08/12] qdev: move reset register/unregister code to qdev-system.c Eduardo Habkost
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

The reset register/unregister code is specific to qemu-system-*, so
isolate it so it can be moved to qdev-system.c.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/qdev-core.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/hw/qdev-core.c b/hw/qdev-core.c
index af0af52..a105679 100644
--- a/hw/qdev-core.c
+++ b/hw/qdev-core.c
@@ -47,6 +47,21 @@ void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
 {
 }
 
+static void qbus_register_reset(BusState *bus)
+{
+    if (bus != sysbus_get_default()) {
+        /* TODO: once all bus devices are qdevified,
+           only reset handler for main_system_bus should be registered here. */
+        qemu_register_reset(qbus_reset_all_fn, bus);
+    }
+}
+
+static void qbus_unregister_reset(BusState *bus)
+{
+    assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
+    qemu_unregister_reset(qbus_reset_all_fn, bus);
+}
+
 const char *qdev_fw_name(DeviceState *dev)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
@@ -355,10 +370,8 @@ static void qbus_realize(BusState *bus)
         QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
         bus->parent->num_child_bus++;
         object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
-    } else if (bus != sysbus_get_default()) {
-        /* TODO: once all bus devices are qdevified,
-           only reset handler for main_system_bus should be registered here. */
-        qemu_register_reset(qbus_reset_all_fn, bus);
+    } else {
+        qbus_register_reset(bus);
     }
 }
 
@@ -692,8 +705,7 @@ static void qbus_finalize(Object *obj)
         QLIST_REMOVE(bus, sibling);
         bus->parent->num_child_bus--;
     } else {
-        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
-        qemu_unregister_reset(qbus_reset_all_fn, bus);
+        qbus_unregister_reset(bus);
     }
     g_free((char *)bus->name);
 }
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 08/12] qdev: move reset register/unregister code to qdev-system.c
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (6 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 09/12] move qemu_irq typedef out of cpu-common.h Eduardo Habkost
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

Also, add weak symbols that will be used if qdev-system.o is not
compiled in (i.e. on *-user).

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Changes v1 -> v2:
 - Add GCC_WEAK_DECL to function declarations
---
 hw/qdev-core.c   | 16 +++++++---------
 hw/qdev-core.h   |  3 +++
 hw/qdev-system.c | 15 +++++++++++++++
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/hw/qdev-core.c b/hw/qdev-core.c
index a105679..a756e07 100644
--- a/hw/qdev-core.c
+++ b/hw/qdev-core.c
@@ -47,19 +47,17 @@ void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
 {
 }
 
-static void qbus_register_reset(BusState *bus)
+/* reset handler register/unregister:
+ *
+ * The real implementations are on qdev-system.c. Those are weak symbols
+ * used by *-user.
+ */
+void GCC_WEAK qbus_register_reset(BusState *bus)
 {
-    if (bus != sysbus_get_default()) {
-        /* TODO: once all bus devices are qdevified,
-           only reset handler for main_system_bus should be registered here. */
-        qemu_register_reset(qbus_reset_all_fn, bus);
-    }
 }
 
-static void qbus_unregister_reset(BusState *bus)
+void GCC_WEAK qbus_unregister_reset(BusState *bus)
 {
-    assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
-    qemu_unregister_reset(qbus_reset_all_fn, bus);
 }
 
 const char *qdev_fw_name(DeviceState *dev)
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index 89c54d5..e030fff 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -226,6 +226,9 @@ const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev);
 void GCC_WEAK_DECL qdev_init_vmstate(DeviceState *dev);
 void GCC_WEAK_DECL qdev_finalize_vmstate(DeviceState *dev);
 
+void GCC_WEAK_DECL qbus_register_reset(BusState *bus);
+void GCC_WEAK_DECL qbus_unregister_reset(BusState *bus);
+
 const char *qdev_fw_name(DeviceState *dev);
 
 Object *qdev_get_machine(void);
diff --git a/hw/qdev-system.c b/hw/qdev-system.c
index 0c00ab3..21074a0 100644
--- a/hw/qdev-system.c
+++ b/hw/qdev-system.c
@@ -88,3 +88,18 @@ void qdev_finalize_vmstate(DeviceState *dev)
         vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
     }
 }
+
+void qbus_register_reset(BusState *bus)
+{
+    if (bus != sysbus_get_default()) {
+        /* TODO: once all bus devices are qdevified,
+           only reset handler for main_system_bus should be registered here. */
+        qemu_register_reset(qbus_reset_all_fn, bus);
+    }
+}
+
+void qbus_unregister_reset(BusState *bus)
+{
+    assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
+    qemu_unregister_reset(qbus_reset_all_fn, bus);
+}
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 09/12] move qemu_irq typedef out of cpu-common.h
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (7 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 08/12] qdev: move reset register/unregister code to qdev-system.c Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-17 18:08   ` Anthony Liguori
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 10/12] qdev: use full qdev.h include path on qdev*.c Eduardo Habkost
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

From: Igor Mammedov <imammedo@redhat.com>

it's necessary for making CPU child of DEVICE without
causing circular header deps.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
Changes v2 -> v3:
  imammedo: sysemu.h doesn't need irq.h since 013c2f150
---
 hw/arm-misc.h | 1 +
 hw/bt.h       | 2 ++
 hw/devices.h  | 2 ++
 hw/omap.h     | 1 +
 hw/soc_dma.h  | 1 +
 hw/xen.h      | 1 +
 qemu-common.h | 1 -
 7 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index bdd8fec..b13aa59 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -12,6 +12,7 @@
 #define ARM_MISC_H 1
 
 #include "memory.h"
+#include "hw/irq.h"
 
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
diff --git a/hw/bt.h b/hw/bt.h
index a48b8d4..ebf6a37 100644
--- a/hw/bt.h
+++ b/hw/bt.h
@@ -23,6 +23,8 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "hw/irq.h"
+
 /* BD Address */
 typedef struct {
     uint8_t b[6];
diff --git a/hw/devices.h b/hw/devices.h
index 1a55c1e..c60bcab 100644
--- a/hw/devices.h
+++ b/hw/devices.h
@@ -1,6 +1,8 @@
 #ifndef QEMU_DEVICES_H
 #define QEMU_DEVICES_H
 
+#include "hw/irq.h"
+
 /* ??? Not all users of this file can include cpu-common.h.  */
 struct MemoryRegion;
 
diff --git a/hw/omap.h b/hw/omap.h
index 413851b..8b08462 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -19,6 +19,7 @@
 #ifndef hw_omap_h
 #include "memory.h"
 # define hw_omap_h		"omap.h"
+#include "hw/irq.h"
 
 # define OMAP_EMIFS_BASE	0x00000000
 # define OMAP2_Q0_BASE		0x00000000
diff --git a/hw/soc_dma.h b/hw/soc_dma.h
index 904b26c..e386ace 100644
--- a/hw/soc_dma.h
+++ b/hw/soc_dma.h
@@ -19,6 +19,7 @@
  */
 
 #include "memory.h"
+#include "hw/irq.h"
 
 struct soc_dma_s;
 struct soc_dma_ch_s;
diff --git a/hw/xen.h b/hw/xen.h
index d14e92d..e3cca7f 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -8,6 +8,7 @@
  */
 #include <inttypes.h>
 
+#include "hw/irq.h"
 #include "qemu-common.h"
 
 /* xen-machine.c */
diff --git a/qemu-common.h b/qemu-common.h
index b54612b..95585b8 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -286,7 +286,6 @@ typedef struct PCIEPort PCIEPort;
 typedef struct PCIESlot PCIESlot;
 typedef struct MSIMessage MSIMessage;
 typedef struct SerialState SerialState;
-typedef struct IRQState *qemu_irq;
 typedef struct PCMCIACardState PCMCIACardState;
 typedef struct MouseTransformInfo MouseTransformInfo;
 typedef struct uWireSlave uWireSlave;
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 10/12] qdev: use full qdev.h include path on qdev*.c
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (8 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 09/12] move qemu_irq typedef out of cpu-common.h Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too Eduardo Habkost
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 12/12] qom: make CPU a child of DeviceState Eduardo Habkost
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

This way, the files can be moved to the qom/ directory as-is.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/qdev-core.c       | 2 +-
 hw/qdev-properties.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/qdev-core.c b/hw/qdev-core.c
index a756e07..fbb7cb5 100644
--- a/hw/qdev-core.c
+++ b/hw/qdev-core.c
@@ -25,7 +25,7 @@
    inherit from a particular bus (e.g. PCI or I2C) rather than
    this API directly.  */
 
-#include "qdev.h"
+#include "hw/qdev.h"
 #include "sysemu.h"
 #include "error.h"
 #include "qapi/qapi-visit-core.h"
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 917d986..2e82cb9 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1,5 +1,5 @@
 #include "net.h"
-#include "qdev.h"
+#include "hw/qdev.h"
 #include "qerror.h"
 #include "blockdev.h"
 #include "hw/block-common.h"
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (9 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 10/12] qdev: use full qdev.h include path on qdev*.c Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  2012-10-17 18:11   ` Anthony Liguori
  2012-10-22 12:36   ` Igor Mammedov
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 12/12] qom: make CPU a child of DeviceState Eduardo Habkost
  11 siblings, 2 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

The code depends on some functions from qemu-option.o, so add
qemu-option.o to universal-obj-y to make sure it's included.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 Makefile.objs         |   3 +
 hw/Makefile.objs      |   2 +-
 hw/qdev-core.c        | 727 -------------------------------------
 hw/qdev-properties.c  | 963 --------------------------------------------------
 qom/Makefile.objs     |   2 +-
 qom/qdev-core.c       | 727 +++++++++++++++++++++++++++++++++++++
 qom/qdev-properties.c | 963 ++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 1695 insertions(+), 1692 deletions(-)
 delete mode 100644 hw/qdev-core.c
 delete mode 100644 hw/qdev-properties.c
 create mode 100644 qom/qdev-core.c
 create mode 100644 qom/qdev-properties.c

diff --git a/Makefile.objs b/Makefile.objs
index 74b3542..fcd1336 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -16,6 +16,9 @@ universal-obj-y += $(qobject-obj-y)
 qom-obj-y = qom/
 
 universal-obj-y += $(qom-obj-y)
+# QOM qdev-core.o requires qemu-option.o:
+universal-obj-y += qemu-option.o
+
 
 #######################################################################
 # oslib-obj-y is code depending on the OS (win32 vs posix)
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 70f2014..3ce38d2 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -180,7 +180,7 @@ common-obj-$(CONFIG_SD) += sd.o
 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-core.o qdev-properties.o qdev-monitor.o
+common-obj-y += qdev-monitor.o
 common-obj-y += qdev-system.o qdev-properties-system.o
 common-obj-$(CONFIG_BRLAPI) += baum.o
 
diff --git a/hw/qdev-core.c b/hw/qdev-core.c
deleted file mode 100644
index fbb7cb5..0000000
--- a/hw/qdev-core.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
- *  Dynamic device configuration and creation.
- *
- *  Copyright (c) 2009 CodeSourcery
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* The theory here is that it should be possible to create a machine without
-   knowledge of specific devices.  Historically board init routines have
-   passed a bunch of arguments to each device, requiring the board know
-   exactly which device it is dealing with.  This file provides an abstract
-   API for device configuration and initialization.  Devices will generally
-   inherit from a particular bus (e.g. PCI or I2C) rather than
-   this API directly.  */
-
-#include "hw/qdev.h"
-#include "sysemu.h"
-#include "error.h"
-#include "qapi/qapi-visit-core.h"
-
-int qdev_hotplug = 0;
-static bool qdev_hot_added = false;
-static bool qdev_hot_removed = false;
-
-/* vmstate handling:
- *
- * The real implementations are on qdev-system.c. Those are weak symbols
- * used by *-user.
- */
-void GCC_WEAK qdev_init_vmstate(DeviceState *dev)
-{
-}
-
-void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
-{
-}
-
-/* reset handler register/unregister:
- *
- * The real implementations are on qdev-system.c. Those are weak symbols
- * used by *-user.
- */
-void GCC_WEAK qbus_register_reset(BusState *bus)
-{
-}
-
-void GCC_WEAK qbus_unregister_reset(BusState *bus)
-{
-}
-
-const char *qdev_fw_name(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-    if (dc->fw_name) {
-        return dc->fw_name;
-    }
-
-    return object_get_typename(OBJECT(dev));
-}
-
-static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
-                                     Error **errp);
-
-static void bus_remove_child(BusState *bus, DeviceState *child)
-{
-    BusChild *kid;
-
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        if (kid->child == child) {
-            char name[32];
-
-            snprintf(name, sizeof(name), "child[%d]", kid->index);
-            QTAILQ_REMOVE(&bus->children, kid, sibling);
-            object_property_del(OBJECT(bus), name, NULL);
-            g_free(kid);
-            return;
-        }
-    }
-}
-
-static void bus_add_child(BusState *bus, DeviceState *child)
-{
-    char name[32];
-    BusChild *kid = g_malloc0(sizeof(*kid));
-
-    if (qdev_hotplug) {
-        assert(bus->allow_hotplug);
-    }
-
-    kid->index = bus->max_index++;
-    kid->child = child;
-
-    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
-
-    snprintf(name, sizeof(name), "child[%d]", kid->index);
-    object_property_add_link(OBJECT(bus), name,
-                             object_get_typename(OBJECT(child)),
-                             (Object **)&kid->child,
-                             NULL);
-}
-
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
-{
-    dev->parent_bus = bus;
-    bus_add_child(bus, 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.
-   On failure, destroy the device and return negative value.
-   Return 0 on success.  */
-int qdev_init(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-    int rc;
-
-    assert(dev->state == DEV_STATE_CREATED);
-
-    rc = dc->init(dev);
-    if (rc < 0) {
-        qdev_free(dev);
-        return rc;
-    }
-
-    if (!OBJECT(dev)->parent) {
-        static int unattached_count = 0;
-        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
-
-        object_property_add_child(container_get(qdev_get_machine(),
-                                                "/unattached"),
-                                  name, OBJECT(dev), NULL);
-        g_free(name);
-    }
-
-    qdev_init_vmstate(dev);
-    dev->state = DEV_STATE_INITIALIZED;
-    if (dev->hotplugged) {
-        device_reset(dev);
-    }
-    return 0;
-}
-
-void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
-                                 int required_for_version)
-{
-    assert(dev->state == DEV_STATE_CREATED);
-    dev->instance_id_alias = alias_id;
-    dev->alias_required_for_version = required_for_version;
-}
-
-void qdev_unplug(DeviceState *dev, Error **errp)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-    if (!dev->parent_bus->allow_hotplug) {
-        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
-        return;
-    }
-    assert(dc->unplug != NULL);
-
-    qdev_hot_removed = true;
-
-    if (dc->unplug(dev) < 0) {
-        error_set(errp, QERR_UNDEFINED_ERROR);
-        return;
-    }
-}
-
-static int qdev_reset_one(DeviceState *dev, void *opaque)
-{
-    device_reset(dev);
-
-    return 0;
-}
-
-static int qbus_reset_one(BusState *bus, void *opaque)
-{
-    BusClass *bc = BUS_GET_CLASS(bus);
-    if (bc->reset) {
-        return bc->reset(bus);
-    }
-    return 0;
-}
-
-void qdev_reset_all(DeviceState *dev)
-{
-    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
-}
-
-void qbus_reset_all_fn(void *opaque)
-{
-    BusState *bus = opaque;
-    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
-}
-
-/* can be used as ->unplug() callback for the simple cases */
-int qdev_simple_unplug_cb(DeviceState *dev)
-{
-    /* just zap it */
-    qdev_free(dev);
-    return 0;
-}
-
-
-/* Like qdev_init(), but terminate program via error_report() instead of
-   returning an error value.  This is okay during machine creation.
-   Don't use for hotplug, because there callers need to recover from
-   failure.  Exception: if you know the device's init() callback can't
-   fail, then qdev_init_nofail() can't fail either, and is therefore
-   usable even then.  But relying on the device implementation that
-   way is somewhat unclean, and best avoided.  */
-void qdev_init_nofail(DeviceState *dev)
-{
-    const char *typename = object_get_typename(OBJECT(dev));
-
-    if (qdev_init(dev) < 0) {
-        error_report("Initialization of device %s failed", typename);
-        exit(1);
-    }
-}
-
-/* Unlink device from bus and free the structure.  */
-void qdev_free(DeviceState *dev)
-{
-    object_delete(OBJECT(dev));
-}
-
-void qdev_machine_creation_done(void)
-{
-    /*
-     * ok, initial machine setup is done, starting from now we can
-     * only create hotpluggable devices
-     */
-    qdev_hotplug = 1;
-}
-
-bool qdev_machine_modified(void)
-{
-    return qdev_hot_added || qdev_hot_removed;
-}
-
-BusState *qdev_get_parent_bus(DeviceState *dev)
-{
-    return dev->parent_bus;
-}
-
-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)
-{
-    BusChild *kid;
-    int err;
-
-    if (busfn) {
-        err = busfn(bus, opaque);
-        if (err) {
-            return err;
-        }
-    }
-
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
-        if (err < 0) {
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
-                       qbus_walkerfn *busfn, void *opaque)
-{
-    BusState *bus;
-    int err;
-
-    if (devfn) {
-        err = devfn(dev, opaque);
-        if (err) {
-            return err;
-        }
-    }
-
-    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
-        err = qbus_walk_children(bus, devfn, busfn, opaque);
-        if (err < 0) {
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-DeviceState *qdev_find_recursive(BusState *bus, const char *id)
-{
-    BusChild *kid;
-    DeviceState *ret;
-    BusState *child;
-
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        DeviceState *dev = kid->child;
-
-        if (dev->id && strcmp(dev->id, id) == 0) {
-            return dev;
-        }
-
-        QLIST_FOREACH(child, &dev->child_bus, sibling) {
-            ret = qdev_find_recursive(child, id);
-            if (ret) {
-                return ret;
-            }
-        }
-    }
-    return NULL;
-}
-
-static void qbus_realize(BusState *bus)
-{
-    const char *typename = object_get_typename(OBJECT(bus));
-    char *buf;
-    int i,len;
-
-    if (bus->name) {
-        /* use supplied name */
-    } else if (bus->parent && bus->parent->id) {
-        /* parent device has id -> use it for bus name */
-        len = strlen(bus->parent->id) + 16;
-        buf = g_malloc(len);
-        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
-        bus->name = buf;
-    } else {
-        /* no id -> use lowercase bus type for bus name */
-        len = strlen(typename) + 16;
-        buf = g_malloc(len);
-        len = snprintf(buf, len, "%s.%d", typename,
-                       bus->parent ? bus->parent->num_child_bus : 0);
-        for (i = 0; i < len; i++)
-            buf[i] = qemu_tolower(buf[i]);
-        bus->name = buf;
-    }
-
-    if (bus->parent) {
-        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
-        bus->parent->num_child_bus++;
-        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
-    } else {
-        qbus_register_reset(bus);
-    }
-}
-
-void qbus_create_inplace(BusState *bus, const char *typename,
-                         DeviceState *parent, const char *name)
-{
-    object_initialize(bus, typename);
-
-    bus->parent = parent;
-    bus->name = name ? g_strdup(name) : NULL;
-    qbus_realize(bus);
-}
-
-BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
-{
-    BusState *bus;
-
-    bus = BUS(object_new(typename));
-    bus->qom_allocated = true;
-
-    bus->parent = parent;
-    bus->name = name ? g_strdup(name) : NULL;
-    qbus_realize(bus);
-
-    return bus;
-}
-
-void qbus_free(BusState *bus)
-{
-    if (bus->qom_allocated) {
-        object_delete(OBJECT(bus));
-    } else {
-        object_finalize(OBJECT(bus));
-        if (bus->glib_allocated) {
-            g_free(bus);
-        }
-    }
-}
-
-static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
-{
-    BusClass *bc = BUS_GET_CLASS(bus);
-
-    if (bc->get_fw_dev_path) {
-        return bc->get_fw_dev_path(dev);
-    }
-
-    return NULL;
-}
-
-static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
-{
-    int l = 0;
-
-    if (dev && dev->parent_bus) {
-        char *d;
-        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
-        d = bus_get_fw_dev_path(dev->parent_bus, dev);
-        if (d) {
-            l += snprintf(p + l, size - l, "%s", d);
-            g_free(d);
-        } else {
-            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
-        }
-    }
-    l += snprintf(p + l , size - l, "/");
-
-    return l;
-}
-
-char* qdev_get_fw_dev_path(DeviceState *dev)
-{
-    char path[128];
-    int l;
-
-    l = qdev_get_fw_dev_path_helper(dev, path, 128);
-
-    path[l-1] = '\0';
-
-    return g_strdup(path);
-}
-
-char *qdev_get_dev_path(DeviceState *dev)
-{
-    BusClass *bc;
-
-    if (!dev || !dev->parent_bus) {
-        return NULL;
-    }
-
-    bc = BUS_GET_CLASS(dev->parent_bus);
-    if (bc->get_dev_path) {
-        return bc->get_dev_path(dev);
-    }
-
-    return NULL;
-}
-
-/**
- * Legacy property handling
- */
-
-static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
-                                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-
-    char buffer[1024];
-    char *ptr = buffer;
-
-    prop->info->print(dev, prop, buffer, sizeof(buffer));
-    visit_type_str(v, &ptr, name, errp);
-}
-
-static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
-                                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    Error *local_err = NULL;
-    char *ptr = NULL;
-    int ret;
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_str(v, &ptr, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    ret = prop->info->parse(dev, prop, ptr);
-    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
-    g_free(ptr);
-}
-
-/**
- * @qdev_add_legacy_property - adds a legacy property
- *
- * Do not use this is new code!  Properties added through this interface will
- * be given names and types in the "legacy" namespace.
- *
- * Legacy properties are string versions of other OOM properties.  The format
- * of the string depends on the property type.
- */
-void qdev_property_add_legacy(DeviceState *dev, Property *prop,
-                              Error **errp)
-{
-    gchar *name, *type;
-
-    /* Register pointer properties as legacy properties */
-    if (!prop->info->print && !prop->info->parse &&
-        (prop->info->set || prop->info->get)) {
-        return;
-    }
-
-    name = g_strdup_printf("legacy-%s", prop->name);
-    type = g_strdup_printf("legacy<%s>",
-                           prop->info->legacy_name ?: prop->info->name);
-
-    object_property_add(OBJECT(dev), name, type,
-                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
-                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
-                        NULL,
-                        prop, errp);
-
-    g_free(type);
-    g_free(name);
-}
-
-/**
- * @qdev_property_add_static - add a @Property to a device.
- *
- * Static properties access data in a struct.  The actual type of the
- * property and the field depends on the property type.
- */
-void qdev_property_add_static(DeviceState *dev, Property *prop,
-                              Error **errp)
-{
-    Error *local_err = NULL;
-    Object *obj = OBJECT(dev);
-
-    /*
-     * TODO qdev_prop_ptr does not have getters or setters.  It must
-     * go now that it can be replaced with links.  The test should be
-     * removed along with it: all static properties are read/write.
-     */
-    if (!prop->info->get && !prop->info->set) {
-        return;
-    }
-
-    object_property_add(obj, prop->name, prop->info->name,
-                        prop->info->get, prop->info->set,
-                        prop->info->release,
-                        prop, &local_err);
-
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if (prop->qtype == QTYPE_NONE) {
-        return;
-    }
-
-    if (prop->qtype == QTYPE_QBOOL) {
-        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
-    } else if (prop->info->enum_table) {
-        object_property_set_str(obj, prop->info->enum_table[prop->defval],
-                                prop->name, &local_err);
-    } else if (prop->qtype == QTYPE_QINT) {
-        object_property_set_int(obj, prop->defval, prop->name, &local_err);
-    }
-    assert_no_error(local_err);
-}
-
-static void device_initfn(Object *obj)
-{
-    DeviceState *dev = DEVICE(obj);
-    ObjectClass *class;
-    Property *prop;
-
-    if (qdev_hotplug) {
-        dev->hotplugged = 1;
-        qdev_hot_added = true;
-    }
-
-    dev->instance_id_alias = -1;
-    dev->state = DEV_STATE_CREATED;
-
-    class = object_get_class(OBJECT(dev));
-    do {
-        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
-            qdev_property_add_legacy(dev, prop, NULL);
-            qdev_property_add_static(dev, prop, NULL);
-        }
-        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);
-}
-
-/* Unlink device from bus and free the structure.  */
-static void device_finalize(Object *obj)
-{
-    DeviceState *dev = DEVICE(obj);
-    BusState *bus;
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-    if (dev->state == DEV_STATE_INITIALIZED) {
-        while (dev->num_child_bus) {
-            bus = QLIST_FIRST(&dev->child_bus);
-            qbus_free(bus);
-        }
-        qdev_finalize_vmstate(dev);
-        if (dc->exit) {
-            dc->exit(dev);
-        }
-        if (dev->opts) {
-            qemu_opts_del(dev->opts);
-        }
-    }
-    if (dev->parent_bus) {
-        bus_remove_child(dev->parent_bus, dev);
-    }
-}
-
-static void device_class_base_init(ObjectClass *class, void *data)
-{
-    DeviceClass *klass = DEVICE_CLASS(class);
-
-    /* We explicitly look up properties in the superclasses,
-     * so do not propagate them to the subclasses.
-     */
-    klass->props = NULL;
-}
-
-void device_reset(DeviceState *dev)
-{
-    DeviceClass *klass = DEVICE_GET_CLASS(dev);
-
-    if (klass->reset) {
-        klass->reset(dev);
-    }
-}
-
-Object *qdev_get_machine(void)
-{
-    static Object *dev;
-
-    if (dev == NULL) {
-        dev = container_get(object_get_root(), "/machine");
-    }
-
-    return dev;
-}
-
-static TypeInfo device_type_info = {
-    .name = TYPE_DEVICE,
-    .parent = TYPE_OBJECT,
-    .instance_size = sizeof(DeviceState),
-    .instance_init = device_initfn,
-    .instance_finalize = device_finalize,
-    .class_base_init = device_class_base_init,
-    .abstract = true,
-    .class_size = sizeof(DeviceClass),
-};
-
-static void qbus_initfn(Object *obj)
-{
-    BusState *bus = BUS(obj);
-
-    QTAILQ_INIT(&bus->children);
-}
-
-static void qbus_finalize(Object *obj)
-{
-    BusState *bus = BUS(obj);
-    BusChild *kid;
-
-    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
-        DeviceState *dev = kid->child;
-        qdev_free(dev);
-    }
-    if (bus->parent) {
-        QLIST_REMOVE(bus, sibling);
-        bus->parent->num_child_bus--;
-    } else {
-        qbus_unregister_reset(bus);
-    }
-    g_free((char *)bus->name);
-}
-
-static const TypeInfo bus_info = {
-    .name = TYPE_BUS,
-    .parent = TYPE_OBJECT,
-    .instance_size = sizeof(BusState),
-    .abstract = true,
-    .class_size = sizeof(BusClass),
-    .instance_init = qbus_initfn,
-    .instance_finalize = qbus_finalize,
-};
-
-static void qdev_register_types(void)
-{
-    type_register_static(&bus_info);
-    type_register_static(&device_type_info);
-}
-
-type_init(qdev_register_types)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
deleted file mode 100644
index 2e82cb9..0000000
--- a/hw/qdev-properties.c
+++ /dev/null
@@ -1,963 +0,0 @@
-#include "net.h"
-#include "hw/qdev.h"
-#include "qerror.h"
-#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)
-{
-    void *ptr = dev;
-    ptr += prop->offset;
-    return ptr;
-}
-
-static void get_enum(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
-
-    visit_type_enum(v, ptr, prop->info->enum_table,
-                    prop->info->name, prop->name, errp);
-}
-
-static void set_enum(Object *obj, Visitor *v, void *opaque,
-                     const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    int *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_enum(v, ptr, prop->info->enum_table,
-                    prop->info->name, prop->name, errp);
-}
-
-/* Bit */
-
-static uint32_t qdev_get_prop_mask(Property *prop)
-{
-    assert(prop->info == &qdev_prop_bit);
-    return 0x1 << prop->bitnr;
-}
-
-static void bit_prop_set(DeviceState *dev, Property *props, bool val)
-{
-    uint32_t *p = qdev_get_prop_ptr(dev, props);
-    uint32_t mask = qdev_get_prop_mask(props);
-    if (val)
-        *p |= mask;
-    else
-        *p &= ~mask;
-}
-
-static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    uint32_t *p = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
-}
-
-static void get_bit(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint32_t *p = qdev_get_prop_ptr(dev, prop);
-    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
-
-    visit_type_bool(v, &value, name, errp);
-}
-
-static void set_bit(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    Error *local_err = NULL;
-    bool value;
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_bool(v, &value, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    bit_prop_set(dev, prop, value);
-}
-
-PropertyInfo qdev_prop_bit = {
-    .name  = "boolean",
-    .legacy_name  = "on/off",
-    .print = print_bit,
-    .get   = get_bit,
-    .set   = set_bit,
-};
-
-/* --- 8bit integer --- */
-
-static void get_uint8(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    visit_type_uint8(v, ptr, name, errp);
-}
-
-static void set_uint8(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint8(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint8 = {
-    .name  = "uint8",
-    .get   = get_uint8,
-    .set   = set_uint8,
-};
-
-/* --- 8bit hex value --- */
-
-static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
-{
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoul(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, "0x%" PRIx8, *ptr);
-}
-
-PropertyInfo qdev_prop_hex8 = {
-    .name  = "uint8",
-    .legacy_name  = "hex8",
-    .parse = parse_hex8,
-    .print = print_hex8,
-    .get   = get_uint8,
-    .set   = set_uint8,
-};
-
-/* --- 16bit integer --- */
-
-static void get_uint16(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    visit_type_uint16(v, ptr, name, errp);
-}
-
-static void set_uint16(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint16(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint16 = {
-    .name  = "uint16",
-    .get   = get_uint16,
-    .set   = set_uint16,
-};
-
-/* --- 32bit integer --- */
-
-static void get_uint32(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    visit_type_uint32(v, ptr, name, errp);
-}
-
-static void set_uint32(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint32(v, ptr, name, errp);
-}
-
-static void get_int32(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    visit_type_int32(v, ptr, name, errp);
-}
-
-static void set_int32(Object *obj, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_int32(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint32 = {
-    .name  = "uint32",
-    .get   = get_uint32,
-    .set   = set_uint32,
-};
-
-PropertyInfo qdev_prop_int32 = {
-    .name  = "int32",
-    .get   = get_int32,
-    .set   = set_int32,
-};
-
-/* --- 32bit hex value --- */
-
-static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
-{
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoul(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, "0x%" PRIx32, *ptr);
-}
-
-PropertyInfo qdev_prop_hex32 = {
-    .name  = "uint32",
-    .legacy_name  = "hex32",
-    .parse = parse_hex32,
-    .print = print_hex32,
-    .get   = get_uint32,
-    .set   = set_uint32,
-};
-
-/* --- 64bit integer --- */
-
-static void get_uint64(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    visit_type_uint64(v, ptr, name, errp);
-}
-
-static void set_uint64(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint64(v, ptr, name, errp);
-}
-
-PropertyInfo qdev_prop_uint64 = {
-    .name  = "uint64",
-    .get   = get_uint64,
-    .set   = set_uint64,
-};
-
-/* --- 64bit hex value --- */
-
-static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
-{
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-    char *end;
-
-    if (str[0] != '0' || str[1] != 'x') {
-        return -EINVAL;
-    }
-
-    *ptr = strtoull(str, &end, 16);
-    if ((*end != '\0') || (end == str)) {
-        return -EINVAL;
-    }
-
-    return 0;
-}
-
-static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-    return snprintf(dest, len, "0x%" PRIx64, *ptr);
-}
-
-PropertyInfo qdev_prop_hex64 = {
-    .name  = "uint64",
-    .legacy_name  = "hex64",
-    .parse = parse_hex64,
-    .print = print_hex64,
-    .get   = get_uint64,
-    .set   = set_uint64,
-};
-
-/* --- string --- */
-
-static void release_string(Object *obj, const char *name, void *opaque)
-{
-    Property *prop = opaque;
-    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
-}
-
-static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    char **ptr = qdev_get_prop_ptr(dev, prop);
-    if (!*ptr)
-        return snprintf(dest, len, "<null>");
-    return snprintf(dest, len, "\"%s\"", *ptr);
-}
-
-static void get_string(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (!*ptr) {
-        char *str = (char *)"";
-        visit_type_str(v, &str, name, errp);
-    } else {
-        visit_type_str(v, ptr, name, errp);
-    }
-}
-
-static void set_string(Object *obj, Visitor *v, void *opaque,
-                       const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    char **ptr = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    char *str;
-
-    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 (*ptr) {
-        g_free(*ptr);
-    }
-    *ptr = str;
-}
-
-PropertyInfo qdev_prop_string = {
-    .name  = "string",
-    .print = print_string,
-    .release = release_string,
-    .get   = get_string,
-    .set   = set_string,
-};
-
-/* --- pointer --- */
-
-/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
-PropertyInfo qdev_prop_ptr = {
-    .name  = "ptr",
-};
-
-/* --- mac address --- */
-
-/*
- * accepted syntax versions:
- *   01:02:03:04:05:06
- *   01-02-03-04-05-06
- */
-static void get_mac(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
-    char buffer[2 * 6 + 5 + 1];
-    char *p = buffer;
-
-    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
-             mac->a[0], mac->a[1], mac->a[2],
-             mac->a[3], mac->a[4], mac->a[5]);
-
-    visit_type_str(v, &p, name, errp);
-}
-
-static void set_mac(Object *obj, Visitor *v, void *opaque,
-                    const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    int i, pos;
-    char *str, *p;
-
-    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;
-    }
-
-    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
-        if (!qemu_isxdigit(str[pos]))
-            goto inval;
-        if (!qemu_isxdigit(str[pos+1]))
-            goto inval;
-        if (i == 5) {
-            if (str[pos+2] != '\0')
-                goto inval;
-        } else {
-            if (str[pos+2] != ':' && str[pos+2] != '-')
-                goto inval;
-        }
-        mac->a[i] = strtol(str+pos, &p, 16);
-    }
-    g_free(str);
-    return;
-
-inval:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
-    g_free(str);
-}
-
-PropertyInfo qdev_prop_macaddr = {
-    .name  = "macaddr",
-    .get   = get_mac,
-    .set   = set_mac,
-};
-
-/* --- lost tick policy --- */
-
-static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
-    [LOST_TICK_DISCARD] = "discard",
-    [LOST_TICK_DELAY] = "delay",
-    [LOST_TICK_MERGE] = "merge",
-    [LOST_TICK_SLEW] = "slew",
-    [LOST_TICK_MAX] = NULL,
-};
-
-QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
-
-PropertyInfo qdev_prop_losttickpolicy = {
-    .name  = "LostTickPolicy",
-    .enum_table  = lost_tick_policy_table,
-    .get   = get_enum,
-    .set   = set_enum,
-};
-
-/* --- BIOS CHS translation */
-
-static const char *bios_chs_trans_table[] = {
-    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
-    [BIOS_ATA_TRANSLATION_NONE] = "none",
-    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
-};
-
-PropertyInfo qdev_prop_bios_chs_trans = {
-    .name = "bios-chs-trans",
-    .enum_table = bios_chs_trans_table,
-    .get = get_enum,
-    .set = set_enum,
-};
-
-/* --- pci address --- */
-
-/*
- * bus-local address, i.e. "$slot" or "$slot.$fn"
- */
-static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
-                          const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
-    unsigned int slot, fn, n;
-    Error *local_err = NULL;
-    char *str;
-
-    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_free(local_err);
-        local_err = NULL;
-        visit_type_int32(v, &value, name, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-        } else if (value < -1 || value > 255) {
-            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
-                      "pci_devfn");
-        } else {
-            *ptr = value;
-        }
-        return;
-    }
-
-    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
-        fn = 0;
-        if (sscanf(str, "%x%n", &slot, &n) != 1) {
-            goto invalid;
-        }
-    }
-    if (str[n] != '\0' || fn > 7 || slot > 31) {
-        goto invalid;
-    }
-    *ptr = slot << 3 | fn;
-    g_free(str);
-    return;
-
-invalid:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
-    g_free(str);
-}
-
-static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
-    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
-
-    if (*ptr == -1) {
-        return snprintf(dest, len, "<unset>");
-    } else {
-        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
-    }
-}
-
-PropertyInfo qdev_prop_pci_devfn = {
-    .name  = "int32",
-    .legacy_name  = "pci-devfn",
-    .print = print_pci_devfn,
-    .get   = get_int32,
-    .set   = set_pci_devfn,
-};
-
-/* --- blocksize --- */
-
-static void set_blocksize(Object *obj, Visitor *v, void *opaque,
-                          const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    const int64_t min = 512;
-    const int64_t max = 32768;
-
-    if (dev->state != DEV_STATE_CREATED) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-        return;
-    }
-
-    visit_type_uint16(v, &value, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-    if (value < min || value > max) {
-        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
-                  dev->id?:"", name, (int64_t)value, min, max);
-        return;
-    }
-
-    /* We rely on power-of-2 blocksizes for bitmasks */
-    if ((value & (value - 1)) != 0) {
-        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
-                  dev->id?:"", name, (int64_t)value);
-        return;
-    }
-
-    *ptr = value;
-}
-
-PropertyInfo qdev_prop_blocksize = {
-    .name  = "blocksize",
-    .get   = get_uint16,
-    .set   = set_blocksize,
-};
-
-/* --- pci host address --- */
-
-static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
-                                 const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
-    char buffer[] = "xxxx:xx:xx.x";
-    char *p = buffer;
-    int rc = 0;
-
-    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
-                  addr->domain, addr->bus, addr->slot, addr->function);
-    assert(rc == sizeof(buffer) - 1);
-
-    visit_type_str(v, &p, name, errp);
-}
-
-/*
- * Parse [<domain>:]<bus>:<slot>.<func>
- *   if <domain> is not supplied, it's assumed to be 0.
- */
-static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
-                                 const char *name, Error **errp)
-{
-    DeviceState *dev = DEVICE(obj);
-    Property *prop = opaque;
-    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
-    Error *local_err = NULL;
-    char *str, *p;
-    char *e;
-    unsigned long val;
-    unsigned long dom = 0, bus = 0;
-    unsigned int slot = 0, func = 0;
-
-    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;
-    }
-
-    p = str;
-    val = strtoul(p, &e, 16);
-    if (e == p || *e != ':') {
-        goto inval;
-    }
-    bus = val;
-
-    p = e + 1;
-    val = strtoul(p, &e, 16);
-    if (e == p) {
-        goto inval;
-    }
-    if (*e == ':') {
-        dom = bus;
-        bus = val;
-        p = e + 1;
-        val = strtoul(p, &e, 16);
-        if (e == p) {
-            goto inval;
-        }
-    }
-    slot = val;
-
-    if (*e != '.') {
-        goto inval;
-    }
-    p = e + 1;
-    val = strtoul(p, &e, 10);
-    if (e == p) {
-        goto inval;
-    }
-    func = val;
-
-    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
-        goto inval;
-    }
-
-    if (*e) {
-        goto inval;
-    }
-
-    addr->domain = dom;
-    addr->bus = bus;
-    addr->slot = slot;
-    addr->function = func;
-
-    g_free(str);
-    return;
-
-inval:
-    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
-    g_free(str);
-}
-
-PropertyInfo qdev_prop_pci_host_devaddr = {
-    .name = "pci-host-devaddr",
-    .get = get_pci_host_devaddr,
-    .set = set_pci_host_devaddr,
-};
-
-/* --- public helpers --- */
-
-static Property *qdev_prop_walk(Property *props, const char *name)
-{
-    if (!props)
-        return NULL;
-    while (props->name) {
-        if (strcmp(props->name, name) == 0)
-            return props;
-        props++;
-    }
-    return NULL;
-}
-
-static Property *qdev_prop_find(DeviceState *dev, const char *name)
-{
-    ObjectClass *class;
-    Property *prop;
-
-    /* device properties */
-    class = object_get_class(OBJECT(dev));
-    do {
-        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
-        if (prop) {
-            return prop;
-        }
-        class = object_class_get_parent(class);
-    } while (class != object_class_by_name(TYPE_DEVICE));
-
-    return NULL;
-}
-
-void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
-                                    Property *prop, const char *value)
-{
-    switch (ret) {
-    case -EEXIST:
-        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
-                  object_get_typename(OBJECT(dev)), prop->name, value);
-        break;
-    default:
-    case -EINVAL:
-        error_set(errp, QERR_PROPERTY_VALUE_BAD,
-                  object_get_typename(OBJECT(dev)), prop->name, value);
-        break;
-    case -ENOENT:
-        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
-                  object_get_typename(OBJECT(dev)), prop->name, value);
-        break;
-    case 0:
-        break;
-    }
-}
-
-int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
-{
-    char *legacy_name;
-    Error *err = NULL;
-
-    legacy_name = g_strdup_printf("legacy-%s", name);
-    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
-        object_property_parse(OBJECT(dev), value, legacy_name, &err);
-    } else {
-        object_property_parse(OBJECT(dev), value, name, &err);
-    }
-    g_free(legacy_name);
-
-    if (err) {
-        qerror_report_err(err);
-        error_free(err);
-        return -1;
-    }
-    return 0;
-}
-
-void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
-{
-    Error *errp = NULL;
-    object_property_set_bool(OBJECT(dev), value, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
-{
-    Error *errp = NULL;
-    object_property_set_int(OBJECT(dev), value, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
-{
-    Error *errp = NULL;
-    object_property_set_int(OBJECT(dev), value, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
-{
-    Error *errp = NULL;
-    object_property_set_int(OBJECT(dev), value, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
-{
-    Error *errp = NULL;
-    object_property_set_int(OBJECT(dev), value, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
-{
-    Error *errp = NULL;
-    object_property_set_int(OBJECT(dev), value, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
-{
-    Error *errp = NULL;
-    object_property_set_str(OBJECT(dev), value, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
-{
-    Error *errp = NULL;
-    char str[2 * 6 + 5 + 1];
-    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
-             value[0], value[1], value[2], value[3], value[4], value[5]);
-
-    object_property_set_str(OBJECT(dev), str, name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
-{
-    Property *prop;
-    Error *errp = NULL;
-
-    prop = qdev_prop_find(dev, name);
-    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
-                            name, &errp);
-    assert_no_error(errp);
-}
-
-void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
-{
-    Property *prop;
-    void **ptr;
-
-    prop = qdev_prop_find(dev, name);
-    assert(prop && prop->info == &qdev_prop_ptr);
-    ptr = qdev_get_prop_ptr(dev, prop);
-    *ptr = value;
-}
-
-static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
-
-void qdev_prop_register_global(GlobalProperty *prop)
-{
-    QTAILQ_INSERT_TAIL(&global_props, prop, next);
-}
-
-void qdev_prop_register_global_list(GlobalProperty *props)
-{
-    int i;
-
-    for (i = 0; props[i].driver != NULL; i++) {
-        qdev_prop_register_global(props+i);
-    }
-}
-
-void qdev_prop_set_globals(DeviceState *dev)
-{
-    ObjectClass *class = object_get_class(OBJECT(dev));
-
-    do {
-        GlobalProperty *prop;
-        QTAILQ_FOREACH(prop, &global_props, next) {
-            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
-                continue;
-            }
-            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
-                exit(1);
-            }
-        }
-        class = object_class_get_parent(class);
-    } while (class);
-}
-
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 5ef060a..09ef871 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,4 +1,4 @@
 qom-obj-y = object.o container.o qom-qobject.o
-qom-obj-twice-y = cpu.o
+qom-obj-twice-y = cpu.o qdev-core.o qdev-properties.o
 common-obj-y = $(qom-obj-twice-y)
 user-obj-y = $(qom-obj-twice-y)
diff --git a/qom/qdev-core.c b/qom/qdev-core.c
new file mode 100644
index 0000000..fbb7cb5
--- /dev/null
+++ b/qom/qdev-core.c
@@ -0,0 +1,727 @@
+/*
+ *  Dynamic device configuration and creation.
+ *
+ *  Copyright (c) 2009 CodeSourcery
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The theory here is that it should be possible to create a machine without
+   knowledge of specific devices.  Historically board init routines have
+   passed a bunch of arguments to each device, requiring the board know
+   exactly which device it is dealing with.  This file provides an abstract
+   API for device configuration and initialization.  Devices will generally
+   inherit from a particular bus (e.g. PCI or I2C) rather than
+   this API directly.  */
+
+#include "hw/qdev.h"
+#include "sysemu.h"
+#include "error.h"
+#include "qapi/qapi-visit-core.h"
+
+int qdev_hotplug = 0;
+static bool qdev_hot_added = false;
+static bool qdev_hot_removed = false;
+
+/* vmstate handling:
+ *
+ * The real implementations are on qdev-system.c. Those are weak symbols
+ * used by *-user.
+ */
+void GCC_WEAK qdev_init_vmstate(DeviceState *dev)
+{
+}
+
+void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
+{
+}
+
+/* reset handler register/unregister:
+ *
+ * The real implementations are on qdev-system.c. Those are weak symbols
+ * used by *-user.
+ */
+void GCC_WEAK qbus_register_reset(BusState *bus)
+{
+}
+
+void GCC_WEAK qbus_unregister_reset(BusState *bus)
+{
+}
+
+const char *qdev_fw_name(DeviceState *dev)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (dc->fw_name) {
+        return dc->fw_name;
+    }
+
+    return object_get_typename(OBJECT(dev));
+}
+
+static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+                                     Error **errp);
+
+static void bus_remove_child(BusState *bus, DeviceState *child)
+{
+    BusChild *kid;
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        if (kid->child == child) {
+            char name[32];
+
+            snprintf(name, sizeof(name), "child[%d]", kid->index);
+            QTAILQ_REMOVE(&bus->children, kid, sibling);
+            object_property_del(OBJECT(bus), name, NULL);
+            g_free(kid);
+            return;
+        }
+    }
+}
+
+static void bus_add_child(BusState *bus, DeviceState *child)
+{
+    char name[32];
+    BusChild *kid = g_malloc0(sizeof(*kid));
+
+    if (qdev_hotplug) {
+        assert(bus->allow_hotplug);
+    }
+
+    kid->index = bus->max_index++;
+    kid->child = child;
+
+    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
+
+    snprintf(name, sizeof(name), "child[%d]", kid->index);
+    object_property_add_link(OBJECT(bus), name,
+                             object_get_typename(OBJECT(child)),
+                             (Object **)&kid->child,
+                             NULL);
+}
+
+void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+{
+    dev->parent_bus = bus;
+    bus_add_child(bus, 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.
+   On failure, destroy the device and return negative value.
+   Return 0 on success.  */
+int qdev_init(DeviceState *dev)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    int rc;
+
+    assert(dev->state == DEV_STATE_CREATED);
+
+    rc = dc->init(dev);
+    if (rc < 0) {
+        qdev_free(dev);
+        return rc;
+    }
+
+    if (!OBJECT(dev)->parent) {
+        static int unattached_count = 0;
+        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
+
+        object_property_add_child(container_get(qdev_get_machine(),
+                                                "/unattached"),
+                                  name, OBJECT(dev), NULL);
+        g_free(name);
+    }
+
+    qdev_init_vmstate(dev);
+    dev->state = DEV_STATE_INITIALIZED;
+    if (dev->hotplugged) {
+        device_reset(dev);
+    }
+    return 0;
+}
+
+void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
+                                 int required_for_version)
+{
+    assert(dev->state == DEV_STATE_CREATED);
+    dev->instance_id_alias = alias_id;
+    dev->alias_required_for_version = required_for_version;
+}
+
+void qdev_unplug(DeviceState *dev, Error **errp)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (!dev->parent_bus->allow_hotplug) {
+        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
+        return;
+    }
+    assert(dc->unplug != NULL);
+
+    qdev_hot_removed = true;
+
+    if (dc->unplug(dev) < 0) {
+        error_set(errp, QERR_UNDEFINED_ERROR);
+        return;
+    }
+}
+
+static int qdev_reset_one(DeviceState *dev, void *opaque)
+{
+    device_reset(dev);
+
+    return 0;
+}
+
+static int qbus_reset_one(BusState *bus, void *opaque)
+{
+    BusClass *bc = BUS_GET_CLASS(bus);
+    if (bc->reset) {
+        return bc->reset(bus);
+    }
+    return 0;
+}
+
+void qdev_reset_all(DeviceState *dev)
+{
+    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
+}
+
+void qbus_reset_all_fn(void *opaque)
+{
+    BusState *bus = opaque;
+    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
+}
+
+/* can be used as ->unplug() callback for the simple cases */
+int qdev_simple_unplug_cb(DeviceState *dev)
+{
+    /* just zap it */
+    qdev_free(dev);
+    return 0;
+}
+
+
+/* Like qdev_init(), but terminate program via error_report() instead of
+   returning an error value.  This is okay during machine creation.
+   Don't use for hotplug, because there callers need to recover from
+   failure.  Exception: if you know the device's init() callback can't
+   fail, then qdev_init_nofail() can't fail either, and is therefore
+   usable even then.  But relying on the device implementation that
+   way is somewhat unclean, and best avoided.  */
+void qdev_init_nofail(DeviceState *dev)
+{
+    const char *typename = object_get_typename(OBJECT(dev));
+
+    if (qdev_init(dev) < 0) {
+        error_report("Initialization of device %s failed", typename);
+        exit(1);
+    }
+}
+
+/* Unlink device from bus and free the structure.  */
+void qdev_free(DeviceState *dev)
+{
+    object_delete(OBJECT(dev));
+}
+
+void qdev_machine_creation_done(void)
+{
+    /*
+     * ok, initial machine setup is done, starting from now we can
+     * only create hotpluggable devices
+     */
+    qdev_hotplug = 1;
+}
+
+bool qdev_machine_modified(void)
+{
+    return qdev_hot_added || qdev_hot_removed;
+}
+
+BusState *qdev_get_parent_bus(DeviceState *dev)
+{
+    return dev->parent_bus;
+}
+
+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)
+{
+    BusChild *kid;
+    int err;
+
+    if (busfn) {
+        err = busfn(bus, opaque);
+        if (err) {
+            return err;
+        }
+    }
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
+        if (err < 0) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
+                       qbus_walkerfn *busfn, void *opaque)
+{
+    BusState *bus;
+    int err;
+
+    if (devfn) {
+        err = devfn(dev, opaque);
+        if (err) {
+            return err;
+        }
+    }
+
+    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+        err = qbus_walk_children(bus, devfn, busfn, opaque);
+        if (err < 0) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+DeviceState *qdev_find_recursive(BusState *bus, const char *id)
+{
+    BusChild *kid;
+    DeviceState *ret;
+    BusState *child;
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
+
+        if (dev->id && strcmp(dev->id, id) == 0) {
+            return dev;
+        }
+
+        QLIST_FOREACH(child, &dev->child_bus, sibling) {
+            ret = qdev_find_recursive(child, id);
+            if (ret) {
+                return ret;
+            }
+        }
+    }
+    return NULL;
+}
+
+static void qbus_realize(BusState *bus)
+{
+    const char *typename = object_get_typename(OBJECT(bus));
+    char *buf;
+    int i,len;
+
+    if (bus->name) {
+        /* use supplied name */
+    } else if (bus->parent && bus->parent->id) {
+        /* parent device has id -> use it for bus name */
+        len = strlen(bus->parent->id) + 16;
+        buf = g_malloc(len);
+        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
+        bus->name = buf;
+    } else {
+        /* no id -> use lowercase bus type for bus name */
+        len = strlen(typename) + 16;
+        buf = g_malloc(len);
+        len = snprintf(buf, len, "%s.%d", typename,
+                       bus->parent ? bus->parent->num_child_bus : 0);
+        for (i = 0; i < len; i++)
+            buf[i] = qemu_tolower(buf[i]);
+        bus->name = buf;
+    }
+
+    if (bus->parent) {
+        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
+        bus->parent->num_child_bus++;
+        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
+    } else {
+        qbus_register_reset(bus);
+    }
+}
+
+void qbus_create_inplace(BusState *bus, const char *typename,
+                         DeviceState *parent, const char *name)
+{
+    object_initialize(bus, typename);
+
+    bus->parent = parent;
+    bus->name = name ? g_strdup(name) : NULL;
+    qbus_realize(bus);
+}
+
+BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
+{
+    BusState *bus;
+
+    bus = BUS(object_new(typename));
+    bus->qom_allocated = true;
+
+    bus->parent = parent;
+    bus->name = name ? g_strdup(name) : NULL;
+    qbus_realize(bus);
+
+    return bus;
+}
+
+void qbus_free(BusState *bus)
+{
+    if (bus->qom_allocated) {
+        object_delete(OBJECT(bus));
+    } else {
+        object_finalize(OBJECT(bus));
+        if (bus->glib_allocated) {
+            g_free(bus);
+        }
+    }
+}
+
+static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
+{
+    BusClass *bc = BUS_GET_CLASS(bus);
+
+    if (bc->get_fw_dev_path) {
+        return bc->get_fw_dev_path(dev);
+    }
+
+    return NULL;
+}
+
+static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
+{
+    int l = 0;
+
+    if (dev && dev->parent_bus) {
+        char *d;
+        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
+        d = bus_get_fw_dev_path(dev->parent_bus, dev);
+        if (d) {
+            l += snprintf(p + l, size - l, "%s", d);
+            g_free(d);
+        } else {
+            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
+        }
+    }
+    l += snprintf(p + l , size - l, "/");
+
+    return l;
+}
+
+char* qdev_get_fw_dev_path(DeviceState *dev)
+{
+    char path[128];
+    int l;
+
+    l = qdev_get_fw_dev_path_helper(dev, path, 128);
+
+    path[l-1] = '\0';
+
+    return g_strdup(path);
+}
+
+char *qdev_get_dev_path(DeviceState *dev)
+{
+    BusClass *bc;
+
+    if (!dev || !dev->parent_bus) {
+        return NULL;
+    }
+
+    bc = BUS_GET_CLASS(dev->parent_bus);
+    if (bc->get_dev_path) {
+        return bc->get_dev_path(dev);
+    }
+
+    return NULL;
+}
+
+/**
+ * Legacy property handling
+ */
+
+static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+
+    char buffer[1024];
+    char *ptr = buffer;
+
+    prop->info->print(dev, prop, buffer, sizeof(buffer));
+    visit_type_str(v, &ptr, name, errp);
+}
+
+static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    char *ptr = NULL;
+    int ret;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_str(v, &ptr, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    ret = prop->info->parse(dev, prop, ptr);
+    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
+    g_free(ptr);
+}
+
+/**
+ * @qdev_add_legacy_property - adds a legacy property
+ *
+ * Do not use this is new code!  Properties added through this interface will
+ * be given names and types in the "legacy" namespace.
+ *
+ * Legacy properties are string versions of other OOM properties.  The format
+ * of the string depends on the property type.
+ */
+void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+                              Error **errp)
+{
+    gchar *name, *type;
+
+    /* Register pointer properties as legacy properties */
+    if (!prop->info->print && !prop->info->parse &&
+        (prop->info->set || prop->info->get)) {
+        return;
+    }
+
+    name = g_strdup_printf("legacy-%s", prop->name);
+    type = g_strdup_printf("legacy<%s>",
+                           prop->info->legacy_name ?: prop->info->name);
+
+    object_property_add(OBJECT(dev), name, type,
+                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
+                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
+                        NULL,
+                        prop, errp);
+
+    g_free(type);
+    g_free(name);
+}
+
+/**
+ * @qdev_property_add_static - add a @Property to a device.
+ *
+ * Static properties access data in a struct.  The actual type of the
+ * property and the field depends on the property type.
+ */
+void qdev_property_add_static(DeviceState *dev, Property *prop,
+                              Error **errp)
+{
+    Error *local_err = NULL;
+    Object *obj = OBJECT(dev);
+
+    /*
+     * TODO qdev_prop_ptr does not have getters or setters.  It must
+     * go now that it can be replaced with links.  The test should be
+     * removed along with it: all static properties are read/write.
+     */
+    if (!prop->info->get && !prop->info->set) {
+        return;
+    }
+
+    object_property_add(obj, prop->name, prop->info->name,
+                        prop->info->get, prop->info->set,
+                        prop->info->release,
+                        prop, &local_err);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (prop->qtype == QTYPE_NONE) {
+        return;
+    }
+
+    if (prop->qtype == QTYPE_QBOOL) {
+        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
+    } else if (prop->info->enum_table) {
+        object_property_set_str(obj, prop->info->enum_table[prop->defval],
+                                prop->name, &local_err);
+    } else if (prop->qtype == QTYPE_QINT) {
+        object_property_set_int(obj, prop->defval, prop->name, &local_err);
+    }
+    assert_no_error(local_err);
+}
+
+static void device_initfn(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    ObjectClass *class;
+    Property *prop;
+
+    if (qdev_hotplug) {
+        dev->hotplugged = 1;
+        qdev_hot_added = true;
+    }
+
+    dev->instance_id_alias = -1;
+    dev->state = DEV_STATE_CREATED;
+
+    class = object_get_class(OBJECT(dev));
+    do {
+        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
+            qdev_property_add_legacy(dev, prop, NULL);
+            qdev_property_add_static(dev, prop, NULL);
+        }
+        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);
+}
+
+/* Unlink device from bus and free the structure.  */
+static void device_finalize(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    BusState *bus;
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (dev->state == DEV_STATE_INITIALIZED) {
+        while (dev->num_child_bus) {
+            bus = QLIST_FIRST(&dev->child_bus);
+            qbus_free(bus);
+        }
+        qdev_finalize_vmstate(dev);
+        if (dc->exit) {
+            dc->exit(dev);
+        }
+        if (dev->opts) {
+            qemu_opts_del(dev->opts);
+        }
+    }
+    if (dev->parent_bus) {
+        bus_remove_child(dev->parent_bus, dev);
+    }
+}
+
+static void device_class_base_init(ObjectClass *class, void *data)
+{
+    DeviceClass *klass = DEVICE_CLASS(class);
+
+    /* We explicitly look up properties in the superclasses,
+     * so do not propagate them to the subclasses.
+     */
+    klass->props = NULL;
+}
+
+void device_reset(DeviceState *dev)
+{
+    DeviceClass *klass = DEVICE_GET_CLASS(dev);
+
+    if (klass->reset) {
+        klass->reset(dev);
+    }
+}
+
+Object *qdev_get_machine(void)
+{
+    static Object *dev;
+
+    if (dev == NULL) {
+        dev = container_get(object_get_root(), "/machine");
+    }
+
+    return dev;
+}
+
+static TypeInfo device_type_info = {
+    .name = TYPE_DEVICE,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(DeviceState),
+    .instance_init = device_initfn,
+    .instance_finalize = device_finalize,
+    .class_base_init = device_class_base_init,
+    .abstract = true,
+    .class_size = sizeof(DeviceClass),
+};
+
+static void qbus_initfn(Object *obj)
+{
+    BusState *bus = BUS(obj);
+
+    QTAILQ_INIT(&bus->children);
+}
+
+static void qbus_finalize(Object *obj)
+{
+    BusState *bus = BUS(obj);
+    BusChild *kid;
+
+    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
+        DeviceState *dev = kid->child;
+        qdev_free(dev);
+    }
+    if (bus->parent) {
+        QLIST_REMOVE(bus, sibling);
+        bus->parent->num_child_bus--;
+    } else {
+        qbus_unregister_reset(bus);
+    }
+    g_free((char *)bus->name);
+}
+
+static const TypeInfo bus_info = {
+    .name = TYPE_BUS,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(BusState),
+    .abstract = true,
+    .class_size = sizeof(BusClass),
+    .instance_init = qbus_initfn,
+    .instance_finalize = qbus_finalize,
+};
+
+static void qdev_register_types(void)
+{
+    type_register_static(&bus_info);
+    type_register_static(&device_type_info);
+}
+
+type_init(qdev_register_types)
diff --git a/qom/qdev-properties.c b/qom/qdev-properties.c
new file mode 100644
index 0000000..2e82cb9
--- /dev/null
+++ b/qom/qdev-properties.c
@@ -0,0 +1,963 @@
+#include "net.h"
+#include "hw/qdev.h"
+#include "qerror.h"
+#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)
+{
+    void *ptr = dev;
+    ptr += prop->offset;
+    return ptr;
+}
+
+static void get_enum(Object *obj, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_enum(v, ptr, prop->info->enum_table,
+                    prop->info->name, prop->name, errp);
+}
+
+static void set_enum(Object *obj, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_enum(v, ptr, prop->info->enum_table,
+                    prop->info->name, prop->name, errp);
+}
+
+/* Bit */
+
+static uint32_t qdev_get_prop_mask(Property *prop)
+{
+    assert(prop->info == &qdev_prop_bit);
+    return 0x1 << prop->bitnr;
+}
+
+static void bit_prop_set(DeviceState *dev, Property *props, bool val)
+{
+    uint32_t *p = qdev_get_prop_ptr(dev, props);
+    uint32_t mask = qdev_get_prop_mask(props);
+    if (val)
+        *p |= mask;
+    else
+        *p &= ~mask;
+}
+
+static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+    uint32_t *p = qdev_get_prop_ptr(dev, prop);
+    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
+}
+
+static void get_bit(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint32_t *p = qdev_get_prop_ptr(dev, prop);
+    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
+
+    visit_type_bool(v, &value, name, errp);
+}
+
+static void set_bit(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    Error *local_err = NULL;
+    bool value;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_bool(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    bit_prop_set(dev, prop, value);
+}
+
+PropertyInfo qdev_prop_bit = {
+    .name  = "boolean",
+    .legacy_name  = "on/off",
+    .print = print_bit,
+    .get   = get_bit,
+    .set   = set_bit,
+};
+
+/* --- 8bit integer --- */
+
+static void get_uint8(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_uint8(v, ptr, name, errp);
+}
+
+static void set_uint8(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint8(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint8 = {
+    .name  = "uint8",
+    .get   = get_uint8,
+    .set   = set_uint8,
+};
+
+/* --- 8bit hex value --- */
+
+static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
+{
+    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    char *end;
+
+    if (str[0] != '0' || str[1] != 'x') {
+        return -EINVAL;
+    }
+
+    *ptr = strtoul(str, &end, 16);
+    if ((*end != '\0') || (end == str)) {
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+    return snprintf(dest, len, "0x%" PRIx8, *ptr);
+}
+
+PropertyInfo qdev_prop_hex8 = {
+    .name  = "uint8",
+    .legacy_name  = "hex8",
+    .parse = parse_hex8,
+    .print = print_hex8,
+    .get   = get_uint8,
+    .set   = set_uint8,
+};
+
+/* --- 16bit integer --- */
+
+static void get_uint16(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_uint16(v, ptr, name, errp);
+}
+
+static void set_uint16(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint16(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint16 = {
+    .name  = "uint16",
+    .get   = get_uint16,
+    .set   = set_uint16,
+};
+
+/* --- 32bit integer --- */
+
+static void get_uint32(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_uint32(v, ptr, name, errp);
+}
+
+static void set_uint32(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint32(v, ptr, name, errp);
+}
+
+static void get_int32(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_int32(v, ptr, name, errp);
+}
+
+static void set_int32(Object *obj, Visitor *v, void *opaque,
+                      const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int32(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint32 = {
+    .name  = "uint32",
+    .get   = get_uint32,
+    .set   = set_uint32,
+};
+
+PropertyInfo qdev_prop_int32 = {
+    .name  = "int32",
+    .get   = get_int32,
+    .set   = set_int32,
+};
+
+/* --- 32bit hex value --- */
+
+static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
+{
+    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    char *end;
+
+    if (str[0] != '0' || str[1] != 'x') {
+        return -EINVAL;
+    }
+
+    *ptr = strtoul(str, &end, 16);
+    if ((*end != '\0') || (end == str)) {
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+    return snprintf(dest, len, "0x%" PRIx32, *ptr);
+}
+
+PropertyInfo qdev_prop_hex32 = {
+    .name  = "uint32",
+    .legacy_name  = "hex32",
+    .parse = parse_hex32,
+    .print = print_hex32,
+    .get   = get_uint32,
+    .set   = set_uint32,
+};
+
+/* --- 64bit integer --- */
+
+static void get_uint64(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    visit_type_uint64(v, ptr, name, errp);
+}
+
+static void set_uint64(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint64(v, ptr, name, errp);
+}
+
+PropertyInfo qdev_prop_uint64 = {
+    .name  = "uint64",
+    .get   = get_uint64,
+    .set   = set_uint64,
+};
+
+/* --- 64bit hex value --- */
+
+static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
+{
+    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    char *end;
+
+    if (str[0] != '0' || str[1] != 'x') {
+        return -EINVAL;
+    }
+
+    *ptr = strtoull(str, &end, 16);
+    if ((*end != '\0') || (end == str)) {
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+    return snprintf(dest, len, "0x%" PRIx64, *ptr);
+}
+
+PropertyInfo qdev_prop_hex64 = {
+    .name  = "uint64",
+    .legacy_name  = "hex64",
+    .parse = parse_hex64,
+    .print = print_hex64,
+    .get   = get_uint64,
+    .set   = set_uint64,
+};
+
+/* --- string --- */
+
+static void release_string(Object *obj, const char *name, void *opaque)
+{
+    Property *prop = opaque;
+    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
+}
+
+static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+    char **ptr = qdev_get_prop_ptr(dev, prop);
+    if (!*ptr)
+        return snprintf(dest, len, "<null>");
+    return snprintf(dest, len, "\"%s\"", *ptr);
+}
+
+static void get_string(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    char **ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (!*ptr) {
+        char *str = (char *)"";
+        visit_type_str(v, &str, name, errp);
+    } else {
+        visit_type_str(v, ptr, name, errp);
+    }
+}
+
+static void set_string(Object *obj, Visitor *v, void *opaque,
+                       const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    char **ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    char *str;
+
+    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 (*ptr) {
+        g_free(*ptr);
+    }
+    *ptr = str;
+}
+
+PropertyInfo qdev_prop_string = {
+    .name  = "string",
+    .print = print_string,
+    .release = release_string,
+    .get   = get_string,
+    .set   = set_string,
+};
+
+/* --- pointer --- */
+
+/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
+PropertyInfo qdev_prop_ptr = {
+    .name  = "ptr",
+};
+
+/* --- mac address --- */
+
+/*
+ * accepted syntax versions:
+ *   01:02:03:04:05:06
+ *   01-02-03-04-05-06
+ */
+static void get_mac(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    char buffer[2 * 6 + 5 + 1];
+    char *p = buffer;
+
+    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
+             mac->a[0], mac->a[1], mac->a[2],
+             mac->a[3], mac->a[4], mac->a[5]);
+
+    visit_type_str(v, &p, name, errp);
+}
+
+static void set_mac(Object *obj, Visitor *v, void *opaque,
+                    const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int i, pos;
+    char *str, *p;
+
+    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;
+    }
+
+    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
+        if (!qemu_isxdigit(str[pos]))
+            goto inval;
+        if (!qemu_isxdigit(str[pos+1]))
+            goto inval;
+        if (i == 5) {
+            if (str[pos+2] != '\0')
+                goto inval;
+        } else {
+            if (str[pos+2] != ':' && str[pos+2] != '-')
+                goto inval;
+        }
+        mac->a[i] = strtol(str+pos, &p, 16);
+    }
+    g_free(str);
+    return;
+
+inval:
+    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    g_free(str);
+}
+
+PropertyInfo qdev_prop_macaddr = {
+    .name  = "macaddr",
+    .get   = get_mac,
+    .set   = set_mac,
+};
+
+/* --- lost tick policy --- */
+
+static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
+    [LOST_TICK_DISCARD] = "discard",
+    [LOST_TICK_DELAY] = "delay",
+    [LOST_TICK_MERGE] = "merge",
+    [LOST_TICK_SLEW] = "slew",
+    [LOST_TICK_MAX] = NULL,
+};
+
+QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
+
+PropertyInfo qdev_prop_losttickpolicy = {
+    .name  = "LostTickPolicy",
+    .enum_table  = lost_tick_policy_table,
+    .get   = get_enum,
+    .set   = set_enum,
+};
+
+/* --- BIOS CHS translation */
+
+static const char *bios_chs_trans_table[] = {
+    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
+    [BIOS_ATA_TRANSLATION_NONE] = "none",
+    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
+};
+
+PropertyInfo qdev_prop_bios_chs_trans = {
+    .name = "bios-chs-trans",
+    .enum_table = bios_chs_trans_table,
+    .get = get_enum,
+    .set = set_enum,
+};
+
+/* --- pci address --- */
+
+/*
+ * bus-local address, i.e. "$slot" or "$slot.$fn"
+ */
+static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    unsigned int slot, fn, n;
+    Error *local_err = NULL;
+    char *str;
+
+    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_free(local_err);
+        local_err = NULL;
+        visit_type_int32(v, &value, name, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+        } else if (value < -1 || value > 255) {
+            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
+                      "pci_devfn");
+        } else {
+            *ptr = value;
+        }
+        return;
+    }
+
+    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
+        fn = 0;
+        if (sscanf(str, "%x%n", &slot, &n) != 1) {
+            goto invalid;
+        }
+    }
+    if (str[n] != '\0' || fn > 7 || slot > 31) {
+        goto invalid;
+    }
+    *ptr = slot << 3 | fn;
+    g_free(str);
+    return;
+
+invalid:
+    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    g_free(str);
+}
+
+static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+    if (*ptr == -1) {
+        return snprintf(dest, len, "<unset>");
+    } else {
+        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
+    }
+}
+
+PropertyInfo qdev_prop_pci_devfn = {
+    .name  = "int32",
+    .legacy_name  = "pci-devfn",
+    .print = print_pci_devfn,
+    .get   = get_int32,
+    .set   = set_pci_devfn,
+};
+
+/* --- blocksize --- */
+
+static void set_blocksize(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    const int64_t min = 512;
+    const int64_t max = 32768;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_uint16(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (value < min || value > max) {
+        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+                  dev->id?:"", name, (int64_t)value, min, max);
+        return;
+    }
+
+    /* We rely on power-of-2 blocksizes for bitmasks */
+    if ((value & (value - 1)) != 0) {
+        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
+                  dev->id?:"", name, (int64_t)value);
+        return;
+    }
+
+    *ptr = value;
+}
+
+PropertyInfo qdev_prop_blocksize = {
+    .name  = "blocksize",
+    .get   = get_uint16,
+    .set   = set_blocksize,
+};
+
+/* --- pci host address --- */
+
+static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
+                                 const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    char buffer[] = "xxxx:xx:xx.x";
+    char *p = buffer;
+    int rc = 0;
+
+    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
+                  addr->domain, addr->bus, addr->slot, addr->function);
+    assert(rc == sizeof(buffer) - 1);
+
+    visit_type_str(v, &p, name, errp);
+}
+
+/*
+ * Parse [<domain>:]<bus>:<slot>.<func>
+ *   if <domain> is not supplied, it's assumed to be 0.
+ */
+static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
+                                 const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    char *str, *p;
+    char *e;
+    unsigned long val;
+    unsigned long dom = 0, bus = 0;
+    unsigned int slot = 0, func = 0;
+
+    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;
+    }
+
+    p = str;
+    val = strtoul(p, &e, 16);
+    if (e == p || *e != ':') {
+        goto inval;
+    }
+    bus = val;
+
+    p = e + 1;
+    val = strtoul(p, &e, 16);
+    if (e == p) {
+        goto inval;
+    }
+    if (*e == ':') {
+        dom = bus;
+        bus = val;
+        p = e + 1;
+        val = strtoul(p, &e, 16);
+        if (e == p) {
+            goto inval;
+        }
+    }
+    slot = val;
+
+    if (*e != '.') {
+        goto inval;
+    }
+    p = e + 1;
+    val = strtoul(p, &e, 10);
+    if (e == p) {
+        goto inval;
+    }
+    func = val;
+
+    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
+        goto inval;
+    }
+
+    if (*e) {
+        goto inval;
+    }
+
+    addr->domain = dom;
+    addr->bus = bus;
+    addr->slot = slot;
+    addr->function = func;
+
+    g_free(str);
+    return;
+
+inval:
+    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+    g_free(str);
+}
+
+PropertyInfo qdev_prop_pci_host_devaddr = {
+    .name = "pci-host-devaddr",
+    .get = get_pci_host_devaddr,
+    .set = set_pci_host_devaddr,
+};
+
+/* --- public helpers --- */
+
+static Property *qdev_prop_walk(Property *props, const char *name)
+{
+    if (!props)
+        return NULL;
+    while (props->name) {
+        if (strcmp(props->name, name) == 0)
+            return props;
+        props++;
+    }
+    return NULL;
+}
+
+static Property *qdev_prop_find(DeviceState *dev, const char *name)
+{
+    ObjectClass *class;
+    Property *prop;
+
+    /* device properties */
+    class = object_get_class(OBJECT(dev));
+    do {
+        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
+        if (prop) {
+            return prop;
+        }
+        class = object_class_get_parent(class);
+    } while (class != object_class_by_name(TYPE_DEVICE));
+
+    return NULL;
+}
+
+void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+                                    Property *prop, const char *value)
+{
+    switch (ret) {
+    case -EEXIST:
+        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
+                  object_get_typename(OBJECT(dev)), prop->name, value);
+        break;
+    default:
+    case -EINVAL:
+        error_set(errp, QERR_PROPERTY_VALUE_BAD,
+                  object_get_typename(OBJECT(dev)), prop->name, value);
+        break;
+    case -ENOENT:
+        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
+                  object_get_typename(OBJECT(dev)), prop->name, value);
+        break;
+    case 0:
+        break;
+    }
+}
+
+int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
+{
+    char *legacy_name;
+    Error *err = NULL;
+
+    legacy_name = g_strdup_printf("legacy-%s", name);
+    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
+        object_property_parse(OBJECT(dev), value, legacy_name, &err);
+    } else {
+        object_property_parse(OBJECT(dev), value, name, &err);
+    }
+    g_free(legacy_name);
+
+    if (err) {
+        qerror_report_err(err);
+        error_free(err);
+        return -1;
+    }
+    return 0;
+}
+
+void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
+{
+    Error *errp = NULL;
+    object_property_set_bool(OBJECT(dev), value, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
+{
+    Error *errp = NULL;
+    object_property_set_int(OBJECT(dev), value, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
+{
+    Error *errp = NULL;
+    object_property_set_int(OBJECT(dev), value, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
+{
+    Error *errp = NULL;
+    object_property_set_int(OBJECT(dev), value, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
+{
+    Error *errp = NULL;
+    object_property_set_int(OBJECT(dev), value, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
+{
+    Error *errp = NULL;
+    object_property_set_int(OBJECT(dev), value, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
+{
+    Error *errp = NULL;
+    object_property_set_str(OBJECT(dev), value, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
+{
+    Error *errp = NULL;
+    char str[2 * 6 + 5 + 1];
+    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
+             value[0], value[1], value[2], value[3], value[4], value[5]);
+
+    object_property_set_str(OBJECT(dev), str, name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
+{
+    Property *prop;
+    Error *errp = NULL;
+
+    prop = qdev_prop_find(dev, name);
+    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
+                            name, &errp);
+    assert_no_error(errp);
+}
+
+void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
+{
+    Property *prop;
+    void **ptr;
+
+    prop = qdev_prop_find(dev, name);
+    assert(prop && prop->info == &qdev_prop_ptr);
+    ptr = qdev_get_prop_ptr(dev, prop);
+    *ptr = value;
+}
+
+static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
+
+void qdev_prop_register_global(GlobalProperty *prop)
+{
+    QTAILQ_INSERT_TAIL(&global_props, prop, next);
+}
+
+void qdev_prop_register_global_list(GlobalProperty *props)
+{
+    int i;
+
+    for (i = 0; props[i].driver != NULL; i++) {
+        qdev_prop_register_global(props+i);
+    }
+}
+
+void qdev_prop_set_globals(DeviceState *dev)
+{
+    ObjectClass *class = object_get_class(OBJECT(dev));
+
+    do {
+        GlobalProperty *prop;
+        QTAILQ_FOREACH(prop, &global_props, next) {
+            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
+                continue;
+            }
+            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
+                exit(1);
+            }
+        }
+        class = object_class_get_parent(class);
+    } while (class);
+}
+
-- 
1.7.11.7

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

* [Qemu-devel] [PATCH 12/12] qom: make CPU a child of DeviceState
  2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
                   ` (10 preceding siblings ...)
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too Eduardo Habkost
@ 2012-10-16 19:08 ` Eduardo Habkost
  11 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-16 19:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, riku.voipio, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

From: Igor Mammedov <imammedo@redhat.com>

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
[ehabkost: change CPU type declaration to hae TYPE_DEVICE as parent]
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
Yes, there is "changelog" data before the "---" mark, but I believe that
in this case they are important to indicate authorship and the scope of
the Signed-off-by lines (so they need to get into the git commit
message).
---
 include/qemu/cpu.h | 6 +++---
 qom/cpu.c          | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
index ad706a6..ac44057 100644
--- a/include/qemu/cpu.h
+++ b/include/qemu/cpu.h
@@ -20,7 +20,7 @@
 #ifndef QEMU_CPU_H
 #define QEMU_CPU_H
 
-#include "qemu/object.h"
+#include "hw/qdev-core.h"
 #include "qemu-thread.h"
 
 /**
@@ -46,7 +46,7 @@ typedef struct CPUState CPUState;
  */
 typedef struct CPUClass {
     /*< private >*/
-    ObjectClass parent_class;
+    DeviceClass parent_class;
     /*< public >*/
 
     void (*reset)(CPUState *cpu);
@@ -59,7 +59,7 @@ typedef struct CPUClass {
  */
 struct CPUState {
     /*< private >*/
-    Object parent_obj;
+    DeviceState parent_obj;
     /*< public >*/
 
     struct QemuThread *thread;
diff --git a/qom/cpu.c b/qom/cpu.c
index 5b36046..f59db7d 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -20,6 +20,7 @@
 
 #include "qemu/cpu.h"
 #include "qemu-common.h"
+#include "hw/qdev-core.h"
 
 void cpu_reset(CPUState *cpu)
 {
@@ -43,7 +44,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
 
 static TypeInfo cpu_type_info = {
     .name = TYPE_CPU,
-    .parent = TYPE_OBJECT,
+    .parent = TYPE_DEVICE,
     .instance_size = sizeof(CPUState),
     .abstract = true,
     .class_size = sizeof(CPUClass),
-- 
1.7.11.7

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

* Re: [Qemu-devel] [PATCH 05/12] qdev-core: isolate vmstate handling into separate functions
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 05/12] qdev-core: isolate vmstate handling into separate functions Eduardo Habkost
@ 2012-10-17 18:06   ` Anthony Liguori
  0 siblings, 0 replies; 27+ messages in thread
From: Anthony Liguori @ 2012-10-17 18:06 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: blauwirbel, Igor Mammedov, riku.voipio, Andreas Färber,
	peter.maydell

Eduardo Habkost <ehabkost@redhat.com> writes:

> Those functions will eventually be moved somewhere else, and won't get
> included on *-user.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  hw/qdev-core.c | 26 ++++++++++++++++++--------
>  1 file changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/hw/qdev-core.c b/hw/qdev-core.c
> index ee19dd5..92c3021 100644
> --- a/hw/qdev-core.c
> +++ b/hw/qdev-core.c
> @@ -40,6 +40,22 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
>      return dc->vmsd;
>  }
>  
> +static void qdev_init_vmstate(DeviceState *dev)
> +{
> +    if (qdev_get_vmsd(dev)) {
> +        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
> +                                       dev->instance_id_alias,
> +                                       dev->alias_required_for_version);
> +    }
> +}
> +
> +static void qdev_finalize_vmstate(DeviceState *dev)
> +{
> +    if (qdev_get_vmsd(dev)) {
> +        vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
> +    }
> +}
> +

You're stubbing at the wrong level.  The place to implement stubs ought
to be vmstate_register/vmstate_unregister.

Regards,

Anthony Liguori

>  const char *qdev_fw_name(DeviceState *dev)
>  {
>      DeviceClass *dc = DEVICE_GET_CLASS(dev);
> @@ -126,11 +142,7 @@ int qdev_init(DeviceState *dev)
>          g_free(name);
>      }
>  
> -    if (qdev_get_vmsd(dev)) {
> -        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
> -                                       dev->instance_id_alias,
> -                                       dev->alias_required_for_version);
> -    }
> +    qdev_init_vmstate(dev);
>      dev->state = DEV_STATE_INITIALIZED;
>      if (dev->hotplugged) {
>          device_reset(dev);
> @@ -615,9 +627,7 @@ static void device_finalize(Object *obj)
>              bus = QLIST_FIRST(&dev->child_bus);
>              qbus_free(bus);
>          }
> -        if (qdev_get_vmsd(dev)) {
> -            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
> -        }
> +        qdev_finalize_vmstate(dev);
>          if (dc->exit) {
>              dc->exit(dev);
>          }
> -- 
> 1.7.11.7

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

* Re: [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code Eduardo Habkost
@ 2012-10-17 18:08   ` Anthony Liguori
  2012-10-17 18:32     ` Eduardo Habkost
  2012-10-23 14:56     ` Eduardo Habkost
  0 siblings, 2 replies; 27+ messages in thread
From: Anthony Liguori @ 2012-10-17 18:08 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: blauwirbel, Igor Mammedov, riku.voipio, Andreas Färber,
	peter.maydell

Eduardo Habkost <ehabkost@redhat.com> writes:

> The reset register/unregister code is specific to qemu-system-*, so
> isolate it so it can be moved to qdev-system.c.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  hw/qdev-core.c | 24 ++++++++++++++++++------
>  1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/hw/qdev-core.c b/hw/qdev-core.c
> index af0af52..a105679 100644
> --- a/hw/qdev-core.c
> +++ b/hw/qdev-core.c
> @@ -47,6 +47,21 @@ void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
>  {
>  }
>  
> +static void qbus_register_reset(BusState *bus)
> +{
> +    if (bus != sysbus_get_default()) {
> +        /* TODO: once all bus devices are qdevified,
> +           only reset handler for main_system_bus should be registered here. */
> +        qemu_register_reset(qbus_reset_all_fn, bus);
> +    }
> +}
> +
> +static void qbus_unregister_reset(BusState *bus)
> +{
> +    assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> +    qemu_unregister_reset(qbus_reset_all_fn, bus);
> +}
> +

Again, I'd suggest stubbing out qemu_[un]register_reset instead of
trying to cope with it's users.

Regards,

Anthony Liguori

>  const char *qdev_fw_name(DeviceState *dev)
>  {
>      DeviceClass *dc = DEVICE_GET_CLASS(dev);
> @@ -355,10 +370,8 @@ static void qbus_realize(BusState *bus)
>          QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
>          bus->parent->num_child_bus++;
>          object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> -    } else if (bus != sysbus_get_default()) {
> -        /* TODO: once all bus devices are qdevified,
> -           only reset handler for main_system_bus should be registered here. */
> -        qemu_register_reset(qbus_reset_all_fn, bus);
> +    } else {
> +        qbus_register_reset(bus);
>      }
>  }
>  
> @@ -692,8 +705,7 @@ static void qbus_finalize(Object *obj)
>          QLIST_REMOVE(bus, sibling);
>          bus->parent->num_child_bus--;
>      } else {
> -        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> -        qemu_unregister_reset(qbus_reset_all_fn, bus);
> +        qbus_unregister_reset(bus);
>      }
>      g_free((char *)bus->name);
>  }
> -- 
> 1.7.11.7

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

* Re: [Qemu-devel] [PATCH 09/12] move qemu_irq typedef out of cpu-common.h
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 09/12] move qemu_irq typedef out of cpu-common.h Eduardo Habkost
@ 2012-10-17 18:08   ` Anthony Liguori
  0 siblings, 0 replies; 27+ messages in thread
From: Anthony Liguori @ 2012-10-17 18:08 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: blauwirbel, Igor Mammedov, riku.voipio, Andreas Färber,
	peter.maydell

Eduardo Habkost <ehabkost@redhat.com> writes:

> From: Igor Mammedov <imammedo@redhat.com>
>
> it's necessary for making CPU child of DEVICE without
> causing circular header deps.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
> Changes v2 -> v3:
>   imammedo: sysemu.h doesn't need irq.h since 013c2f150
> ---
>  hw/arm-misc.h | 1 +
>  hw/bt.h       | 2 ++
>  hw/devices.h  | 2 ++
>  hw/omap.h     | 1 +
>  hw/soc_dma.h  | 1 +
>  hw/xen.h      | 1 +
>  qemu-common.h | 1 -
>  7 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/hw/arm-misc.h b/hw/arm-misc.h
> index bdd8fec..b13aa59 100644
> --- a/hw/arm-misc.h
> +++ b/hw/arm-misc.h
> @@ -12,6 +12,7 @@
>  #define ARM_MISC_H 1
>  
>  #include "memory.h"
> +#include "hw/irq.h"
>  
>  /* The CPU is also modeled as an interrupt controller.  */
>  #define ARM_PIC_CPU_IRQ 0
> diff --git a/hw/bt.h b/hw/bt.h
> index a48b8d4..ebf6a37 100644
> --- a/hw/bt.h
> +++ b/hw/bt.h
> @@ -23,6 +23,8 @@
>   * along with this program; if not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include "hw/irq.h"
> +
>  /* BD Address */
>  typedef struct {
>      uint8_t b[6];
> diff --git a/hw/devices.h b/hw/devices.h
> index 1a55c1e..c60bcab 100644
> --- a/hw/devices.h
> +++ b/hw/devices.h
> @@ -1,6 +1,8 @@
>  #ifndef QEMU_DEVICES_H
>  #define QEMU_DEVICES_H
>  
> +#include "hw/irq.h"
> +
>  /* ??? Not all users of this file can include cpu-common.h.  */
>  struct MemoryRegion;
>  
> diff --git a/hw/omap.h b/hw/omap.h
> index 413851b..8b08462 100644
> --- a/hw/omap.h
> +++ b/hw/omap.h
> @@ -19,6 +19,7 @@
>  #ifndef hw_omap_h
>  #include "memory.h"
>  # define hw_omap_h		"omap.h"
> +#include "hw/irq.h"
>  
>  # define OMAP_EMIFS_BASE	0x00000000
>  # define OMAP2_Q0_BASE		0x00000000
> diff --git a/hw/soc_dma.h b/hw/soc_dma.h
> index 904b26c..e386ace 100644
> --- a/hw/soc_dma.h
> +++ b/hw/soc_dma.h
> @@ -19,6 +19,7 @@
>   */
>  
>  #include "memory.h"
> +#include "hw/irq.h"
>  
>  struct soc_dma_s;
>  struct soc_dma_ch_s;
> diff --git a/hw/xen.h b/hw/xen.h
> index d14e92d..e3cca7f 100644
> --- a/hw/xen.h
> +++ b/hw/xen.h
> @@ -8,6 +8,7 @@
>   */
>  #include <inttypes.h>
>  
> +#include "hw/irq.h"
>  #include "qemu-common.h"
>  
>  /* xen-machine.c */
> diff --git a/qemu-common.h b/qemu-common.h
> index b54612b..95585b8 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -286,7 +286,6 @@ typedef struct PCIEPort PCIEPort;
>  typedef struct PCIESlot PCIESlot;
>  typedef struct MSIMessage MSIMessage;
>  typedef struct SerialState SerialState;
> -typedef struct IRQState *qemu_irq;
>  typedef struct PCMCIACardState PCMCIACardState;
>  typedef struct MouseTransformInfo MouseTransformInfo;
>  typedef struct uWireSlave uWireSlave;
> -- 
> 1.7.11.7

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

* Re: [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too Eduardo Habkost
@ 2012-10-17 18:11   ` Anthony Liguori
  2012-10-17 18:18     ` Eduardo Habkost
  2012-10-17 19:21     ` Peter Maydell
  2012-10-22 12:36   ` Igor Mammedov
  1 sibling, 2 replies; 27+ messages in thread
From: Anthony Liguori @ 2012-10-17 18:11 UTC (permalink / raw)
  To: Eduardo Habkost, qemu-devel
  Cc: blauwirbel, Igor Mammedov, riku.voipio, Andreas Färber,
	peter.maydell

Eduardo Habkost <ehabkost@redhat.com> writes:

> The code depends on some functions from qemu-option.o, so add
> qemu-option.o to universal-obj-y to make sure it's included.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  Makefile.objs         |   3 +
>  hw/Makefile.objs      |   2 +-
>  hw/qdev-core.c        | 727 -------------------------------------
>  hw/qdev-properties.c  | 963 --------------------------------------------------
>  qom/Makefile.objs     |   2 +-
>  qom/qdev-core.c       | 727 +++++++++++++++++++++++++++++++++++++
>  qom/qdev-properties.c | 963 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 1695 insertions(+), 1692 deletions(-)
>  delete mode 100644 hw/qdev-core.c
>  delete mode 100644 hw/qdev-properties.c
>  create mode 100644 qom/qdev-core.c
>  create mode 100644 qom/qdev-properties.c

Stick the following in your .git/config:

[diff]
        renames = true

It's dangerously close to bike-shedding, but i don't think qdev belongs
in qom/.  It's not core infrastructure.  It's the device base class and
belongs IMHO in hw/.

Regards,

Anthony Liguori

>
> diff --git a/Makefile.objs b/Makefile.objs
> index 74b3542..fcd1336 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -16,6 +16,9 @@ universal-obj-y += $(qobject-obj-y)
>  qom-obj-y = qom/
>  
>  universal-obj-y += $(qom-obj-y)
> +# QOM qdev-core.o requires qemu-option.o:
> +universal-obj-y += qemu-option.o
> +
>  
>  #######################################################################
>  # oslib-obj-y is code depending on the OS (win32 vs posix)
> diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> index 70f2014..3ce38d2 100644
> --- a/hw/Makefile.objs
> +++ b/hw/Makefile.objs
> @@ -180,7 +180,7 @@ common-obj-$(CONFIG_SD) += sd.o
>  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-core.o qdev-properties.o qdev-monitor.o
> +common-obj-y += qdev-monitor.o
>  common-obj-y += qdev-system.o qdev-properties-system.o
>  common-obj-$(CONFIG_BRLAPI) += baum.o
>  
> diff --git a/hw/qdev-core.c b/hw/qdev-core.c
> deleted file mode 100644
> index fbb7cb5..0000000
> --- a/hw/qdev-core.c
> +++ /dev/null
> @@ -1,727 +0,0 @@
> -/*
> - *  Dynamic device configuration and creation.
> - *
> - *  Copyright (c) 2009 CodeSourcery
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2 of the License, or (at your option) any later version.
> - *
> - * This library is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -/* The theory here is that it should be possible to create a machine without
> -   knowledge of specific devices.  Historically board init routines have
> -   passed a bunch of arguments to each device, requiring the board know
> -   exactly which device it is dealing with.  This file provides an abstract
> -   API for device configuration and initialization.  Devices will generally
> -   inherit from a particular bus (e.g. PCI or I2C) rather than
> -   this API directly.  */
> -
> -#include "hw/qdev.h"
> -#include "sysemu.h"
> -#include "error.h"
> -#include "qapi/qapi-visit-core.h"
> -
> -int qdev_hotplug = 0;
> -static bool qdev_hot_added = false;
> -static bool qdev_hot_removed = false;
> -
> -/* vmstate handling:
> - *
> - * The real implementations are on qdev-system.c. Those are weak symbols
> - * used by *-user.
> - */
> -void GCC_WEAK qdev_init_vmstate(DeviceState *dev)
> -{
> -}
> -
> -void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
> -{
> -}
> -
> -/* reset handler register/unregister:
> - *
> - * The real implementations are on qdev-system.c. Those are weak symbols
> - * used by *-user.
> - */
> -void GCC_WEAK qbus_register_reset(BusState *bus)
> -{
> -}
> -
> -void GCC_WEAK qbus_unregister_reset(BusState *bus)
> -{
> -}
> -
> -const char *qdev_fw_name(DeviceState *dev)
> -{
> -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> -
> -    if (dc->fw_name) {
> -        return dc->fw_name;
> -    }
> -
> -    return object_get_typename(OBJECT(dev));
> -}
> -
> -static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> -                                     Error **errp);
> -
> -static void bus_remove_child(BusState *bus, DeviceState *child)
> -{
> -    BusChild *kid;
> -
> -    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> -        if (kid->child == child) {
> -            char name[32];
> -
> -            snprintf(name, sizeof(name), "child[%d]", kid->index);
> -            QTAILQ_REMOVE(&bus->children, kid, sibling);
> -            object_property_del(OBJECT(bus), name, NULL);
> -            g_free(kid);
> -            return;
> -        }
> -    }
> -}
> -
> -static void bus_add_child(BusState *bus, DeviceState *child)
> -{
> -    char name[32];
> -    BusChild *kid = g_malloc0(sizeof(*kid));
> -
> -    if (qdev_hotplug) {
> -        assert(bus->allow_hotplug);
> -    }
> -
> -    kid->index = bus->max_index++;
> -    kid->child = child;
> -
> -    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
> -
> -    snprintf(name, sizeof(name), "child[%d]", kid->index);
> -    object_property_add_link(OBJECT(bus), name,
> -                             object_get_typename(OBJECT(child)),
> -                             (Object **)&kid->child,
> -                             NULL);
> -}
> -
> -void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
> -{
> -    dev->parent_bus = bus;
> -    bus_add_child(bus, 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.
> -   On failure, destroy the device and return negative value.
> -   Return 0 on success.  */
> -int qdev_init(DeviceState *dev)
> -{
> -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> -    int rc;
> -
> -    assert(dev->state == DEV_STATE_CREATED);
> -
> -    rc = dc->init(dev);
> -    if (rc < 0) {
> -        qdev_free(dev);
> -        return rc;
> -    }
> -
> -    if (!OBJECT(dev)->parent) {
> -        static int unattached_count = 0;
> -        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
> -
> -        object_property_add_child(container_get(qdev_get_machine(),
> -                                                "/unattached"),
> -                                  name, OBJECT(dev), NULL);
> -        g_free(name);
> -    }
> -
> -    qdev_init_vmstate(dev);
> -    dev->state = DEV_STATE_INITIALIZED;
> -    if (dev->hotplugged) {
> -        device_reset(dev);
> -    }
> -    return 0;
> -}
> -
> -void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
> -                                 int required_for_version)
> -{
> -    assert(dev->state == DEV_STATE_CREATED);
> -    dev->instance_id_alias = alias_id;
> -    dev->alias_required_for_version = required_for_version;
> -}
> -
> -void qdev_unplug(DeviceState *dev, Error **errp)
> -{
> -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> -
> -    if (!dev->parent_bus->allow_hotplug) {
> -        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
> -        return;
> -    }
> -    assert(dc->unplug != NULL);
> -
> -    qdev_hot_removed = true;
> -
> -    if (dc->unplug(dev) < 0) {
> -        error_set(errp, QERR_UNDEFINED_ERROR);
> -        return;
> -    }
> -}
> -
> -static int qdev_reset_one(DeviceState *dev, void *opaque)
> -{
> -    device_reset(dev);
> -
> -    return 0;
> -}
> -
> -static int qbus_reset_one(BusState *bus, void *opaque)
> -{
> -    BusClass *bc = BUS_GET_CLASS(bus);
> -    if (bc->reset) {
> -        return bc->reset(bus);
> -    }
> -    return 0;
> -}
> -
> -void qdev_reset_all(DeviceState *dev)
> -{
> -    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
> -}
> -
> -void qbus_reset_all_fn(void *opaque)
> -{
> -    BusState *bus = opaque;
> -    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
> -}
> -
> -/* can be used as ->unplug() callback for the simple cases */
> -int qdev_simple_unplug_cb(DeviceState *dev)
> -{
> -    /* just zap it */
> -    qdev_free(dev);
> -    return 0;
> -}
> -
> -
> -/* Like qdev_init(), but terminate program via error_report() instead of
> -   returning an error value.  This is okay during machine creation.
> -   Don't use for hotplug, because there callers need to recover from
> -   failure.  Exception: if you know the device's init() callback can't
> -   fail, then qdev_init_nofail() can't fail either, and is therefore
> -   usable even then.  But relying on the device implementation that
> -   way is somewhat unclean, and best avoided.  */
> -void qdev_init_nofail(DeviceState *dev)
> -{
> -    const char *typename = object_get_typename(OBJECT(dev));
> -
> -    if (qdev_init(dev) < 0) {
> -        error_report("Initialization of device %s failed", typename);
> -        exit(1);
> -    }
> -}
> -
> -/* Unlink device from bus and free the structure.  */
> -void qdev_free(DeviceState *dev)
> -{
> -    object_delete(OBJECT(dev));
> -}
> -
> -void qdev_machine_creation_done(void)
> -{
> -    /*
> -     * ok, initial machine setup is done, starting from now we can
> -     * only create hotpluggable devices
> -     */
> -    qdev_hotplug = 1;
> -}
> -
> -bool qdev_machine_modified(void)
> -{
> -    return qdev_hot_added || qdev_hot_removed;
> -}
> -
> -BusState *qdev_get_parent_bus(DeviceState *dev)
> -{
> -    return dev->parent_bus;
> -}
> -
> -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)
> -{
> -    BusChild *kid;
> -    int err;
> -
> -    if (busfn) {
> -        err = busfn(bus, opaque);
> -        if (err) {
> -            return err;
> -        }
> -    }
> -
> -    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> -        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
> -        if (err < 0) {
> -            return err;
> -        }
> -    }
> -
> -    return 0;
> -}
> -
> -int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
> -                       qbus_walkerfn *busfn, void *opaque)
> -{
> -    BusState *bus;
> -    int err;
> -
> -    if (devfn) {
> -        err = devfn(dev, opaque);
> -        if (err) {
> -            return err;
> -        }
> -    }
> -
> -    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
> -        err = qbus_walk_children(bus, devfn, busfn, opaque);
> -        if (err < 0) {
> -            return err;
> -        }
> -    }
> -
> -    return 0;
> -}
> -
> -DeviceState *qdev_find_recursive(BusState *bus, const char *id)
> -{
> -    BusChild *kid;
> -    DeviceState *ret;
> -    BusState *child;
> -
> -    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> -        DeviceState *dev = kid->child;
> -
> -        if (dev->id && strcmp(dev->id, id) == 0) {
> -            return dev;
> -        }
> -
> -        QLIST_FOREACH(child, &dev->child_bus, sibling) {
> -            ret = qdev_find_recursive(child, id);
> -            if (ret) {
> -                return ret;
> -            }
> -        }
> -    }
> -    return NULL;
> -}
> -
> -static void qbus_realize(BusState *bus)
> -{
> -    const char *typename = object_get_typename(OBJECT(bus));
> -    char *buf;
> -    int i,len;
> -
> -    if (bus->name) {
> -        /* use supplied name */
> -    } else if (bus->parent && bus->parent->id) {
> -        /* parent device has id -> use it for bus name */
> -        len = strlen(bus->parent->id) + 16;
> -        buf = g_malloc(len);
> -        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
> -        bus->name = buf;
> -    } else {
> -        /* no id -> use lowercase bus type for bus name */
> -        len = strlen(typename) + 16;
> -        buf = g_malloc(len);
> -        len = snprintf(buf, len, "%s.%d", typename,
> -                       bus->parent ? bus->parent->num_child_bus : 0);
> -        for (i = 0; i < len; i++)
> -            buf[i] = qemu_tolower(buf[i]);
> -        bus->name = buf;
> -    }
> -
> -    if (bus->parent) {
> -        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
> -        bus->parent->num_child_bus++;
> -        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> -    } else {
> -        qbus_register_reset(bus);
> -    }
> -}
> -
> -void qbus_create_inplace(BusState *bus, const char *typename,
> -                         DeviceState *parent, const char *name)
> -{
> -    object_initialize(bus, typename);
> -
> -    bus->parent = parent;
> -    bus->name = name ? g_strdup(name) : NULL;
> -    qbus_realize(bus);
> -}
> -
> -BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
> -{
> -    BusState *bus;
> -
> -    bus = BUS(object_new(typename));
> -    bus->qom_allocated = true;
> -
> -    bus->parent = parent;
> -    bus->name = name ? g_strdup(name) : NULL;
> -    qbus_realize(bus);
> -
> -    return bus;
> -}
> -
> -void qbus_free(BusState *bus)
> -{
> -    if (bus->qom_allocated) {
> -        object_delete(OBJECT(bus));
> -    } else {
> -        object_finalize(OBJECT(bus));
> -        if (bus->glib_allocated) {
> -            g_free(bus);
> -        }
> -    }
> -}
> -
> -static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
> -{
> -    BusClass *bc = BUS_GET_CLASS(bus);
> -
> -    if (bc->get_fw_dev_path) {
> -        return bc->get_fw_dev_path(dev);
> -    }
> -
> -    return NULL;
> -}
> -
> -static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
> -{
> -    int l = 0;
> -
> -    if (dev && dev->parent_bus) {
> -        char *d;
> -        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
> -        d = bus_get_fw_dev_path(dev->parent_bus, dev);
> -        if (d) {
> -            l += snprintf(p + l, size - l, "%s", d);
> -            g_free(d);
> -        } else {
> -            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
> -        }
> -    }
> -    l += snprintf(p + l , size - l, "/");
> -
> -    return l;
> -}
> -
> -char* qdev_get_fw_dev_path(DeviceState *dev)
> -{
> -    char path[128];
> -    int l;
> -
> -    l = qdev_get_fw_dev_path_helper(dev, path, 128);
> -
> -    path[l-1] = '\0';
> -
> -    return g_strdup(path);
> -}
> -
> -char *qdev_get_dev_path(DeviceState *dev)
> -{
> -    BusClass *bc;
> -
> -    if (!dev || !dev->parent_bus) {
> -        return NULL;
> -    }
> -
> -    bc = BUS_GET_CLASS(dev->parent_bus);
> -    if (bc->get_dev_path) {
> -        return bc->get_dev_path(dev);
> -    }
> -
> -    return NULL;
> -}
> -
> -/**
> - * Legacy property handling
> - */
> -
> -static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
> -                                     const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -
> -    char buffer[1024];
> -    char *ptr = buffer;
> -
> -    prop->info->print(dev, prop, buffer, sizeof(buffer));
> -    visit_type_str(v, &ptr, name, errp);
> -}
> -
> -static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
> -                                     const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    Error *local_err = NULL;
> -    char *ptr = NULL;
> -    int ret;
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_str(v, &ptr, name, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
> -    ret = prop->info->parse(dev, prop, ptr);
> -    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
> -    g_free(ptr);
> -}
> -
> -/**
> - * @qdev_add_legacy_property - adds a legacy property
> - *
> - * Do not use this is new code!  Properties added through this interface will
> - * be given names and types in the "legacy" namespace.
> - *
> - * Legacy properties are string versions of other OOM properties.  The format
> - * of the string depends on the property type.
> - */
> -void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> -                              Error **errp)
> -{
> -    gchar *name, *type;
> -
> -    /* Register pointer properties as legacy properties */
> -    if (!prop->info->print && !prop->info->parse &&
> -        (prop->info->set || prop->info->get)) {
> -        return;
> -    }
> -
> -    name = g_strdup_printf("legacy-%s", prop->name);
> -    type = g_strdup_printf("legacy<%s>",
> -                           prop->info->legacy_name ?: prop->info->name);
> -
> -    object_property_add(OBJECT(dev), name, type,
> -                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
> -                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
> -                        NULL,
> -                        prop, errp);
> -
> -    g_free(type);
> -    g_free(name);
> -}
> -
> -/**
> - * @qdev_property_add_static - add a @Property to a device.
> - *
> - * Static properties access data in a struct.  The actual type of the
> - * property and the field depends on the property type.
> - */
> -void qdev_property_add_static(DeviceState *dev, Property *prop,
> -                              Error **errp)
> -{
> -    Error *local_err = NULL;
> -    Object *obj = OBJECT(dev);
> -
> -    /*
> -     * TODO qdev_prop_ptr does not have getters or setters.  It must
> -     * go now that it can be replaced with links.  The test should be
> -     * removed along with it: all static properties are read/write.
> -     */
> -    if (!prop->info->get && !prop->info->set) {
> -        return;
> -    }
> -
> -    object_property_add(obj, prop->name, prop->info->name,
> -                        prop->info->get, prop->info->set,
> -                        prop->info->release,
> -                        prop, &local_err);
> -
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -    if (prop->qtype == QTYPE_NONE) {
> -        return;
> -    }
> -
> -    if (prop->qtype == QTYPE_QBOOL) {
> -        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
> -    } else if (prop->info->enum_table) {
> -        object_property_set_str(obj, prop->info->enum_table[prop->defval],
> -                                prop->name, &local_err);
> -    } else if (prop->qtype == QTYPE_QINT) {
> -        object_property_set_int(obj, prop->defval, prop->name, &local_err);
> -    }
> -    assert_no_error(local_err);
> -}
> -
> -static void device_initfn(Object *obj)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    ObjectClass *class;
> -    Property *prop;
> -
> -    if (qdev_hotplug) {
> -        dev->hotplugged = 1;
> -        qdev_hot_added = true;
> -    }
> -
> -    dev->instance_id_alias = -1;
> -    dev->state = DEV_STATE_CREATED;
> -
> -    class = object_get_class(OBJECT(dev));
> -    do {
> -        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
> -            qdev_property_add_legacy(dev, prop, NULL);
> -            qdev_property_add_static(dev, prop, NULL);
> -        }
> -        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);
> -}
> -
> -/* Unlink device from bus and free the structure.  */
> -static void device_finalize(Object *obj)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    BusState *bus;
> -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> -
> -    if (dev->state == DEV_STATE_INITIALIZED) {
> -        while (dev->num_child_bus) {
> -            bus = QLIST_FIRST(&dev->child_bus);
> -            qbus_free(bus);
> -        }
> -        qdev_finalize_vmstate(dev);
> -        if (dc->exit) {
> -            dc->exit(dev);
> -        }
> -        if (dev->opts) {
> -            qemu_opts_del(dev->opts);
> -        }
> -    }
> -    if (dev->parent_bus) {
> -        bus_remove_child(dev->parent_bus, dev);
> -    }
> -}
> -
> -static void device_class_base_init(ObjectClass *class, void *data)
> -{
> -    DeviceClass *klass = DEVICE_CLASS(class);
> -
> -    /* We explicitly look up properties in the superclasses,
> -     * so do not propagate them to the subclasses.
> -     */
> -    klass->props = NULL;
> -}
> -
> -void device_reset(DeviceState *dev)
> -{
> -    DeviceClass *klass = DEVICE_GET_CLASS(dev);
> -
> -    if (klass->reset) {
> -        klass->reset(dev);
> -    }
> -}
> -
> -Object *qdev_get_machine(void)
> -{
> -    static Object *dev;
> -
> -    if (dev == NULL) {
> -        dev = container_get(object_get_root(), "/machine");
> -    }
> -
> -    return dev;
> -}
> -
> -static TypeInfo device_type_info = {
> -    .name = TYPE_DEVICE,
> -    .parent = TYPE_OBJECT,
> -    .instance_size = sizeof(DeviceState),
> -    .instance_init = device_initfn,
> -    .instance_finalize = device_finalize,
> -    .class_base_init = device_class_base_init,
> -    .abstract = true,
> -    .class_size = sizeof(DeviceClass),
> -};
> -
> -static void qbus_initfn(Object *obj)
> -{
> -    BusState *bus = BUS(obj);
> -
> -    QTAILQ_INIT(&bus->children);
> -}
> -
> -static void qbus_finalize(Object *obj)
> -{
> -    BusState *bus = BUS(obj);
> -    BusChild *kid;
> -
> -    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
> -        DeviceState *dev = kid->child;
> -        qdev_free(dev);
> -    }
> -    if (bus->parent) {
> -        QLIST_REMOVE(bus, sibling);
> -        bus->parent->num_child_bus--;
> -    } else {
> -        qbus_unregister_reset(bus);
> -    }
> -    g_free((char *)bus->name);
> -}
> -
> -static const TypeInfo bus_info = {
> -    .name = TYPE_BUS,
> -    .parent = TYPE_OBJECT,
> -    .instance_size = sizeof(BusState),
> -    .abstract = true,
> -    .class_size = sizeof(BusClass),
> -    .instance_init = qbus_initfn,
> -    .instance_finalize = qbus_finalize,
> -};
> -
> -static void qdev_register_types(void)
> -{
> -    type_register_static(&bus_info);
> -    type_register_static(&device_type_info);
> -}
> -
> -type_init(qdev_register_types)
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> deleted file mode 100644
> index 2e82cb9..0000000
> --- a/hw/qdev-properties.c
> +++ /dev/null
> @@ -1,963 +0,0 @@
> -#include "net.h"
> -#include "hw/qdev.h"
> -#include "qerror.h"
> -#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)
> -{
> -    void *ptr = dev;
> -    ptr += prop->offset;
> -    return ptr;
> -}
> -
> -static void get_enum(Object *obj, Visitor *v, void *opaque,
> -                     const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    int *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    visit_type_enum(v, ptr, prop->info->enum_table,
> -                    prop->info->name, prop->name, errp);
> -}
> -
> -static void set_enum(Object *obj, Visitor *v, void *opaque,
> -                     const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    int *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_enum(v, ptr, prop->info->enum_table,
> -                    prop->info->name, prop->name, errp);
> -}
> -
> -/* Bit */
> -
> -static uint32_t qdev_get_prop_mask(Property *prop)
> -{
> -    assert(prop->info == &qdev_prop_bit);
> -    return 0x1 << prop->bitnr;
> -}
> -
> -static void bit_prop_set(DeviceState *dev, Property *props, bool val)
> -{
> -    uint32_t *p = qdev_get_prop_ptr(dev, props);
> -    uint32_t mask = qdev_get_prop_mask(props);
> -    if (val)
> -        *p |= mask;
> -    else
> -        *p &= ~mask;
> -}
> -
> -static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
> -{
> -    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> -    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
> -}
> -
> -static void get_bit(Object *obj, Visitor *v, void *opaque,
> -                    const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> -    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> -
> -    visit_type_bool(v, &value, name, errp);
> -}
> -
> -static void set_bit(Object *obj, Visitor *v, void *opaque,
> -                    const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    Error *local_err = NULL;
> -    bool value;
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_bool(v, &value, name, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -    bit_prop_set(dev, prop, value);
> -}
> -
> -PropertyInfo qdev_prop_bit = {
> -    .name  = "boolean",
> -    .legacy_name  = "on/off",
> -    .print = print_bit,
> -    .get   = get_bit,
> -    .set   = set_bit,
> -};
> -
> -/* --- 8bit integer --- */
> -
> -static void get_uint8(Object *obj, Visitor *v, void *opaque,
> -                      const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    visit_type_uint8(v, ptr, name, errp);
> -}
> -
> -static void set_uint8(Object *obj, Visitor *v, void *opaque,
> -                      const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_uint8(v, ptr, name, errp);
> -}
> -
> -PropertyInfo qdev_prop_uint8 = {
> -    .name  = "uint8",
> -    .get   = get_uint8,
> -    .set   = set_uint8,
> -};
> -
> -/* --- 8bit hex value --- */
> -
> -static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
> -{
> -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> -    char *end;
> -
> -    if (str[0] != '0' || str[1] != 'x') {
> -        return -EINVAL;
> -    }
> -
> -    *ptr = strtoul(str, &end, 16);
> -    if ((*end != '\0') || (end == str)) {
> -        return -EINVAL;
> -    }
> -
> -    return 0;
> -}
> -
> -static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
> -{
> -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> -    return snprintf(dest, len, "0x%" PRIx8, *ptr);
> -}
> -
> -PropertyInfo qdev_prop_hex8 = {
> -    .name  = "uint8",
> -    .legacy_name  = "hex8",
> -    .parse = parse_hex8,
> -    .print = print_hex8,
> -    .get   = get_uint8,
> -    .set   = set_uint8,
> -};
> -
> -/* --- 16bit integer --- */
> -
> -static void get_uint16(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    visit_type_uint16(v, ptr, name, errp);
> -}
> -
> -static void set_uint16(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_uint16(v, ptr, name, errp);
> -}
> -
> -PropertyInfo qdev_prop_uint16 = {
> -    .name  = "uint16",
> -    .get   = get_uint16,
> -    .set   = set_uint16,
> -};
> -
> -/* --- 32bit integer --- */
> -
> -static void get_uint32(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    visit_type_uint32(v, ptr, name, errp);
> -}
> -
> -static void set_uint32(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_uint32(v, ptr, name, errp);
> -}
> -
> -static void get_int32(Object *obj, Visitor *v, void *opaque,
> -                      const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    visit_type_int32(v, ptr, name, errp);
> -}
> -
> -static void set_int32(Object *obj, Visitor *v, void *opaque,
> -                      const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_int32(v, ptr, name, errp);
> -}
> -
> -PropertyInfo qdev_prop_uint32 = {
> -    .name  = "uint32",
> -    .get   = get_uint32,
> -    .set   = set_uint32,
> -};
> -
> -PropertyInfo qdev_prop_int32 = {
> -    .name  = "int32",
> -    .get   = get_int32,
> -    .set   = set_int32,
> -};
> -
> -/* --- 32bit hex value --- */
> -
> -static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
> -{
> -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> -    char *end;
> -
> -    if (str[0] != '0' || str[1] != 'x') {
> -        return -EINVAL;
> -    }
> -
> -    *ptr = strtoul(str, &end, 16);
> -    if ((*end != '\0') || (end == str)) {
> -        return -EINVAL;
> -    }
> -
> -    return 0;
> -}
> -
> -static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
> -{
> -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> -    return snprintf(dest, len, "0x%" PRIx32, *ptr);
> -}
> -
> -PropertyInfo qdev_prop_hex32 = {
> -    .name  = "uint32",
> -    .legacy_name  = "hex32",
> -    .parse = parse_hex32,
> -    .print = print_hex32,
> -    .get   = get_uint32,
> -    .set   = set_uint32,
> -};
> -
> -/* --- 64bit integer --- */
> -
> -static void get_uint64(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    visit_type_uint64(v, ptr, name, errp);
> -}
> -
> -static void set_uint64(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_uint64(v, ptr, name, errp);
> -}
> -
> -PropertyInfo qdev_prop_uint64 = {
> -    .name  = "uint64",
> -    .get   = get_uint64,
> -    .set   = set_uint64,
> -};
> -
> -/* --- 64bit hex value --- */
> -
> -static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
> -{
> -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> -    char *end;
> -
> -    if (str[0] != '0' || str[1] != 'x') {
> -        return -EINVAL;
> -    }
> -
> -    *ptr = strtoull(str, &end, 16);
> -    if ((*end != '\0') || (end == str)) {
> -        return -EINVAL;
> -    }
> -
> -    return 0;
> -}
> -
> -static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
> -{
> -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> -    return snprintf(dest, len, "0x%" PRIx64, *ptr);
> -}
> -
> -PropertyInfo qdev_prop_hex64 = {
> -    .name  = "uint64",
> -    .legacy_name  = "hex64",
> -    .parse = parse_hex64,
> -    .print = print_hex64,
> -    .get   = get_uint64,
> -    .set   = set_uint64,
> -};
> -
> -/* --- string --- */
> -
> -static void release_string(Object *obj, const char *name, void *opaque)
> -{
> -    Property *prop = opaque;
> -    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
> -}
> -
> -static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
> -{
> -    char **ptr = qdev_get_prop_ptr(dev, prop);
> -    if (!*ptr)
> -        return snprintf(dest, len, "<null>");
> -    return snprintf(dest, len, "\"%s\"", *ptr);
> -}
> -
> -static void get_string(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    char **ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (!*ptr) {
> -        char *str = (char *)"";
> -        visit_type_str(v, &str, name, errp);
> -    } else {
> -        visit_type_str(v, ptr, name, errp);
> -    }
> -}
> -
> -static void set_string(Object *obj, Visitor *v, void *opaque,
> -                       const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    char **ptr = qdev_get_prop_ptr(dev, prop);
> -    Error *local_err = NULL;
> -    char *str;
> -
> -    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 (*ptr) {
> -        g_free(*ptr);
> -    }
> -    *ptr = str;
> -}
> -
> -PropertyInfo qdev_prop_string = {
> -    .name  = "string",
> -    .print = print_string,
> -    .release = release_string,
> -    .get   = get_string,
> -    .set   = set_string,
> -};
> -
> -/* --- pointer --- */
> -
> -/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
> -PropertyInfo qdev_prop_ptr = {
> -    .name  = "ptr",
> -};
> -
> -/* --- mac address --- */
> -
> -/*
> - * accepted syntax versions:
> - *   01:02:03:04:05:06
> - *   01-02-03-04-05-06
> - */
> -static void get_mac(Object *obj, Visitor *v, void *opaque,
> -                    const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> -    char buffer[2 * 6 + 5 + 1];
> -    char *p = buffer;
> -
> -    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
> -             mac->a[0], mac->a[1], mac->a[2],
> -             mac->a[3], mac->a[4], mac->a[5]);
> -
> -    visit_type_str(v, &p, name, errp);
> -}
> -
> -static void set_mac(Object *obj, Visitor *v, void *opaque,
> -                    const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> -    Error *local_err = NULL;
> -    int i, pos;
> -    char *str, *p;
> -
> -    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;
> -    }
> -
> -    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
> -        if (!qemu_isxdigit(str[pos]))
> -            goto inval;
> -        if (!qemu_isxdigit(str[pos+1]))
> -            goto inval;
> -        if (i == 5) {
> -            if (str[pos+2] != '\0')
> -                goto inval;
> -        } else {
> -            if (str[pos+2] != ':' && str[pos+2] != '-')
> -                goto inval;
> -        }
> -        mac->a[i] = strtol(str+pos, &p, 16);
> -    }
> -    g_free(str);
> -    return;
> -
> -inval:
> -    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> -    g_free(str);
> -}
> -
> -PropertyInfo qdev_prop_macaddr = {
> -    .name  = "macaddr",
> -    .get   = get_mac,
> -    .set   = set_mac,
> -};
> -
> -/* --- lost tick policy --- */
> -
> -static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
> -    [LOST_TICK_DISCARD] = "discard",
> -    [LOST_TICK_DELAY] = "delay",
> -    [LOST_TICK_MERGE] = "merge",
> -    [LOST_TICK_SLEW] = "slew",
> -    [LOST_TICK_MAX] = NULL,
> -};
> -
> -QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
> -
> -PropertyInfo qdev_prop_losttickpolicy = {
> -    .name  = "LostTickPolicy",
> -    .enum_table  = lost_tick_policy_table,
> -    .get   = get_enum,
> -    .set   = set_enum,
> -};
> -
> -/* --- BIOS CHS translation */
> -
> -static const char *bios_chs_trans_table[] = {
> -    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
> -    [BIOS_ATA_TRANSLATION_NONE] = "none",
> -    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
> -};
> -
> -PropertyInfo qdev_prop_bios_chs_trans = {
> -    .name = "bios-chs-trans",
> -    .enum_table = bios_chs_trans_table,
> -    .get = get_enum,
> -    .set = set_enum,
> -};
> -
> -/* --- pci address --- */
> -
> -/*
> - * bus-local address, i.e. "$slot" or "$slot.$fn"
> - */
> -static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
> -                          const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> -    unsigned int slot, fn, n;
> -    Error *local_err = NULL;
> -    char *str;
> -
> -    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_free(local_err);
> -        local_err = NULL;
> -        visit_type_int32(v, &value, name, &local_err);
> -        if (local_err) {
> -            error_propagate(errp, local_err);
> -        } else if (value < -1 || value > 255) {
> -            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
> -                      "pci_devfn");
> -        } else {
> -            *ptr = value;
> -        }
> -        return;
> -    }
> -
> -    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
> -        fn = 0;
> -        if (sscanf(str, "%x%n", &slot, &n) != 1) {
> -            goto invalid;
> -        }
> -    }
> -    if (str[n] != '\0' || fn > 7 || slot > 31) {
> -        goto invalid;
> -    }
> -    *ptr = slot << 3 | fn;
> -    g_free(str);
> -    return;
> -
> -invalid:
> -    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> -    g_free(str);
> -}
> -
> -static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
> -{
> -    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> -
> -    if (*ptr == -1) {
> -        return snprintf(dest, len, "<unset>");
> -    } else {
> -        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
> -    }
> -}
> -
> -PropertyInfo qdev_prop_pci_devfn = {
> -    .name  = "int32",
> -    .legacy_name  = "pci-devfn",
> -    .print = print_pci_devfn,
> -    .get   = get_int32,
> -    .set   = set_pci_devfn,
> -};
> -
> -/* --- blocksize --- */
> -
> -static void set_blocksize(Object *obj, Visitor *v, void *opaque,
> -                          const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> -    Error *local_err = NULL;
> -    const int64_t min = 512;
> -    const int64_t max = 32768;
> -
> -    if (dev->state != DEV_STATE_CREATED) {
> -        error_set(errp, QERR_PERMISSION_DENIED);
> -        return;
> -    }
> -
> -    visit_type_uint16(v, &value, name, &local_err);
> -    if (local_err) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -    if (value < min || value > max) {
> -        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> -                  dev->id?:"", name, (int64_t)value, min, max);
> -        return;
> -    }
> -
> -    /* We rely on power-of-2 blocksizes for bitmasks */
> -    if ((value & (value - 1)) != 0) {
> -        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
> -                  dev->id?:"", name, (int64_t)value);
> -        return;
> -    }
> -
> -    *ptr = value;
> -}
> -
> -PropertyInfo qdev_prop_blocksize = {
> -    .name  = "blocksize",
> -    .get   = get_uint16,
> -    .set   = set_blocksize,
> -};
> -
> -/* --- pci host address --- */
> -
> -static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> -                                 const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> -    char buffer[] = "xxxx:xx:xx.x";
> -    char *p = buffer;
> -    int rc = 0;
> -
> -    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
> -                  addr->domain, addr->bus, addr->slot, addr->function);
> -    assert(rc == sizeof(buffer) - 1);
> -
> -    visit_type_str(v, &p, name, errp);
> -}
> -
> -/*
> - * Parse [<domain>:]<bus>:<slot>.<func>
> - *   if <domain> is not supplied, it's assumed to be 0.
> - */
> -static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> -                                 const char *name, Error **errp)
> -{
> -    DeviceState *dev = DEVICE(obj);
> -    Property *prop = opaque;
> -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> -    Error *local_err = NULL;
> -    char *str, *p;
> -    char *e;
> -    unsigned long val;
> -    unsigned long dom = 0, bus = 0;
> -    unsigned int slot = 0, func = 0;
> -
> -    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;
> -    }
> -
> -    p = str;
> -    val = strtoul(p, &e, 16);
> -    if (e == p || *e != ':') {
> -        goto inval;
> -    }
> -    bus = val;
> -
> -    p = e + 1;
> -    val = strtoul(p, &e, 16);
> -    if (e == p) {
> -        goto inval;
> -    }
> -    if (*e == ':') {
> -        dom = bus;
> -        bus = val;
> -        p = e + 1;
> -        val = strtoul(p, &e, 16);
> -        if (e == p) {
> -            goto inval;
> -        }
> -    }
> -    slot = val;
> -
> -    if (*e != '.') {
> -        goto inval;
> -    }
> -    p = e + 1;
> -    val = strtoul(p, &e, 10);
> -    if (e == p) {
> -        goto inval;
> -    }
> -    func = val;
> -
> -    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
> -        goto inval;
> -    }
> -
> -    if (*e) {
> -        goto inval;
> -    }
> -
> -    addr->domain = dom;
> -    addr->bus = bus;
> -    addr->slot = slot;
> -    addr->function = func;
> -
> -    g_free(str);
> -    return;
> -
> -inval:
> -    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> -    g_free(str);
> -}
> -
> -PropertyInfo qdev_prop_pci_host_devaddr = {
> -    .name = "pci-host-devaddr",
> -    .get = get_pci_host_devaddr,
> -    .set = set_pci_host_devaddr,
> -};
> -
> -/* --- public helpers --- */
> -
> -static Property *qdev_prop_walk(Property *props, const char *name)
> -{
> -    if (!props)
> -        return NULL;
> -    while (props->name) {
> -        if (strcmp(props->name, name) == 0)
> -            return props;
> -        props++;
> -    }
> -    return NULL;
> -}
> -
> -static Property *qdev_prop_find(DeviceState *dev, const char *name)
> -{
> -    ObjectClass *class;
> -    Property *prop;
> -
> -    /* device properties */
> -    class = object_get_class(OBJECT(dev));
> -    do {
> -        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
> -        if (prop) {
> -            return prop;
> -        }
> -        class = object_class_get_parent(class);
> -    } while (class != object_class_by_name(TYPE_DEVICE));
> -
> -    return NULL;
> -}
> -
> -void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
> -                                    Property *prop, const char *value)
> -{
> -    switch (ret) {
> -    case -EEXIST:
> -        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
> -                  object_get_typename(OBJECT(dev)), prop->name, value);
> -        break;
> -    default:
> -    case -EINVAL:
> -        error_set(errp, QERR_PROPERTY_VALUE_BAD,
> -                  object_get_typename(OBJECT(dev)), prop->name, value);
> -        break;
> -    case -ENOENT:
> -        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
> -                  object_get_typename(OBJECT(dev)), prop->name, value);
> -        break;
> -    case 0:
> -        break;
> -    }
> -}
> -
> -int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> -{
> -    char *legacy_name;
> -    Error *err = NULL;
> -
> -    legacy_name = g_strdup_printf("legacy-%s", name);
> -    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
> -        object_property_parse(OBJECT(dev), value, legacy_name, &err);
> -    } else {
> -        object_property_parse(OBJECT(dev), value, name, &err);
> -    }
> -    g_free(legacy_name);
> -
> -    if (err) {
> -        qerror_report_err(err);
> -        error_free(err);
> -        return -1;
> -    }
> -    return 0;
> -}
> -
> -void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
> -{
> -    Error *errp = NULL;
> -    object_property_set_bool(OBJECT(dev), value, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
> -{
> -    Error *errp = NULL;
> -    object_property_set_int(OBJECT(dev), value, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
> -{
> -    Error *errp = NULL;
> -    object_property_set_int(OBJECT(dev), value, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
> -{
> -    Error *errp = NULL;
> -    object_property_set_int(OBJECT(dev), value, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
> -{
> -    Error *errp = NULL;
> -    object_property_set_int(OBJECT(dev), value, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
> -{
> -    Error *errp = NULL;
> -    object_property_set_int(OBJECT(dev), value, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
> -{
> -    Error *errp = NULL;
> -    object_property_set_str(OBJECT(dev), value, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
> -{
> -    Error *errp = NULL;
> -    char str[2 * 6 + 5 + 1];
> -    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
> -             value[0], value[1], value[2], value[3], value[4], value[5]);
> -
> -    object_property_set_str(OBJECT(dev), str, name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
> -{
> -    Property *prop;
> -    Error *errp = NULL;
> -
> -    prop = qdev_prop_find(dev, name);
> -    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
> -                            name, &errp);
> -    assert_no_error(errp);
> -}
> -
> -void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
> -{
> -    Property *prop;
> -    void **ptr;
> -
> -    prop = qdev_prop_find(dev, name);
> -    assert(prop && prop->info == &qdev_prop_ptr);
> -    ptr = qdev_get_prop_ptr(dev, prop);
> -    *ptr = value;
> -}
> -
> -static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
> -
> -void qdev_prop_register_global(GlobalProperty *prop)
> -{
> -    QTAILQ_INSERT_TAIL(&global_props, prop, next);
> -}
> -
> -void qdev_prop_register_global_list(GlobalProperty *props)
> -{
> -    int i;
> -
> -    for (i = 0; props[i].driver != NULL; i++) {
> -        qdev_prop_register_global(props+i);
> -    }
> -}
> -
> -void qdev_prop_set_globals(DeviceState *dev)
> -{
> -    ObjectClass *class = object_get_class(OBJECT(dev));
> -
> -    do {
> -        GlobalProperty *prop;
> -        QTAILQ_FOREACH(prop, &global_props, next) {
> -            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
> -                continue;
> -            }
> -            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> -                exit(1);
> -            }
> -        }
> -        class = object_class_get_parent(class);
> -    } while (class);
> -}
> -
> diff --git a/qom/Makefile.objs b/qom/Makefile.objs
> index 5ef060a..09ef871 100644
> --- a/qom/Makefile.objs
> +++ b/qom/Makefile.objs
> @@ -1,4 +1,4 @@
>  qom-obj-y = object.o container.o qom-qobject.o
> -qom-obj-twice-y = cpu.o
> +qom-obj-twice-y = cpu.o qdev-core.o qdev-properties.o
>  common-obj-y = $(qom-obj-twice-y)
>  user-obj-y = $(qom-obj-twice-y)
> diff --git a/qom/qdev-core.c b/qom/qdev-core.c
> new file mode 100644
> index 0000000..fbb7cb5
> --- /dev/null
> +++ b/qom/qdev-core.c
> @@ -0,0 +1,727 @@
> +/*
> + *  Dynamic device configuration and creation.
> + *
> + *  Copyright (c) 2009 CodeSourcery
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/* The theory here is that it should be possible to create a machine without
> +   knowledge of specific devices.  Historically board init routines have
> +   passed a bunch of arguments to each device, requiring the board know
> +   exactly which device it is dealing with.  This file provides an abstract
> +   API for device configuration and initialization.  Devices will generally
> +   inherit from a particular bus (e.g. PCI or I2C) rather than
> +   this API directly.  */
> +
> +#include "hw/qdev.h"
> +#include "sysemu.h"
> +#include "error.h"
> +#include "qapi/qapi-visit-core.h"
> +
> +int qdev_hotplug = 0;
> +static bool qdev_hot_added = false;
> +static bool qdev_hot_removed = false;
> +
> +/* vmstate handling:
> + *
> + * The real implementations are on qdev-system.c. Those are weak symbols
> + * used by *-user.
> + */
> +void GCC_WEAK qdev_init_vmstate(DeviceState *dev)
> +{
> +}
> +
> +void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
> +{
> +}
> +
> +/* reset handler register/unregister:
> + *
> + * The real implementations are on qdev-system.c. Those are weak symbols
> + * used by *-user.
> + */
> +void GCC_WEAK qbus_register_reset(BusState *bus)
> +{
> +}
> +
> +void GCC_WEAK qbus_unregister_reset(BusState *bus)
> +{
> +}
> +
> +const char *qdev_fw_name(DeviceState *dev)
> +{
> +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> +
> +    if (dc->fw_name) {
> +        return dc->fw_name;
> +    }
> +
> +    return object_get_typename(OBJECT(dev));
> +}
> +
> +static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> +                                     Error **errp);
> +
> +static void bus_remove_child(BusState *bus, DeviceState *child)
> +{
> +    BusChild *kid;
> +
> +    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> +        if (kid->child == child) {
> +            char name[32];
> +
> +            snprintf(name, sizeof(name), "child[%d]", kid->index);
> +            QTAILQ_REMOVE(&bus->children, kid, sibling);
> +            object_property_del(OBJECT(bus), name, NULL);
> +            g_free(kid);
> +            return;
> +        }
> +    }
> +}
> +
> +static void bus_add_child(BusState *bus, DeviceState *child)
> +{
> +    char name[32];
> +    BusChild *kid = g_malloc0(sizeof(*kid));
> +
> +    if (qdev_hotplug) {
> +        assert(bus->allow_hotplug);
> +    }
> +
> +    kid->index = bus->max_index++;
> +    kid->child = child;
> +
> +    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
> +
> +    snprintf(name, sizeof(name), "child[%d]", kid->index);
> +    object_property_add_link(OBJECT(bus), name,
> +                             object_get_typename(OBJECT(child)),
> +                             (Object **)&kid->child,
> +                             NULL);
> +}
> +
> +void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
> +{
> +    dev->parent_bus = bus;
> +    bus_add_child(bus, 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.
> +   On failure, destroy the device and return negative value.
> +   Return 0 on success.  */
> +int qdev_init(DeviceState *dev)
> +{
> +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> +    int rc;
> +
> +    assert(dev->state == DEV_STATE_CREATED);
> +
> +    rc = dc->init(dev);
> +    if (rc < 0) {
> +        qdev_free(dev);
> +        return rc;
> +    }
> +
> +    if (!OBJECT(dev)->parent) {
> +        static int unattached_count = 0;
> +        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
> +
> +        object_property_add_child(container_get(qdev_get_machine(),
> +                                                "/unattached"),
> +                                  name, OBJECT(dev), NULL);
> +        g_free(name);
> +    }
> +
> +    qdev_init_vmstate(dev);
> +    dev->state = DEV_STATE_INITIALIZED;
> +    if (dev->hotplugged) {
> +        device_reset(dev);
> +    }
> +    return 0;
> +}
> +
> +void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
> +                                 int required_for_version)
> +{
> +    assert(dev->state == DEV_STATE_CREATED);
> +    dev->instance_id_alias = alias_id;
> +    dev->alias_required_for_version = required_for_version;
> +}
> +
> +void qdev_unplug(DeviceState *dev, Error **errp)
> +{
> +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> +
> +    if (!dev->parent_bus->allow_hotplug) {
> +        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
> +        return;
> +    }
> +    assert(dc->unplug != NULL);
> +
> +    qdev_hot_removed = true;
> +
> +    if (dc->unplug(dev) < 0) {
> +        error_set(errp, QERR_UNDEFINED_ERROR);
> +        return;
> +    }
> +}
> +
> +static int qdev_reset_one(DeviceState *dev, void *opaque)
> +{
> +    device_reset(dev);
> +
> +    return 0;
> +}
> +
> +static int qbus_reset_one(BusState *bus, void *opaque)
> +{
> +    BusClass *bc = BUS_GET_CLASS(bus);
> +    if (bc->reset) {
> +        return bc->reset(bus);
> +    }
> +    return 0;
> +}
> +
> +void qdev_reset_all(DeviceState *dev)
> +{
> +    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
> +}
> +
> +void qbus_reset_all_fn(void *opaque)
> +{
> +    BusState *bus = opaque;
> +    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
> +}
> +
> +/* can be used as ->unplug() callback for the simple cases */
> +int qdev_simple_unplug_cb(DeviceState *dev)
> +{
> +    /* just zap it */
> +    qdev_free(dev);
> +    return 0;
> +}
> +
> +
> +/* Like qdev_init(), but terminate program via error_report() instead of
> +   returning an error value.  This is okay during machine creation.
> +   Don't use for hotplug, because there callers need to recover from
> +   failure.  Exception: if you know the device's init() callback can't
> +   fail, then qdev_init_nofail() can't fail either, and is therefore
> +   usable even then.  But relying on the device implementation that
> +   way is somewhat unclean, and best avoided.  */
> +void qdev_init_nofail(DeviceState *dev)
> +{
> +    const char *typename = object_get_typename(OBJECT(dev));
> +
> +    if (qdev_init(dev) < 0) {
> +        error_report("Initialization of device %s failed", typename);
> +        exit(1);
> +    }
> +}
> +
> +/* Unlink device from bus and free the structure.  */
> +void qdev_free(DeviceState *dev)
> +{
> +    object_delete(OBJECT(dev));
> +}
> +
> +void qdev_machine_creation_done(void)
> +{
> +    /*
> +     * ok, initial machine setup is done, starting from now we can
> +     * only create hotpluggable devices
> +     */
> +    qdev_hotplug = 1;
> +}
> +
> +bool qdev_machine_modified(void)
> +{
> +    return qdev_hot_added || qdev_hot_removed;
> +}
> +
> +BusState *qdev_get_parent_bus(DeviceState *dev)
> +{
> +    return dev->parent_bus;
> +}
> +
> +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)
> +{
> +    BusChild *kid;
> +    int err;
> +
> +    if (busfn) {
> +        err = busfn(bus, opaque);
> +        if (err) {
> +            return err;
> +        }
> +    }
> +
> +    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> +        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
> +        if (err < 0) {
> +            return err;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
> +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
> +                       qbus_walkerfn *busfn, void *opaque)
> +{
> +    BusState *bus;
> +    int err;
> +
> +    if (devfn) {
> +        err = devfn(dev, opaque);
> +        if (err) {
> +            return err;
> +        }
> +    }
> +
> +    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
> +        err = qbus_walk_children(bus, devfn, busfn, opaque);
> +        if (err < 0) {
> +            return err;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
> +DeviceState *qdev_find_recursive(BusState *bus, const char *id)
> +{
> +    BusChild *kid;
> +    DeviceState *ret;
> +    BusState *child;
> +
> +    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> +        DeviceState *dev = kid->child;
> +
> +        if (dev->id && strcmp(dev->id, id) == 0) {
> +            return dev;
> +        }
> +
> +        QLIST_FOREACH(child, &dev->child_bus, sibling) {
> +            ret = qdev_find_recursive(child, id);
> +            if (ret) {
> +                return ret;
> +            }
> +        }
> +    }
> +    return NULL;
> +}
> +
> +static void qbus_realize(BusState *bus)
> +{
> +    const char *typename = object_get_typename(OBJECT(bus));
> +    char *buf;
> +    int i,len;
> +
> +    if (bus->name) {
> +        /* use supplied name */
> +    } else if (bus->parent && bus->parent->id) {
> +        /* parent device has id -> use it for bus name */
> +        len = strlen(bus->parent->id) + 16;
> +        buf = g_malloc(len);
> +        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
> +        bus->name = buf;
> +    } else {
> +        /* no id -> use lowercase bus type for bus name */
> +        len = strlen(typename) + 16;
> +        buf = g_malloc(len);
> +        len = snprintf(buf, len, "%s.%d", typename,
> +                       bus->parent ? bus->parent->num_child_bus : 0);
> +        for (i = 0; i < len; i++)
> +            buf[i] = qemu_tolower(buf[i]);
> +        bus->name = buf;
> +    }
> +
> +    if (bus->parent) {
> +        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
> +        bus->parent->num_child_bus++;
> +        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> +    } else {
> +        qbus_register_reset(bus);
> +    }
> +}
> +
> +void qbus_create_inplace(BusState *bus, const char *typename,
> +                         DeviceState *parent, const char *name)
> +{
> +    object_initialize(bus, typename);
> +
> +    bus->parent = parent;
> +    bus->name = name ? g_strdup(name) : NULL;
> +    qbus_realize(bus);
> +}
> +
> +BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
> +{
> +    BusState *bus;
> +
> +    bus = BUS(object_new(typename));
> +    bus->qom_allocated = true;
> +
> +    bus->parent = parent;
> +    bus->name = name ? g_strdup(name) : NULL;
> +    qbus_realize(bus);
> +
> +    return bus;
> +}
> +
> +void qbus_free(BusState *bus)
> +{
> +    if (bus->qom_allocated) {
> +        object_delete(OBJECT(bus));
> +    } else {
> +        object_finalize(OBJECT(bus));
> +        if (bus->glib_allocated) {
> +            g_free(bus);
> +        }
> +    }
> +}
> +
> +static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
> +{
> +    BusClass *bc = BUS_GET_CLASS(bus);
> +
> +    if (bc->get_fw_dev_path) {
> +        return bc->get_fw_dev_path(dev);
> +    }
> +
> +    return NULL;
> +}
> +
> +static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
> +{
> +    int l = 0;
> +
> +    if (dev && dev->parent_bus) {
> +        char *d;
> +        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
> +        d = bus_get_fw_dev_path(dev->parent_bus, dev);
> +        if (d) {
> +            l += snprintf(p + l, size - l, "%s", d);
> +            g_free(d);
> +        } else {
> +            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
> +        }
> +    }
> +    l += snprintf(p + l , size - l, "/");
> +
> +    return l;
> +}
> +
> +char* qdev_get_fw_dev_path(DeviceState *dev)
> +{
> +    char path[128];
> +    int l;
> +
> +    l = qdev_get_fw_dev_path_helper(dev, path, 128);
> +
> +    path[l-1] = '\0';
> +
> +    return g_strdup(path);
> +}
> +
> +char *qdev_get_dev_path(DeviceState *dev)
> +{
> +    BusClass *bc;
> +
> +    if (!dev || !dev->parent_bus) {
> +        return NULL;
> +    }
> +
> +    bc = BUS_GET_CLASS(dev->parent_bus);
> +    if (bc->get_dev_path) {
> +        return bc->get_dev_path(dev);
> +    }
> +
> +    return NULL;
> +}
> +
> +/**
> + * Legacy property handling
> + */
> +
> +static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
> +                                     const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +
> +    char buffer[1024];
> +    char *ptr = buffer;
> +
> +    prop->info->print(dev, prop, buffer, sizeof(buffer));
> +    visit_type_str(v, &ptr, name, errp);
> +}
> +
> +static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
> +                                     const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    Error *local_err = NULL;
> +    char *ptr = NULL;
> +    int ret;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_str(v, &ptr, name, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
> +    ret = prop->info->parse(dev, prop, ptr);
> +    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
> +    g_free(ptr);
> +}
> +
> +/**
> + * @qdev_add_legacy_property - adds a legacy property
> + *
> + * Do not use this is new code!  Properties added through this interface will
> + * be given names and types in the "legacy" namespace.
> + *
> + * Legacy properties are string versions of other OOM properties.  The format
> + * of the string depends on the property type.
> + */
> +void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> +                              Error **errp)
> +{
> +    gchar *name, *type;
> +
> +    /* Register pointer properties as legacy properties */
> +    if (!prop->info->print && !prop->info->parse &&
> +        (prop->info->set || prop->info->get)) {
> +        return;
> +    }
> +
> +    name = g_strdup_printf("legacy-%s", prop->name);
> +    type = g_strdup_printf("legacy<%s>",
> +                           prop->info->legacy_name ?: prop->info->name);
> +
> +    object_property_add(OBJECT(dev), name, type,
> +                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
> +                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
> +                        NULL,
> +                        prop, errp);
> +
> +    g_free(type);
> +    g_free(name);
> +}
> +
> +/**
> + * @qdev_property_add_static - add a @Property to a device.
> + *
> + * Static properties access data in a struct.  The actual type of the
> + * property and the field depends on the property type.
> + */
> +void qdev_property_add_static(DeviceState *dev, Property *prop,
> +                              Error **errp)
> +{
> +    Error *local_err = NULL;
> +    Object *obj = OBJECT(dev);
> +
> +    /*
> +     * TODO qdev_prop_ptr does not have getters or setters.  It must
> +     * go now that it can be replaced with links.  The test should be
> +     * removed along with it: all static properties are read/write.
> +     */
> +    if (!prop->info->get && !prop->info->set) {
> +        return;
> +    }
> +
> +    object_property_add(obj, prop->name, prop->info->name,
> +                        prop->info->get, prop->info->set,
> +                        prop->info->release,
> +                        prop, &local_err);
> +
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (prop->qtype == QTYPE_NONE) {
> +        return;
> +    }
> +
> +    if (prop->qtype == QTYPE_QBOOL) {
> +        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
> +    } else if (prop->info->enum_table) {
> +        object_property_set_str(obj, prop->info->enum_table[prop->defval],
> +                                prop->name, &local_err);
> +    } else if (prop->qtype == QTYPE_QINT) {
> +        object_property_set_int(obj, prop->defval, prop->name, &local_err);
> +    }
> +    assert_no_error(local_err);
> +}
> +
> +static void device_initfn(Object *obj)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    ObjectClass *class;
> +    Property *prop;
> +
> +    if (qdev_hotplug) {
> +        dev->hotplugged = 1;
> +        qdev_hot_added = true;
> +    }
> +
> +    dev->instance_id_alias = -1;
> +    dev->state = DEV_STATE_CREATED;
> +
> +    class = object_get_class(OBJECT(dev));
> +    do {
> +        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
> +            qdev_property_add_legacy(dev, prop, NULL);
> +            qdev_property_add_static(dev, prop, NULL);
> +        }
> +        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);
> +}
> +
> +/* Unlink device from bus and free the structure.  */
> +static void device_finalize(Object *obj)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    BusState *bus;
> +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> +
> +    if (dev->state == DEV_STATE_INITIALIZED) {
> +        while (dev->num_child_bus) {
> +            bus = QLIST_FIRST(&dev->child_bus);
> +            qbus_free(bus);
> +        }
> +        qdev_finalize_vmstate(dev);
> +        if (dc->exit) {
> +            dc->exit(dev);
> +        }
> +        if (dev->opts) {
> +            qemu_opts_del(dev->opts);
> +        }
> +    }
> +    if (dev->parent_bus) {
> +        bus_remove_child(dev->parent_bus, dev);
> +    }
> +}
> +
> +static void device_class_base_init(ObjectClass *class, void *data)
> +{
> +    DeviceClass *klass = DEVICE_CLASS(class);
> +
> +    /* We explicitly look up properties in the superclasses,
> +     * so do not propagate them to the subclasses.
> +     */
> +    klass->props = NULL;
> +}
> +
> +void device_reset(DeviceState *dev)
> +{
> +    DeviceClass *klass = DEVICE_GET_CLASS(dev);
> +
> +    if (klass->reset) {
> +        klass->reset(dev);
> +    }
> +}
> +
> +Object *qdev_get_machine(void)
> +{
> +    static Object *dev;
> +
> +    if (dev == NULL) {
> +        dev = container_get(object_get_root(), "/machine");
> +    }
> +
> +    return dev;
> +}
> +
> +static TypeInfo device_type_info = {
> +    .name = TYPE_DEVICE,
> +    .parent = TYPE_OBJECT,
> +    .instance_size = sizeof(DeviceState),
> +    .instance_init = device_initfn,
> +    .instance_finalize = device_finalize,
> +    .class_base_init = device_class_base_init,
> +    .abstract = true,
> +    .class_size = sizeof(DeviceClass),
> +};
> +
> +static void qbus_initfn(Object *obj)
> +{
> +    BusState *bus = BUS(obj);
> +
> +    QTAILQ_INIT(&bus->children);
> +}
> +
> +static void qbus_finalize(Object *obj)
> +{
> +    BusState *bus = BUS(obj);
> +    BusChild *kid;
> +
> +    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
> +        DeviceState *dev = kid->child;
> +        qdev_free(dev);
> +    }
> +    if (bus->parent) {
> +        QLIST_REMOVE(bus, sibling);
> +        bus->parent->num_child_bus--;
> +    } else {
> +        qbus_unregister_reset(bus);
> +    }
> +    g_free((char *)bus->name);
> +}
> +
> +static const TypeInfo bus_info = {
> +    .name = TYPE_BUS,
> +    .parent = TYPE_OBJECT,
> +    .instance_size = sizeof(BusState),
> +    .abstract = true,
> +    .class_size = sizeof(BusClass),
> +    .instance_init = qbus_initfn,
> +    .instance_finalize = qbus_finalize,
> +};
> +
> +static void qdev_register_types(void)
> +{
> +    type_register_static(&bus_info);
> +    type_register_static(&device_type_info);
> +}
> +
> +type_init(qdev_register_types)
> diff --git a/qom/qdev-properties.c b/qom/qdev-properties.c
> new file mode 100644
> index 0000000..2e82cb9
> --- /dev/null
> +++ b/qom/qdev-properties.c
> @@ -0,0 +1,963 @@
> +#include "net.h"
> +#include "hw/qdev.h"
> +#include "qerror.h"
> +#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)
> +{
> +    void *ptr = dev;
> +    ptr += prop->offset;
> +    return ptr;
> +}
> +
> +static void get_enum(Object *obj, Visitor *v, void *opaque,
> +                     const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    int *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    visit_type_enum(v, ptr, prop->info->enum_table,
> +                    prop->info->name, prop->name, errp);
> +}
> +
> +static void set_enum(Object *obj, Visitor *v, void *opaque,
> +                     const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    int *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_enum(v, ptr, prop->info->enum_table,
> +                    prop->info->name, prop->name, errp);
> +}
> +
> +/* Bit */
> +
> +static uint32_t qdev_get_prop_mask(Property *prop)
> +{
> +    assert(prop->info == &qdev_prop_bit);
> +    return 0x1 << prop->bitnr;
> +}
> +
> +static void bit_prop_set(DeviceState *dev, Property *props, bool val)
> +{
> +    uint32_t *p = qdev_get_prop_ptr(dev, props);
> +    uint32_t mask = qdev_get_prop_mask(props);
> +    if (val)
> +        *p |= mask;
> +    else
> +        *p &= ~mask;
> +}
> +
> +static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
> +{
> +    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> +    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
> +}
> +
> +static void get_bit(Object *obj, Visitor *v, void *opaque,
> +                    const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> +    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> +
> +    visit_type_bool(v, &value, name, errp);
> +}
> +
> +static void set_bit(Object *obj, Visitor *v, void *opaque,
> +                    const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    Error *local_err = NULL;
> +    bool value;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_bool(v, &value, name, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    bit_prop_set(dev, prop, value);
> +}
> +
> +PropertyInfo qdev_prop_bit = {
> +    .name  = "boolean",
> +    .legacy_name  = "on/off",
> +    .print = print_bit,
> +    .get   = get_bit,
> +    .set   = set_bit,
> +};
> +
> +/* --- 8bit integer --- */
> +
> +static void get_uint8(Object *obj, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    visit_type_uint8(v, ptr, name, errp);
> +}
> +
> +static void set_uint8(Object *obj, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_uint8(v, ptr, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_uint8 = {
> +    .name  = "uint8",
> +    .get   = get_uint8,
> +    .set   = set_uint8,
> +};
> +
> +/* --- 8bit hex value --- */
> +
> +static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
> +{
> +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    char *end;
> +
> +    if (str[0] != '0' || str[1] != 'x') {
> +        return -EINVAL;
> +    }
> +
> +    *ptr = strtoul(str, &end, 16);
> +    if ((*end != '\0') || (end == str)) {
> +        return -EINVAL;
> +    }
> +
> +    return 0;
> +}
> +
> +static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
> +{
> +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    return snprintf(dest, len, "0x%" PRIx8, *ptr);
> +}
> +
> +PropertyInfo qdev_prop_hex8 = {
> +    .name  = "uint8",
> +    .legacy_name  = "hex8",
> +    .parse = parse_hex8,
> +    .print = print_hex8,
> +    .get   = get_uint8,
> +    .set   = set_uint8,
> +};
> +
> +/* --- 16bit integer --- */
> +
> +static void get_uint16(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    visit_type_uint16(v, ptr, name, errp);
> +}
> +
> +static void set_uint16(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_uint16(v, ptr, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_uint16 = {
> +    .name  = "uint16",
> +    .get   = get_uint16,
> +    .set   = set_uint16,
> +};
> +
> +/* --- 32bit integer --- */
> +
> +static void get_uint32(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    visit_type_uint32(v, ptr, name, errp);
> +}
> +
> +static void set_uint32(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_uint32(v, ptr, name, errp);
> +}
> +
> +static void get_int32(Object *obj, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    visit_type_int32(v, ptr, name, errp);
> +}
> +
> +static void set_int32(Object *obj, Visitor *v, void *opaque,
> +                      const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_int32(v, ptr, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_uint32 = {
> +    .name  = "uint32",
> +    .get   = get_uint32,
> +    .set   = set_uint32,
> +};
> +
> +PropertyInfo qdev_prop_int32 = {
> +    .name  = "int32",
> +    .get   = get_int32,
> +    .set   = set_int32,
> +};
> +
> +/* --- 32bit hex value --- */
> +
> +static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
> +{
> +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    char *end;
> +
> +    if (str[0] != '0' || str[1] != 'x') {
> +        return -EINVAL;
> +    }
> +
> +    *ptr = strtoul(str, &end, 16);
> +    if ((*end != '\0') || (end == str)) {
> +        return -EINVAL;
> +    }
> +
> +    return 0;
> +}
> +
> +static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
> +{
> +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    return snprintf(dest, len, "0x%" PRIx32, *ptr);
> +}
> +
> +PropertyInfo qdev_prop_hex32 = {
> +    .name  = "uint32",
> +    .legacy_name  = "hex32",
> +    .parse = parse_hex32,
> +    .print = print_hex32,
> +    .get   = get_uint32,
> +    .set   = set_uint32,
> +};
> +
> +/* --- 64bit integer --- */
> +
> +static void get_uint64(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    visit_type_uint64(v, ptr, name, errp);
> +}
> +
> +static void set_uint64(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_uint64(v, ptr, name, errp);
> +}
> +
> +PropertyInfo qdev_prop_uint64 = {
> +    .name  = "uint64",
> +    .get   = get_uint64,
> +    .set   = set_uint64,
> +};
> +
> +/* --- 64bit hex value --- */
> +
> +static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
> +{
> +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    char *end;
> +
> +    if (str[0] != '0' || str[1] != 'x') {
> +        return -EINVAL;
> +    }
> +
> +    *ptr = strtoull(str, &end, 16);
> +    if ((*end != '\0') || (end == str)) {
> +        return -EINVAL;
> +    }
> +
> +    return 0;
> +}
> +
> +static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
> +{
> +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> +    return snprintf(dest, len, "0x%" PRIx64, *ptr);
> +}
> +
> +PropertyInfo qdev_prop_hex64 = {
> +    .name  = "uint64",
> +    .legacy_name  = "hex64",
> +    .parse = parse_hex64,
> +    .print = print_hex64,
> +    .get   = get_uint64,
> +    .set   = set_uint64,
> +};
> +
> +/* --- string --- */
> +
> +static void release_string(Object *obj, const char *name, void *opaque)
> +{
> +    Property *prop = opaque;
> +    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
> +}
> +
> +static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
> +{
> +    char **ptr = qdev_get_prop_ptr(dev, prop);
> +    if (!*ptr)
> +        return snprintf(dest, len, "<null>");
> +    return snprintf(dest, len, "\"%s\"", *ptr);
> +}
> +
> +static void get_string(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    char **ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (!*ptr) {
> +        char *str = (char *)"";
> +        visit_type_str(v, &str, name, errp);
> +    } else {
> +        visit_type_str(v, ptr, name, errp);
> +    }
> +}
> +
> +static void set_string(Object *obj, Visitor *v, void *opaque,
> +                       const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    char **ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    char *str;
> +
> +    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 (*ptr) {
> +        g_free(*ptr);
> +    }
> +    *ptr = str;
> +}
> +
> +PropertyInfo qdev_prop_string = {
> +    .name  = "string",
> +    .print = print_string,
> +    .release = release_string,
> +    .get   = get_string,
> +    .set   = set_string,
> +};
> +
> +/* --- pointer --- */
> +
> +/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
> +PropertyInfo qdev_prop_ptr = {
> +    .name  = "ptr",
> +};
> +
> +/* --- mac address --- */
> +
> +/*
> + * accepted syntax versions:
> + *   01:02:03:04:05:06
> + *   01-02-03-04-05-06
> + */
> +static void get_mac(Object *obj, Visitor *v, void *opaque,
> +                    const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> +    char buffer[2 * 6 + 5 + 1];
> +    char *p = buffer;
> +
> +    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
> +             mac->a[0], mac->a[1], mac->a[2],
> +             mac->a[3], mac->a[4], mac->a[5]);
> +
> +    visit_type_str(v, &p, name, errp);
> +}
> +
> +static void set_mac(Object *obj, Visitor *v, void *opaque,
> +                    const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    int i, pos;
> +    char *str, *p;
> +
> +    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;
> +    }
> +
> +    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
> +        if (!qemu_isxdigit(str[pos]))
> +            goto inval;
> +        if (!qemu_isxdigit(str[pos+1]))
> +            goto inval;
> +        if (i == 5) {
> +            if (str[pos+2] != '\0')
> +                goto inval;
> +        } else {
> +            if (str[pos+2] != ':' && str[pos+2] != '-')
> +                goto inval;
> +        }
> +        mac->a[i] = strtol(str+pos, &p, 16);
> +    }
> +    g_free(str);
> +    return;
> +
> +inval:
> +    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> +    g_free(str);
> +}
> +
> +PropertyInfo qdev_prop_macaddr = {
> +    .name  = "macaddr",
> +    .get   = get_mac,
> +    .set   = set_mac,
> +};
> +
> +/* --- lost tick policy --- */
> +
> +static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
> +    [LOST_TICK_DISCARD] = "discard",
> +    [LOST_TICK_DELAY] = "delay",
> +    [LOST_TICK_MERGE] = "merge",
> +    [LOST_TICK_SLEW] = "slew",
> +    [LOST_TICK_MAX] = NULL,
> +};
> +
> +QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
> +
> +PropertyInfo qdev_prop_losttickpolicy = {
> +    .name  = "LostTickPolicy",
> +    .enum_table  = lost_tick_policy_table,
> +    .get   = get_enum,
> +    .set   = set_enum,
> +};
> +
> +/* --- BIOS CHS translation */
> +
> +static const char *bios_chs_trans_table[] = {
> +    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
> +    [BIOS_ATA_TRANSLATION_NONE] = "none",
> +    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
> +};
> +
> +PropertyInfo qdev_prop_bios_chs_trans = {
> +    .name = "bios-chs-trans",
> +    .enum_table = bios_chs_trans_table,
> +    .get = get_enum,
> +    .set = set_enum,
> +};
> +
> +/* --- pci address --- */
> +
> +/*
> + * bus-local address, i.e. "$slot" or "$slot.$fn"
> + */
> +static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
> +                          const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> +    unsigned int slot, fn, n;
> +    Error *local_err = NULL;
> +    char *str;
> +
> +    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_free(local_err);
> +        local_err = NULL;
> +        visit_type_int32(v, &value, name, &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +        } else if (value < -1 || value > 255) {
> +            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
> +                      "pci_devfn");
> +        } else {
> +            *ptr = value;
> +        }
> +        return;
> +    }
> +
> +    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
> +        fn = 0;
> +        if (sscanf(str, "%x%n", &slot, &n) != 1) {
> +            goto invalid;
> +        }
> +    }
> +    if (str[n] != '\0' || fn > 7 || slot > 31) {
> +        goto invalid;
> +    }
> +    *ptr = slot << 3 | fn;
> +    g_free(str);
> +    return;
> +
> +invalid:
> +    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> +    g_free(str);
> +}
> +
> +static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
> +{
> +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> +
> +    if (*ptr == -1) {
> +        return snprintf(dest, len, "<unset>");
> +    } else {
> +        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
> +    }
> +}
> +
> +PropertyInfo qdev_prop_pci_devfn = {
> +    .name  = "int32",
> +    .legacy_name  = "pci-devfn",
> +    .print = print_pci_devfn,
> +    .get   = get_int32,
> +    .set   = set_pci_devfn,
> +};
> +
> +/* --- blocksize --- */
> +
> +static void set_blocksize(Object *obj, Visitor *v, void *opaque,
> +                          const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    const int64_t min = 512;
> +    const int64_t max = 32768;
> +
> +    if (dev->state != DEV_STATE_CREATED) {
> +        error_set(errp, QERR_PERMISSION_DENIED);
> +        return;
> +    }
> +
> +    visit_type_uint16(v, &value, name, &local_err);
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (value < min || value > max) {
> +        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> +                  dev->id?:"", name, (int64_t)value, min, max);
> +        return;
> +    }
> +
> +    /* We rely on power-of-2 blocksizes for bitmasks */
> +    if ((value & (value - 1)) != 0) {
> +        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
> +                  dev->id?:"", name, (int64_t)value);
> +        return;
> +    }
> +
> +    *ptr = value;
> +}
> +
> +PropertyInfo qdev_prop_blocksize = {
> +    .name  = "blocksize",
> +    .get   = get_uint16,
> +    .set   = set_blocksize,
> +};
> +
> +/* --- pci host address --- */
> +
> +static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> +                                 const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> +    char buffer[] = "xxxx:xx:xx.x";
> +    char *p = buffer;
> +    int rc = 0;
> +
> +    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
> +                  addr->domain, addr->bus, addr->slot, addr->function);
> +    assert(rc == sizeof(buffer) - 1);
> +
> +    visit_type_str(v, &p, name, errp);
> +}
> +
> +/*
> + * Parse [<domain>:]<bus>:<slot>.<func>
> + *   if <domain> is not supplied, it's assumed to be 0.
> + */
> +static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> +                                 const char *name, Error **errp)
> +{
> +    DeviceState *dev = DEVICE(obj);
> +    Property *prop = opaque;
> +    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> +    Error *local_err = NULL;
> +    char *str, *p;
> +    char *e;
> +    unsigned long val;
> +    unsigned long dom = 0, bus = 0;
> +    unsigned int slot = 0, func = 0;
> +
> +    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;
> +    }
> +
> +    p = str;
> +    val = strtoul(p, &e, 16);
> +    if (e == p || *e != ':') {
> +        goto inval;
> +    }
> +    bus = val;
> +
> +    p = e + 1;
> +    val = strtoul(p, &e, 16);
> +    if (e == p) {
> +        goto inval;
> +    }
> +    if (*e == ':') {
> +        dom = bus;
> +        bus = val;
> +        p = e + 1;
> +        val = strtoul(p, &e, 16);
> +        if (e == p) {
> +            goto inval;
> +        }
> +    }
> +    slot = val;
> +
> +    if (*e != '.') {
> +        goto inval;
> +    }
> +    p = e + 1;
> +    val = strtoul(p, &e, 10);
> +    if (e == p) {
> +        goto inval;
> +    }
> +    func = val;
> +
> +    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
> +        goto inval;
> +    }
> +
> +    if (*e) {
> +        goto inval;
> +    }
> +
> +    addr->domain = dom;
> +    addr->bus = bus;
> +    addr->slot = slot;
> +    addr->function = func;
> +
> +    g_free(str);
> +    return;
> +
> +inval:
> +    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> +    g_free(str);
> +}
> +
> +PropertyInfo qdev_prop_pci_host_devaddr = {
> +    .name = "pci-host-devaddr",
> +    .get = get_pci_host_devaddr,
> +    .set = set_pci_host_devaddr,
> +};
> +
> +/* --- public helpers --- */
> +
> +static Property *qdev_prop_walk(Property *props, const char *name)
> +{
> +    if (!props)
> +        return NULL;
> +    while (props->name) {
> +        if (strcmp(props->name, name) == 0)
> +            return props;
> +        props++;
> +    }
> +    return NULL;
> +}
> +
> +static Property *qdev_prop_find(DeviceState *dev, const char *name)
> +{
> +    ObjectClass *class;
> +    Property *prop;
> +
> +    /* device properties */
> +    class = object_get_class(OBJECT(dev));
> +    do {
> +        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
> +        if (prop) {
> +            return prop;
> +        }
> +        class = object_class_get_parent(class);
> +    } while (class != object_class_by_name(TYPE_DEVICE));
> +
> +    return NULL;
> +}
> +
> +void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
> +                                    Property *prop, const char *value)
> +{
> +    switch (ret) {
> +    case -EEXIST:
> +        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
> +                  object_get_typename(OBJECT(dev)), prop->name, value);
> +        break;
> +    default:
> +    case -EINVAL:
> +        error_set(errp, QERR_PROPERTY_VALUE_BAD,
> +                  object_get_typename(OBJECT(dev)), prop->name, value);
> +        break;
> +    case -ENOENT:
> +        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
> +                  object_get_typename(OBJECT(dev)), prop->name, value);
> +        break;
> +    case 0:
> +        break;
> +    }
> +}
> +
> +int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> +{
> +    char *legacy_name;
> +    Error *err = NULL;
> +
> +    legacy_name = g_strdup_printf("legacy-%s", name);
> +    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
> +        object_property_parse(OBJECT(dev), value, legacy_name, &err);
> +    } else {
> +        object_property_parse(OBJECT(dev), value, name, &err);
> +    }
> +    g_free(legacy_name);
> +
> +    if (err) {
> +        qerror_report_err(err);
> +        error_free(err);
> +        return -1;
> +    }
> +    return 0;
> +}
> +
> +void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
> +{
> +    Error *errp = NULL;
> +    object_property_set_bool(OBJECT(dev), value, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
> +{
> +    Error *errp = NULL;
> +    object_property_set_int(OBJECT(dev), value, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
> +{
> +    Error *errp = NULL;
> +    object_property_set_int(OBJECT(dev), value, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
> +{
> +    Error *errp = NULL;
> +    object_property_set_int(OBJECT(dev), value, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
> +{
> +    Error *errp = NULL;
> +    object_property_set_int(OBJECT(dev), value, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
> +{
> +    Error *errp = NULL;
> +    object_property_set_int(OBJECT(dev), value, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
> +{
> +    Error *errp = NULL;
> +    object_property_set_str(OBJECT(dev), value, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
> +{
> +    Error *errp = NULL;
> +    char str[2 * 6 + 5 + 1];
> +    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
> +             value[0], value[1], value[2], value[3], value[4], value[5]);
> +
> +    object_property_set_str(OBJECT(dev), str, name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
> +{
> +    Property *prop;
> +    Error *errp = NULL;
> +
> +    prop = qdev_prop_find(dev, name);
> +    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
> +                            name, &errp);
> +    assert_no_error(errp);
> +}
> +
> +void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
> +{
> +    Property *prop;
> +    void **ptr;
> +
> +    prop = qdev_prop_find(dev, name);
> +    assert(prop && prop->info == &qdev_prop_ptr);
> +    ptr = qdev_get_prop_ptr(dev, prop);
> +    *ptr = value;
> +}
> +
> +static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
> +
> +void qdev_prop_register_global(GlobalProperty *prop)
> +{
> +    QTAILQ_INSERT_TAIL(&global_props, prop, next);
> +}
> +
> +void qdev_prop_register_global_list(GlobalProperty *props)
> +{
> +    int i;
> +
> +    for (i = 0; props[i].driver != NULL; i++) {
> +        qdev_prop_register_global(props+i);
> +    }
> +}
> +
> +void qdev_prop_set_globals(DeviceState *dev)
> +{
> +    ObjectClass *class = object_get_class(OBJECT(dev));
> +
> +    do {
> +        GlobalProperty *prop;
> +        QTAILQ_FOREACH(prop, &global_props, next) {
> +            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
> +                continue;
> +            }
> +            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> +                exit(1);
> +            }
> +        }
> +        class = object_class_get_parent(class);
> +    } while (class);
> +}
> +
> -- 
> 1.7.11.7

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

* Re: [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too
  2012-10-17 18:11   ` Anthony Liguori
@ 2012-10-17 18:18     ` Eduardo Habkost
  2012-10-17 19:21     ` Peter Maydell
  1 sibling, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-17 18:18 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: peter.maydell, riku.voipio, qemu-devel, blauwirbel, Igor Mammedov,
	Andreas Färber

On Wed, Oct 17, 2012 at 01:11:41PM -0500, Anthony Liguori wrote:
> Eduardo Habkost <ehabkost@redhat.com> writes:
> 
> > The code depends on some functions from qemu-option.o, so add
> > qemu-option.o to universal-obj-y to make sure it's included.
> >
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  Makefile.objs         |   3 +
> >  hw/Makefile.objs      |   2 +-
> >  hw/qdev-core.c        | 727 -------------------------------------
> >  hw/qdev-properties.c  | 963 --------------------------------------------------
> >  qom/Makefile.objs     |   2 +-
> >  qom/qdev-core.c       | 727 +++++++++++++++++++++++++++++++++++++
> >  qom/qdev-properties.c | 963 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  7 files changed, 1695 insertions(+), 1692 deletions(-)
> >  delete mode 100644 hw/qdev-core.c
> >  delete mode 100644 hw/qdev-properties.c
> >  create mode 100644 qom/qdev-core.c
> >  create mode 100644 qom/qdev-properties.c
> 
> Stick the following in your .git/config:
> 
> [diff]
>         renames = true

Done.

> 
> It's dangerously close to bike-shedding, but i don't think qdev belongs
> in qom/.  It's not core infrastructure.  It's the device base class and
> belongs IMHO in hw/.

I don't mind keeping it on hw/, either. I was unsure wheter to move it,
or if it would be OK for *-user to start including files from the hw/
directory.

If nobody complains, I will change the patches to keep the files on
"hw/" on the next version of the series.


> 
> Regards,
> 
> Anthony Liguori
> 
> >
> > diff --git a/Makefile.objs b/Makefile.objs
> > index 74b3542..fcd1336 100644
> > --- a/Makefile.objs
> > +++ b/Makefile.objs
> > @@ -16,6 +16,9 @@ universal-obj-y += $(qobject-obj-y)
> >  qom-obj-y = qom/
> >  
> >  universal-obj-y += $(qom-obj-y)
> > +# QOM qdev-core.o requires qemu-option.o:
> > +universal-obj-y += qemu-option.o
> > +
> >  
> >  #######################################################################
> >  # oslib-obj-y is code depending on the OS (win32 vs posix)
> > diff --git a/hw/Makefile.objs b/hw/Makefile.objs
> > index 70f2014..3ce38d2 100644
> > --- a/hw/Makefile.objs
> > +++ b/hw/Makefile.objs
> > @@ -180,7 +180,7 @@ common-obj-$(CONFIG_SD) += sd.o
> >  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-core.o qdev-properties.o qdev-monitor.o
> > +common-obj-y += qdev-monitor.o
> >  common-obj-y += qdev-system.o qdev-properties-system.o
> >  common-obj-$(CONFIG_BRLAPI) += baum.o
> >  
> > diff --git a/hw/qdev-core.c b/hw/qdev-core.c
> > deleted file mode 100644
> > index fbb7cb5..0000000
> > --- a/hw/qdev-core.c
> > +++ /dev/null
> > @@ -1,727 +0,0 @@
> > -/*
> > - *  Dynamic device configuration and creation.
> > - *
> > - *  Copyright (c) 2009 CodeSourcery
> > - *
> > - * This library is free software; you can redistribute it and/or
> > - * modify it under the terms of the GNU Lesser General Public
> > - * License as published by the Free Software Foundation; either
> > - * version 2 of the License, or (at your option) any later version.
> > - *
> > - * This library is distributed in the hope that it will be useful,
> > - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > - * Lesser General Public License for more details.
> > - *
> > - * You should have received a copy of the GNU Lesser General Public
> > - * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> > - */
> > -
> > -/* The theory here is that it should be possible to create a machine without
> > -   knowledge of specific devices.  Historically board init routines have
> > -   passed a bunch of arguments to each device, requiring the board know
> > -   exactly which device it is dealing with.  This file provides an abstract
> > -   API for device configuration and initialization.  Devices will generally
> > -   inherit from a particular bus (e.g. PCI or I2C) rather than
> > -   this API directly.  */
> > -
> > -#include "hw/qdev.h"
> > -#include "sysemu.h"
> > -#include "error.h"
> > -#include "qapi/qapi-visit-core.h"
> > -
> > -int qdev_hotplug = 0;
> > -static bool qdev_hot_added = false;
> > -static bool qdev_hot_removed = false;
> > -
> > -/* vmstate handling:
> > - *
> > - * The real implementations are on qdev-system.c. Those are weak symbols
> > - * used by *-user.
> > - */
> > -void GCC_WEAK qdev_init_vmstate(DeviceState *dev)
> > -{
> > -}
> > -
> > -void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
> > -{
> > -}
> > -
> > -/* reset handler register/unregister:
> > - *
> > - * The real implementations are on qdev-system.c. Those are weak symbols
> > - * used by *-user.
> > - */
> > -void GCC_WEAK qbus_register_reset(BusState *bus)
> > -{
> > -}
> > -
> > -void GCC_WEAK qbus_unregister_reset(BusState *bus)
> > -{
> > -}
> > -
> > -const char *qdev_fw_name(DeviceState *dev)
> > -{
> > -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > -
> > -    if (dc->fw_name) {
> > -        return dc->fw_name;
> > -    }
> > -
> > -    return object_get_typename(OBJECT(dev));
> > -}
> > -
> > -static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> > -                                     Error **errp);
> > -
> > -static void bus_remove_child(BusState *bus, DeviceState *child)
> > -{
> > -    BusChild *kid;
> > -
> > -    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> > -        if (kid->child == child) {
> > -            char name[32];
> > -
> > -            snprintf(name, sizeof(name), "child[%d]", kid->index);
> > -            QTAILQ_REMOVE(&bus->children, kid, sibling);
> > -            object_property_del(OBJECT(bus), name, NULL);
> > -            g_free(kid);
> > -            return;
> > -        }
> > -    }
> > -}
> > -
> > -static void bus_add_child(BusState *bus, DeviceState *child)
> > -{
> > -    char name[32];
> > -    BusChild *kid = g_malloc0(sizeof(*kid));
> > -
> > -    if (qdev_hotplug) {
> > -        assert(bus->allow_hotplug);
> > -    }
> > -
> > -    kid->index = bus->max_index++;
> > -    kid->child = child;
> > -
> > -    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
> > -
> > -    snprintf(name, sizeof(name), "child[%d]", kid->index);
> > -    object_property_add_link(OBJECT(bus), name,
> > -                             object_get_typename(OBJECT(child)),
> > -                             (Object **)&kid->child,
> > -                             NULL);
> > -}
> > -
> > -void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
> > -{
> > -    dev->parent_bus = bus;
> > -    bus_add_child(bus, 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.
> > -   On failure, destroy the device and return negative value.
> > -   Return 0 on success.  */
> > -int qdev_init(DeviceState *dev)
> > -{
> > -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > -    int rc;
> > -
> > -    assert(dev->state == DEV_STATE_CREATED);
> > -
> > -    rc = dc->init(dev);
> > -    if (rc < 0) {
> > -        qdev_free(dev);
> > -        return rc;
> > -    }
> > -
> > -    if (!OBJECT(dev)->parent) {
> > -        static int unattached_count = 0;
> > -        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
> > -
> > -        object_property_add_child(container_get(qdev_get_machine(),
> > -                                                "/unattached"),
> > -                                  name, OBJECT(dev), NULL);
> > -        g_free(name);
> > -    }
> > -
> > -    qdev_init_vmstate(dev);
> > -    dev->state = DEV_STATE_INITIALIZED;
> > -    if (dev->hotplugged) {
> > -        device_reset(dev);
> > -    }
> > -    return 0;
> > -}
> > -
> > -void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
> > -                                 int required_for_version)
> > -{
> > -    assert(dev->state == DEV_STATE_CREATED);
> > -    dev->instance_id_alias = alias_id;
> > -    dev->alias_required_for_version = required_for_version;
> > -}
> > -
> > -void qdev_unplug(DeviceState *dev, Error **errp)
> > -{
> > -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > -
> > -    if (!dev->parent_bus->allow_hotplug) {
> > -        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
> > -        return;
> > -    }
> > -    assert(dc->unplug != NULL);
> > -
> > -    qdev_hot_removed = true;
> > -
> > -    if (dc->unplug(dev) < 0) {
> > -        error_set(errp, QERR_UNDEFINED_ERROR);
> > -        return;
> > -    }
> > -}
> > -
> > -static int qdev_reset_one(DeviceState *dev, void *opaque)
> > -{
> > -    device_reset(dev);
> > -
> > -    return 0;
> > -}
> > -
> > -static int qbus_reset_one(BusState *bus, void *opaque)
> > -{
> > -    BusClass *bc = BUS_GET_CLASS(bus);
> > -    if (bc->reset) {
> > -        return bc->reset(bus);
> > -    }
> > -    return 0;
> > -}
> > -
> > -void qdev_reset_all(DeviceState *dev)
> > -{
> > -    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
> > -}
> > -
> > -void qbus_reset_all_fn(void *opaque)
> > -{
> > -    BusState *bus = opaque;
> > -    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
> > -}
> > -
> > -/* can be used as ->unplug() callback for the simple cases */
> > -int qdev_simple_unplug_cb(DeviceState *dev)
> > -{
> > -    /* just zap it */
> > -    qdev_free(dev);
> > -    return 0;
> > -}
> > -
> > -
> > -/* Like qdev_init(), but terminate program via error_report() instead of
> > -   returning an error value.  This is okay during machine creation.
> > -   Don't use for hotplug, because there callers need to recover from
> > -   failure.  Exception: if you know the device's init() callback can't
> > -   fail, then qdev_init_nofail() can't fail either, and is therefore
> > -   usable even then.  But relying on the device implementation that
> > -   way is somewhat unclean, and best avoided.  */
> > -void qdev_init_nofail(DeviceState *dev)
> > -{
> > -    const char *typename = object_get_typename(OBJECT(dev));
> > -
> > -    if (qdev_init(dev) < 0) {
> > -        error_report("Initialization of device %s failed", typename);
> > -        exit(1);
> > -    }
> > -}
> > -
> > -/* Unlink device from bus and free the structure.  */
> > -void qdev_free(DeviceState *dev)
> > -{
> > -    object_delete(OBJECT(dev));
> > -}
> > -
> > -void qdev_machine_creation_done(void)
> > -{
> > -    /*
> > -     * ok, initial machine setup is done, starting from now we can
> > -     * only create hotpluggable devices
> > -     */
> > -    qdev_hotplug = 1;
> > -}
> > -
> > -bool qdev_machine_modified(void)
> > -{
> > -    return qdev_hot_added || qdev_hot_removed;
> > -}
> > -
> > -BusState *qdev_get_parent_bus(DeviceState *dev)
> > -{
> > -    return dev->parent_bus;
> > -}
> > -
> > -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)
> > -{
> > -    BusChild *kid;
> > -    int err;
> > -
> > -    if (busfn) {
> > -        err = busfn(bus, opaque);
> > -        if (err) {
> > -            return err;
> > -        }
> > -    }
> > -
> > -    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> > -        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
> > -        if (err < 0) {
> > -            return err;
> > -        }
> > -    }
> > -
> > -    return 0;
> > -}
> > -
> > -int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
> > -                       qbus_walkerfn *busfn, void *opaque)
> > -{
> > -    BusState *bus;
> > -    int err;
> > -
> > -    if (devfn) {
> > -        err = devfn(dev, opaque);
> > -        if (err) {
> > -            return err;
> > -        }
> > -    }
> > -
> > -    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
> > -        err = qbus_walk_children(bus, devfn, busfn, opaque);
> > -        if (err < 0) {
> > -            return err;
> > -        }
> > -    }
> > -
> > -    return 0;
> > -}
> > -
> > -DeviceState *qdev_find_recursive(BusState *bus, const char *id)
> > -{
> > -    BusChild *kid;
> > -    DeviceState *ret;
> > -    BusState *child;
> > -
> > -    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> > -        DeviceState *dev = kid->child;
> > -
> > -        if (dev->id && strcmp(dev->id, id) == 0) {
> > -            return dev;
> > -        }
> > -
> > -        QLIST_FOREACH(child, &dev->child_bus, sibling) {
> > -            ret = qdev_find_recursive(child, id);
> > -            if (ret) {
> > -                return ret;
> > -            }
> > -        }
> > -    }
> > -    return NULL;
> > -}
> > -
> > -static void qbus_realize(BusState *bus)
> > -{
> > -    const char *typename = object_get_typename(OBJECT(bus));
> > -    char *buf;
> > -    int i,len;
> > -
> > -    if (bus->name) {
> > -        /* use supplied name */
> > -    } else if (bus->parent && bus->parent->id) {
> > -        /* parent device has id -> use it for bus name */
> > -        len = strlen(bus->parent->id) + 16;
> > -        buf = g_malloc(len);
> > -        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
> > -        bus->name = buf;
> > -    } else {
> > -        /* no id -> use lowercase bus type for bus name */
> > -        len = strlen(typename) + 16;
> > -        buf = g_malloc(len);
> > -        len = snprintf(buf, len, "%s.%d", typename,
> > -                       bus->parent ? bus->parent->num_child_bus : 0);
> > -        for (i = 0; i < len; i++)
> > -            buf[i] = qemu_tolower(buf[i]);
> > -        bus->name = buf;
> > -    }
> > -
> > -    if (bus->parent) {
> > -        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
> > -        bus->parent->num_child_bus++;
> > -        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> > -    } else {
> > -        qbus_register_reset(bus);
> > -    }
> > -}
> > -
> > -void qbus_create_inplace(BusState *bus, const char *typename,
> > -                         DeviceState *parent, const char *name)
> > -{
> > -    object_initialize(bus, typename);
> > -
> > -    bus->parent = parent;
> > -    bus->name = name ? g_strdup(name) : NULL;
> > -    qbus_realize(bus);
> > -}
> > -
> > -BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
> > -{
> > -    BusState *bus;
> > -
> > -    bus = BUS(object_new(typename));
> > -    bus->qom_allocated = true;
> > -
> > -    bus->parent = parent;
> > -    bus->name = name ? g_strdup(name) : NULL;
> > -    qbus_realize(bus);
> > -
> > -    return bus;
> > -}
> > -
> > -void qbus_free(BusState *bus)
> > -{
> > -    if (bus->qom_allocated) {
> > -        object_delete(OBJECT(bus));
> > -    } else {
> > -        object_finalize(OBJECT(bus));
> > -        if (bus->glib_allocated) {
> > -            g_free(bus);
> > -        }
> > -    }
> > -}
> > -
> > -static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
> > -{
> > -    BusClass *bc = BUS_GET_CLASS(bus);
> > -
> > -    if (bc->get_fw_dev_path) {
> > -        return bc->get_fw_dev_path(dev);
> > -    }
> > -
> > -    return NULL;
> > -}
> > -
> > -static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
> > -{
> > -    int l = 0;
> > -
> > -    if (dev && dev->parent_bus) {
> > -        char *d;
> > -        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
> > -        d = bus_get_fw_dev_path(dev->parent_bus, dev);
> > -        if (d) {
> > -            l += snprintf(p + l, size - l, "%s", d);
> > -            g_free(d);
> > -        } else {
> > -            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
> > -        }
> > -    }
> > -    l += snprintf(p + l , size - l, "/");
> > -
> > -    return l;
> > -}
> > -
> > -char* qdev_get_fw_dev_path(DeviceState *dev)
> > -{
> > -    char path[128];
> > -    int l;
> > -
> > -    l = qdev_get_fw_dev_path_helper(dev, path, 128);
> > -
> > -    path[l-1] = '\0';
> > -
> > -    return g_strdup(path);
> > -}
> > -
> > -char *qdev_get_dev_path(DeviceState *dev)
> > -{
> > -    BusClass *bc;
> > -
> > -    if (!dev || !dev->parent_bus) {
> > -        return NULL;
> > -    }
> > -
> > -    bc = BUS_GET_CLASS(dev->parent_bus);
> > -    if (bc->get_dev_path) {
> > -        return bc->get_dev_path(dev);
> > -    }
> > -
> > -    return NULL;
> > -}
> > -
> > -/**
> > - * Legacy property handling
> > - */
> > -
> > -static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
> > -                                     const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -
> > -    char buffer[1024];
> > -    char *ptr = buffer;
> > -
> > -    prop->info->print(dev, prop, buffer, sizeof(buffer));
> > -    visit_type_str(v, &ptr, name, errp);
> > -}
> > -
> > -static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
> > -                                     const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    Error *local_err = NULL;
> > -    char *ptr = NULL;
> > -    int ret;
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_str(v, &ptr, name, &local_err);
> > -    if (local_err) {
> > -        error_propagate(errp, local_err);
> > -        return;
> > -    }
> > -
> > -    ret = prop->info->parse(dev, prop, ptr);
> > -    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
> > -    g_free(ptr);
> > -}
> > -
> > -/**
> > - * @qdev_add_legacy_property - adds a legacy property
> > - *
> > - * Do not use this is new code!  Properties added through this interface will
> > - * be given names and types in the "legacy" namespace.
> > - *
> > - * Legacy properties are string versions of other OOM properties.  The format
> > - * of the string depends on the property type.
> > - */
> > -void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> > -                              Error **errp)
> > -{
> > -    gchar *name, *type;
> > -
> > -    /* Register pointer properties as legacy properties */
> > -    if (!prop->info->print && !prop->info->parse &&
> > -        (prop->info->set || prop->info->get)) {
> > -        return;
> > -    }
> > -
> > -    name = g_strdup_printf("legacy-%s", prop->name);
> > -    type = g_strdup_printf("legacy<%s>",
> > -                           prop->info->legacy_name ?: prop->info->name);
> > -
> > -    object_property_add(OBJECT(dev), name, type,
> > -                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
> > -                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
> > -                        NULL,
> > -                        prop, errp);
> > -
> > -    g_free(type);
> > -    g_free(name);
> > -}
> > -
> > -/**
> > - * @qdev_property_add_static - add a @Property to a device.
> > - *
> > - * Static properties access data in a struct.  The actual type of the
> > - * property and the field depends on the property type.
> > - */
> > -void qdev_property_add_static(DeviceState *dev, Property *prop,
> > -                              Error **errp)
> > -{
> > -    Error *local_err = NULL;
> > -    Object *obj = OBJECT(dev);
> > -
> > -    /*
> > -     * TODO qdev_prop_ptr does not have getters or setters.  It must
> > -     * go now that it can be replaced with links.  The test should be
> > -     * removed along with it: all static properties are read/write.
> > -     */
> > -    if (!prop->info->get && !prop->info->set) {
> > -        return;
> > -    }
> > -
> > -    object_property_add(obj, prop->name, prop->info->name,
> > -                        prop->info->get, prop->info->set,
> > -                        prop->info->release,
> > -                        prop, &local_err);
> > -
> > -    if (local_err) {
> > -        error_propagate(errp, local_err);
> > -        return;
> > -    }
> > -    if (prop->qtype == QTYPE_NONE) {
> > -        return;
> > -    }
> > -
> > -    if (prop->qtype == QTYPE_QBOOL) {
> > -        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
> > -    } else if (prop->info->enum_table) {
> > -        object_property_set_str(obj, prop->info->enum_table[prop->defval],
> > -                                prop->name, &local_err);
> > -    } else if (prop->qtype == QTYPE_QINT) {
> > -        object_property_set_int(obj, prop->defval, prop->name, &local_err);
> > -    }
> > -    assert_no_error(local_err);
> > -}
> > -
> > -static void device_initfn(Object *obj)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    ObjectClass *class;
> > -    Property *prop;
> > -
> > -    if (qdev_hotplug) {
> > -        dev->hotplugged = 1;
> > -        qdev_hot_added = true;
> > -    }
> > -
> > -    dev->instance_id_alias = -1;
> > -    dev->state = DEV_STATE_CREATED;
> > -
> > -    class = object_get_class(OBJECT(dev));
> > -    do {
> > -        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
> > -            qdev_property_add_legacy(dev, prop, NULL);
> > -            qdev_property_add_static(dev, prop, NULL);
> > -        }
> > -        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);
> > -}
> > -
> > -/* Unlink device from bus and free the structure.  */
> > -static void device_finalize(Object *obj)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    BusState *bus;
> > -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > -
> > -    if (dev->state == DEV_STATE_INITIALIZED) {
> > -        while (dev->num_child_bus) {
> > -            bus = QLIST_FIRST(&dev->child_bus);
> > -            qbus_free(bus);
> > -        }
> > -        qdev_finalize_vmstate(dev);
> > -        if (dc->exit) {
> > -            dc->exit(dev);
> > -        }
> > -        if (dev->opts) {
> > -            qemu_opts_del(dev->opts);
> > -        }
> > -    }
> > -    if (dev->parent_bus) {
> > -        bus_remove_child(dev->parent_bus, dev);
> > -    }
> > -}
> > -
> > -static void device_class_base_init(ObjectClass *class, void *data)
> > -{
> > -    DeviceClass *klass = DEVICE_CLASS(class);
> > -
> > -    /* We explicitly look up properties in the superclasses,
> > -     * so do not propagate them to the subclasses.
> > -     */
> > -    klass->props = NULL;
> > -}
> > -
> > -void device_reset(DeviceState *dev)
> > -{
> > -    DeviceClass *klass = DEVICE_GET_CLASS(dev);
> > -
> > -    if (klass->reset) {
> > -        klass->reset(dev);
> > -    }
> > -}
> > -
> > -Object *qdev_get_machine(void)
> > -{
> > -    static Object *dev;
> > -
> > -    if (dev == NULL) {
> > -        dev = container_get(object_get_root(), "/machine");
> > -    }
> > -
> > -    return dev;
> > -}
> > -
> > -static TypeInfo device_type_info = {
> > -    .name = TYPE_DEVICE,
> > -    .parent = TYPE_OBJECT,
> > -    .instance_size = sizeof(DeviceState),
> > -    .instance_init = device_initfn,
> > -    .instance_finalize = device_finalize,
> > -    .class_base_init = device_class_base_init,
> > -    .abstract = true,
> > -    .class_size = sizeof(DeviceClass),
> > -};
> > -
> > -static void qbus_initfn(Object *obj)
> > -{
> > -    BusState *bus = BUS(obj);
> > -
> > -    QTAILQ_INIT(&bus->children);
> > -}
> > -
> > -static void qbus_finalize(Object *obj)
> > -{
> > -    BusState *bus = BUS(obj);
> > -    BusChild *kid;
> > -
> > -    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
> > -        DeviceState *dev = kid->child;
> > -        qdev_free(dev);
> > -    }
> > -    if (bus->parent) {
> > -        QLIST_REMOVE(bus, sibling);
> > -        bus->parent->num_child_bus--;
> > -    } else {
> > -        qbus_unregister_reset(bus);
> > -    }
> > -    g_free((char *)bus->name);
> > -}
> > -
> > -static const TypeInfo bus_info = {
> > -    .name = TYPE_BUS,
> > -    .parent = TYPE_OBJECT,
> > -    .instance_size = sizeof(BusState),
> > -    .abstract = true,
> > -    .class_size = sizeof(BusClass),
> > -    .instance_init = qbus_initfn,
> > -    .instance_finalize = qbus_finalize,
> > -};
> > -
> > -static void qdev_register_types(void)
> > -{
> > -    type_register_static(&bus_info);
> > -    type_register_static(&device_type_info);
> > -}
> > -
> > -type_init(qdev_register_types)
> > diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> > deleted file mode 100644
> > index 2e82cb9..0000000
> > --- a/hw/qdev-properties.c
> > +++ /dev/null
> > @@ -1,963 +0,0 @@
> > -#include "net.h"
> > -#include "hw/qdev.h"
> > -#include "qerror.h"
> > -#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)
> > -{
> > -    void *ptr = dev;
> > -    ptr += prop->offset;
> > -    return ptr;
> > -}
> > -
> > -static void get_enum(Object *obj, Visitor *v, void *opaque,
> > -                     const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    int *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    visit_type_enum(v, ptr, prop->info->enum_table,
> > -                    prop->info->name, prop->name, errp);
> > -}
> > -
> > -static void set_enum(Object *obj, Visitor *v, void *opaque,
> > -                     const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    int *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_enum(v, ptr, prop->info->enum_table,
> > -                    prop->info->name, prop->name, errp);
> > -}
> > -
> > -/* Bit */
> > -
> > -static uint32_t qdev_get_prop_mask(Property *prop)
> > -{
> > -    assert(prop->info == &qdev_prop_bit);
> > -    return 0x1 << prop->bitnr;
> > -}
> > -
> > -static void bit_prop_set(DeviceState *dev, Property *props, bool val)
> > -{
> > -    uint32_t *p = qdev_get_prop_ptr(dev, props);
> > -    uint32_t mask = qdev_get_prop_mask(props);
> > -    if (val)
> > -        *p |= mask;
> > -    else
> > -        *p &= ~mask;
> > -}
> > -
> > -static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
> > -{
> > -    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> > -    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
> > -}
> > -
> > -static void get_bit(Object *obj, Visitor *v, void *opaque,
> > -                    const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> > -    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> > -
> > -    visit_type_bool(v, &value, name, errp);
> > -}
> > -
> > -static void set_bit(Object *obj, Visitor *v, void *opaque,
> > -                    const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    Error *local_err = NULL;
> > -    bool value;
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_bool(v, &value, name, &local_err);
> > -    if (local_err) {
> > -        error_propagate(errp, local_err);
> > -        return;
> > -    }
> > -    bit_prop_set(dev, prop, value);
> > -}
> > -
> > -PropertyInfo qdev_prop_bit = {
> > -    .name  = "boolean",
> > -    .legacy_name  = "on/off",
> > -    .print = print_bit,
> > -    .get   = get_bit,
> > -    .set   = set_bit,
> > -};
> > -
> > -/* --- 8bit integer --- */
> > -
> > -static void get_uint8(Object *obj, Visitor *v, void *opaque,
> > -                      const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    visit_type_uint8(v, ptr, name, errp);
> > -}
> > -
> > -static void set_uint8(Object *obj, Visitor *v, void *opaque,
> > -                      const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_uint8(v, ptr, name, errp);
> > -}
> > -
> > -PropertyInfo qdev_prop_uint8 = {
> > -    .name  = "uint8",
> > -    .get   = get_uint8,
> > -    .set   = set_uint8,
> > -};
> > -
> > -/* --- 8bit hex value --- */
> > -
> > -static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
> > -{
> > -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -    char *end;
> > -
> > -    if (str[0] != '0' || str[1] != 'x') {
> > -        return -EINVAL;
> > -    }
> > -
> > -    *ptr = strtoul(str, &end, 16);
> > -    if ((*end != '\0') || (end == str)) {
> > -        return -EINVAL;
> > -    }
> > -
> > -    return 0;
> > -}
> > -
> > -static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
> > -{
> > -    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -    return snprintf(dest, len, "0x%" PRIx8, *ptr);
> > -}
> > -
> > -PropertyInfo qdev_prop_hex8 = {
> > -    .name  = "uint8",
> > -    .legacy_name  = "hex8",
> > -    .parse = parse_hex8,
> > -    .print = print_hex8,
> > -    .get   = get_uint8,
> > -    .set   = set_uint8,
> > -};
> > -
> > -/* --- 16bit integer --- */
> > -
> > -static void get_uint16(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    visit_type_uint16(v, ptr, name, errp);
> > -}
> > -
> > -static void set_uint16(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_uint16(v, ptr, name, errp);
> > -}
> > -
> > -PropertyInfo qdev_prop_uint16 = {
> > -    .name  = "uint16",
> > -    .get   = get_uint16,
> > -    .set   = set_uint16,
> > -};
> > -
> > -/* --- 32bit integer --- */
> > -
> > -static void get_uint32(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    visit_type_uint32(v, ptr, name, errp);
> > -}
> > -
> > -static void set_uint32(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_uint32(v, ptr, name, errp);
> > -}
> > -
> > -static void get_int32(Object *obj, Visitor *v, void *opaque,
> > -                      const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    visit_type_int32(v, ptr, name, errp);
> > -}
> > -
> > -static void set_int32(Object *obj, Visitor *v, void *opaque,
> > -                      const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_int32(v, ptr, name, errp);
> > -}
> > -
> > -PropertyInfo qdev_prop_uint32 = {
> > -    .name  = "uint32",
> > -    .get   = get_uint32,
> > -    .set   = set_uint32,
> > -};
> > -
> > -PropertyInfo qdev_prop_int32 = {
> > -    .name  = "int32",
> > -    .get   = get_int32,
> > -    .set   = set_int32,
> > -};
> > -
> > -/* --- 32bit hex value --- */
> > -
> > -static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
> > -{
> > -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -    char *end;
> > -
> > -    if (str[0] != '0' || str[1] != 'x') {
> > -        return -EINVAL;
> > -    }
> > -
> > -    *ptr = strtoul(str, &end, 16);
> > -    if ((*end != '\0') || (end == str)) {
> > -        return -EINVAL;
> > -    }
> > -
> > -    return 0;
> > -}
> > -
> > -static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
> > -{
> > -    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -    return snprintf(dest, len, "0x%" PRIx32, *ptr);
> > -}
> > -
> > -PropertyInfo qdev_prop_hex32 = {
> > -    .name  = "uint32",
> > -    .legacy_name  = "hex32",
> > -    .parse = parse_hex32,
> > -    .print = print_hex32,
> > -    .get   = get_uint32,
> > -    .set   = set_uint32,
> > -};
> > -
> > -/* --- 64bit integer --- */
> > -
> > -static void get_uint64(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    visit_type_uint64(v, ptr, name, errp);
> > -}
> > -
> > -static void set_uint64(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_uint64(v, ptr, name, errp);
> > -}
> > -
> > -PropertyInfo qdev_prop_uint64 = {
> > -    .name  = "uint64",
> > -    .get   = get_uint64,
> > -    .set   = set_uint64,
> > -};
> > -
> > -/* --- 64bit hex value --- */
> > -
> > -static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
> > -{
> > -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -    char *end;
> > -
> > -    if (str[0] != '0' || str[1] != 'x') {
> > -        return -EINVAL;
> > -    }
> > -
> > -    *ptr = strtoull(str, &end, 16);
> > -    if ((*end != '\0') || (end == str)) {
> > -        return -EINVAL;
> > -    }
> > -
> > -    return 0;
> > -}
> > -
> > -static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
> > -{
> > -    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -    return snprintf(dest, len, "0x%" PRIx64, *ptr);
> > -}
> > -
> > -PropertyInfo qdev_prop_hex64 = {
> > -    .name  = "uint64",
> > -    .legacy_name  = "hex64",
> > -    .parse = parse_hex64,
> > -    .print = print_hex64,
> > -    .get   = get_uint64,
> > -    .set   = set_uint64,
> > -};
> > -
> > -/* --- string --- */
> > -
> > -static void release_string(Object *obj, const char *name, void *opaque)
> > -{
> > -    Property *prop = opaque;
> > -    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
> > -}
> > -
> > -static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
> > -{
> > -    char **ptr = qdev_get_prop_ptr(dev, prop);
> > -    if (!*ptr)
> > -        return snprintf(dest, len, "<null>");
> > -    return snprintf(dest, len, "\"%s\"", *ptr);
> > -}
> > -
> > -static void get_string(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    char **ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (!*ptr) {
> > -        char *str = (char *)"";
> > -        visit_type_str(v, &str, name, errp);
> > -    } else {
> > -        visit_type_str(v, ptr, name, errp);
> > -    }
> > -}
> > -
> > -static void set_string(Object *obj, Visitor *v, void *opaque,
> > -                       const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    char **ptr = qdev_get_prop_ptr(dev, prop);
> > -    Error *local_err = NULL;
> > -    char *str;
> > -
> > -    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 (*ptr) {
> > -        g_free(*ptr);
> > -    }
> > -    *ptr = str;
> > -}
> > -
> > -PropertyInfo qdev_prop_string = {
> > -    .name  = "string",
> > -    .print = print_string,
> > -    .release = release_string,
> > -    .get   = get_string,
> > -    .set   = set_string,
> > -};
> > -
> > -/* --- pointer --- */
> > -
> > -/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
> > -PropertyInfo qdev_prop_ptr = {
> > -    .name  = "ptr",
> > -};
> > -
> > -/* --- mac address --- */
> > -
> > -/*
> > - * accepted syntax versions:
> > - *   01:02:03:04:05:06
> > - *   01-02-03-04-05-06
> > - */
> > -static void get_mac(Object *obj, Visitor *v, void *opaque,
> > -                    const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> > -    char buffer[2 * 6 + 5 + 1];
> > -    char *p = buffer;
> > -
> > -    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
> > -             mac->a[0], mac->a[1], mac->a[2],
> > -             mac->a[3], mac->a[4], mac->a[5]);
> > -
> > -    visit_type_str(v, &p, name, errp);
> > -}
> > -
> > -static void set_mac(Object *obj, Visitor *v, void *opaque,
> > -                    const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> > -    Error *local_err = NULL;
> > -    int i, pos;
> > -    char *str, *p;
> > -
> > -    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;
> > -    }
> > -
> > -    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
> > -        if (!qemu_isxdigit(str[pos]))
> > -            goto inval;
> > -        if (!qemu_isxdigit(str[pos+1]))
> > -            goto inval;
> > -        if (i == 5) {
> > -            if (str[pos+2] != '\0')
> > -                goto inval;
> > -        } else {
> > -            if (str[pos+2] != ':' && str[pos+2] != '-')
> > -                goto inval;
> > -        }
> > -        mac->a[i] = strtol(str+pos, &p, 16);
> > -    }
> > -    g_free(str);
> > -    return;
> > -
> > -inval:
> > -    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> > -    g_free(str);
> > -}
> > -
> > -PropertyInfo qdev_prop_macaddr = {
> > -    .name  = "macaddr",
> > -    .get   = get_mac,
> > -    .set   = set_mac,
> > -};
> > -
> > -/* --- lost tick policy --- */
> > -
> > -static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
> > -    [LOST_TICK_DISCARD] = "discard",
> > -    [LOST_TICK_DELAY] = "delay",
> > -    [LOST_TICK_MERGE] = "merge",
> > -    [LOST_TICK_SLEW] = "slew",
> > -    [LOST_TICK_MAX] = NULL,
> > -};
> > -
> > -QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
> > -
> > -PropertyInfo qdev_prop_losttickpolicy = {
> > -    .name  = "LostTickPolicy",
> > -    .enum_table  = lost_tick_policy_table,
> > -    .get   = get_enum,
> > -    .set   = set_enum,
> > -};
> > -
> > -/* --- BIOS CHS translation */
> > -
> > -static const char *bios_chs_trans_table[] = {
> > -    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
> > -    [BIOS_ATA_TRANSLATION_NONE] = "none",
> > -    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
> > -};
> > -
> > -PropertyInfo qdev_prop_bios_chs_trans = {
> > -    .name = "bios-chs-trans",
> > -    .enum_table = bios_chs_trans_table,
> > -    .get = get_enum,
> > -    .set = set_enum,
> > -};
> > -
> > -/* --- pci address --- */
> > -
> > -/*
> > - * bus-local address, i.e. "$slot" or "$slot.$fn"
> > - */
> > -static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
> > -                          const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> > -    unsigned int slot, fn, n;
> > -    Error *local_err = NULL;
> > -    char *str;
> > -
> > -    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_free(local_err);
> > -        local_err = NULL;
> > -        visit_type_int32(v, &value, name, &local_err);
> > -        if (local_err) {
> > -            error_propagate(errp, local_err);
> > -        } else if (value < -1 || value > 255) {
> > -            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
> > -                      "pci_devfn");
> > -        } else {
> > -            *ptr = value;
> > -        }
> > -        return;
> > -    }
> > -
> > -    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
> > -        fn = 0;
> > -        if (sscanf(str, "%x%n", &slot, &n) != 1) {
> > -            goto invalid;
> > -        }
> > -    }
> > -    if (str[n] != '\0' || fn > 7 || slot > 31) {
> > -        goto invalid;
> > -    }
> > -    *ptr = slot << 3 | fn;
> > -    g_free(str);
> > -    return;
> > -
> > -invalid:
> > -    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> > -    g_free(str);
> > -}
> > -
> > -static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
> > -{
> > -    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > -
> > -    if (*ptr == -1) {
> > -        return snprintf(dest, len, "<unset>");
> > -    } else {
> > -        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
> > -    }
> > -}
> > -
> > -PropertyInfo qdev_prop_pci_devfn = {
> > -    .name  = "int32",
> > -    .legacy_name  = "pci-devfn",
> > -    .print = print_pci_devfn,
> > -    .get   = get_int32,
> > -    .set   = set_pci_devfn,
> > -};
> > -
> > -/* --- blocksize --- */
> > -
> > -static void set_blocksize(Object *obj, Visitor *v, void *opaque,
> > -                          const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> > -    Error *local_err = NULL;
> > -    const int64_t min = 512;
> > -    const int64_t max = 32768;
> > -
> > -    if (dev->state != DEV_STATE_CREATED) {
> > -        error_set(errp, QERR_PERMISSION_DENIED);
> > -        return;
> > -    }
> > -
> > -    visit_type_uint16(v, &value, name, &local_err);
> > -    if (local_err) {
> > -        error_propagate(errp, local_err);
> > -        return;
> > -    }
> > -    if (value < min || value > max) {
> > -        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> > -                  dev->id?:"", name, (int64_t)value, min, max);
> > -        return;
> > -    }
> > -
> > -    /* We rely on power-of-2 blocksizes for bitmasks */
> > -    if ((value & (value - 1)) != 0) {
> > -        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
> > -                  dev->id?:"", name, (int64_t)value);
> > -        return;
> > -    }
> > -
> > -    *ptr = value;
> > -}
> > -
> > -PropertyInfo qdev_prop_blocksize = {
> > -    .name  = "blocksize",
> > -    .get   = get_uint16,
> > -    .set   = set_blocksize,
> > -};
> > -
> > -/* --- pci host address --- */
> > -
> > -static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> > -                                 const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> > -    char buffer[] = "xxxx:xx:xx.x";
> > -    char *p = buffer;
> > -    int rc = 0;
> > -
> > -    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
> > -                  addr->domain, addr->bus, addr->slot, addr->function);
> > -    assert(rc == sizeof(buffer) - 1);
> > -
> > -    visit_type_str(v, &p, name, errp);
> > -}
> > -
> > -/*
> > - * Parse [<domain>:]<bus>:<slot>.<func>
> > - *   if <domain> is not supplied, it's assumed to be 0.
> > - */
> > -static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> > -                                 const char *name, Error **errp)
> > -{
> > -    DeviceState *dev = DEVICE(obj);
> > -    Property *prop = opaque;
> > -    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> > -    Error *local_err = NULL;
> > -    char *str, *p;
> > -    char *e;
> > -    unsigned long val;
> > -    unsigned long dom = 0, bus = 0;
> > -    unsigned int slot = 0, func = 0;
> > -
> > -    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;
> > -    }
> > -
> > -    p = str;
> > -    val = strtoul(p, &e, 16);
> > -    if (e == p || *e != ':') {
> > -        goto inval;
> > -    }
> > -    bus = val;
> > -
> > -    p = e + 1;
> > -    val = strtoul(p, &e, 16);
> > -    if (e == p) {
> > -        goto inval;
> > -    }
> > -    if (*e == ':') {
> > -        dom = bus;
> > -        bus = val;
> > -        p = e + 1;
> > -        val = strtoul(p, &e, 16);
> > -        if (e == p) {
> > -            goto inval;
> > -        }
> > -    }
> > -    slot = val;
> > -
> > -    if (*e != '.') {
> > -        goto inval;
> > -    }
> > -    p = e + 1;
> > -    val = strtoul(p, &e, 10);
> > -    if (e == p) {
> > -        goto inval;
> > -    }
> > -    func = val;
> > -
> > -    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
> > -        goto inval;
> > -    }
> > -
> > -    if (*e) {
> > -        goto inval;
> > -    }
> > -
> > -    addr->domain = dom;
> > -    addr->bus = bus;
> > -    addr->slot = slot;
> > -    addr->function = func;
> > -
> > -    g_free(str);
> > -    return;
> > -
> > -inval:
> > -    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> > -    g_free(str);
> > -}
> > -
> > -PropertyInfo qdev_prop_pci_host_devaddr = {
> > -    .name = "pci-host-devaddr",
> > -    .get = get_pci_host_devaddr,
> > -    .set = set_pci_host_devaddr,
> > -};
> > -
> > -/* --- public helpers --- */
> > -
> > -static Property *qdev_prop_walk(Property *props, const char *name)
> > -{
> > -    if (!props)
> > -        return NULL;
> > -    while (props->name) {
> > -        if (strcmp(props->name, name) == 0)
> > -            return props;
> > -        props++;
> > -    }
> > -    return NULL;
> > -}
> > -
> > -static Property *qdev_prop_find(DeviceState *dev, const char *name)
> > -{
> > -    ObjectClass *class;
> > -    Property *prop;
> > -
> > -    /* device properties */
> > -    class = object_get_class(OBJECT(dev));
> > -    do {
> > -        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
> > -        if (prop) {
> > -            return prop;
> > -        }
> > -        class = object_class_get_parent(class);
> > -    } while (class != object_class_by_name(TYPE_DEVICE));
> > -
> > -    return NULL;
> > -}
> > -
> > -void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
> > -                                    Property *prop, const char *value)
> > -{
> > -    switch (ret) {
> > -    case -EEXIST:
> > -        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
> > -                  object_get_typename(OBJECT(dev)), prop->name, value);
> > -        break;
> > -    default:
> > -    case -EINVAL:
> > -        error_set(errp, QERR_PROPERTY_VALUE_BAD,
> > -                  object_get_typename(OBJECT(dev)), prop->name, value);
> > -        break;
> > -    case -ENOENT:
> > -        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
> > -                  object_get_typename(OBJECT(dev)), prop->name, value);
> > -        break;
> > -    case 0:
> > -        break;
> > -    }
> > -}
> > -
> > -int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> > -{
> > -    char *legacy_name;
> > -    Error *err = NULL;
> > -
> > -    legacy_name = g_strdup_printf("legacy-%s", name);
> > -    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
> > -        object_property_parse(OBJECT(dev), value, legacy_name, &err);
> > -    } else {
> > -        object_property_parse(OBJECT(dev), value, name, &err);
> > -    }
> > -    g_free(legacy_name);
> > -
> > -    if (err) {
> > -        qerror_report_err(err);
> > -        error_free(err);
> > -        return -1;
> > -    }
> > -    return 0;
> > -}
> > -
> > -void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
> > -{
> > -    Error *errp = NULL;
> > -    object_property_set_bool(OBJECT(dev), value, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
> > -{
> > -    Error *errp = NULL;
> > -    object_property_set_int(OBJECT(dev), value, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
> > -{
> > -    Error *errp = NULL;
> > -    object_property_set_int(OBJECT(dev), value, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
> > -{
> > -    Error *errp = NULL;
> > -    object_property_set_int(OBJECT(dev), value, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
> > -{
> > -    Error *errp = NULL;
> > -    object_property_set_int(OBJECT(dev), value, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
> > -{
> > -    Error *errp = NULL;
> > -    object_property_set_int(OBJECT(dev), value, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
> > -{
> > -    Error *errp = NULL;
> > -    object_property_set_str(OBJECT(dev), value, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
> > -{
> > -    Error *errp = NULL;
> > -    char str[2 * 6 + 5 + 1];
> > -    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
> > -             value[0], value[1], value[2], value[3], value[4], value[5]);
> > -
> > -    object_property_set_str(OBJECT(dev), str, name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
> > -{
> > -    Property *prop;
> > -    Error *errp = NULL;
> > -
> > -    prop = qdev_prop_find(dev, name);
> > -    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
> > -                            name, &errp);
> > -    assert_no_error(errp);
> > -}
> > -
> > -void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
> > -{
> > -    Property *prop;
> > -    void **ptr;
> > -
> > -    prop = qdev_prop_find(dev, name);
> > -    assert(prop && prop->info == &qdev_prop_ptr);
> > -    ptr = qdev_get_prop_ptr(dev, prop);
> > -    *ptr = value;
> > -}
> > -
> > -static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
> > -
> > -void qdev_prop_register_global(GlobalProperty *prop)
> > -{
> > -    QTAILQ_INSERT_TAIL(&global_props, prop, next);
> > -}
> > -
> > -void qdev_prop_register_global_list(GlobalProperty *props)
> > -{
> > -    int i;
> > -
> > -    for (i = 0; props[i].driver != NULL; i++) {
> > -        qdev_prop_register_global(props+i);
> > -    }
> > -}
> > -
> > -void qdev_prop_set_globals(DeviceState *dev)
> > -{
> > -    ObjectClass *class = object_get_class(OBJECT(dev));
> > -
> > -    do {
> > -        GlobalProperty *prop;
> > -        QTAILQ_FOREACH(prop, &global_props, next) {
> > -            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
> > -                continue;
> > -            }
> > -            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> > -                exit(1);
> > -            }
> > -        }
> > -        class = object_class_get_parent(class);
> > -    } while (class);
> > -}
> > -
> > diff --git a/qom/Makefile.objs b/qom/Makefile.objs
> > index 5ef060a..09ef871 100644
> > --- a/qom/Makefile.objs
> > +++ b/qom/Makefile.objs
> > @@ -1,4 +1,4 @@
> >  qom-obj-y = object.o container.o qom-qobject.o
> > -qom-obj-twice-y = cpu.o
> > +qom-obj-twice-y = cpu.o qdev-core.o qdev-properties.o
> >  common-obj-y = $(qom-obj-twice-y)
> >  user-obj-y = $(qom-obj-twice-y)
> > diff --git a/qom/qdev-core.c b/qom/qdev-core.c
> > new file mode 100644
> > index 0000000..fbb7cb5
> > --- /dev/null
> > +++ b/qom/qdev-core.c
> > @@ -0,0 +1,727 @@
> > +/*
> > + *  Dynamic device configuration and creation.
> > + *
> > + *  Copyright (c) 2009 CodeSourcery
> > + *
> > + * This library is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2 of the License, or (at your option) any later version.
> > + *
> > + * This library is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +/* The theory here is that it should be possible to create a machine without
> > +   knowledge of specific devices.  Historically board init routines have
> > +   passed a bunch of arguments to each device, requiring the board know
> > +   exactly which device it is dealing with.  This file provides an abstract
> > +   API for device configuration and initialization.  Devices will generally
> > +   inherit from a particular bus (e.g. PCI or I2C) rather than
> > +   this API directly.  */
> > +
> > +#include "hw/qdev.h"
> > +#include "sysemu.h"
> > +#include "error.h"
> > +#include "qapi/qapi-visit-core.h"
> > +
> > +int qdev_hotplug = 0;
> > +static bool qdev_hot_added = false;
> > +static bool qdev_hot_removed = false;
> > +
> > +/* vmstate handling:
> > + *
> > + * The real implementations are on qdev-system.c. Those are weak symbols
> > + * used by *-user.
> > + */
> > +void GCC_WEAK qdev_init_vmstate(DeviceState *dev)
> > +{
> > +}
> > +
> > +void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
> > +{
> > +}
> > +
> > +/* reset handler register/unregister:
> > + *
> > + * The real implementations are on qdev-system.c. Those are weak symbols
> > + * used by *-user.
> > + */
> > +void GCC_WEAK qbus_register_reset(BusState *bus)
> > +{
> > +}
> > +
> > +void GCC_WEAK qbus_unregister_reset(BusState *bus)
> > +{
> > +}
> > +
> > +const char *qdev_fw_name(DeviceState *dev)
> > +{
> > +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > +
> > +    if (dc->fw_name) {
> > +        return dc->fw_name;
> > +    }
> > +
> > +    return object_get_typename(OBJECT(dev));
> > +}
> > +
> > +static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> > +                                     Error **errp);
> > +
> > +static void bus_remove_child(BusState *bus, DeviceState *child)
> > +{
> > +    BusChild *kid;
> > +
> > +    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> > +        if (kid->child == child) {
> > +            char name[32];
> > +
> > +            snprintf(name, sizeof(name), "child[%d]", kid->index);
> > +            QTAILQ_REMOVE(&bus->children, kid, sibling);
> > +            object_property_del(OBJECT(bus), name, NULL);
> > +            g_free(kid);
> > +            return;
> > +        }
> > +    }
> > +}
> > +
> > +static void bus_add_child(BusState *bus, DeviceState *child)
> > +{
> > +    char name[32];
> > +    BusChild *kid = g_malloc0(sizeof(*kid));
> > +
> > +    if (qdev_hotplug) {
> > +        assert(bus->allow_hotplug);
> > +    }
> > +
> > +    kid->index = bus->max_index++;
> > +    kid->child = child;
> > +
> > +    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
> > +
> > +    snprintf(name, sizeof(name), "child[%d]", kid->index);
> > +    object_property_add_link(OBJECT(bus), name,
> > +                             object_get_typename(OBJECT(child)),
> > +                             (Object **)&kid->child,
> > +                             NULL);
> > +}
> > +
> > +void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
> > +{
> > +    dev->parent_bus = bus;
> > +    bus_add_child(bus, 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.
> > +   On failure, destroy the device and return negative value.
> > +   Return 0 on success.  */
> > +int qdev_init(DeviceState *dev)
> > +{
> > +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > +    int rc;
> > +
> > +    assert(dev->state == DEV_STATE_CREATED);
> > +
> > +    rc = dc->init(dev);
> > +    if (rc < 0) {
> > +        qdev_free(dev);
> > +        return rc;
> > +    }
> > +
> > +    if (!OBJECT(dev)->parent) {
> > +        static int unattached_count = 0;
> > +        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
> > +
> > +        object_property_add_child(container_get(qdev_get_machine(),
> > +                                                "/unattached"),
> > +                                  name, OBJECT(dev), NULL);
> > +        g_free(name);
> > +    }
> > +
> > +    qdev_init_vmstate(dev);
> > +    dev->state = DEV_STATE_INITIALIZED;
> > +    if (dev->hotplugged) {
> > +        device_reset(dev);
> > +    }
> > +    return 0;
> > +}
> > +
> > +void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
> > +                                 int required_for_version)
> > +{
> > +    assert(dev->state == DEV_STATE_CREATED);
> > +    dev->instance_id_alias = alias_id;
> > +    dev->alias_required_for_version = required_for_version;
> > +}
> > +
> > +void qdev_unplug(DeviceState *dev, Error **errp)
> > +{
> > +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > +
> > +    if (!dev->parent_bus->allow_hotplug) {
> > +        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
> > +        return;
> > +    }
> > +    assert(dc->unplug != NULL);
> > +
> > +    qdev_hot_removed = true;
> > +
> > +    if (dc->unplug(dev) < 0) {
> > +        error_set(errp, QERR_UNDEFINED_ERROR);
> > +        return;
> > +    }
> > +}
> > +
> > +static int qdev_reset_one(DeviceState *dev, void *opaque)
> > +{
> > +    device_reset(dev);
> > +
> > +    return 0;
> > +}
> > +
> > +static int qbus_reset_one(BusState *bus, void *opaque)
> > +{
> > +    BusClass *bc = BUS_GET_CLASS(bus);
> > +    if (bc->reset) {
> > +        return bc->reset(bus);
> > +    }
> > +    return 0;
> > +}
> > +
> > +void qdev_reset_all(DeviceState *dev)
> > +{
> > +    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
> > +}
> > +
> > +void qbus_reset_all_fn(void *opaque)
> > +{
> > +    BusState *bus = opaque;
> > +    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
> > +}
> > +
> > +/* can be used as ->unplug() callback for the simple cases */
> > +int qdev_simple_unplug_cb(DeviceState *dev)
> > +{
> > +    /* just zap it */
> > +    qdev_free(dev);
> > +    return 0;
> > +}
> > +
> > +
> > +/* Like qdev_init(), but terminate program via error_report() instead of
> > +   returning an error value.  This is okay during machine creation.
> > +   Don't use for hotplug, because there callers need to recover from
> > +   failure.  Exception: if you know the device's init() callback can't
> > +   fail, then qdev_init_nofail() can't fail either, and is therefore
> > +   usable even then.  But relying on the device implementation that
> > +   way is somewhat unclean, and best avoided.  */
> > +void qdev_init_nofail(DeviceState *dev)
> > +{
> > +    const char *typename = object_get_typename(OBJECT(dev));
> > +
> > +    if (qdev_init(dev) < 0) {
> > +        error_report("Initialization of device %s failed", typename);
> > +        exit(1);
> > +    }
> > +}
> > +
> > +/* Unlink device from bus and free the structure.  */
> > +void qdev_free(DeviceState *dev)
> > +{
> > +    object_delete(OBJECT(dev));
> > +}
> > +
> > +void qdev_machine_creation_done(void)
> > +{
> > +    /*
> > +     * ok, initial machine setup is done, starting from now we can
> > +     * only create hotpluggable devices
> > +     */
> > +    qdev_hotplug = 1;
> > +}
> > +
> > +bool qdev_machine_modified(void)
> > +{
> > +    return qdev_hot_added || qdev_hot_removed;
> > +}
> > +
> > +BusState *qdev_get_parent_bus(DeviceState *dev)
> > +{
> > +    return dev->parent_bus;
> > +}
> > +
> > +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)
> > +{
> > +    BusChild *kid;
> > +    int err;
> > +
> > +    if (busfn) {
> > +        err = busfn(bus, opaque);
> > +        if (err) {
> > +            return err;
> > +        }
> > +    }
> > +
> > +    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> > +        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
> > +        if (err < 0) {
> > +            return err;
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
> > +                       qbus_walkerfn *busfn, void *opaque)
> > +{
> > +    BusState *bus;
> > +    int err;
> > +
> > +    if (devfn) {
> > +        err = devfn(dev, opaque);
> > +        if (err) {
> > +            return err;
> > +        }
> > +    }
> > +
> > +    QLIST_FOREACH(bus, &dev->child_bus, sibling) {
> > +        err = qbus_walk_children(bus, devfn, busfn, opaque);
> > +        if (err < 0) {
> > +            return err;
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +DeviceState *qdev_find_recursive(BusState *bus, const char *id)
> > +{
> > +    BusChild *kid;
> > +    DeviceState *ret;
> > +    BusState *child;
> > +
> > +    QTAILQ_FOREACH(kid, &bus->children, sibling) {
> > +        DeviceState *dev = kid->child;
> > +
> > +        if (dev->id && strcmp(dev->id, id) == 0) {
> > +            return dev;
> > +        }
> > +
> > +        QLIST_FOREACH(child, &dev->child_bus, sibling) {
> > +            ret = qdev_find_recursive(child, id);
> > +            if (ret) {
> > +                return ret;
> > +            }
> > +        }
> > +    }
> > +    return NULL;
> > +}
> > +
> > +static void qbus_realize(BusState *bus)
> > +{
> > +    const char *typename = object_get_typename(OBJECT(bus));
> > +    char *buf;
> > +    int i,len;
> > +
> > +    if (bus->name) {
> > +        /* use supplied name */
> > +    } else if (bus->parent && bus->parent->id) {
> > +        /* parent device has id -> use it for bus name */
> > +        len = strlen(bus->parent->id) + 16;
> > +        buf = g_malloc(len);
> > +        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
> > +        bus->name = buf;
> > +    } else {
> > +        /* no id -> use lowercase bus type for bus name */
> > +        len = strlen(typename) + 16;
> > +        buf = g_malloc(len);
> > +        len = snprintf(buf, len, "%s.%d", typename,
> > +                       bus->parent ? bus->parent->num_child_bus : 0);
> > +        for (i = 0; i < len; i++)
> > +            buf[i] = qemu_tolower(buf[i]);
> > +        bus->name = buf;
> > +    }
> > +
> > +    if (bus->parent) {
> > +        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
> > +        bus->parent->num_child_bus++;
> > +        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> > +    } else {
> > +        qbus_register_reset(bus);
> > +    }
> > +}
> > +
> > +void qbus_create_inplace(BusState *bus, const char *typename,
> > +                         DeviceState *parent, const char *name)
> > +{
> > +    object_initialize(bus, typename);
> > +
> > +    bus->parent = parent;
> > +    bus->name = name ? g_strdup(name) : NULL;
> > +    qbus_realize(bus);
> > +}
> > +
> > +BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
> > +{
> > +    BusState *bus;
> > +
> > +    bus = BUS(object_new(typename));
> > +    bus->qom_allocated = true;
> > +
> > +    bus->parent = parent;
> > +    bus->name = name ? g_strdup(name) : NULL;
> > +    qbus_realize(bus);
> > +
> > +    return bus;
> > +}
> > +
> > +void qbus_free(BusState *bus)
> > +{
> > +    if (bus->qom_allocated) {
> > +        object_delete(OBJECT(bus));
> > +    } else {
> > +        object_finalize(OBJECT(bus));
> > +        if (bus->glib_allocated) {
> > +            g_free(bus);
> > +        }
> > +    }
> > +}
> > +
> > +static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
> > +{
> > +    BusClass *bc = BUS_GET_CLASS(bus);
> > +
> > +    if (bc->get_fw_dev_path) {
> > +        return bc->get_fw_dev_path(dev);
> > +    }
> > +
> > +    return NULL;
> > +}
> > +
> > +static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
> > +{
> > +    int l = 0;
> > +
> > +    if (dev && dev->parent_bus) {
> > +        char *d;
> > +        l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
> > +        d = bus_get_fw_dev_path(dev->parent_bus, dev);
> > +        if (d) {
> > +            l += snprintf(p + l, size - l, "%s", d);
> > +            g_free(d);
> > +        } else {
> > +            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
> > +        }
> > +    }
> > +    l += snprintf(p + l , size - l, "/");
> > +
> > +    return l;
> > +}
> > +
> > +char* qdev_get_fw_dev_path(DeviceState *dev)
> > +{
> > +    char path[128];
> > +    int l;
> > +
> > +    l = qdev_get_fw_dev_path_helper(dev, path, 128);
> > +
> > +    path[l-1] = '\0';
> > +
> > +    return g_strdup(path);
> > +}
> > +
> > +char *qdev_get_dev_path(DeviceState *dev)
> > +{
> > +    BusClass *bc;
> > +
> > +    if (!dev || !dev->parent_bus) {
> > +        return NULL;
> > +    }
> > +
> > +    bc = BUS_GET_CLASS(dev->parent_bus);
> > +    if (bc->get_dev_path) {
> > +        return bc->get_dev_path(dev);
> > +    }
> > +
> > +    return NULL;
> > +}
> > +
> > +/**
> > + * Legacy property handling
> > + */
> > +
> > +static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
> > +                                     const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +
> > +    char buffer[1024];
> > +    char *ptr = buffer;
> > +
> > +    prop->info->print(dev, prop, buffer, sizeof(buffer));
> > +    visit_type_str(v, &ptr, name, errp);
> > +}
> > +
> > +static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
> > +                                     const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    Error *local_err = NULL;
> > +    char *ptr = NULL;
> > +    int ret;
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_str(v, &ptr, name, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        return;
> > +    }
> > +
> > +    ret = prop->info->parse(dev, prop, ptr);
> > +    error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
> > +    g_free(ptr);
> > +}
> > +
> > +/**
> > + * @qdev_add_legacy_property - adds a legacy property
> > + *
> > + * Do not use this is new code!  Properties added through this interface will
> > + * be given names and types in the "legacy" namespace.
> > + *
> > + * Legacy properties are string versions of other OOM properties.  The format
> > + * of the string depends on the property type.
> > + */
> > +void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> > +                              Error **errp)
> > +{
> > +    gchar *name, *type;
> > +
> > +    /* Register pointer properties as legacy properties */
> > +    if (!prop->info->print && !prop->info->parse &&
> > +        (prop->info->set || prop->info->get)) {
> > +        return;
> > +    }
> > +
> > +    name = g_strdup_printf("legacy-%s", prop->name);
> > +    type = g_strdup_printf("legacy<%s>",
> > +                           prop->info->legacy_name ?: prop->info->name);
> > +
> > +    object_property_add(OBJECT(dev), name, type,
> > +                        prop->info->print ? qdev_get_legacy_property : prop->info->get,
> > +                        prop->info->parse ? qdev_set_legacy_property : prop->info->set,
> > +                        NULL,
> > +                        prop, errp);
> > +
> > +    g_free(type);
> > +    g_free(name);
> > +}
> > +
> > +/**
> > + * @qdev_property_add_static - add a @Property to a device.
> > + *
> > + * Static properties access data in a struct.  The actual type of the
> > + * property and the field depends on the property type.
> > + */
> > +void qdev_property_add_static(DeviceState *dev, Property *prop,
> > +                              Error **errp)
> > +{
> > +    Error *local_err = NULL;
> > +    Object *obj = OBJECT(dev);
> > +
> > +    /*
> > +     * TODO qdev_prop_ptr does not have getters or setters.  It must
> > +     * go now that it can be replaced with links.  The test should be
> > +     * removed along with it: all static properties are read/write.
> > +     */
> > +    if (!prop->info->get && !prop->info->set) {
> > +        return;
> > +    }
> > +
> > +    object_property_add(obj, prop->name, prop->info->name,
> > +                        prop->info->get, prop->info->set,
> > +                        prop->info->release,
> > +                        prop, &local_err);
> > +
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        return;
> > +    }
> > +    if (prop->qtype == QTYPE_NONE) {
> > +        return;
> > +    }
> > +
> > +    if (prop->qtype == QTYPE_QBOOL) {
> > +        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
> > +    } else if (prop->info->enum_table) {
> > +        object_property_set_str(obj, prop->info->enum_table[prop->defval],
> > +                                prop->name, &local_err);
> > +    } else if (prop->qtype == QTYPE_QINT) {
> > +        object_property_set_int(obj, prop->defval, prop->name, &local_err);
> > +    }
> > +    assert_no_error(local_err);
> > +}
> > +
> > +static void device_initfn(Object *obj)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    ObjectClass *class;
> > +    Property *prop;
> > +
> > +    if (qdev_hotplug) {
> > +        dev->hotplugged = 1;
> > +        qdev_hot_added = true;
> > +    }
> > +
> > +    dev->instance_id_alias = -1;
> > +    dev->state = DEV_STATE_CREATED;
> > +
> > +    class = object_get_class(OBJECT(dev));
> > +    do {
> > +        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
> > +            qdev_property_add_legacy(dev, prop, NULL);
> > +            qdev_property_add_static(dev, prop, NULL);
> > +        }
> > +        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);
> > +}
> > +
> > +/* Unlink device from bus and free the structure.  */
> > +static void device_finalize(Object *obj)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    BusState *bus;
> > +    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > +
> > +    if (dev->state == DEV_STATE_INITIALIZED) {
> > +        while (dev->num_child_bus) {
> > +            bus = QLIST_FIRST(&dev->child_bus);
> > +            qbus_free(bus);
> > +        }
> > +        qdev_finalize_vmstate(dev);
> > +        if (dc->exit) {
> > +            dc->exit(dev);
> > +        }
> > +        if (dev->opts) {
> > +            qemu_opts_del(dev->opts);
> > +        }
> > +    }
> > +    if (dev->parent_bus) {
> > +        bus_remove_child(dev->parent_bus, dev);
> > +    }
> > +}
> > +
> > +static void device_class_base_init(ObjectClass *class, void *data)
> > +{
> > +    DeviceClass *klass = DEVICE_CLASS(class);
> > +
> > +    /* We explicitly look up properties in the superclasses,
> > +     * so do not propagate them to the subclasses.
> > +     */
> > +    klass->props = NULL;
> > +}
> > +
> > +void device_reset(DeviceState *dev)
> > +{
> > +    DeviceClass *klass = DEVICE_GET_CLASS(dev);
> > +
> > +    if (klass->reset) {
> > +        klass->reset(dev);
> > +    }
> > +}
> > +
> > +Object *qdev_get_machine(void)
> > +{
> > +    static Object *dev;
> > +
> > +    if (dev == NULL) {
> > +        dev = container_get(object_get_root(), "/machine");
> > +    }
> > +
> > +    return dev;
> > +}
> > +
> > +static TypeInfo device_type_info = {
> > +    .name = TYPE_DEVICE,
> > +    .parent = TYPE_OBJECT,
> > +    .instance_size = sizeof(DeviceState),
> > +    .instance_init = device_initfn,
> > +    .instance_finalize = device_finalize,
> > +    .class_base_init = device_class_base_init,
> > +    .abstract = true,
> > +    .class_size = sizeof(DeviceClass),
> > +};
> > +
> > +static void qbus_initfn(Object *obj)
> > +{
> > +    BusState *bus = BUS(obj);
> > +
> > +    QTAILQ_INIT(&bus->children);
> > +}
> > +
> > +static void qbus_finalize(Object *obj)
> > +{
> > +    BusState *bus = BUS(obj);
> > +    BusChild *kid;
> > +
> > +    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
> > +        DeviceState *dev = kid->child;
> > +        qdev_free(dev);
> > +    }
> > +    if (bus->parent) {
> > +        QLIST_REMOVE(bus, sibling);
> > +        bus->parent->num_child_bus--;
> > +    } else {
> > +        qbus_unregister_reset(bus);
> > +    }
> > +    g_free((char *)bus->name);
> > +}
> > +
> > +static const TypeInfo bus_info = {
> > +    .name = TYPE_BUS,
> > +    .parent = TYPE_OBJECT,
> > +    .instance_size = sizeof(BusState),
> > +    .abstract = true,
> > +    .class_size = sizeof(BusClass),
> > +    .instance_init = qbus_initfn,
> > +    .instance_finalize = qbus_finalize,
> > +};
> > +
> > +static void qdev_register_types(void)
> > +{
> > +    type_register_static(&bus_info);
> > +    type_register_static(&device_type_info);
> > +}
> > +
> > +type_init(qdev_register_types)
> > diff --git a/qom/qdev-properties.c b/qom/qdev-properties.c
> > new file mode 100644
> > index 0000000..2e82cb9
> > --- /dev/null
> > +++ b/qom/qdev-properties.c
> > @@ -0,0 +1,963 @@
> > +#include "net.h"
> > +#include "hw/qdev.h"
> > +#include "qerror.h"
> > +#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)
> > +{
> > +    void *ptr = dev;
> > +    ptr += prop->offset;
> > +    return ptr;
> > +}
> > +
> > +static void get_enum(Object *obj, Visitor *v, void *opaque,
> > +                     const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    int *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    visit_type_enum(v, ptr, prop->info->enum_table,
> > +                    prop->info->name, prop->name, errp);
> > +}
> > +
> > +static void set_enum(Object *obj, Visitor *v, void *opaque,
> > +                     const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    int *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_enum(v, ptr, prop->info->enum_table,
> > +                    prop->info->name, prop->name, errp);
> > +}
> > +
> > +/* Bit */
> > +
> > +static uint32_t qdev_get_prop_mask(Property *prop)
> > +{
> > +    assert(prop->info == &qdev_prop_bit);
> > +    return 0x1 << prop->bitnr;
> > +}
> > +
> > +static void bit_prop_set(DeviceState *dev, Property *props, bool val)
> > +{
> > +    uint32_t *p = qdev_get_prop_ptr(dev, props);
> > +    uint32_t mask = qdev_get_prop_mask(props);
> > +    if (val)
> > +        *p |= mask;
> > +    else
> > +        *p &= ~mask;
> > +}
> > +
> > +static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
> > +{
> > +    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> > +    return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
> > +}
> > +
> > +static void get_bit(Object *obj, Visitor *v, void *opaque,
> > +                    const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint32_t *p = qdev_get_prop_ptr(dev, prop);
> > +    bool value = (*p & qdev_get_prop_mask(prop)) != 0;
> > +
> > +    visit_type_bool(v, &value, name, errp);
> > +}
> > +
> > +static void set_bit(Object *obj, Visitor *v, void *opaque,
> > +                    const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    Error *local_err = NULL;
> > +    bool value;
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_bool(v, &value, name, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        return;
> > +    }
> > +    bit_prop_set(dev, prop, value);
> > +}
> > +
> > +PropertyInfo qdev_prop_bit = {
> > +    .name  = "boolean",
> > +    .legacy_name  = "on/off",
> > +    .print = print_bit,
> > +    .get   = get_bit,
> > +    .set   = set_bit,
> > +};
> > +
> > +/* --- 8bit integer --- */
> > +
> > +static void get_uint8(Object *obj, Visitor *v, void *opaque,
> > +                      const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    visit_type_uint8(v, ptr, name, errp);
> > +}
> > +
> > +static void set_uint8(Object *obj, Visitor *v, void *opaque,
> > +                      const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_uint8(v, ptr, name, errp);
> > +}
> > +
> > +PropertyInfo qdev_prop_uint8 = {
> > +    .name  = "uint8",
> > +    .get   = get_uint8,
> > +    .set   = set_uint8,
> > +};
> > +
> > +/* --- 8bit hex value --- */
> > +
> > +static int parse_hex8(DeviceState *dev, Property *prop, const char *str)
> > +{
> > +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +    char *end;
> > +
> > +    if (str[0] != '0' || str[1] != 'x') {
> > +        return -EINVAL;
> > +    }
> > +
> > +    *ptr = strtoul(str, &end, 16);
> > +    if ((*end != '\0') || (end == str)) {
> > +        return -EINVAL;
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
> > +{
> > +    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +    return snprintf(dest, len, "0x%" PRIx8, *ptr);
> > +}
> > +
> > +PropertyInfo qdev_prop_hex8 = {
> > +    .name  = "uint8",
> > +    .legacy_name  = "hex8",
> > +    .parse = parse_hex8,
> > +    .print = print_hex8,
> > +    .get   = get_uint8,
> > +    .set   = set_uint8,
> > +};
> > +
> > +/* --- 16bit integer --- */
> > +
> > +static void get_uint16(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    visit_type_uint16(v, ptr, name, errp);
> > +}
> > +
> > +static void set_uint16(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_uint16(v, ptr, name, errp);
> > +}
> > +
> > +PropertyInfo qdev_prop_uint16 = {
> > +    .name  = "uint16",
> > +    .get   = get_uint16,
> > +    .set   = set_uint16,
> > +};
> > +
> > +/* --- 32bit integer --- */
> > +
> > +static void get_uint32(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    visit_type_uint32(v, ptr, name, errp);
> > +}
> > +
> > +static void set_uint32(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_uint32(v, ptr, name, errp);
> > +}
> > +
> > +static void get_int32(Object *obj, Visitor *v, void *opaque,
> > +                      const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    visit_type_int32(v, ptr, name, errp);
> > +}
> > +
> > +static void set_int32(Object *obj, Visitor *v, void *opaque,
> > +                      const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_int32(v, ptr, name, errp);
> > +}
> > +
> > +PropertyInfo qdev_prop_uint32 = {
> > +    .name  = "uint32",
> > +    .get   = get_uint32,
> > +    .set   = set_uint32,
> > +};
> > +
> > +PropertyInfo qdev_prop_int32 = {
> > +    .name  = "int32",
> > +    .get   = get_int32,
> > +    .set   = set_int32,
> > +};
> > +
> > +/* --- 32bit hex value --- */
> > +
> > +static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
> > +{
> > +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +    char *end;
> > +
> > +    if (str[0] != '0' || str[1] != 'x') {
> > +        return -EINVAL;
> > +    }
> > +
> > +    *ptr = strtoul(str, &end, 16);
> > +    if ((*end != '\0') || (end == str)) {
> > +        return -EINVAL;
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
> > +{
> > +    uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +    return snprintf(dest, len, "0x%" PRIx32, *ptr);
> > +}
> > +
> > +PropertyInfo qdev_prop_hex32 = {
> > +    .name  = "uint32",
> > +    .legacy_name  = "hex32",
> > +    .parse = parse_hex32,
> > +    .print = print_hex32,
> > +    .get   = get_uint32,
> > +    .set   = set_uint32,
> > +};
> > +
> > +/* --- 64bit integer --- */
> > +
> > +static void get_uint64(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    visit_type_uint64(v, ptr, name, errp);
> > +}
> > +
> > +static void set_uint64(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_uint64(v, ptr, name, errp);
> > +}
> > +
> > +PropertyInfo qdev_prop_uint64 = {
> > +    .name  = "uint64",
> > +    .get   = get_uint64,
> > +    .set   = set_uint64,
> > +};
> > +
> > +/* --- 64bit hex value --- */
> > +
> > +static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
> > +{
> > +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +    char *end;
> > +
> > +    if (str[0] != '0' || str[1] != 'x') {
> > +        return -EINVAL;
> > +    }
> > +
> > +    *ptr = strtoull(str, &end, 16);
> > +    if ((*end != '\0') || (end == str)) {
> > +        return -EINVAL;
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
> > +{
> > +    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +    return snprintf(dest, len, "0x%" PRIx64, *ptr);
> > +}
> > +
> > +PropertyInfo qdev_prop_hex64 = {
> > +    .name  = "uint64",
> > +    .legacy_name  = "hex64",
> > +    .parse = parse_hex64,
> > +    .print = print_hex64,
> > +    .get   = get_uint64,
> > +    .set   = set_uint64,
> > +};
> > +
> > +/* --- string --- */
> > +
> > +static void release_string(Object *obj, const char *name, void *opaque)
> > +{
> > +    Property *prop = opaque;
> > +    g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
> > +}
> > +
> > +static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
> > +{
> > +    char **ptr = qdev_get_prop_ptr(dev, prop);
> > +    if (!*ptr)
> > +        return snprintf(dest, len, "<null>");
> > +    return snprintf(dest, len, "\"%s\"", *ptr);
> > +}
> > +
> > +static void get_string(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    char **ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (!*ptr) {
> > +        char *str = (char *)"";
> > +        visit_type_str(v, &str, name, errp);
> > +    } else {
> > +        visit_type_str(v, ptr, name, errp);
> > +    }
> > +}
> > +
> > +static void set_string(Object *obj, Visitor *v, void *opaque,
> > +                       const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    char **ptr = qdev_get_prop_ptr(dev, prop);
> > +    Error *local_err = NULL;
> > +    char *str;
> > +
> > +    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 (*ptr) {
> > +        g_free(*ptr);
> > +    }
> > +    *ptr = str;
> > +}
> > +
> > +PropertyInfo qdev_prop_string = {
> > +    .name  = "string",
> > +    .print = print_string,
> > +    .release = release_string,
> > +    .get   = get_string,
> > +    .set   = set_string,
> > +};
> > +
> > +/* --- pointer --- */
> > +
> > +/* Not a proper property, just for dirty hacks.  TODO Remove it!  */
> > +PropertyInfo qdev_prop_ptr = {
> > +    .name  = "ptr",
> > +};
> > +
> > +/* --- mac address --- */
> > +
> > +/*
> > + * accepted syntax versions:
> > + *   01:02:03:04:05:06
> > + *   01-02-03-04-05-06
> > + */
> > +static void get_mac(Object *obj, Visitor *v, void *opaque,
> > +                    const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> > +    char buffer[2 * 6 + 5 + 1];
> > +    char *p = buffer;
> > +
> > +    snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
> > +             mac->a[0], mac->a[1], mac->a[2],
> > +             mac->a[3], mac->a[4], mac->a[5]);
> > +
> > +    visit_type_str(v, &p, name, errp);
> > +}
> > +
> > +static void set_mac(Object *obj, Visitor *v, void *opaque,
> > +                    const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> > +    Error *local_err = NULL;
> > +    int i, pos;
> > +    char *str, *p;
> > +
> > +    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;
> > +    }
> > +
> > +    for (i = 0, pos = 0; i < 6; i++, pos += 3) {
> > +        if (!qemu_isxdigit(str[pos]))
> > +            goto inval;
> > +        if (!qemu_isxdigit(str[pos+1]))
> > +            goto inval;
> > +        if (i == 5) {
> > +            if (str[pos+2] != '\0')
> > +                goto inval;
> > +        } else {
> > +            if (str[pos+2] != ':' && str[pos+2] != '-')
> > +                goto inval;
> > +        }
> > +        mac->a[i] = strtol(str+pos, &p, 16);
> > +    }
> > +    g_free(str);
> > +    return;
> > +
> > +inval:
> > +    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> > +    g_free(str);
> > +}
> > +
> > +PropertyInfo qdev_prop_macaddr = {
> > +    .name  = "macaddr",
> > +    .get   = get_mac,
> > +    .set   = set_mac,
> > +};
> > +
> > +/* --- lost tick policy --- */
> > +
> > +static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
> > +    [LOST_TICK_DISCARD] = "discard",
> > +    [LOST_TICK_DELAY] = "delay",
> > +    [LOST_TICK_MERGE] = "merge",
> > +    [LOST_TICK_SLEW] = "slew",
> > +    [LOST_TICK_MAX] = NULL,
> > +};
> > +
> > +QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
> > +
> > +PropertyInfo qdev_prop_losttickpolicy = {
> > +    .name  = "LostTickPolicy",
> > +    .enum_table  = lost_tick_policy_table,
> > +    .get   = get_enum,
> > +    .set   = set_enum,
> > +};
> > +
> > +/* --- BIOS CHS translation */
> > +
> > +static const char *bios_chs_trans_table[] = {
> > +    [BIOS_ATA_TRANSLATION_AUTO] = "auto",
> > +    [BIOS_ATA_TRANSLATION_NONE] = "none",
> > +    [BIOS_ATA_TRANSLATION_LBA]  = "lba",
> > +};
> > +
> > +PropertyInfo qdev_prop_bios_chs_trans = {
> > +    .name = "bios-chs-trans",
> > +    .enum_table = bios_chs_trans_table,
> > +    .get = get_enum,
> > +    .set = set_enum,
> > +};
> > +
> > +/* --- pci address --- */
> > +
> > +/*
> > + * bus-local address, i.e. "$slot" or "$slot.$fn"
> > + */
> > +static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
> > +                          const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> > +    unsigned int slot, fn, n;
> > +    Error *local_err = NULL;
> > +    char *str;
> > +
> > +    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_free(local_err);
> > +        local_err = NULL;
> > +        visit_type_int32(v, &value, name, &local_err);
> > +        if (local_err) {
> > +            error_propagate(errp, local_err);
> > +        } else if (value < -1 || value > 255) {
> > +            error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : "null",
> > +                      "pci_devfn");
> > +        } else {
> > +            *ptr = value;
> > +        }
> > +        return;
> > +    }
> > +
> > +    if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
> > +        fn = 0;
> > +        if (sscanf(str, "%x%n", &slot, &n) != 1) {
> > +            goto invalid;
> > +        }
> > +    }
> > +    if (str[n] != '\0' || fn > 7 || slot > 31) {
> > +        goto invalid;
> > +    }
> > +    *ptr = slot << 3 | fn;
> > +    g_free(str);
> > +    return;
> > +
> > +invalid:
> > +    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> > +    g_free(str);
> > +}
> > +
> > +static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t len)
> > +{
> > +    int32_t *ptr = qdev_get_prop_ptr(dev, prop);
> > +
> > +    if (*ptr == -1) {
> > +        return snprintf(dest, len, "<unset>");
> > +    } else {
> > +        return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
> > +    }
> > +}
> > +
> > +PropertyInfo qdev_prop_pci_devfn = {
> > +    .name  = "int32",
> > +    .legacy_name  = "pci-devfn",
> > +    .print = print_pci_devfn,
> > +    .get   = get_int32,
> > +    .set   = set_pci_devfn,
> > +};
> > +
> > +/* --- blocksize --- */
> > +
> > +static void set_blocksize(Object *obj, Visitor *v, void *opaque,
> > +                          const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
> > +    Error *local_err = NULL;
> > +    const int64_t min = 512;
> > +    const int64_t max = 32768;
> > +
> > +    if (dev->state != DEV_STATE_CREATED) {
> > +        error_set(errp, QERR_PERMISSION_DENIED);
> > +        return;
> > +    }
> > +
> > +    visit_type_uint16(v, &value, name, &local_err);
> > +    if (local_err) {
> > +        error_propagate(errp, local_err);
> > +        return;
> > +    }
> > +    if (value < min || value > max) {
> > +        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> > +                  dev->id?:"", name, (int64_t)value, min, max);
> > +        return;
> > +    }
> > +
> > +    /* We rely on power-of-2 blocksizes for bitmasks */
> > +    if ((value & (value - 1)) != 0) {
> > +        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
> > +                  dev->id?:"", name, (int64_t)value);
> > +        return;
> > +    }
> > +
> > +    *ptr = value;
> > +}
> > +
> > +PropertyInfo qdev_prop_blocksize = {
> > +    .name  = "blocksize",
> > +    .get   = get_uint16,
> > +    .set   = set_blocksize,
> > +};
> > +
> > +/* --- pci host address --- */
> > +
> > +static void get_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> > +                                 const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> > +    char buffer[] = "xxxx:xx:xx.x";
> > +    char *p = buffer;
> > +    int rc = 0;
> > +
> > +    rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%d",
> > +                  addr->domain, addr->bus, addr->slot, addr->function);
> > +    assert(rc == sizeof(buffer) - 1);
> > +
> > +    visit_type_str(v, &p, name, errp);
> > +}
> > +
> > +/*
> > + * Parse [<domain>:]<bus>:<slot>.<func>
> > + *   if <domain> is not supplied, it's assumed to be 0.
> > + */
> > +static void set_pci_host_devaddr(Object *obj, Visitor *v, void *opaque,
> > +                                 const char *name, Error **errp)
> > +{
> > +    DeviceState *dev = DEVICE(obj);
> > +    Property *prop = opaque;
> > +    PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> > +    Error *local_err = NULL;
> > +    char *str, *p;
> > +    char *e;
> > +    unsigned long val;
> > +    unsigned long dom = 0, bus = 0;
> > +    unsigned int slot = 0, func = 0;
> > +
> > +    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;
> > +    }
> > +
> > +    p = str;
> > +    val = strtoul(p, &e, 16);
> > +    if (e == p || *e != ':') {
> > +        goto inval;
> > +    }
> > +    bus = val;
> > +
> > +    p = e + 1;
> > +    val = strtoul(p, &e, 16);
> > +    if (e == p) {
> > +        goto inval;
> > +    }
> > +    if (*e == ':') {
> > +        dom = bus;
> > +        bus = val;
> > +        p = e + 1;
> > +        val = strtoul(p, &e, 16);
> > +        if (e == p) {
> > +            goto inval;
> > +        }
> > +    }
> > +    slot = val;
> > +
> > +    if (*e != '.') {
> > +        goto inval;
> > +    }
> > +    p = e + 1;
> > +    val = strtoul(p, &e, 10);
> > +    if (e == p) {
> > +        goto inval;
> > +    }
> > +    func = val;
> > +
> > +    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
> > +        goto inval;
> > +    }
> > +
> > +    if (*e) {
> > +        goto inval;
> > +    }
> > +
> > +    addr->domain = dom;
> > +    addr->bus = bus;
> > +    addr->slot = slot;
> > +    addr->function = func;
> > +
> > +    g_free(str);
> > +    return;
> > +
> > +inval:
> > +    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> > +    g_free(str);
> > +}
> > +
> > +PropertyInfo qdev_prop_pci_host_devaddr = {
> > +    .name = "pci-host-devaddr",
> > +    .get = get_pci_host_devaddr,
> > +    .set = set_pci_host_devaddr,
> > +};
> > +
> > +/* --- public helpers --- */
> > +
> > +static Property *qdev_prop_walk(Property *props, const char *name)
> > +{
> > +    if (!props)
> > +        return NULL;
> > +    while (props->name) {
> > +        if (strcmp(props->name, name) == 0)
> > +            return props;
> > +        props++;
> > +    }
> > +    return NULL;
> > +}
> > +
> > +static Property *qdev_prop_find(DeviceState *dev, const char *name)
> > +{
> > +    ObjectClass *class;
> > +    Property *prop;
> > +
> > +    /* device properties */
> > +    class = object_get_class(OBJECT(dev));
> > +    do {
> > +        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
> > +        if (prop) {
> > +            return prop;
> > +        }
> > +        class = object_class_get_parent(class);
> > +    } while (class != object_class_by_name(TYPE_DEVICE));
> > +
> > +    return NULL;
> > +}
> > +
> > +void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
> > +                                    Property *prop, const char *value)
> > +{
> > +    switch (ret) {
> > +    case -EEXIST:
> > +        error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
> > +                  object_get_typename(OBJECT(dev)), prop->name, value);
> > +        break;
> > +    default:
> > +    case -EINVAL:
> > +        error_set(errp, QERR_PROPERTY_VALUE_BAD,
> > +                  object_get_typename(OBJECT(dev)), prop->name, value);
> > +        break;
> > +    case -ENOENT:
> > +        error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
> > +                  object_get_typename(OBJECT(dev)), prop->name, value);
> > +        break;
> > +    case 0:
> > +        break;
> > +    }
> > +}
> > +
> > +int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> > +{
> > +    char *legacy_name;
> > +    Error *err = NULL;
> > +
> > +    legacy_name = g_strdup_printf("legacy-%s", name);
> > +    if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
> > +        object_property_parse(OBJECT(dev), value, legacy_name, &err);
> > +    } else {
> > +        object_property_parse(OBJECT(dev), value, name, &err);
> > +    }
> > +    g_free(legacy_name);
> > +
> > +    if (err) {
> > +        qerror_report_err(err);
> > +        error_free(err);
> > +        return -1;
> > +    }
> > +    return 0;
> > +}
> > +
> > +void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
> > +{
> > +    Error *errp = NULL;
> > +    object_property_set_bool(OBJECT(dev), value, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
> > +{
> > +    Error *errp = NULL;
> > +    object_property_set_int(OBJECT(dev), value, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
> > +{
> > +    Error *errp = NULL;
> > +    object_property_set_int(OBJECT(dev), value, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
> > +{
> > +    Error *errp = NULL;
> > +    object_property_set_int(OBJECT(dev), value, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
> > +{
> > +    Error *errp = NULL;
> > +    object_property_set_int(OBJECT(dev), value, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
> > +{
> > +    Error *errp = NULL;
> > +    object_property_set_int(OBJECT(dev), value, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
> > +{
> > +    Error *errp = NULL;
> > +    object_property_set_str(OBJECT(dev), value, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
> > +{
> > +    Error *errp = NULL;
> > +    char str[2 * 6 + 5 + 1];
> > +    snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
> > +             value[0], value[1], value[2], value[3], value[4], value[5]);
> > +
> > +    object_property_set_str(OBJECT(dev), str, name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
> > +{
> > +    Property *prop;
> > +    Error *errp = NULL;
> > +
> > +    prop = qdev_prop_find(dev, name);
> > +    object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
> > +                            name, &errp);
> > +    assert_no_error(errp);
> > +}
> > +
> > +void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
> > +{
> > +    Property *prop;
> > +    void **ptr;
> > +
> > +    prop = qdev_prop_find(dev, name);
> > +    assert(prop && prop->info == &qdev_prop_ptr);
> > +    ptr = qdev_get_prop_ptr(dev, prop);
> > +    *ptr = value;
> > +}
> > +
> > +static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
> > +
> > +void qdev_prop_register_global(GlobalProperty *prop)
> > +{
> > +    QTAILQ_INSERT_TAIL(&global_props, prop, next);
> > +}
> > +
> > +void qdev_prop_register_global_list(GlobalProperty *props)
> > +{
> > +    int i;
> > +
> > +    for (i = 0; props[i].driver != NULL; i++) {
> > +        qdev_prop_register_global(props+i);
> > +    }
> > +}
> > +
> > +void qdev_prop_set_globals(DeviceState *dev)
> > +{
> > +    ObjectClass *class = object_get_class(OBJECT(dev));
> > +
> > +    do {
> > +        GlobalProperty *prop;
> > +        QTAILQ_FOREACH(prop, &global_props, next) {
> > +            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
> > +                continue;
> > +            }
> > +            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> > +                exit(1);
> > +            }
> > +        }
> > +        class = object_class_get_parent(class);
> > +    } while (class);
> > +}
> > +
> > -- 
> > 1.7.11.7

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code
  2012-10-17 18:08   ` Anthony Liguori
@ 2012-10-17 18:32     ` Eduardo Habkost
  2012-10-18 14:51       ` Andreas Färber
  2012-10-23 14:56     ` Eduardo Habkost
  1 sibling, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-17 18:32 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: peter.maydell, riku.voipio, qemu-devel, blauwirbel, Igor Mammedov,
	Andreas Färber

On Wed, Oct 17, 2012 at 01:08:23PM -0500, Anthony Liguori wrote:
> Eduardo Habkost <ehabkost@redhat.com> writes:
> 
> > The reset register/unregister code is specific to qemu-system-*, so
> > isolate it so it can be moved to qdev-system.c.
> >
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  hw/qdev-core.c | 24 ++++++++++++++++++------
> >  1 file changed, 18 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/qdev-core.c b/hw/qdev-core.c
> > index af0af52..a105679 100644
> > --- a/hw/qdev-core.c
> > +++ b/hw/qdev-core.c
> > @@ -47,6 +47,21 @@ void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
> >  {
> >  }
> >  
> > +static void qbus_register_reset(BusState *bus)
> > +{
> > +    if (bus != sysbus_get_default()) {
> > +        /* TODO: once all bus devices are qdevified,
> > +           only reset handler for main_system_bus should be registered here. */
> > +        qemu_register_reset(qbus_reset_all_fn, bus);
> > +    }
> > +}
> > +
> > +static void qbus_unregister_reset(BusState *bus)
> > +{
> > +    assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> > +    qemu_unregister_reset(qbus_reset_all_fn, bus);
> > +}
> > +
> 
> Again, I'd suggest stubbing out qemu_[un]register_reset instead of
> trying to cope with it's users.

I agree on the vmstate case (the other patch), but on this case this
would require implementing a sysbus_get_default() stub as well. Skipping
the whole check for sysbus_get_default() on *-user looks like the right
thing to do, to me.

Anyway, I am actually wondering if we really need to include the qbus
code on *-user. Do you think *-user will eventually use BusState objects
too, or it will use only DeviceState objects in the foreseeable future?


> 
> Regards,
> 
> Anthony Liguori
> 
> >  const char *qdev_fw_name(DeviceState *dev)
> >  {
> >      DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > @@ -355,10 +370,8 @@ static void qbus_realize(BusState *bus)
> >          QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
> >          bus->parent->num_child_bus++;
> >          object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> > -    } else if (bus != sysbus_get_default()) {
> > -        /* TODO: once all bus devices are qdevified,
> > -           only reset handler for main_system_bus should be registered here. */
> > -        qemu_register_reset(qbus_reset_all_fn, bus);
> > +    } else {
> > +        qbus_register_reset(bus);
> >      }
> >  }
> >  
> > @@ -692,8 +705,7 @@ static void qbus_finalize(Object *obj)
> >          QLIST_REMOVE(bus, sibling);
> >          bus->parent->num_child_bus--;
> >      } else {
> > -        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> > -        qemu_unregister_reset(qbus_reset_all_fn, bus);
> > +        qbus_unregister_reset(bus);
> >      }
> >      g_free((char *)bus->name);
> >  }
> > -- 
> > 1.7.11.7

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too
  2012-10-17 18:11   ` Anthony Liguori
  2012-10-17 18:18     ` Eduardo Habkost
@ 2012-10-17 19:21     ` Peter Maydell
  2012-10-19 16:59       ` Eduardo Habkost
  1 sibling, 1 reply; 27+ messages in thread
From: Peter Maydell @ 2012-10-17 19:21 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Eduardo Habkost, riku.voipio, qemu-devel, blauwirbel,
	Igor Mammedov, Andreas Färber

On 17 October 2012 19:11, Anthony Liguori <anthony@codemonkey.ws> wrote:
> It's dangerously close to bike-shedding, but i don't think qdev belongs
> in qom/.  It's not core infrastructure.  It's the device base class and
> belongs IMHO in hw/.

"-user emulators don't get anything from hw/" is one of those semi
arbitrary but easily definable lines that I'd prefer it if we didn't
break. (Although IIRC there was a directory-renaming proposal recently
which maybe defines some different lines instead.)

-- PMM

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

* Re: [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code
  2012-10-17 18:32     ` Eduardo Habkost
@ 2012-10-18 14:51       ` Andreas Färber
  0 siblings, 0 replies; 27+ messages in thread
From: Andreas Färber @ 2012-10-18 14:51 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, riku.voipio, qemu-devel, blauwirbel,
	Anthony Liguori, Igor Mammedov

Am 17.10.2012 20:32, schrieb Eduardo Habkost:
> Anyway, I am actually wondering if we really need to include the qbus
> code on *-user. Do you think *-user will eventually use BusState objects
> too, or it will use only DeviceState objects in the foreseeable future?

My understanding is that we want DeviceState as a consistent parent and
its static properties mechanisms. Most of it, including BusState, is
going to be unused. At runtime *-user only needs the TCG fields in
CPUArchState plus the name -> object mapping mechanisms of the day for
initialization.

Andreas

-- 
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] 27+ messages in thread

* Re: [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too
  2012-10-17 19:21     ` Peter Maydell
@ 2012-10-19 16:59       ` Eduardo Habkost
  0 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-19 16:59 UTC (permalink / raw)
  To: Peter Maydell
  Cc: riku.voipio, qemu-devel, blauwirbel, Anthony Liguori,
	Igor Mammedov, Andreas Färber

On Wed, Oct 17, 2012 at 08:21:17PM +0100, Peter Maydell wrote:
> On 17 October 2012 19:11, Anthony Liguori <anthony@codemonkey.ws> wrote:
> > It's dangerously close to bike-shedding, but i don't think qdev belongs
> > in qom/.  It's not core infrastructure.  It's the device base class and
> > belongs IMHO in hw/.
> 
> "-user emulators don't get anything from hw/" is one of those semi
> arbitrary but easily definable lines that I'd prefer it if we didn't
> break. (Although IIRC there was a directory-renaming proposal recently
> which maybe defines some different lines instead.)

I just rememberd another reason for moving qdev-core to qom: the CPU
class itself (that's going to be a child of DeviceState) is already
inside qom. Keeping qdev-core it on hw/ would mean having a qom->hw->qom
dependency chain (qom/cpu.c -> hw/qdev.c -> qom/object.c).

So, by now I am keeping the proposed patch as-is (moving qdev-core to
qom/).

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too
  2012-10-16 19:08 ` [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too Eduardo Habkost
  2012-10-17 18:11   ` Anthony Liguori
@ 2012-10-22 12:36   ` Igor Mammedov
  2012-10-22 12:43     ` Eduardo Habkost
  1 sibling, 1 reply; 27+ messages in thread
From: Igor Mammedov @ 2012-10-22 12:36 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, riku.voipio, qemu-devel, blauwirbel,
	Anthony Liguori, Andreas Färber

On Tue, 16 Oct 2012 16:08:42 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:
[...]
> diff --git a/qom/qdev-properties.c b/qom/qdev-properties.c
> new file mode 100644
> index 0000000..2e82cb9
> --- /dev/null
> +++ b/qom/qdev-properties.c
[...]
> +void qdev_prop_set_globals(DeviceState *dev)
> +{
> +    ObjectClass *class = object_get_class(OBJECT(dev));
> +
> +    do {
> +        GlobalProperty *prop;
> +        QTAILQ_FOREACH(prop, &global_props, next) {
> +            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
> +                continue;
> +            }
> +            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> +                exit(1);
> +            }
> +        }
> +        class = object_class_get_parent(class);
> +    } while (class);
> +}
> +
^^^ git complains "whitespace line at EOF" 

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

* Re: [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too
  2012-10-22 12:36   ` Igor Mammedov
@ 2012-10-22 12:43     ` Eduardo Habkost
  0 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-22 12:43 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, riku.voipio, qemu-devel, blauwirbel,
	Anthony Liguori, Andreas Färber

On Mon, Oct 22, 2012 at 02:36:01PM +0200, Igor Mammedov wrote:
> On Tue, 16 Oct 2012 16:08:42 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> [...]
> > diff --git a/qom/qdev-properties.c b/qom/qdev-properties.c
> > new file mode 100644
> > index 0000000..2e82cb9
> > --- /dev/null
> > +++ b/qom/qdev-properties.c
> [...]
> > +void qdev_prop_set_globals(DeviceState *dev)
> > +{
> > +    ObjectClass *class = object_get_class(OBJECT(dev));
> > +
> > +    do {
> > +        GlobalProperty *prop;
> > +        QTAILQ_FOREACH(prop, &global_props, next) {
> > +            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
> > +                continue;
> > +            }
> > +            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> > +                exit(1);
> > +            }
> > +        }
> > +        class = object_class_get_parent(class);
> > +    } while (class);
> > +}
> > +
> ^^^ git complains "whitespace line at EOF" 

I will fix it on the next version. Thanks.

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code
  2012-10-17 18:08   ` Anthony Liguori
  2012-10-17 18:32     ` Eduardo Habkost
@ 2012-10-23 14:56     ` Eduardo Habkost
  2012-10-24  2:43       ` Eduardo Habkost
  1 sibling, 1 reply; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-23 14:56 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: peter.maydell, riku.voipio, qemu-devel, blauwirbel, Igor Mammedov,
	Andreas Färber

On Wed, Oct 17, 2012 at 01:08:23PM -0500, Anthony Liguori wrote:
> Eduardo Habkost <ehabkost@redhat.com> writes:
> 
> > The reset register/unregister code is specific to qemu-system-*, so
> > isolate it so it can be moved to qdev-system.c.
> >
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  hw/qdev-core.c | 24 ++++++++++++++++++------
> >  1 file changed, 18 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/qdev-core.c b/hw/qdev-core.c
> > index af0af52..a105679 100644
> > --- a/hw/qdev-core.c
> > +++ b/hw/qdev-core.c
> > @@ -47,6 +47,21 @@ void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
> >  {
> >  }
> >  
> > +static void qbus_register_reset(BusState *bus)
> > +{
> > +    if (bus != sysbus_get_default()) {
> > +        /* TODO: once all bus devices are qdevified,
> > +           only reset handler for main_system_bus should be registered here. */
> > +        qemu_register_reset(qbus_reset_all_fn, bus);
> > +    }
> > +}
> > +
> > +static void qbus_unregister_reset(BusState *bus)
> > +{
> > +    assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> > +    qemu_unregister_reset(qbus_reset_all_fn, bus);
> > +}
> > +
> 
> Again, I'd suggest stubbing out qemu_[un]register_reset instead of
> trying to cope with it's users.

I was going to implement it the way you suggested. But then I noticed
that I _ *-user will need to request the devices to be reset once, too
(even if the only devices available are the CPU objects).

On the next version, I will move the reset-function list from vl.c to
qdev-core.c. Code that uses qdev will need to take care of calling
qemu_devices_reset() eventually (qemu-system does that on vl.c *-user
will need to that somewhere else).

> 
> Regards,
> 
> Anthony Liguori
> 
> >  const char *qdev_fw_name(DeviceState *dev)
> >  {
> >      DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > @@ -355,10 +370,8 @@ static void qbus_realize(BusState *bus)
> >          QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
> >          bus->parent->num_child_bus++;
> >          object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> > -    } else if (bus != sysbus_get_default()) {
> > -        /* TODO: once all bus devices are qdevified,
> > -           only reset handler for main_system_bus should be registered here. */
> > -        qemu_register_reset(qbus_reset_all_fn, bus);
> > +    } else {
> > +        qbus_register_reset(bus);
> >      }
> >  }
> >  
> > @@ -692,8 +705,7 @@ static void qbus_finalize(Object *obj)
> >          QLIST_REMOVE(bus, sibling);
> >          bus->parent->num_child_bus--;
> >      } else {
> > -        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> > -        qemu_unregister_reset(qbus_reset_all_fn, bus);
> > +        qbus_unregister_reset(bus);
> >      }
> >      g_free((char *)bus->name);
> >  }
> > -- 
> > 1.7.11.7
> 

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code
  2012-10-23 14:56     ` Eduardo Habkost
@ 2012-10-24  2:43       ` Eduardo Habkost
  0 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2012-10-24  2:43 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: peter.maydell, riku.voipio, qemu-devel, blauwirbel, Igor Mammedov,
	Andreas Färber

On Tue, Oct 23, 2012 at 12:56:18PM -0200, Eduardo Habkost wrote:
> On Wed, Oct 17, 2012 at 01:08:23PM -0500, Anthony Liguori wrote:
> > Eduardo Habkost <ehabkost@redhat.com> writes:
> > 
> > > The reset register/unregister code is specific to qemu-system-*, so
> > > isolate it so it can be moved to qdev-system.c.
> > >
> > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > > ---
> > >  hw/qdev-core.c | 24 ++++++++++++++++++------
> > >  1 file changed, 18 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/hw/qdev-core.c b/hw/qdev-core.c
> > > index af0af52..a105679 100644
> > > --- a/hw/qdev-core.c
> > > +++ b/hw/qdev-core.c
> > > @@ -47,6 +47,21 @@ void GCC_WEAK qdev_finalize_vmstate(DeviceState *dev)
> > >  {
> > >  }
> > >  
> > > +static void qbus_register_reset(BusState *bus)
> > > +{
> > > +    if (bus != sysbus_get_default()) {
> > > +        /* TODO: once all bus devices are qdevified,
> > > +           only reset handler for main_system_bus should be registered here. */
> > > +        qemu_register_reset(qbus_reset_all_fn, bus);
> > > +    }
> > > +}
> > > +
> > > +static void qbus_unregister_reset(BusState *bus)
> > > +{
> > > +    assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> > > +    qemu_unregister_reset(qbus_reset_all_fn, bus);
> > > +}
> > > +
> > 
> > Again, I'd suggest stubbing out qemu_[un]register_reset instead of
> > trying to cope with it's users.
> 
> I was going to implement it the way you suggested. But then I noticed
> that I _ *-user will need to request the devices to be reset once, too
> (even if the only devices available are the CPU objects).
> 
> On the next version, I will move the reset-function list from vl.c to
> qdev-core.c. Code that uses qdev will need to take care of calling
> qemu_devices_reset() eventually (qemu-system does that on vl.c *-user
> will need to that somewhere else).

I don't usually reply to myself to correct typos, but the message above
was almost impossible to parse. So, rewriting it:

  I was going to implement it the way you suggested. But then I noticed
  that *-user will need to request the devices to be reset once, too
  (even if the only devices available are the CPU objects).

  On the next version, I will move the reset-function list from vl.c to
  qdev-core.c. Code that uses qdev will need to take care of calling
  qemu_devices_reset() eventually (qemu-system does that on vl.c, and
  *-user will need to that somewhere else).


> 
> > 
> > Regards,
> > 
> > Anthony Liguori
> > 
> > >  const char *qdev_fw_name(DeviceState *dev)
> > >  {
> > >      DeviceClass *dc = DEVICE_GET_CLASS(dev);
> > > @@ -355,10 +370,8 @@ static void qbus_realize(BusState *bus)
> > >          QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
> > >          bus->parent->num_child_bus++;
> > >          object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
> > > -    } else if (bus != sysbus_get_default()) {
> > > -        /* TODO: once all bus devices are qdevified,
> > > -           only reset handler for main_system_bus should be registered here. */
> > > -        qemu_register_reset(qbus_reset_all_fn, bus);
> > > +    } else {
> > > +        qbus_register_reset(bus);
> > >      }
> > >  }
> > >  
> > > @@ -692,8 +705,7 @@ static void qbus_finalize(Object *obj)
> > >          QLIST_REMOVE(bus, sibling);
> > >          bus->parent->num_child_bus--;
> > >      } else {
> > > -        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
> > > -        qemu_unregister_reset(qbus_reset_all_fn, bus);
> > > +        qbus_unregister_reset(bus);
> > >      }
> > >      g_free((char *)bus->name);
> > >  }
> > > -- 
> > > 1.7.11.7
> > 
> 
> -- 
> Eduardo
> 

-- 
Eduardo

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

end of thread, other threads:[~2012-10-24  2:43 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-16 19:08 [Qemu-devel] [PATCH 00/12] make CPU child of DeviceState and include qdev core in *-user Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 01/12] qdev: split up header so it can be used in cpu.h Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 02/12] qapi-types.h doesn't really need to include qemu-common.h Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 03/12] qdev: separate core from the code used only by qemu-system-* Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 04/12] qdev: rename qdev.c to qdev-core.c Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 05/12] qdev-core: isolate vmstate handling into separate functions Eduardo Habkost
2012-10-17 18:06   ` Anthony Liguori
2012-10-16 19:08 ` [Qemu-devel] [PATCH 06/12] qdev: move vmstate handling to qdev-system.c Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 07/12] qdev-core: isolate reset register/unregister code Eduardo Habkost
2012-10-17 18:08   ` Anthony Liguori
2012-10-17 18:32     ` Eduardo Habkost
2012-10-18 14:51       ` Andreas Färber
2012-10-23 14:56     ` Eduardo Habkost
2012-10-24  2:43       ` Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 08/12] qdev: move reset register/unregister code to qdev-system.c Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 09/12] move qemu_irq typedef out of cpu-common.h Eduardo Habkost
2012-10-17 18:08   ` Anthony Liguori
2012-10-16 19:08 ` [Qemu-devel] [PATCH 10/12] qdev: use full qdev.h include path on qdev*.c Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 11/12] include core qdev code into *-user, too Eduardo Habkost
2012-10-17 18:11   ` Anthony Liguori
2012-10-17 18:18     ` Eduardo Habkost
2012-10-17 19:21     ` Peter Maydell
2012-10-19 16:59       ` Eduardo Habkost
2012-10-22 12:36   ` Igor Mammedov
2012-10-22 12:43     ` Eduardo Habkost
2012-10-16 19:08 ` [Qemu-devel] [PATCH 12/12] qom: make CPU a child of DeviceState Eduardo Habkost
  -- strict thread matches above, loose matches on Subject: below --
2012-10-16  1:57 [Qemu-devel] [PATCH v3 00/12] make CPU child of DeviceState and include qdev core in *-user Igor Mammedov
2012-10-16  1:57 ` [Qemu-devel] [PATCH 10/12] qdev: use full qdev.h include path on qdev*.c Igor Mammedov

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).