Eduardo Habkost
2012-Aug-21 15:42 UTC
[RFC 0/8] include qdev core in *-user, make CPU child of DeviceState
So, here''s a third suggestion to the CPU/DeviceState problem. Basically I split the qdev code into a core (that can be easily compiled into *-user), and a part specific to qemu-system-*. There are two remaining parts that forced me to use #ifdefs in the "core" .c files: - vmstate handling on qdev_init() - the qemu_register_reset() hack If we address those two issues inside qemu-system-* (instead of inside the qdev core code), using DeviceState inside *-user shouldn''t be a big problem anymore. Anthony Liguori (1): qdev: split up header so it can be used in cpu.h Eduardo Habkost (3): split qdev into a core and code used only by qemu-system-* qdev: use full qdev.h include path on qdev*.c include core qdev code into *-user, too Igor Mammedov (4): move qemu_irq typedef out of cpu-common.h qapi-types.h doesn''t really need to include qemu-common.h cleanup error.h, included qapi-types.h aready has stdbool.h make CPU a child of DeviceState Makefile.objs | 1 + error.h | 1 - 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 | 240 +++++++++++++++ hw/qdev-monitor.h | 16 + hw/qdev-properties-system.c | 329 +++++++++++++++++++++ hw/qdev-properties.h | 129 ++++++++ hw/qdev-system.c | 93 ++++++ hw/qdev.h | 371 +----------------------- 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 +- hw/qdev-properties.c => qom/device-properties.c | 323 +-------------------- hw/qdev.c => qom/device.c | 106 +------ scripts/qapi-types.py | 2 +- sysemu.h | 1 + 26 files changed, 849 insertions(+), 790 deletions(-) create mode 100644 hw/qdev-core.h create mode 100644 hw/qdev-monitor.h create mode 100644 hw/qdev-properties-system.c create mode 100644 hw/qdev-properties.h create mode 100644 hw/qdev-system.c rename hw/qdev-properties.c => qom/device-properties.c (75%) rename hw/qdev.c => qom/device.c (89%) -- 1.7.11.4
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> --- hw/arm-misc.h | 1 + hw/bt.h | 2 ++ hw/devices.h | 2 ++ hw/irq.h | 2 ++ hw/omap.h | 1 + hw/soc_dma.h | 1 + hw/xen.h | 1 + qemu-common.h | 1 - sysemu.h | 1 + 9 files changed, 11 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/irq.h b/hw/irq.h index 56c55f0..1339a3a 100644 --- a/hw/irq.h +++ b/hw/irq.h @@ -3,6 +3,8 @@ /* Generic IRQ/GPIO pin infrastructure. */ +typedef struct IRQState *qemu_irq; + typedef void (*qemu_irq_handler)(void *opaque, int n, int level); void qemu_set_irq(qemu_irq irq, int level); diff --git a/hw/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 e5926b7..ff11dfd 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 e5c2bcd..6677a30 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -273,7 +273,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; diff --git a/sysemu.h b/sysemu.h index 65552ac..f765821 100644 --- a/sysemu.h +++ b/sysemu.h @@ -9,6 +9,7 @@ #include "qapi-types.h" #include "notify.h" #include "main-loop.h" +#include "hw/irq.h" /* vl.c */ -- 1.7.11.4
Eduardo Habkost
2012-Aug-21 15:42 UTC
[RFC 2/8] qdev: split up header so it can be used in cpu.h
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 v1->v2: move qemu_irq typedef out of this patch into a separate one with an additional cleanup of headers to fix build breakage Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- hw/mc146818rtc.c | 1 + hw/qdev-addr.c | 1 + hw/qdev-core.h | 240 +++++++++++++++++++++++++++++++++ hw/qdev-monitor.h | 16 +++ hw/qdev-properties.c | 1 + hw/qdev-properties.h | 128 ++++++++++++++++++ hw/qdev.c | 1 + hw/qdev.h | 371 +-------------------------------------------------- 8 files changed, 392 insertions(+), 367 deletions(-) create mode 100644 hw/qdev-core.h create mode 100644 hw/qdev-monitor.h create mode 100644 hw/qdev-properties.h diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 3777f85..3780617 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -25,6 +25,7 @@ #include "qemu-timer.h" #include "sysemu.h" #include "mc146818rtc.h" +#include "qapi/qapi-visit-core.h" #ifdef TARGET_I386 #include "apic.h" diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c index b711b6b..5b5d38f 100644 --- a/hw/qdev-addr.c +++ b/hw/qdev-addr.c @@ -1,6 +1,7 @@ #include "qdev.h" #include "qdev-addr.h" #include "targphys.h" +#include "qapi/qapi-visit-core.h" /* --- target physical address --- */ diff --git a/hw/qdev-core.h b/hw/qdev-core.h new file mode 100644 index 0000000..ca205fc --- /dev/null +++ b/hw/qdev-core.h @@ -0,0 +1,240 @@ +#ifndef QDEV_CORE_H +#define QDEV_CORE_H + +#include "qemu-queue.h" +#include "qemu-option.h" +#include "qemu/object.h" +#include "hw/irq.h" +#include "error.h" + +typedef struct Property Property; + +typedef struct PropertyInfo PropertyInfo; + +typedef struct CompatProperty CompatProperty; + +typedef struct BusState BusState; + +typedef struct BusClass BusClass; + +enum DevState { + DEV_STATE_CREATED = 1, + DEV_STATE_INITIALIZED, +}; + +enum { + DEV_NVECTORS_UNSPECIFIED = -1, +}; + +#define TYPE_DEVICE "device" +#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE) +#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE) +#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE) + +typedef int (*qdev_initfn)(DeviceState *dev); +typedef int (*qdev_event)(DeviceState *dev); +typedef void (*qdev_resetfn)(DeviceState *dev); + +struct VMStateDescription; + +typedef struct DeviceClass { + ObjectClass parent_class; + + const char *fw_name; + const char *desc; + Property *props; + int no_user; + + /* callbacks */ + void (*reset)(DeviceState *dev); + + /* device state */ + const struct VMStateDescription *vmsd; + + /* Private to qdev / bus. */ + qdev_initfn init; + qdev_event unplug; + qdev_event exit; + const char *bus_type; +} DeviceClass; + +/* This structure should not be accessed directly. We declare it here + so that it can be embedded in individual device state structures. */ +struct DeviceState { + Object parent_obj; + + const char *id; + enum DevState state; + struct QemuOpts *opts; + int hotplugged; + BusState *parent_bus; + int num_gpio_out; + qemu_irq *gpio_out; + int num_gpio_in; + qemu_irq *gpio_in; + QLIST_HEAD(, BusState) child_bus; + int num_child_bus; + int instance_id_alias; + int alias_required_for_version; +}; + +/* + * This callback is used to create Open Firmware device path in accordance with + * OF spec http://forthworks.com/standards/of1275.pdf. Indicidual bus bindings + * can be found here http://playground.sun.com/1275/bindings/. + */ + +#define TYPE_BUS "bus" +#define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS) +#define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS) +#define BUS_GET_CLASS(obj) OBJECT_GET_CLASS(BusClass, (obj), TYPE_BUS) + +struct BusClass { + ObjectClass parent_class; + + /* FIXME first arg should be BusState */ + void (*print_dev)(Monitor *mon, DeviceState *dev, int indent); + char *(*get_dev_path)(DeviceState *dev); + char *(*get_fw_dev_path)(DeviceState *dev); + int (*reset)(BusState *bus); +}; + +typedef struct BusChild { + DeviceState *child; + int index; + QTAILQ_ENTRY(BusChild) sibling; +} BusChild; + +/** + * BusState: + * @qom_allocated: Indicates whether the object was allocated by QOM. + * @glib_allocated: Indicates whether the object was initialized in-place + * yet is expected to be freed with g_free(). + */ +struct BusState { + Object obj; + DeviceState *parent; + const char *name; + int allow_hotplug; + bool qom_allocated; + bool glib_allocated; + int max_index; + QTAILQ_HEAD(ChildrenHead, BusChild) children; + QLIST_ENTRY(BusState) sibling; +}; + +struct Property { + const char *name; + PropertyInfo *info; + int offset; + uint8_t bitnr; + uint8_t qtype; + int64_t defval; +}; + +struct PropertyInfo { + const char *name; + const char *legacy_name; + const char **enum_table; + int (*parse)(DeviceState *dev, Property *prop, const char *str); + int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); + ObjectPropertyAccessor *get; + ObjectPropertyAccessor *set; + ObjectPropertyRelease *release; +}; + +typedef struct GlobalProperty { + const char *driver; + const char *property; + const char *value; + QTAILQ_ENTRY(GlobalProperty) next; +} GlobalProperty; + +/*** Board API. This should go away once we have a machine config file. ***/ + +DeviceState *qdev_create(BusState *bus, const char *name); +DeviceState *qdev_try_create(BusState *bus, const char *name); +bool qdev_exists(const char *name); +int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT; +void qdev_init_nofail(DeviceState *dev); +void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, + int required_for_version); +void qdev_unplug(DeviceState *dev, Error **errp); +void qdev_free(DeviceState *dev); +int qdev_simple_unplug_cb(DeviceState *dev); +void qdev_machine_creation_done(void); +bool qdev_machine_modified(void); + +qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); +void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); + +BusState *qdev_get_child_bus(DeviceState *dev, const char *name); + +/*** Device API. ***/ + +/* Register device properties. */ +/* GPIO inputs also double as IRQ sinks. */ +void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); +void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); + +BusState *qdev_get_parent_bus(DeviceState *dev); + +/*** BUS API. ***/ + +DeviceState *qdev_find_recursive(BusState *bus, const char *id); + +/* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */ +typedef int (qbus_walkerfn)(BusState *bus, void *opaque); +typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque); + +void qbus_create_inplace(BusState *bus, const char *typename, + DeviceState *parent, const char *name); +BusState *qbus_create(const char *typename, DeviceState *parent, const char *name); +/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion, + * < 0 if either devfn or busfn terminate walk somewhere in cursion, + * 0 otherwise. */ +int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque); +int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, + qbus_walkerfn *busfn, void *opaque); +void qdev_reset_all(DeviceState *dev); +void qbus_reset_all_fn(void *opaque); + +void qbus_free(BusState *bus); + +#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev) + +/* This should go away once we get rid of the NULL bus hack */ +BusState *sysbus_get_default(void); + +char *qdev_get_fw_dev_path(DeviceState *dev); + +/** + * @qdev_machine_init + * + * Initialize platform devices before machine init. This is a hack until full + * support for composition is added. + */ +void qdev_machine_init(void); + +/** + * @device_reset + * + * Reset a single device (by calling the reset method). + */ +void device_reset(DeviceState *dev); + +const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev); + +const char *qdev_fw_name(DeviceState *dev); + +Object *qdev_get_machine(void); + +/* FIXME: make this a link<> */ +void qdev_set_parent_bus(DeviceState *dev, BusState *bus); + +extern int qdev_hotplug; + +char *qdev_get_dev_path(DeviceState *dev); + +#endif diff --git a/hw/qdev-monitor.h b/hw/qdev-monitor.h new file mode 100644 index 0000000..220ceba --- /dev/null +++ b/hw/qdev-monitor.h @@ -0,0 +1,16 @@ +#ifndef QEMU_QDEV_MONITOR_H +#define QEMU_QDEV_MONITOR_H + +#include "qdev-core.h" +#include "monitor.h" + +/*** monitor commands ***/ + +void do_info_qtree(Monitor *mon); +void do_info_qdm(Monitor *mon); +int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data); +int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data); +int qdev_device_help(QemuOpts *opts); +DeviceState *qdev_device_add(QemuOpts *opts); + +#endif diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 8aca0d4..81d901c 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -4,6 +4,7 @@ #include "blockdev.h" #include "hw/block-common.h" #include "net/hub.h" +#include "qapi/qapi-visit-core.h" void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) { diff --git a/hw/qdev-properties.h b/hw/qdev-properties.h new file mode 100644 index 0000000..e93336a --- /dev/null +++ b/hw/qdev-properties.h @@ -0,0 +1,128 @@ +#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; + +#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_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); +void qdev_prop_set_vlan(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 b5b74b9..36c3e4b 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -29,6 +29,7 @@ #include "qdev.h" #include "sysemu.h" #include "error.h" +#include "qapi/qapi-visit-core.h" int qdev_hotplug = 0; static bool qdev_hot_added = false; diff --git a/hw/qdev.h b/hw/qdev.h index d699194..365b8d6 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -1,372 +1,9 @@ #ifndef QDEV_H #define QDEV_H -#include "hw.h" -#include "qemu-queue.h" -#include "qemu-char.h" -#include "qemu-option.h" -#include "qapi/qapi-visit-core.h" -#include "qemu/object.h" -#include "error.h" - -typedef struct Property Property; - -typedef struct PropertyInfo PropertyInfo; - -typedef struct CompatProperty CompatProperty; - -typedef struct BusState BusState; - -typedef struct BusClass BusClass; - -enum DevState { - DEV_STATE_CREATED = 1, - DEV_STATE_INITIALIZED, -}; - -enum { - DEV_NVECTORS_UNSPECIFIED = -1, -}; - -#define TYPE_DEVICE "device" -#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE) -#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE) -#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE) - -typedef int (*qdev_initfn)(DeviceState *dev); -typedef int (*qdev_event)(DeviceState *dev); -typedef void (*qdev_resetfn)(DeviceState *dev); - -typedef struct DeviceClass { - ObjectClass parent_class; - - const char *fw_name; - const char *desc; - Property *props; - int no_user; - - /* callbacks */ - void (*reset)(DeviceState *dev); - - /* device state */ - const VMStateDescription *vmsd; - - /* Private to qdev / bus. */ - qdev_initfn init; - qdev_event unplug; - qdev_event exit; - const char *bus_type; -} DeviceClass; - -/* This structure should not be accessed directly. We declare it here - so that it can be embedded in individual device state structures. */ -struct DeviceState { - Object parent_obj; - - const char *id; - enum DevState state; - QemuOpts *opts; - int hotplugged; - BusState *parent_bus; - int num_gpio_out; - qemu_irq *gpio_out; - int num_gpio_in; - qemu_irq *gpio_in; - QLIST_HEAD(, BusState) child_bus; - int num_child_bus; - int instance_id_alias; - int alias_required_for_version; -}; - -#define TYPE_BUS "bus" -#define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS) -#define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS) -#define BUS_GET_CLASS(obj) OBJECT_GET_CLASS(BusClass, (obj), TYPE_BUS) - -struct BusClass { - ObjectClass parent_class; - - /* FIXME first arg should be BusState */ - void (*print_dev)(Monitor *mon, DeviceState *dev, int indent); - char *(*get_dev_path)(DeviceState *dev); - /* - * This callback is used to create Open Firmware device path in accordance - * with OF spec http://forthworks.com/standards/of1275.pdf. Individual bus - * bindings can be found at http://playground.sun.com/1275/bindings/. - */ - char *(*get_fw_dev_path)(DeviceState *dev); - int (*reset)(BusState *bus); -}; - -typedef struct BusChild { - DeviceState *child; - int index; - QTAILQ_ENTRY(BusChild) sibling; -} BusChild; - -/** - * BusState: - * @qom_allocated: Indicates whether the object was allocated by QOM. - * @glib_allocated: Indicates whether the object was initialized in-place - * yet is expected to be freed with g_free(). - */ -struct BusState { - Object obj; - DeviceState *parent; - const char *name; - int allow_hotplug; - bool qom_allocated; - bool glib_allocated; - int max_index; - QTAILQ_HEAD(ChildrenHead, BusChild) children; - QLIST_ENTRY(BusState) sibling; -}; - -struct Property { - const char *name; - PropertyInfo *info; - int offset; - uint8_t bitnr; - uint8_t qtype; - int64_t defval; -}; - -struct PropertyInfo { - const char *name; - const char *legacy_name; - const char **enum_table; - int (*parse)(DeviceState *dev, Property *prop, const char *str); - int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); - ObjectPropertyAccessor *get; - ObjectPropertyAccessor *set; - ObjectPropertyRelease *release; -}; - -typedef struct GlobalProperty { - const char *driver; - const char *property; - const char *value; - QTAILQ_ENTRY(GlobalProperty) next; -} GlobalProperty; - -/*** Board API. This should go away once we have a machine config file. ***/ - -DeviceState *qdev_create(BusState *bus, const char *name); -DeviceState *qdev_try_create(BusState *bus, const char *name); -bool qdev_exists(const char *name); -int qdev_device_help(QemuOpts *opts); -DeviceState *qdev_device_add(QemuOpts *opts); -int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT; -void qdev_init_nofail(DeviceState *dev); -void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, - int required_for_version); -void qdev_unplug(DeviceState *dev, Error **errp); -void qdev_free(DeviceState *dev); -int qdev_simple_unplug_cb(DeviceState *dev); -void qdev_machine_creation_done(void); -bool qdev_machine_modified(void); - -qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); -void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); - -BusState *qdev_get_child_bus(DeviceState *dev, const char *name); - -/*** Device API. ***/ - -/* Register device properties. */ -/* GPIO inputs also double as IRQ sinks. */ -void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); -void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); - -BusState *qdev_get_parent_bus(DeviceState *dev); - -/*** BUS API. ***/ - -DeviceState *qdev_find_recursive(BusState *bus, const char *id); - -/* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */ -typedef int (qbus_walkerfn)(BusState *bus, void *opaque); -typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque); - -void qbus_create_inplace(BusState *bus, const char *typename, - DeviceState *parent, const char *name); -BusState *qbus_create(const char *typename, DeviceState *parent, const char *name); -/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion, - * < 0 if either devfn or busfn terminate walk somewhere in cursion, - * 0 otherwise. */ -int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque); -int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque); -void qdev_reset_all(DeviceState *dev); -void qbus_reset_all_fn(void *opaque); - -void qbus_free(BusState *bus); - -#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev) - -/* This should go away once we get rid of the NULL bus hack */ -BusState *sysbus_get_default(void); - -/*** monitor commands ***/ - -void do_info_qtree(Monitor *mon); -void do_info_qdm(Monitor *mon); -int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data); -int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data); - -/*** qdev-properties.c ***/ - -extern PropertyInfo qdev_prop_bit; -extern PropertyInfo qdev_prop_uint8; -extern PropertyInfo qdev_prop_uint16; -extern PropertyInfo qdev_prop_uint32; -extern PropertyInfo qdev_prop_int32; -extern PropertyInfo qdev_prop_uint64; -extern PropertyInfo qdev_prop_hex8; -extern PropertyInfo qdev_prop_hex32; -extern PropertyInfo qdev_prop_hex64; -extern PropertyInfo qdev_prop_string; -extern PropertyInfo qdev_prop_chr; -extern PropertyInfo qdev_prop_ptr; -extern PropertyInfo qdev_prop_macaddr; -extern PropertyInfo qdev_prop_losttickpolicy; -extern PropertyInfo qdev_prop_bios_chs_trans; -extern PropertyInfo qdev_prop_drive; -extern PropertyInfo qdev_prop_netdev; -extern PropertyInfo qdev_prop_vlan; -extern PropertyInfo qdev_prop_pci_devfn; -extern PropertyInfo qdev_prop_blocksize; -extern PropertyInfo qdev_prop_pci_host_devaddr; - -#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ - .name = (_name), \ - .info = &(_prop), \ - .offset = offsetof(_state, _field) \ - + type_check(_type,typeof_field(_state, _field)), \ - } -#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \ - .name = (_name), \ - .info = &(_prop), \ - .offset = offsetof(_state, _field) \ - + type_check(_type,typeof_field(_state, _field)), \ - .qtype = QTYPE_QINT, \ - .defval = (_type)_defval, \ - } -#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \ - .name = (_name), \ - .info = &(qdev_prop_bit), \ - .bitnr = (_bit), \ - .offset = offsetof(_state, _field) \ - + type_check(uint32_t,typeof_field(_state, _field)), \ - .qtype = QTYPE_QBOOL, \ - .defval = (bool)_defval, \ - } - -#define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t) -#define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t) -#define DEFINE_PROP_UINT32(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t) -#define DEFINE_PROP_INT32(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t) -#define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) -#define DEFINE_PROP_HEX8(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t) -#define DEFINE_PROP_HEX32(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t) -#define DEFINE_PROP_HEX64(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t) -#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) - -#define DEFINE_PROP_PTR(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) -#define DEFINE_PROP_CHR(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*) -#define DEFINE_PROP_STRING(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*) -#define DEFINE_PROP_NETDEV(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NetClientState*) -#define DEFINE_PROP_VLAN(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NetClientState*) -#define DEFINE_PROP_DRIVE(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *) -#define DEFINE_PROP_MACADDR(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr) -#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \ - LostTickPolicy) -#define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int) -#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t) -#define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress) - -#define DEFINE_PROP_END_OF_LIST() \ - {} - -/* Set properties between creation and init. */ -void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); -int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); -void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value); -void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value); -void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value); -void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value); -void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value); -void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value); -void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value); -void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value); -void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value); -int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT; -void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value); -void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value); -void qdev_prop_set_enum(DeviceState *dev, const char *name, int value); -/* FIXME: Remove opaque pointer properties. */ -void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); - -void qdev_prop_register_global_list(GlobalProperty *props); -void qdev_prop_set_globals(DeviceState *dev); -void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, - Property *prop, const char *value); - -char *qdev_get_fw_dev_path(DeviceState *dev); - -/** - * @qdev_property_add_static - add a @Property to a device referencing a - * field in a struct. - */ -void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp); - -/** - * @qdev_machine_init - * - * Initialize platform devices before machine init. This is a hack until full - * support for composition is added. - */ -void qdev_machine_init(void); - -/** - * @device_reset - * - * Reset a single device (by calling the reset method). - */ -void device_reset(DeviceState *dev); - -const VMStateDescription *qdev_get_vmsd(DeviceState *dev); - -const char *qdev_fw_name(DeviceState *dev); - -Object *qdev_get_machine(void); - -/* FIXME: make this a link<> */ -void qdev_set_parent_bus(DeviceState *dev, BusState *bus); - -extern int qdev_hotplug; - -char *qdev_get_dev_path(DeviceState *dev); +#include "hw/hw.h" +#include "qdev-core.h" +#include "qdev-properties.h" +#include "qdev-monitor.h" #endif -- 1.7.11.4
Eduardo Habkost
2012-Aug-21 15:42 UTC
[RFC 3/8] qapi-types.h doesn''t really need to include qemu-common.h
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> --- scripts/qapi-types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py index cf601ae..f34addb 100644 --- a/scripts/qapi-types.py +++ b/scripts/qapi-types.py @@ -263,7 +263,7 @@ fdecl.write(mcgen('''''' #ifndef %(guard)s #define %(guard)s -#include "qemu-common.h" +#include <stdbool.h> '''''', guard=guardname(h_file))) -- 1.7.11.4
Eduardo Habkost
2012-Aug-21 15:42 UTC
[RFC 4/8] cleanup error.h, included qapi-types.h aready has stdbool.h
From: Igor Mammedov <imammedo@redhat.com> Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- error.h | 1 - 1 file changed, 1 deletion(-) diff --git a/error.h b/error.h index 96fc203..643a372 100644 --- a/error.h +++ b/error.h @@ -14,7 +14,6 @@ #include "compiler.h" #include "qapi-types.h" -#include <stdbool.h> /** * A class representing internal errors within QEMU. An error has a ErrorClass -- 1.7.11.4
Eduardo Habkost
2012-Aug-21 15:42 UTC
[RFC 5/8] split qdev into a core and code used only by qemu-system-*
This also makes it visible what are the parts of qdev that we may want to split more cleanly (as they are using #ifdefs, now). There are basically two parts that are specific to qemu-system-*, but are still inside qdev.c (but inside a "#ifndef CONFIG_USER_ONLY"). - vmstate handling - reset function registration Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- hw/Makefile.objs | 1 + hw/qdev-properties-system.c | 329 ++++++++++++++++++++++++++++++++++++++++++++ hw/qdev-properties.c | 320 +----------------------------------------- hw/qdev-properties.h | 1 + hw/qdev-system.c | 93 +++++++++++++ hw/qdev.c | 103 ++------------ 6 files changed, 435 insertions(+), 412 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 7f57ed5..04d3b5e 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -177,6 +177,7 @@ common-obj-y += bt.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o common-obj-y += bt-hci-csr.o common-obj-y += msmouse.o ps2.o common-obj-y += qdev.o qdev-properties.o qdev-monitor.o +common-obj-y += qdev-system.o qdev-properties-system.o common-obj-$(CONFIG_BRLAPI) += baum.o # xen backend driver support diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c new file mode 100644 index 0000000..c42e656 --- /dev/null +++ b/hw/qdev-properties-system.c @@ -0,0 +1,329 @@ +#include "net.h" +#include "qdev.h" +#include "qerror.h" +#include "blockdev.h" +#include "hw/block-common.h" +#include "net/hub.h" +#include "qapi/qapi-visit-core.h" + +static void get_pointer(Object *obj, Visitor *v, Property *prop, + const char *(*print)(void *ptr), + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + void **ptr = qdev_get_prop_ptr(dev, prop); + char *p; + + p = (char *) (*ptr ? print(*ptr) : ""); + visit_type_str(v, &p, name, errp); +} + +static void set_pointer(Object *obj, Visitor *v, Property *prop, + int (*parse)(DeviceState *dev, const char *str, + void **ptr), + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Error *local_err = NULL; + void **ptr = qdev_get_prop_ptr(dev, prop); + char *str; + int ret; + + if (dev->state != DEV_STATE_CREATED) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } + + visit_type_str(v, &str, name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + if (!*str) { + g_free(str); + *ptr = NULL; + return; + } + ret = parse(dev, str, ptr); + error_set_from_qdev_prop_error(errp, ret, dev, prop, str); + g_free(str); +} + + +/* --- drive --- */ + +static int parse_drive(DeviceState *dev, const char *str, void **ptr) +{ + BlockDriverState *bs; + + bs = bdrv_find(str); + if (bs == NULL) + return -ENOENT; + if (bdrv_attach_dev(bs, dev) < 0) + return -EEXIST; + *ptr = bs; + return 0; +} + +static void release_drive(Object *obj, const char *name, void *opaque) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); + + if (*ptr) { + bdrv_detach_dev(*ptr, dev); + blockdev_auto_del(*ptr); + } +} + +static const char *print_drive(void *ptr) +{ + return bdrv_get_device_name(ptr); +} + +static void get_drive(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + get_pointer(obj, v, opaque, print_drive, name, errp); +} + +static void set_drive(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + set_pointer(obj, v, opaque, parse_drive, name, errp); +} + +PropertyInfo qdev_prop_drive = { + .name = "drive", + .get = get_drive, + .set = set_drive, + .release = release_drive, +}; + +/* --- character device --- */ + +static int parse_chr(DeviceState *dev, const char *str, void **ptr) +{ + CharDriverState *chr = qemu_chr_find(str); + if (chr == NULL) { + return -ENOENT; + } + if (chr->avail_connections < 1) { + return -EEXIST; + } + *ptr = chr; + --chr->avail_connections; + return 0; +} + +static void release_chr(Object *obj, const char *name, void *opaque) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); + + if (*ptr) { + qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); + } +} + + +static const char *print_chr(void *ptr) +{ + CharDriverState *chr = ptr; + + return chr->label ? chr->label : ""; +} + +static void get_chr(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + get_pointer(obj, v, opaque, print_chr, name, errp); +} + +static void set_chr(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + set_pointer(obj, v, opaque, parse_chr, name, errp); +} + +PropertyInfo qdev_prop_chr = { + .name = "chr", + .get = get_chr, + .set = set_chr, + .release = release_chr, +}; + +/* --- netdev device --- */ + +static int parse_netdev(DeviceState *dev, const char *str, void **ptr) +{ + NetClientState *netdev = qemu_find_netdev(str); + + if (netdev == NULL) { + return -ENOENT; + } + if (netdev->peer) { + return -EEXIST; + } + *ptr = netdev; + return 0; +} + +static const char *print_netdev(void *ptr) +{ + NetClientState *netdev = ptr; + + return netdev->name ? netdev->name : ""; +} + +static void get_netdev(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + get_pointer(obj, v, opaque, print_netdev, name, errp); +} + +static void set_netdev(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + set_pointer(obj, v, opaque, parse_netdev, name, errp); +} + +PropertyInfo qdev_prop_netdev = { + .name = "netdev", + .get = get_netdev, + .set = set_netdev, +}; + +/* --- vlan --- */ + +static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len) +{ + NetClientState **ptr = qdev_get_prop_ptr(dev, prop); + + if (*ptr) { + int id; + if (!net_hub_id_for_client(*ptr, &id)) { + return snprintf(dest, len, "%d", id); + } + } + + return snprintf(dest, len, "<null>"); +} + +static void get_vlan(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + NetClientState **ptr = qdev_get_prop_ptr(dev, prop); + int32_t id = -1; + + if (*ptr) { + int hub_id; + if (!net_hub_id_for_client(*ptr, &hub_id)) { + id = hub_id; + } + } + + visit_type_int32(v, &id, name, errp); +} + +static void set_vlan(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + NetClientState **ptr = qdev_get_prop_ptr(dev, prop); + Error *local_err = NULL; + int32_t id; + NetClientState *hubport; + + if (dev->state != DEV_STATE_CREATED) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } + + visit_type_int32(v, &id, name, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + if (id == -1) { + *ptr = NULL; + return; + } + + hubport = net_hub_port_find(id); + if (!hubport) { + error_set(errp, QERR_INVALID_PARAMETER_VALUE, + name, prop->info->name); + return; + } + *ptr = hubport; +} + +PropertyInfo qdev_prop_vlan = { + .name = "vlan", + .print = print_vlan, + .get = get_vlan, + .set = set_vlan, +}; + + +int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) +{ + Error *errp = NULL; + const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; + object_property_set_str(OBJECT(dev), bdrv_name, + name, &errp); + if (errp) { + qerror_report_err(errp); + error_free(errp); + return -1; + } + return 0; +} + +void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value) +{ + if (qdev_prop_set_drive(dev, name, value) < 0) { + exit(1); + } +} + +void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value) +{ + Error *errp = NULL; + assert(!value || value->label); + object_property_set_str(OBJECT(dev), + value ? value->label : "", name, &errp); + assert_no_error(errp); +} + +void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value) +{ + Error *errp = NULL; + assert(!value || value->name); + object_property_set_str(OBJECT(dev), + value ? value->name : "", name, &errp); + assert_no_error(errp); +} + +static int qdev_add_one_global(QemuOpts *opts, void *opaque) +{ + GlobalProperty *g; + + g = g_malloc0(sizeof(*g)); + g->driver = qemu_opt_get(opts, "driver"); + g->property = qemu_opt_get(opts, "property"); + g->value = qemu_opt_get(opts, "value"); + qdev_prop_register_global(g); + return 0; +} + +void qemu_add_globals(void) +{ + qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0); +} diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 81d901c..917d986 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -13,49 +13,6 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) return ptr; } -static void get_pointer(Object *obj, Visitor *v, Property *prop, - const char *(*print)(void *ptr), - const char *name, Error **errp) -{ - DeviceState *dev = DEVICE(obj); - void **ptr = qdev_get_prop_ptr(dev, prop); - char *p; - - p = (char *) (*ptr ? print(*ptr) : ""); - visit_type_str(v, &p, name, errp); -} - -static void set_pointer(Object *obj, Visitor *v, Property *prop, - int (*parse)(DeviceState *dev, const char *str, - void **ptr), - const char *name, Error **errp) -{ - DeviceState *dev = DEVICE(obj); - Error *local_err = NULL; - void **ptr = qdev_get_prop_ptr(dev, prop); - char *str; - int ret; - - if (dev->state != DEV_STATE_CREATED) { - error_set(errp, QERR_PERMISSION_DENIED); - return; - } - - visit_type_str(v, &str, name, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - if (!*str) { - g_free(str); - *ptr = NULL; - return; - } - ret = parse(dev, str, ptr); - error_set_from_qdev_prop_error(errp, ret, dev, prop, str); - g_free(str); -} - static void get_enum(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { @@ -476,227 +433,6 @@ PropertyInfo qdev_prop_string = { .set = set_string, }; -/* --- drive --- */ - -static int parse_drive(DeviceState *dev, const char *str, void **ptr) -{ - BlockDriverState *bs; - - bs = bdrv_find(str); - if (bs == NULL) - return -ENOENT; - if (bdrv_attach_dev(bs, dev) < 0) - return -EEXIST; - *ptr = bs; - return 0; -} - -static void release_drive(Object *obj, const char *name, void *opaque) -{ - DeviceState *dev = DEVICE(obj); - Property *prop = opaque; - BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); - - if (*ptr) { - bdrv_detach_dev(*ptr, dev); - blockdev_auto_del(*ptr); - } -} - -static const char *print_drive(void *ptr) -{ - return bdrv_get_device_name(ptr); -} - -static void get_drive(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - get_pointer(obj, v, opaque, print_drive, name, errp); -} - -static void set_drive(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - set_pointer(obj, v, opaque, parse_drive, name, errp); -} - -PropertyInfo qdev_prop_drive = { - .name = "drive", - .get = get_drive, - .set = set_drive, - .release = release_drive, -}; - -/* --- character device --- */ - -static int parse_chr(DeviceState *dev, const char *str, void **ptr) -{ - CharDriverState *chr = qemu_chr_find(str); - if (chr == NULL) { - return -ENOENT; - } - if (chr->avail_connections < 1) { - return -EEXIST; - } - *ptr = chr; - --chr->avail_connections; - return 0; -} - -static void release_chr(Object *obj, const char *name, void *opaque) -{ - DeviceState *dev = DEVICE(obj); - Property *prop = opaque; - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); - - if (*ptr) { - qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); - } -} - - -static const char *print_chr(void *ptr) -{ - CharDriverState *chr = ptr; - - return chr->label ? chr->label : ""; -} - -static void get_chr(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - get_pointer(obj, v, opaque, print_chr, name, errp); -} - -static void set_chr(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - set_pointer(obj, v, opaque, parse_chr, name, errp); -} - -PropertyInfo qdev_prop_chr = { - .name = "chr", - .get = get_chr, - .set = set_chr, - .release = release_chr, -}; - -/* --- netdev device --- */ - -static int parse_netdev(DeviceState *dev, const char *str, void **ptr) -{ - NetClientState *netdev = qemu_find_netdev(str); - - if (netdev == NULL) { - return -ENOENT; - } - if (netdev->peer) { - return -EEXIST; - } - *ptr = netdev; - return 0; -} - -static const char *print_netdev(void *ptr) -{ - NetClientState *netdev = ptr; - - return netdev->name ? netdev->name : ""; -} - -static void get_netdev(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - get_pointer(obj, v, opaque, print_netdev, name, errp); -} - -static void set_netdev(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - set_pointer(obj, v, opaque, parse_netdev, name, errp); -} - -PropertyInfo qdev_prop_netdev = { - .name = "netdev", - .get = get_netdev, - .set = set_netdev, -}; - -/* --- vlan --- */ - -static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len) -{ - NetClientState **ptr = qdev_get_prop_ptr(dev, prop); - - if (*ptr) { - int id; - if (!net_hub_id_for_client(*ptr, &id)) { - return snprintf(dest, len, "%d", id); - } - } - - return snprintf(dest, len, "<null>"); -} - -static void get_vlan(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState *dev = DEVICE(obj); - Property *prop = opaque; - NetClientState **ptr = qdev_get_prop_ptr(dev, prop); - int32_t id = -1; - - if (*ptr) { - int hub_id; - if (!net_hub_id_for_client(*ptr, &hub_id)) { - id = hub_id; - } - } - - visit_type_int32(v, &id, name, errp); -} - -static void set_vlan(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState *dev = DEVICE(obj); - Property *prop = opaque; - NetClientState **ptr = qdev_get_prop_ptr(dev, prop); - Error *local_err = NULL; - int32_t id; - NetClientState *hubport; - - if (dev->state != DEV_STATE_CREATED) { - error_set(errp, QERR_PERMISSION_DENIED); - return; - } - - visit_type_int32(v, &id, name, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - if (id == -1) { - *ptr = NULL; - return; - } - - hubport = net_hub_port_find(id); - if (!hubport) { - error_set(errp, QERR_INVALID_PARAMETER_VALUE, - name, prop->info->name); - return; - } - *ptr = hubport; -} - -PropertyInfo qdev_prop_vlan = { - .name = "vlan", - .print = print_vlan, - .get = get_vlan, - .set = set_vlan, -}; - /* --- pointer --- */ /* Not a proper property, just for dirty hacks. TODO Remove it! */ @@ -1158,44 +894,6 @@ void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) assert_no_error(errp); } -int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) -{ - Error *errp = NULL; - const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; - object_property_set_str(OBJECT(dev), bdrv_name, - name, &errp); - if (errp) { - qerror_report_err(errp); - error_free(errp); - return -1; - } - return 0; -} - -void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value) -{ - if (qdev_prop_set_drive(dev, name, value) < 0) { - exit(1); - } -} -void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value) -{ - Error *errp = NULL; - assert(!value || value->label); - object_property_set_str(OBJECT(dev), - value ? value->label : "", name, &errp); - assert_no_error(errp); -} - -void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value) -{ - Error *errp = NULL; - assert(!value || value->name); - object_property_set_str(OBJECT(dev), - value ? value->name : "", name, &errp); - assert_no_error(errp); -} - void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value) { Error *errp = NULL; @@ -1231,7 +929,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props); -static void qdev_prop_register_global(GlobalProperty *prop) +void qdev_prop_register_global(GlobalProperty *prop) { QTAILQ_INSERT_TAIL(&global_props, prop, next); } @@ -1263,19 +961,3 @@ void qdev_prop_set_globals(DeviceState *dev) } while (class); } -static int qdev_add_one_global(QemuOpts *opts, void *opaque) -{ - GlobalProperty *g; - - g = g_malloc0(sizeof(*g)); - g->driver = qemu_opt_get(opts, "driver"); - g->property = qemu_opt_get(opts, "property"); - g->value = qemu_opt_get(opts, "value"); - qdev_prop_register_global(g); - return 0; -} - -void qemu_add_globals(void) -{ - qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0); -} diff --git a/hw/qdev-properties.h b/hw/qdev-properties.h index e93336a..a145084 100644 --- a/hw/qdev-properties.h +++ b/hw/qdev-properties.h @@ -114,6 +114,7 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value); /* FIXME: Remove opaque pointer properties. */ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); +void qdev_prop_register_global(GlobalProperty *prop); void qdev_prop_register_global_list(GlobalProperty *props); void qdev_prop_set_globals(DeviceState *dev); void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, diff --git a/hw/qdev-system.c b/hw/qdev-system.c new file mode 100644 index 0000000..4891d2f --- /dev/null +++ b/hw/qdev-system.c @@ -0,0 +1,93 @@ +#include "net.h" +#include "qdev.h" + +void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) +{ + assert(dev->num_gpio_in == 0); + dev->num_gpio_in = n; + dev->gpio_in = qemu_allocate_irqs(handler, dev, n); +} + +void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n) +{ + assert(dev->num_gpio_out == 0); + dev->num_gpio_out = n; + dev->gpio_out = pins; +} + +qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) +{ + assert(n >= 0 && n < dev->num_gpio_in); + return dev->gpio_in[n]; +} + +void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) +{ + assert(n >= 0 && n < dev->num_gpio_out); + dev->gpio_out[n] = pin; +} + +void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) +{ + qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a); + if (nd->netdev) + qdev_prop_set_netdev(dev, "netdev", nd->netdev); + if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED && + object_property_find(OBJECT(dev), "vectors", NULL)) { + qdev_prop_set_uint32(dev, "vectors", nd->nvectors); + } + nd->instantiated = 1; +} + +BusState *qdev_get_child_bus(DeviceState *dev, const char *name) +{ + BusState *bus; + + QLIST_FOREACH(bus, &dev->child_bus, sibling) { + if (strcmp(name, bus->name) == 0) { + return bus; + } + } + return NULL; +} + +/* Create a new device. This only initializes the device state structure + and allows properties to be set. qdev_init should be called to + initialize the actual device emulation. */ +DeviceState *qdev_create(BusState *bus, const char *name) +{ + DeviceState *dev; + + dev = qdev_try_create(bus, name); + if (!dev) { + if (bus) { + hw_error("Unknown device ''%s'' for bus ''%s''\n", name, + object_get_typename(OBJECT(bus))); + } else { + hw_error("Unknown device ''%s'' for default sysbus\n", name); + } + } + + return dev; +} + +DeviceState *qdev_try_create(BusState *bus, const char *type) +{ + DeviceState *dev; + + if (object_class_by_name(type) == NULL) { + return NULL; + } + dev = DEVICE(object_new(type)); + if (!dev) { + return NULL; + } + + if (!bus) { + bus = sysbus_get_default(); + } + + qdev_set_parent_bus(dev, bus); + + return dev; +} diff --git a/hw/qdev.c b/hw/qdev.c index 36c3e4b..3dc38f7 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -25,7 +25,6 @@ inherit from a particular bus (e.g. PCI or I2C) rather than this API directly. */ -#include "net.h" #include "qdev.h" #include "sysemu.h" #include "error.h" @@ -105,47 +104,6 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus) bus_add_child(bus, dev); } -/* Create a new device. This only initializes the device state structure - and allows properties to be set. qdev_init should be called to - initialize the actual device emulation. */ -DeviceState *qdev_create(BusState *bus, const char *name) -{ - DeviceState *dev; - - dev = qdev_try_create(bus, name); - if (!dev) { - if (bus) { - hw_error("Unknown device ''%s'' for bus ''%s''\n", name, - object_get_typename(OBJECT(bus))); - } else { - hw_error("Unknown device ''%s'' for default sysbus\n", name); - } - } - - return dev; -} - -DeviceState *qdev_try_create(BusState *bus, const char *type) -{ - DeviceState *dev; - - if (object_class_by_name(type) == NULL) { - return NULL; - } - dev = DEVICE(object_new(type)); - if (!dev) { - return NULL; - } - - if (!bus) { - bus = sysbus_get_default(); - } - - qdev_set_parent_bus(dev, bus); - - return dev; -} - /* Initialize a device. Device properties should be set before calling this function. IRQs and MMIO regions should be connected/mapped after calling this function. @@ -175,11 +133,13 @@ int qdev_init(DeviceState *dev) g_free(name); } +#ifndef CONFIG_USER_ONLY 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); } +#endif dev->state = DEV_STATE_INITIALIZED; if (dev->hotplugged) { device_reset(dev); @@ -292,56 +252,6 @@ BusState *qdev_get_parent_bus(DeviceState *dev) return dev->parent_bus; } -void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) -{ - assert(dev->num_gpio_in == 0); - dev->num_gpio_in = n; - dev->gpio_in = qemu_allocate_irqs(handler, dev, n); -} - -void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n) -{ - assert(dev->num_gpio_out == 0); - dev->num_gpio_out = n; - dev->gpio_out = pins; -} - -qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) -{ - assert(n >= 0 && n < dev->num_gpio_in); - return dev->gpio_in[n]; -} - -void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) -{ - assert(n >= 0 && n < dev->num_gpio_out); - dev->gpio_out[n] = pin; -} - -void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) -{ - qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a); - if (nd->netdev) - qdev_prop_set_netdev(dev, "netdev", nd->netdev); - if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED && - object_property_find(OBJECT(dev), "vectors", NULL)) { - qdev_prop_set_uint32(dev, "vectors", nd->nvectors); - } - nd->instantiated = 1; -} - -BusState *qdev_get_child_bus(DeviceState *dev, const char *name) -{ - BusState *bus; - - QLIST_FOREACH(bus, &dev->child_bus, sibling) { - if (strcmp(name, bus->name) == 0) { - return bus; - } - } - return NULL; -} - int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, qbus_walkerfn *busfn, void *opaque) { @@ -440,11 +350,14 @@ 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()) { + } +#ifndef CONFIG_USER_ONLY + 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); } +#endif } void qbus_create_inplace(BusState *bus, const char *typename, @@ -703,9 +616,11 @@ static void device_finalize(Object *obj) bus = QLIST_FIRST(&dev->child_bus); qbus_free(bus); } +#ifndef CONFIG_USER_ONLY if (qdev_get_vmsd(dev)) { vmstate_unregister(dev, qdev_get_vmsd(dev), dev); } +#endif if (dc->exit) { dc->exit(dev); } @@ -779,8 +694,10 @@ static void qbus_finalize(Object *obj) QLIST_REMOVE(bus, sibling); bus->parent->num_child_bus--; } else { +#ifndef CONFIG_USER_ONLY assert(bus != sysbus_get_default()); /* main_system_bus is never freed */ qemu_unregister_reset(qbus_reset_all_fn, bus); +#endif } g_free((char *)bus->name); } -- 1.7.11.4
Eduardo Habkost
2012-Aug-21 15:43 UTC
[RFC 6/8] qdev: use full qdev.h include path on qdev*.c
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- hw/qdev-properties.c | 2 +- hw/qdev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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" diff --git a/hw/qdev.c b/hw/qdev.c index 3dc38f7..ebe6671 100644 --- a/hw/qdev.c +++ b/hw/qdev.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" -- 1.7.11.4
The code depends on some functions from qemu-option.o, so add qemu-option.o to qom-obj-y to make sure it''s included. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- Makefile.objs | 1 + hw/Makefile.objs | 2 +- qom/Makefile.objs | 2 +- hw/qdev-properties.c => qom/device-properties.c | 0 hw/qdev.c => qom/device.c | 0 5 files changed, 3 insertions(+), 2 deletions(-) rename hw/qdev-properties.c => qom/device-properties.c (100%) rename hw/qdev.c => qom/device.c (100%) diff --git a/Makefile.objs b/Makefile.objs index 4412757..2cf91c2 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -14,6 +14,7 @@ universal-obj-y += $(qobject-obj-y) ####################################################################### # QOM qom-obj-y = qom/ +qom-obj-y += qemu-option.o universal-obj-y += $(qom-obj-y) diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 04d3b5e..c09e291 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -176,7 +176,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-monitor.o common-obj-y += qdev-system.o qdev-properties-system.o common-obj-$(CONFIG_BRLAPI) += baum.o diff --git a/qom/Makefile.objs b/qom/Makefile.objs index 5ef060a..9d86d88 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 device.o device-properties.o common-obj-y = $(qom-obj-twice-y) user-obj-y = $(qom-obj-twice-y) diff --git a/hw/qdev-properties.c b/qom/device-properties.c similarity index 100% rename from hw/qdev-properties.c rename to qom/device-properties.c diff --git a/hw/qdev.c b/qom/device.c similarity index 100% rename from hw/qdev.c rename to qom/device.c -- 1.7.11.4
From: Igor Mammedov <imammedo@redhat.com> [ehabkost: change CPU type declaration to hae TYPE_DEVICE as parent] Signed-off-by: Igor Mammedov <imammedo@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- 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.4
Peter Maydell
2012-Aug-21 16:10 UTC
Re: [RFC 1/8] move qemu_irq typedef out of cpu-common.h
On 21 August 2012 16:42, Eduardo Habkost <ehabkost@redhat.com> wrote:> diff --git a/qemu-common.h b/qemu-common.h > index e5c2bcd..6677a30 100644 > --- a/qemu-common.h > +++ b/qemu-common.h > @@ -273,7 +273,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; > diff --git a/sysemu.h b/sysemu.h > index 65552ac..f765821 100644 > --- a/sysemu.h > +++ b/sysemu.h > @@ -9,6 +9,7 @@ > #include "qapi-types.h" > #include "notify.h" > #include "main-loop.h" > +#include "hw/irq.h" > > /* vl.c */I''m not objecting to this patch if it helps us move forwards, but adding the #include to sysemu.h is effectively just adding the definition to another grabbag header (183 files include sysemu.h). It would be nicer long-term to separate out the one thing in this header that cares about qemu_irq (the extern declaration of qemu_system_powerdown). [I''m not really convinced that a qemu_irq is even the right way to signal "hey the system has actually powered down now"...] -- PMM
Peter Maydell
2012-Aug-21 16:29 UTC
Re: [RFC 6/8] qdev: use full qdev.h include path on qdev*.c
On 21 August 2012 16:43, Eduardo Habkost <ehabkost@redhat.com> wrote:> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>This could use a commit message saying why rather than merely what the patch does. -- PMM
Peter Maydell
2012-Aug-21 16:45 UTC
Re: [RFC 4/8] cleanup error.h, included qapi-types.h aready has stdbool.h
On 21 August 2012 16:42, Eduardo Habkost <ehabkost@redhat.com> wrote:> From: Igor Mammedov <imammedo@redhat.com> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>I thought we''d agreed to drop this patch? http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg03644.html -- PMM
Eduardo Habkost
2012-Aug-21 16:53 UTC
Re: [RFC 4/8] cleanup error.h, included qapi-types.h aready has stdbool.h
On Tue, Aug 21, 2012 at 05:45:26PM +0100, Peter Maydell wrote:> On 21 August 2012 16:42, Eduardo Habkost <ehabkost@redhat.com> wrote: > > From: Igor Mammedov <imammedo@redhat.com> > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com> > > I thought we''d agreed to drop this patch? > http://lists.gnu.org/archive/html/qemu-devel/2012-08/msg03644.htmlSure. I just used the existing series as base. The main point is to ask for comments about the last 4 patches. -- Eduardo
On 21 August 2012 16:43, Eduardo Habkost <ehabkost@redhat.com> wrote:> The code depends on some functions from qemu-option.o, so add > qemu-option.o to qom-obj-y to make sure it''s included. > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > --- > Makefile.objs | 1 + > hw/Makefile.objs | 2 +- > qom/Makefile.objs | 2 +- > hw/qdev-properties.c => qom/device-properties.c | 0 > hw/qdev.c => qom/device.c | 0 > 5 files changed, 3 insertions(+), 2 deletions(-) > rename hw/qdev-properties.c => qom/device-properties.c (100%) > rename hw/qdev.c => qom/device.c (100%) > > diff --git a/Makefile.objs b/Makefile.objs > index 4412757..2cf91c2 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -14,6 +14,7 @@ universal-obj-y += $(qobject-obj-y) > ####################################################################### > # QOM > qom-obj-y = qom/ > +qom-obj-y += qemu-option.oqemu-option.c isn''t actually QOM related code... -- PMM
Luiz Capitulino
2012-Aug-21 18:21 UTC
Re: [RFC 3/8] qapi-types.h doesn''t really need to include qemu-common.h
On Tue, 21 Aug 2012 12:42:57 -0300 Eduardo Habkost <ehabkost@redhat.com> wrote:> 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> > --- > scripts/qapi-types.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py > index cf601ae..f34addb 100644 > --- a/scripts/qapi-types.py > +++ b/scripts/qapi-types.py > @@ -263,7 +263,7 @@ fdecl.write(mcgen('''''' > #ifndef %(guard)s > #define %(guard)s > > -#include "qemu-common.h" > +#include <stdbool.h>Case you didn''t notice my last review: we should also include <stdint.h> here.> > '''''', > guard=guardname(h_file)))
Eduardo Habkost
2012-Aug-21 18:25 UTC
Re: [RFC 6/8] qdev: use full qdev.h include path on qdev*.c
On Tue, Aug 21, 2012 at 05:29:41PM +0100, Peter Maydell wrote:> On 21 August 2012 16:43, Eduardo Habkost <ehabkost@redhat.com> wrote: > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > > This could use a commit message saying why rather than merely > what the patch does.Sorry. The reason is to allow the files to be moved inside "qom/" in the next commit. -- Eduardo
Blue Swirl
2012-Aug-21 18:44 UTC
Re: [RFC 5/8] split qdev into a core and code used only by qemu-system-*
On Tue, Aug 21, 2012 at 3:42 PM, Eduardo Habkost <ehabkost@redhat.com> wrote:> This also makes it visible what are the parts of qdev that we may want > to split more cleanly (as they are using #ifdefs, now).Nice.> > There are basically two parts that are specific to qemu-system-*, but > are still inside qdev.c (but inside a "#ifndef CONFIG_USER_ONLY"). > > - vmstate handling > - reset function registration > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > --- > hw/Makefile.objs | 1 + > hw/qdev-properties-system.c | 329 ++++++++++++++++++++++++++++++++++++++++++++ > hw/qdev-properties.c | 320 +----------------------------------------- > hw/qdev-properties.h | 1 + > hw/qdev-system.c | 93 +++++++++++++ > hw/qdev.c | 103 ++------------ > 6 files changed, 435 insertions(+), 412 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 7f57ed5..04d3b5e 100644 > --- a/hw/Makefile.objs > +++ b/hw/Makefile.objs > @@ -177,6 +177,7 @@ common-obj-y += bt.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o > common-obj-y += bt-hci-csr.o > common-obj-y += msmouse.o ps2.o > common-obj-y += qdev.o qdev-properties.o qdev-monitor.o > +common-obj-y += qdev-system.o qdev-properties-system.o > common-obj-$(CONFIG_BRLAPI) += baum.o > > # xen backend driver support > diff --git a/hw/qdev-properties-system.c b/hw/qdev-properties-system.c > new file mode 100644 > index 0000000..c42e656 > --- /dev/null > +++ b/hw/qdev-properties-system.c > @@ -0,0 +1,329 @@There''s no header, neither has qdev-properties.c though. Agreeing on license would need some detective work.> +#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;Before moving, please add braces here and below if. That way the new file gets a fresh start.> + if (bdrv_attach_dev(bs, dev) < 0) > + return -EEXIST; > + *ptr = bs; > + return 0; > +} > + > +static void release_drive(Object *obj, const char *name, void *opaque) > +{ > + DeviceState *dev = DEVICE(obj); > + Property *prop = opaque; > + BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); > + > + if (*ptr) { > + bdrv_detach_dev(*ptr, dev); > + blockdev_auto_del(*ptr); > + } > +} > + > +static const char *print_drive(void *ptr) > +{ > + return bdrv_get_device_name(ptr); > +} > + > +static void get_drive(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + get_pointer(obj, v, opaque, print_drive, name, errp); > +} > + > +static void set_drive(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + set_pointer(obj, v, opaque, parse_drive, name, errp); > +} > + > +PropertyInfo qdev_prop_drive = { > + .name = "drive", > + .get = get_drive, > + .set = set_drive, > + .release = release_drive, > +}; > + > +/* --- character device --- */ > + > +static int parse_chr(DeviceState *dev, const char *str, void **ptr) > +{ > + CharDriverState *chr = qemu_chr_find(str); > + if (chr == NULL) { > + return -ENOENT; > + } > + if (chr->avail_connections < 1) { > + return -EEXIST; > + } > + *ptr = chr; > + --chr->avail_connections; > + return 0; > +} > + > +static void release_chr(Object *obj, const char *name, void *opaque) > +{ > + DeviceState *dev = DEVICE(obj); > + Property *prop = opaque; > + CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); > + > + if (*ptr) { > + qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); > + } > +} > + > + > +static const char *print_chr(void *ptr) > +{ > + CharDriverState *chr = ptr; > + > + return chr->label ? chr->label : ""; > +} > + > +static void get_chr(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + get_pointer(obj, v, opaque, print_chr, name, errp); > +} > + > +static void set_chr(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + set_pointer(obj, v, opaque, parse_chr, name, errp); > +} > + > +PropertyInfo qdev_prop_chr = { > + .name = "chr", > + .get = get_chr, > + .set = set_chr, > + .release = release_chr, > +}; > + > +/* --- netdev device --- */ > + > +static int parse_netdev(DeviceState *dev, const char *str, void **ptr) > +{ > + NetClientState *netdev = qemu_find_netdev(str); > + > + if (netdev == NULL) { > + return -ENOENT; > + } > + if (netdev->peer) { > + return -EEXIST; > + } > + *ptr = netdev; > + return 0; > +} > + > +static const char *print_netdev(void *ptr) > +{ > + NetClientState *netdev = ptr; > + > + return netdev->name ? netdev->name : ""; > +} > + > +static void get_netdev(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + get_pointer(obj, v, opaque, print_netdev, name, errp); > +} > + > +static void set_netdev(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + set_pointer(obj, v, opaque, parse_netdev, name, errp); > +} > + > +PropertyInfo qdev_prop_netdev = { > + .name = "netdev", > + .get = get_netdev, > + .set = set_netdev, > +}; > + > +/* --- vlan --- */ > + > +static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len) > +{ > + NetClientState **ptr = qdev_get_prop_ptr(dev, prop); > + > + if (*ptr) { > + int id; > + if (!net_hub_id_for_client(*ptr, &id)) { > + return snprintf(dest, len, "%d", id); > + } > + } > + > + return snprintf(dest, len, "<null>"); > +} > + > +static void get_vlan(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + DeviceState *dev = DEVICE(obj); > + Property *prop = opaque; > + NetClientState **ptr = qdev_get_prop_ptr(dev, prop); > + int32_t id = -1; > + > + if (*ptr) { > + int hub_id; > + if (!net_hub_id_for_client(*ptr, &hub_id)) { > + id = hub_id; > + } > + } > + > + visit_type_int32(v, &id, name, errp); > +} > + > +static void set_vlan(Object *obj, Visitor *v, void *opaque, > + const char *name, Error **errp) > +{ > + DeviceState *dev = DEVICE(obj); > + Property *prop = opaque; > + NetClientState **ptr = qdev_get_prop_ptr(dev, prop); > + Error *local_err = NULL; > + int32_t id; > + NetClientState *hubport; > + > + if (dev->state != DEV_STATE_CREATED) { > + error_set(errp, QERR_PERMISSION_DENIED); > + return; > + } > + > + visit_type_int32(v, &id, name, &local_err); > + if (local_err) { > + error_propagate(errp, local_err); > + return; > + } > + if (id == -1) { > + *ptr = NULL; > + return; > + } > + > + hubport = net_hub_port_find(id); > + if (!hubport) { > + error_set(errp, QERR_INVALID_PARAMETER_VALUE, > + name, prop->info->name); > + return; > + } > + *ptr = hubport; > +} > + > +PropertyInfo qdev_prop_vlan = { > + .name = "vlan", > + .print = print_vlan, > + .get = get_vlan, > + .set = set_vlan, > +}; > + > + > +int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) > +{ > + Error *errp = NULL; > + const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; > + object_property_set_str(OBJECT(dev), bdrv_name, > + name, &errp); > + if (errp) { > + qerror_report_err(errp); > + error_free(errp); > + return -1; > + } > + return 0; > +} > + > +void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value) > +{ > + if (qdev_prop_set_drive(dev, name, value) < 0) { > + exit(1); > + } > +} > + > +void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value) > +{ > + Error *errp = NULL; > + assert(!value || value->label); > + object_property_set_str(OBJECT(dev), > + value ? value->label : "", name, &errp); > + assert_no_error(errp); > +} > + > +void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value) > +{ > + Error *errp = NULL; > + assert(!value || value->name); > + object_property_set_str(OBJECT(dev), > + value ? value->name : "", name, &errp); > + assert_no_error(errp); > +} > + > +static int qdev_add_one_global(QemuOpts *opts, void *opaque) > +{ > + GlobalProperty *g; > + > + g = g_malloc0(sizeof(*g)); > + g->driver = qemu_opt_get(opts, "driver"); > + g->property = qemu_opt_get(opts, "property"); > + g->value = qemu_opt_get(opts, "value"); > + qdev_prop_register_global(g); > + return 0; > +} > + > +void qemu_add_globals(void) > +{ > + qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0); > +} > diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c > index 81d901c..917d986 100644 > --- a/hw/qdev-properties.c > +++ b/hw/qdev-properties.c > @@ -13,49 +13,6 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) > return ptr; > } > > -static void get_pointer(Object *obj, Visitor *v, Property *prop, > - const char *(*print)(void *ptr), > - const char *name, Error **errp) > -{ > - DeviceState *dev = DEVICE(obj); > - void **ptr = qdev_get_prop_ptr(dev, prop); > - char *p; > - > - p = (char *) (*ptr ? print(*ptr) : ""); > - visit_type_str(v, &p, name, errp); > -} > - > -static void set_pointer(Object *obj, Visitor *v, Property *prop, > - int (*parse)(DeviceState *dev, const char *str, > - void **ptr), > - const char *name, Error **errp) > -{ > - DeviceState *dev = DEVICE(obj); > - Error *local_err = NULL; > - void **ptr = qdev_get_prop_ptr(dev, prop); > - char *str; > - int ret; > - > - if (dev->state != DEV_STATE_CREATED) { > - error_set(errp, QERR_PERMISSION_DENIED); > - return; > - } > - > - visit_type_str(v, &str, name, &local_err); > - if (local_err) { > - error_propagate(errp, local_err); > - return; > - } > - if (!*str) { > - g_free(str); > - *ptr = NULL; > - return; > - } > - ret = parse(dev, str, ptr); > - error_set_from_qdev_prop_error(errp, ret, dev, prop, str); > - g_free(str); > -} > - > static void get_enum(Object *obj, Visitor *v, void *opaque, > const char *name, Error **errp) > { > @@ -476,227 +433,6 @@ PropertyInfo qdev_prop_string = { > .set = set_string, > }; > > -/* --- drive --- */ > - > -static int parse_drive(DeviceState *dev, const char *str, void **ptr) > -{ > - BlockDriverState *bs; > - > - bs = bdrv_find(str); > - if (bs == NULL) > - return -ENOENT; > - if (bdrv_attach_dev(bs, dev) < 0) > - return -EEXIST; > - *ptr = bs; > - return 0; > -} > - > -static void release_drive(Object *obj, const char *name, void *opaque) > -{ > - DeviceState *dev = DEVICE(obj); > - Property *prop = opaque; > - BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop); > - > - if (*ptr) { > - bdrv_detach_dev(*ptr, dev); > - blockdev_auto_del(*ptr); > - } > -} > - > -static const char *print_drive(void *ptr) > -{ > - return bdrv_get_device_name(ptr); > -} > - > -static void get_drive(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - get_pointer(obj, v, opaque, print_drive, name, errp); > -} > - > -static void set_drive(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - set_pointer(obj, v, opaque, parse_drive, name, errp); > -} > - > -PropertyInfo qdev_prop_drive = { > - .name = "drive", > - .get = get_drive, > - .set = set_drive, > - .release = release_drive, > -}; > - > -/* --- character device --- */ > - > -static int parse_chr(DeviceState *dev, const char *str, void **ptr) > -{ > - CharDriverState *chr = qemu_chr_find(str); > - if (chr == NULL) { > - return -ENOENT; > - } > - if (chr->avail_connections < 1) { > - return -EEXIST; > - } > - *ptr = chr; > - --chr->avail_connections; > - return 0; > -} > - > -static void release_chr(Object *obj, const char *name, void *opaque) > -{ > - DeviceState *dev = DEVICE(obj); > - Property *prop = opaque; > - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); > - > - if (*ptr) { > - qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL); > - } > -} > - > - > -static const char *print_chr(void *ptr) > -{ > - CharDriverState *chr = ptr; > - > - return chr->label ? chr->label : ""; > -} > - > -static void get_chr(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - get_pointer(obj, v, opaque, print_chr, name, errp); > -} > - > -static void set_chr(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - set_pointer(obj, v, opaque, parse_chr, name, errp); > -} > - > -PropertyInfo qdev_prop_chr = { > - .name = "chr", > - .get = get_chr, > - .set = set_chr, > - .release = release_chr, > -}; > - > -/* --- netdev device --- */ > - > -static int parse_netdev(DeviceState *dev, const char *str, void **ptr) > -{ > - NetClientState *netdev = qemu_find_netdev(str); > - > - if (netdev == NULL) { > - return -ENOENT; > - } > - if (netdev->peer) { > - return -EEXIST; > - } > - *ptr = netdev; > - return 0; > -} > - > -static const char *print_netdev(void *ptr) > -{ > - NetClientState *netdev = ptr; > - > - return netdev->name ? netdev->name : ""; > -} > - > -static void get_netdev(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - get_pointer(obj, v, opaque, print_netdev, name, errp); > -} > - > -static void set_netdev(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - set_pointer(obj, v, opaque, parse_netdev, name, errp); > -} > - > -PropertyInfo qdev_prop_netdev = { > - .name = "netdev", > - .get = get_netdev, > - .set = set_netdev, > -}; > - > -/* --- vlan --- */ > - > -static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len) > -{ > - NetClientState **ptr = qdev_get_prop_ptr(dev, prop); > - > - if (*ptr) { > - int id; > - if (!net_hub_id_for_client(*ptr, &id)) { > - return snprintf(dest, len, "%d", id); > - } > - } > - > - return snprintf(dest, len, "<null>"); > -} > - > -static void get_vlan(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - DeviceState *dev = DEVICE(obj); > - Property *prop = opaque; > - NetClientState **ptr = qdev_get_prop_ptr(dev, prop); > - int32_t id = -1; > - > - if (*ptr) { > - int hub_id; > - if (!net_hub_id_for_client(*ptr, &hub_id)) { > - id = hub_id; > - } > - } > - > - visit_type_int32(v, &id, name, errp); > -} > - > -static void set_vlan(Object *obj, Visitor *v, void *opaque, > - const char *name, Error **errp) > -{ > - DeviceState *dev = DEVICE(obj); > - Property *prop = opaque; > - NetClientState **ptr = qdev_get_prop_ptr(dev, prop); > - Error *local_err = NULL; > - int32_t id; > - NetClientState *hubport; > - > - if (dev->state != DEV_STATE_CREATED) { > - error_set(errp, QERR_PERMISSION_DENIED); > - return; > - } > - > - visit_type_int32(v, &id, name, &local_err); > - if (local_err) { > - error_propagate(errp, local_err); > - return; > - } > - if (id == -1) { > - *ptr = NULL; > - return; > - } > - > - hubport = net_hub_port_find(id); > - if (!hubport) { > - error_set(errp, QERR_INVALID_PARAMETER_VALUE, > - name, prop->info->name); > - return; > - } > - *ptr = hubport; > -} > - > -PropertyInfo qdev_prop_vlan = { > - .name = "vlan", > - .print = print_vlan, > - .get = get_vlan, > - .set = set_vlan, > -}; > - > /* --- pointer --- */ > > /* Not a proper property, just for dirty hacks. TODO Remove it! */ > @@ -1158,44 +894,6 @@ void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value) > assert_no_error(errp); > } > > -int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) > -{ > - Error *errp = NULL; > - const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; > - object_property_set_str(OBJECT(dev), bdrv_name, > - name, &errp); > - if (errp) { > - qerror_report_err(errp); > - error_free(errp); > - return -1; > - } > - return 0; > -} > - > -void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value) > -{ > - if (qdev_prop_set_drive(dev, name, value) < 0) { > - exit(1); > - } > -} > -void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value) > -{ > - Error *errp = NULL; > - assert(!value || value->label); > - object_property_set_str(OBJECT(dev), > - value ? value->label : "", name, &errp); > - assert_no_error(errp); > -} > - > -void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value) > -{ > - Error *errp = NULL; > - assert(!value || value->name); > - object_property_set_str(OBJECT(dev), > - value ? value->name : "", name, &errp); > - assert_no_error(errp); > -} > - > void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value) > { > Error *errp = NULL; > @@ -1231,7 +929,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value) > > static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props); > > -static void qdev_prop_register_global(GlobalProperty *prop) > +void qdev_prop_register_global(GlobalProperty *prop) > { > QTAILQ_INSERT_TAIL(&global_props, prop, next); > } > @@ -1263,19 +961,3 @@ void qdev_prop_set_globals(DeviceState *dev) > } while (class); > } > > -static int qdev_add_one_global(QemuOpts *opts, void *opaque) > -{ > - GlobalProperty *g; > - > - g = g_malloc0(sizeof(*g)); > - g->driver = qemu_opt_get(opts, "driver"); > - g->property = qemu_opt_get(opts, "property"); > - g->value = qemu_opt_get(opts, "value"); > - qdev_prop_register_global(g); > - return 0; > -} > - > -void qemu_add_globals(void) > -{ > - qemu_opts_foreach(qemu_find_opts("global"), qdev_add_one_global, NULL, 0); > -} > diff --git a/hw/qdev-properties.h b/hw/qdev-properties.h > index e93336a..a145084 100644 > --- a/hw/qdev-properties.h > +++ b/hw/qdev-properties.h > @@ -114,6 +114,7 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value); > /* FIXME: Remove opaque pointer properties. */ > void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); > > +void qdev_prop_register_global(GlobalProperty *prop); > void qdev_prop_register_global_list(GlobalProperty *props); > void qdev_prop_set_globals(DeviceState *dev); > void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, > diff --git a/hw/qdev-system.c b/hw/qdev-system.c > new file mode 100644 > index 0000000..4891d2f > --- /dev/null > +++ b/hw/qdev-system.c > @@ -0,0 +1,93 @@ > +#include "net.h" > +#include "qdev.h" > + > +void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) > +{ > + assert(dev->num_gpio_in == 0); > + dev->num_gpio_in = n; > + dev->gpio_in = qemu_allocate_irqs(handler, dev, n); > +} > + > +void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n) > +{ > + assert(dev->num_gpio_out == 0); > + dev->num_gpio_out = n; > + dev->gpio_out = pins; > +} > + > +qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) > +{ > + assert(n >= 0 && n < dev->num_gpio_in); > + return dev->gpio_in[n]; > +} > + > +void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) > +{ > + assert(n >= 0 && n < dev->num_gpio_out); > + dev->gpio_out[n] = pin; > +} > + > +void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) > +{ > + qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a); > + if (nd->netdev) > + qdev_prop_set_netdev(dev, "netdev", nd->netdev);Also here.> + if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED && > + object_property_find(OBJECT(dev), "vectors", NULL)) { > + qdev_prop_set_uint32(dev, "vectors", nd->nvectors); > + } > + nd->instantiated = 1; > +} > + > +BusState *qdev_get_child_bus(DeviceState *dev, const char *name) > +{ > + BusState *bus; > + > + QLIST_FOREACH(bus, &dev->child_bus, sibling) { > + if (strcmp(name, bus->name) == 0) { > + return bus; > + } > + } > + return NULL; > +} > + > +/* Create a new device. This only initializes the device state structure > + and allows properties to be set. qdev_init should be called to > + initialize the actual device emulation. */ > +DeviceState *qdev_create(BusState *bus, const char *name) > +{ > + DeviceState *dev; > + > + dev = qdev_try_create(bus, name); > + if (!dev) { > + if (bus) { > + hw_error("Unknown device ''%s'' for bus ''%s''\n", name, > + object_get_typename(OBJECT(bus))); > + } else { > + hw_error("Unknown device ''%s'' for default sysbus\n", name); > + } > + } > + > + return dev; > +} > + > +DeviceState *qdev_try_create(BusState *bus, const char *type) > +{ > + DeviceState *dev; > + > + if (object_class_by_name(type) == NULL) { > + return NULL; > + } > + dev = DEVICE(object_new(type)); > + if (!dev) { > + return NULL; > + } > + > + if (!bus) { > + bus = sysbus_get_default(); > + } > + > + qdev_set_parent_bus(dev, bus); > + > + return dev; > +} > diff --git a/hw/qdev.c b/hw/qdev.c > index 36c3e4b..3dc38f7 100644 > --- a/hw/qdev.c > +++ b/hw/qdev.c > @@ -25,7 +25,6 @@ > inherit from a particular bus (e.g. PCI or I2C) rather than > this API directly. */ > > -#include "net.h" > #include "qdev.h" > #include "sysemu.h" > #include "error.h" > @@ -105,47 +104,6 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus) > bus_add_child(bus, dev); > } > > -/* Create a new device. This only initializes the device state structure > - and allows properties to be set. qdev_init should be called to > - initialize the actual device emulation. */ > -DeviceState *qdev_create(BusState *bus, const char *name) > -{ > - DeviceState *dev; > - > - dev = qdev_try_create(bus, name); > - if (!dev) { > - if (bus) { > - hw_error("Unknown device ''%s'' for bus ''%s''\n", name, > - object_get_typename(OBJECT(bus))); > - } else { > - hw_error("Unknown device ''%s'' for default sysbus\n", name); > - } > - } > - > - return dev; > -} > - > -DeviceState *qdev_try_create(BusState *bus, const char *type) > -{ > - DeviceState *dev; > - > - if (object_class_by_name(type) == NULL) { > - return NULL; > - } > - dev = DEVICE(object_new(type)); > - if (!dev) { > - return NULL; > - } > - > - if (!bus) { > - bus = sysbus_get_default(); > - } > - > - qdev_set_parent_bus(dev, bus); > - > - return dev; > -} > - > /* Initialize a device. Device properties should be set before calling > this function. IRQs and MMIO regions should be connected/mapped after > calling this function. > @@ -175,11 +133,13 @@ int qdev_init(DeviceState *dev) > g_free(name); > } > > +#ifndef CONFIG_USER_ONLY > 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); > } > +#endif > dev->state = DEV_STATE_INITIALIZED; > if (dev->hotplugged) { > device_reset(dev); > @@ -292,56 +252,6 @@ BusState *qdev_get_parent_bus(DeviceState *dev) > return dev->parent_bus; > } > > -void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) > -{ > - assert(dev->num_gpio_in == 0); > - dev->num_gpio_in = n; > - dev->gpio_in = qemu_allocate_irqs(handler, dev, n); > -} > - > -void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n) > -{ > - assert(dev->num_gpio_out == 0); > - dev->num_gpio_out = n; > - dev->gpio_out = pins; > -} > - > -qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) > -{ > - assert(n >= 0 && n < dev->num_gpio_in); > - return dev->gpio_in[n]; > -} > - > -void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) > -{ > - assert(n >= 0 && n < dev->num_gpio_out); > - dev->gpio_out[n] = pin; > -} > - > -void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) > -{ > - qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a); > - if (nd->netdev) > - qdev_prop_set_netdev(dev, "netdev", nd->netdev); > - if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED && > - object_property_find(OBJECT(dev), "vectors", NULL)) { > - qdev_prop_set_uint32(dev, "vectors", nd->nvectors); > - } > - nd->instantiated = 1; > -} > - > -BusState *qdev_get_child_bus(DeviceState *dev, const char *name) > -{ > - BusState *bus; > - > - QLIST_FOREACH(bus, &dev->child_bus, sibling) { > - if (strcmp(name, bus->name) == 0) { > - return bus; > - } > - } > - return NULL; > -} > - > int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, > qbus_walkerfn *busfn, void *opaque) > { > @@ -440,11 +350,14 @@ 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()) { > + } > +#ifndef CONFIG_USER_ONLY > + 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); > } > +#endif > } > > void qbus_create_inplace(BusState *bus, const char *typename, > @@ -703,9 +616,11 @@ static void device_finalize(Object *obj) > bus = QLIST_FIRST(&dev->child_bus); > qbus_free(bus); > } > +#ifndef CONFIG_USER_ONLY > if (qdev_get_vmsd(dev)) { > vmstate_unregister(dev, qdev_get_vmsd(dev), dev); > } > +#endif > if (dc->exit) { > dc->exit(dev); > } > @@ -779,8 +694,10 @@ static void qbus_finalize(Object *obj) > QLIST_REMOVE(bus, sibling); > bus->parent->num_child_bus--; > } else { > +#ifndef CONFIG_USER_ONLY > assert(bus != sysbus_get_default()); /* main_system_bus is never freed */ > qemu_unregister_reset(qbus_reset_all_fn, bus); > +#endif > } > g_free((char *)bus->name); > } > -- > 1.7.11.4 >
Eduardo Habkost
2012-Aug-21 18:55 UTC
Re: [RFC 7/8] include core qdev code into *-user, too
On Tue, Aug 21, 2012 at 05:59:22PM +0100, Peter Maydell wrote:> On 21 August 2012 16:43, Eduardo Habkost <ehabkost@redhat.com> wrote: > > The code depends on some functions from qemu-option.o, so add > > qemu-option.o to qom-obj-y to make sure it''s included. > > > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> > > --- > > Makefile.objs | 1 + > > hw/Makefile.objs | 2 +- > > qom/Makefile.objs | 2 +- > > hw/qdev-properties.c => qom/device-properties.c | 0 > > hw/qdev.c => qom/device.c | 0 > > 5 files changed, 3 insertions(+), 2 deletions(-) > > rename hw/qdev-properties.c => qom/device-properties.c (100%) > > rename hw/qdev.c => qom/device.c (100%) > > > > diff --git a/Makefile.objs b/Makefile.objs > > index 4412757..2cf91c2 100644 > > --- a/Makefile.objs > > +++ b/Makefile.objs > > @@ -14,6 +14,7 @@ universal-obj-y += $(qobject-obj-y) > > ####################################################################### > > # QOM > > qom-obj-y = qom/ > > +qom-obj-y += qemu-option.o > > qemu-option.c isn''t actually QOM related code...True, but it''s a dependency of the QOM DeviceState code. I don''t know if qom-obj-y is for "the QOM code" or "QOM code + dependencies". I simply added it to qom-obj-y to avoid having to repeat myself (otherwise I would need to add qemu-option.o to both common-obj-y and user-obj-y). -- Eduardo
Avi Kivity
2012-Aug-22 09:05 UTC
Re: [RFC 0/8] include qdev core in *-user, make CPU child of DeviceState
On 08/21/2012 06:42 PM, Eduardo Habkost wrote:> So, here''s a third suggestion to the CPU/DeviceState problem. Basically I split > the qdev code into a core (that can be easily compiled into *-user), and a part > specific to qemu-system-*. >I''m barging in late here, so sorry if this has been suggested and shot down: is it not possible to use composition here? typedef ... CPU; typedef struct CPUState { DeviceState qdev; CPU cpu; } CPUState; But I guess bringing qdev to -user is inevitable. -- error compiling committee.c: too many arguments to function
Eduardo Habkost
2012-Aug-22 13:08 UTC
Re: [RFC 0/8] include qdev core in *-user, make CPU child of DeviceState
On Wed, Aug 22, 2012 at 12:05:44PM +0300, Avi Kivity wrote:> On 08/21/2012 06:42 PM, Eduardo Habkost wrote: > > So, here''s a third suggestion to the CPU/DeviceState problem. Basically I split > > the qdev code into a core (that can be easily compiled into *-user), and a part > > specific to qemu-system-*. > > > > I''m barging in late here, so sorry if this has been suggested and shot > down: is it not possible to use composition here? > > typedef ... CPU; > > typedef struct CPUState { > DeviceState qdev; > CPU cpu; > } CPUState; > > But I guess bringing qdev to -user is inevitable.I guess it would be OK, and almost equivalent to the suggestion by Anthony (use a different parent class for the CPU class on system-* and *-user), as most state today is in the arch-specific classes. The only problem I see is when some part of the CPU code starts using a DeviceState feature (e.g. calling x86_cpu_realize() only at qdev_init()-time). Then we have to duplicate some code to make *-user work differently (not much code, I guess, but it would still make it easier to break it if we have two implementations). -- Eduardo
Igor Mammedov
2012-Aug-27 14:28 UTC
Re: [RFC 1/8] move qemu_irq typedef out of cpu-common.h
----- Original Message -----> From: "Peter Maydell" <peter.maydell@linaro.org>...> > I''m not objecting to this patch if it helps us move forwards, > but adding the #include to sysemu.h is effectively just adding > the definition to another grabbag header (183 files include > sysemu.h). It would be nicer long-term to separate out the > one thing in this header that cares about qemu_irq (the extern > declaration of qemu_system_powerdown).^^^^ Is there a preference/suggestion in which header it should be declared? ...
Igor Mammedov
2012-Aug-29 15:36 UTC
Re: [Xen-devel] [RFC 1/8] move qemu_irq typedef out of cpu-common.h
On Tue, 21 Aug 2012 17:10:48 +0100 Peter Maydell <peter.maydell@linaro.org> wrote:> On 21 August 2012 16:42, Eduardo Habkost <ehabkost@redhat.com> wrote: > > diff --git a/qemu-common.h b/qemu-common.h > > index e5c2bcd..6677a30 100644 > > --- a/qemu-common.h > > +++ b/qemu-common.h > > @@ -273,7 +273,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; > > diff --git a/sysemu.h b/sysemu.h > > index 65552ac..f765821 100644 > > --- a/sysemu.h > > +++ b/sysemu.h > > @@ -9,6 +9,7 @@ > > #include "qapi-types.h" > > #include "notify.h" > > #include "main-loop.h" > > +#include "hw/irq.h" > > > > /* vl.c */ > > I''m not objecting to this patch if it helps us move forwards, > but adding the #include to sysemu.h is effectively just adding > the definition to another grabbag header (183 files include > sysemu.h). It would be nicer long-term to separate out the > one thing in this header that cares about qemu_irq (the extern > declaration of qemu_system_powerdown). > [I''m not really convinced that a qemu_irq is even the right > way to signal "hey the system has actually powered down now"...]Instead of global qemu_system_powerdown we could use notifiers like it''s done for suspend, I''ll post patches today after testing them on target-i386. BTW getting rid of qemu_system_powerdown is orthogonal to topic of this series. I hope you won''t object to this patch providing there will be follow on series to deal with qemu_system_powerdown.> > -- PMM > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel-- Regards, Igor
Peter Maydell
2012-Aug-29 15:38 UTC
Re: [Xen-devel] [RFC 1/8] move qemu_irq typedef out of cpu-common.h
On 29 August 2012 16:36, Igor Mammedov <imammedo@redhat.com> wrote:> Peter Maydell <peter.maydell@linaro.org> wrote: >> I''m not objecting to this patch if it helps us move forwards, >> but adding the #include to sysemu.h is effectively just adding >> the definition to another grabbag header (183 files include >> sysemu.h). It would be nicer long-term to separate out the >> one thing in this header that cares about qemu_irq (the extern >> declaration of qemu_system_powerdown). >> [I''m not really convinced that a qemu_irq is even the right >> way to signal "hey the system has actually powered down now"...] > > Instead of global qemu_system_powerdown we could use notifiers like it''s done > for suspend, I''ll post patches today after testing them on target-i386. > > BTW getting rid of qemu_system_powerdown is orthogonal to topic of this series. > I hope you won''t object to this patch providing there will be follow on series > to deal with qemu_system_powerdown.Yes, as I say, I don''t object if this patch is useful in the meantime. -- PMM