accel/meson: Only build hw virtualization with system emulation
[qemu/armbru.git] / hw / core / qdev.c
blob84f3019440fcc1c57b59331f706ec90a20ca3f26
1 /*
2 * Dynamic device configuration and creation.
4 * Copyright (c) 2009 CodeSourcery
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 /* The theory here is that it should be possible to create a machine without
21 knowledge of specific devices. Historically board init routines have
22 passed a bunch of arguments to each device, requiring the board know
23 exactly which device it is dealing with. This file provides an abstract
24 API for device configuration and initialization. Devices will generally
25 inherit from a particular bus (e.g. PCI or I2C) rather than
26 this API directly. */
28 #include "qemu/osdep.h"
29 #include "qapi/error.h"
30 #include "qapi/qapi-events-qdev.h"
31 #include "qapi/qmp/qdict.h"
32 #include "qapi/qmp/qerror.h"
33 #include "qapi/visitor.h"
34 #include "qemu/error-report.h"
35 #include "qemu/option.h"
36 #include "hw/irq.h"
37 #include "hw/qdev-properties.h"
38 #include "hw/boards.h"
39 #include "hw/sysbus.h"
40 #include "hw/qdev-clock.h"
41 #include "migration/vmstate.h"
42 #include "trace.h"
44 static bool qdev_hot_added = false;
45 bool qdev_hot_removed = false;
47 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
49 DeviceClass *dc = DEVICE_GET_CLASS(dev);
50 return dc->vmsd;
53 static void bus_free_bus_child(BusChild *kid)
55 object_unref(OBJECT(kid->child));
56 g_free(kid);
59 static void bus_remove_child(BusState *bus, DeviceState *child)
61 BusChild *kid;
63 QTAILQ_FOREACH(kid, &bus->children, sibling) {
64 if (kid->child == child) {
65 char name[32];
67 snprintf(name, sizeof(name), "child[%d]", kid->index);
68 QTAILQ_REMOVE_RCU(&bus->children, kid, sibling);
70 bus->num_children--;
72 /* This gives back ownership of kid->child back to us. */
73 object_property_del(OBJECT(bus), name);
75 /* free the bus kid, when it is safe to do so*/
76 call_rcu(kid, bus_free_bus_child, rcu);
77 break;
82 static void bus_add_child(BusState *bus, DeviceState *child)
84 char name[32];
85 BusChild *kid = g_malloc0(sizeof(*kid));
87 bus->num_children++;
88 kid->index = bus->max_index++;
89 kid->child = child;
90 object_ref(OBJECT(kid->child));
92 QTAILQ_INSERT_HEAD_RCU(&bus->children, kid, sibling);
94 /* This transfers ownership of kid->child to the property. */
95 snprintf(name, sizeof(name), "child[%d]", kid->index);
96 object_property_add_link(OBJECT(bus), name,
97 object_get_typename(OBJECT(child)),
98 (Object **)&kid->child,
99 NULL, /* read-only property */
103 static bool bus_check_address(BusState *bus, DeviceState *child, Error **errp)
105 BusClass *bc = BUS_GET_CLASS(bus);
106 return !bc->check_address || bc->check_address(bus, child, errp);
109 bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp)
111 BusState *old_parent_bus = dev->parent_bus;
112 DeviceClass *dc = DEVICE_GET_CLASS(dev);
114 assert(dc->bus_type && object_dynamic_cast(OBJECT(bus), dc->bus_type));
116 if (!bus_check_address(bus, dev, errp)) {
117 return false;
120 if (old_parent_bus) {
121 trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
122 old_parent_bus, object_get_typename(OBJECT(old_parent_bus)),
123 OBJECT(bus), object_get_typename(OBJECT(bus)));
125 * Keep a reference to the device while it's not plugged into
126 * any bus, to avoid it potentially evaporating when it is
127 * dereffed in bus_remove_child().
128 * Also keep the ref of the parent bus until the end, so that
129 * we can safely call resettable_change_parent() below.
131 object_ref(OBJECT(dev));
132 bus_remove_child(dev->parent_bus, dev);
134 dev->parent_bus = bus;
135 object_ref(OBJECT(bus));
136 bus_add_child(bus, dev);
137 if (dev->realized) {
138 resettable_change_parent(OBJECT(dev), OBJECT(bus),
139 OBJECT(old_parent_bus));
141 if (old_parent_bus) {
142 object_unref(OBJECT(old_parent_bus));
143 object_unref(OBJECT(dev));
145 return true;
148 DeviceState *qdev_new(const char *name)
150 if (!object_class_by_name(name)) {
151 module_load_qom_one(name);
153 return DEVICE(object_new(name));
156 DeviceState *qdev_try_new(const char *name)
158 if (!module_object_class_by_name(name)) {
159 return NULL;
161 return DEVICE(object_new(name));
164 static QTAILQ_HEAD(, DeviceListener) device_listeners
165 = QTAILQ_HEAD_INITIALIZER(device_listeners);
167 enum ListenerDirection { Forward, Reverse };
169 #define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
170 do { \
171 DeviceListener *_listener; \
173 switch (_direction) { \
174 case Forward: \
175 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
176 if (_listener->_callback) { \
177 _listener->_callback(_listener, ##_args); \
180 break; \
181 case Reverse: \
182 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
183 link) { \
184 if (_listener->_callback) { \
185 _listener->_callback(_listener, ##_args); \
188 break; \
189 default: \
190 abort(); \
192 } while (0)
194 static int device_listener_add(DeviceState *dev, void *opaque)
196 DEVICE_LISTENER_CALL(realize, Forward, dev);
198 return 0;
201 void device_listener_register(DeviceListener *listener)
203 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
205 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
206 NULL, NULL);
209 void device_listener_unregister(DeviceListener *listener)
211 QTAILQ_REMOVE(&device_listeners, listener, link);
214 bool qdev_should_hide_device(const QDict *opts, bool from_json, Error **errp)
216 ERRP_GUARD();
217 DeviceListener *listener;
219 QTAILQ_FOREACH(listener, &device_listeners, link) {
220 if (listener->hide_device) {
221 if (listener->hide_device(listener, opts, from_json, errp)) {
222 return true;
223 } else if (*errp) {
224 return false;
229 return false;
232 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
233 int required_for_version)
235 assert(!dev->realized);
236 dev->instance_id_alias = alias_id;
237 dev->alias_required_for_version = required_for_version;
240 static int qdev_prereset(DeviceState *dev, void *opaque)
242 trace_qdev_reset_tree(dev, object_get_typename(OBJECT(dev)));
243 return 0;
246 static int qbus_prereset(BusState *bus, void *opaque)
248 trace_qbus_reset_tree(bus, object_get_typename(OBJECT(bus)));
249 return 0;
252 static int qdev_reset_one(DeviceState *dev, void *opaque)
254 device_legacy_reset(dev);
256 return 0;
259 static int qbus_reset_one(BusState *bus, void *opaque)
261 BusClass *bc = BUS_GET_CLASS(bus);
262 trace_qbus_reset(bus, object_get_typename(OBJECT(bus)));
263 if (bc->reset) {
264 bc->reset(bus);
266 return 0;
269 void qdev_reset_all(DeviceState *dev)
271 trace_qdev_reset_all(dev, object_get_typename(OBJECT(dev)));
272 qdev_walk_children(dev, qdev_prereset, qbus_prereset,
273 qdev_reset_one, qbus_reset_one, NULL);
276 void qdev_reset_all_fn(void *opaque)
278 qdev_reset_all(DEVICE(opaque));
281 void qbus_reset_all(BusState *bus)
283 trace_qbus_reset_all(bus, object_get_typename(OBJECT(bus)));
284 qbus_walk_children(bus, qdev_prereset, qbus_prereset,
285 qdev_reset_one, qbus_reset_one, NULL);
288 void qbus_reset_all_fn(void *opaque)
290 BusState *bus = opaque;
291 qbus_reset_all(bus);
294 void device_cold_reset(DeviceState *dev)
296 resettable_reset(OBJECT(dev), RESET_TYPE_COLD);
299 bool device_is_in_reset(DeviceState *dev)
301 return resettable_is_in_reset(OBJECT(dev));
304 static ResettableState *device_get_reset_state(Object *obj)
306 DeviceState *dev = DEVICE(obj);
307 return &dev->reset;
310 static void device_reset_child_foreach(Object *obj, ResettableChildCallback cb,
311 void *opaque, ResetType type)
313 DeviceState *dev = DEVICE(obj);
314 BusState *bus;
316 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
317 cb(OBJECT(bus), opaque, type);
321 bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp)
323 assert(!dev->realized && !dev->parent_bus);
325 if (bus) {
326 if (!qdev_set_parent_bus(dev, bus, errp)) {
327 return false;
329 } else {
330 assert(!DEVICE_GET_CLASS(dev)->bus_type);
333 return object_property_set_bool(OBJECT(dev), "realized", true, errp);
336 bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp)
338 bool ret;
340 ret = qdev_realize(dev, bus, errp);
341 object_unref(OBJECT(dev));
342 return ret;
345 void qdev_unrealize(DeviceState *dev)
347 object_property_set_bool(OBJECT(dev), "realized", false, &error_abort);
350 static int qdev_assert_realized_properly_cb(Object *obj, void *opaque)
352 DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE));
353 DeviceClass *dc;
355 if (dev) {
356 dc = DEVICE_GET_CLASS(dev);
357 assert(dev->realized);
358 assert(dev->parent_bus || !dc->bus_type);
360 return 0;
363 void qdev_assert_realized_properly(void)
365 object_child_foreach_recursive(object_get_root(),
366 qdev_assert_realized_properly_cb, NULL);
369 bool qdev_machine_modified(void)
371 return qdev_hot_added || qdev_hot_removed;
374 BusState *qdev_get_parent_bus(DeviceState *dev)
376 return dev->parent_bus;
379 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
381 BusState *bus;
382 Object *child = object_resolve_path_component(OBJECT(dev), name);
384 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
385 if (bus) {
386 return bus;
389 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
390 if (strcmp(name, bus->name) == 0) {
391 return bus;
394 return NULL;
397 int qdev_walk_children(DeviceState *dev,
398 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
399 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
400 void *opaque)
402 BusState *bus;
403 int err;
405 if (pre_devfn) {
406 err = pre_devfn(dev, opaque);
407 if (err) {
408 return err;
412 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
413 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
414 post_devfn, post_busfn, opaque);
415 if (err < 0) {
416 return err;
420 if (post_devfn) {
421 err = post_devfn(dev, opaque);
422 if (err) {
423 return err;
427 return 0;
430 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
432 BusChild *kid;
433 DeviceState *ret;
434 BusState *child;
436 WITH_RCU_READ_LOCK_GUARD() {
437 QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) {
438 DeviceState *dev = kid->child;
440 if (dev->id && strcmp(dev->id, id) == 0) {
441 return dev;
444 QLIST_FOREACH(child, &dev->child_bus, sibling) {
445 ret = qdev_find_recursive(child, id);
446 if (ret) {
447 return ret;
452 return NULL;
455 char *qdev_get_dev_path(DeviceState *dev)
457 BusClass *bc;
459 if (!dev || !dev->parent_bus) {
460 return NULL;
463 bc = BUS_GET_CLASS(dev->parent_bus);
464 if (bc->get_dev_path) {
465 return bc->get_dev_path(dev);
468 return NULL;
471 static bool device_get_realized(Object *obj, Error **errp)
473 DeviceState *dev = DEVICE(obj);
474 return dev->realized;
477 static bool check_only_migratable(Object *obj, Error **errp)
479 DeviceClass *dc = DEVICE_GET_CLASS(obj);
481 if (!vmstate_check_only_migratable(dc->vmsd)) {
482 error_setg(errp, "Device %s is not migratable, but "
483 "--only-migratable was specified",
484 object_get_typename(obj));
485 return false;
488 return true;
491 static void device_set_realized(Object *obj, bool value, Error **errp)
493 DeviceState *dev = DEVICE(obj);
494 DeviceClass *dc = DEVICE_GET_CLASS(dev);
495 HotplugHandler *hotplug_ctrl;
496 BusState *bus;
497 NamedClockList *ncl;
498 Error *local_err = NULL;
499 bool unattached_parent = false;
500 static int unattached_count;
502 if (dev->hotplugged && !dc->hotpluggable) {
503 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
504 return;
507 if (value && !dev->realized) {
508 if (!check_only_migratable(obj, errp)) {
509 goto fail;
512 if (!obj->parent) {
513 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
515 object_property_add_child(container_get(qdev_get_machine(),
516 "/unattached"),
517 name, obj);
518 unattached_parent = true;
519 g_free(name);
522 hotplug_ctrl = qdev_get_hotplug_handler(dev);
523 if (hotplug_ctrl) {
524 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
525 if (local_err != NULL) {
526 goto fail;
530 if (dc->realize) {
531 dc->realize(dev, &local_err);
532 if (local_err != NULL) {
533 goto fail;
537 DEVICE_LISTENER_CALL(realize, Forward, dev);
540 * always free/re-initialize here since the value cannot be cleaned up
541 * in device_unrealize due to its usage later on in the unplug path
543 g_free(dev->canonical_path);
544 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
545 QLIST_FOREACH(ncl, &dev->clocks, node) {
546 if (ncl->alias) {
547 continue;
548 } else {
549 clock_setup_canonical_path(ncl->clock);
553 if (qdev_get_vmsd(dev)) {
554 if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
555 VMSTATE_INSTANCE_ID_ANY,
556 qdev_get_vmsd(dev), dev,
557 dev->instance_id_alias,
558 dev->alias_required_for_version,
559 &local_err) < 0) {
560 goto post_realize_fail;
565 * Clear the reset state, in case the object was previously unrealized
566 * with a dirty state.
568 resettable_state_clear(&dev->reset);
570 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
571 if (!qbus_realize(bus, errp)) {
572 goto child_realize_fail;
575 if (dev->hotplugged) {
577 * Reset the device, as well as its subtree which, at this point,
578 * should be realized too.
580 resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
581 resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
582 NULL);
583 resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
585 dev->pending_deleted_event = false;
587 if (hotplug_ctrl) {
588 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
589 if (local_err != NULL) {
590 goto child_realize_fail;
594 qatomic_store_release(&dev->realized, value);
596 } else if (!value && dev->realized) {
599 * Change the value so that any concurrent users are aware
600 * that the device is going to be unrealized
602 * TODO: change .realized property to enum that states
603 * each phase of the device realization/unrealization
606 qatomic_set(&dev->realized, value);
608 * Ensure that concurrent users see this update prior to
609 * any other changes done by unrealize.
611 smp_wmb();
613 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
614 qbus_unrealize(bus);
616 if (qdev_get_vmsd(dev)) {
617 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
619 if (dc->unrealize) {
620 dc->unrealize(dev);
622 dev->pending_deleted_event = true;
623 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
626 assert(local_err == NULL);
627 return;
629 child_realize_fail:
630 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
631 qbus_unrealize(bus);
634 if (qdev_get_vmsd(dev)) {
635 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
638 post_realize_fail:
639 g_free(dev->canonical_path);
640 dev->canonical_path = NULL;
641 if (dc->unrealize) {
642 dc->unrealize(dev);
645 fail:
646 error_propagate(errp, local_err);
647 if (unattached_parent) {
649 * Beware, this doesn't just revert
650 * object_property_add_child(), it also runs bus_remove()!
652 object_unparent(OBJECT(dev));
653 unattached_count--;
657 static bool device_get_hotpluggable(Object *obj, Error **errp)
659 DeviceClass *dc = DEVICE_GET_CLASS(obj);
660 DeviceState *dev = DEVICE(obj);
662 return dc->hotpluggable && (dev->parent_bus == NULL ||
663 qbus_is_hotpluggable(dev->parent_bus));
666 static bool device_get_hotplugged(Object *obj, Error **errp)
668 DeviceState *dev = DEVICE(obj);
670 return dev->hotplugged;
673 static void device_initfn(Object *obj)
675 DeviceState *dev = DEVICE(obj);
677 if (phase_check(PHASE_MACHINE_READY)) {
678 dev->hotplugged = 1;
679 qdev_hot_added = true;
682 dev->instance_id_alias = -1;
683 dev->realized = false;
684 dev->allow_unplug_during_migration = false;
686 QLIST_INIT(&dev->gpios);
687 QLIST_INIT(&dev->clocks);
690 static void device_post_init(Object *obj)
693 * Note: ordered so that the user's global properties take
694 * precedence.
696 object_apply_compat_props(obj);
697 qdev_prop_set_globals(DEVICE(obj));
700 /* Unlink device from bus and free the structure. */
701 static void device_finalize(Object *obj)
703 NamedGPIOList *ngl, *next;
705 DeviceState *dev = DEVICE(obj);
707 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
708 QLIST_REMOVE(ngl, node);
709 qemu_free_irqs(ngl->in, ngl->num_in);
710 g_free(ngl->name);
711 g_free(ngl);
712 /* ngl->out irqs are owned by the other end and should not be freed
713 * here
717 qdev_finalize_clocklist(dev);
719 /* Only send event if the device had been completely realized */
720 if (dev->pending_deleted_event) {
721 g_assert(dev->canonical_path);
723 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path);
724 g_free(dev->canonical_path);
725 dev->canonical_path = NULL;
728 qobject_unref(dev->opts);
729 g_free(dev->id);
732 static void device_class_base_init(ObjectClass *class, void *data)
734 DeviceClass *klass = DEVICE_CLASS(class);
736 /* We explicitly look up properties in the superclasses,
737 * so do not propagate them to the subclasses.
739 klass->props_ = NULL;
742 static void device_unparent(Object *obj)
744 DeviceState *dev = DEVICE(obj);
745 BusState *bus;
747 if (dev->realized) {
748 qdev_unrealize(dev);
750 while (dev->num_child_bus) {
751 bus = QLIST_FIRST(&dev->child_bus);
752 object_unparent(OBJECT(bus));
754 if (dev->parent_bus) {
755 bus_remove_child(dev->parent_bus, dev);
756 object_unref(OBJECT(dev->parent_bus));
757 dev->parent_bus = NULL;
761 static char *
762 device_vmstate_if_get_id(VMStateIf *obj)
764 DeviceState *dev = DEVICE(obj);
766 return qdev_get_dev_path(dev);
770 * device_phases_reset:
771 * Transition reset method for devices to allow moving
772 * smoothly from legacy reset method to multi-phases
774 static void device_phases_reset(DeviceState *dev)
776 ResettableClass *rc = RESETTABLE_GET_CLASS(dev);
778 if (rc->phases.enter) {
779 rc->phases.enter(OBJECT(dev), RESET_TYPE_COLD);
781 if (rc->phases.hold) {
782 rc->phases.hold(OBJECT(dev));
784 if (rc->phases.exit) {
785 rc->phases.exit(OBJECT(dev));
789 static void device_transitional_reset(Object *obj)
791 DeviceClass *dc = DEVICE_GET_CLASS(obj);
794 * This will call either @device_phases_reset (for multi-phases transitioned
795 * devices) or a device's specific method for not-yet transitioned devices.
796 * In both case, it does not reset children.
798 if (dc->reset) {
799 dc->reset(DEVICE(obj));
804 * device_get_transitional_reset:
805 * check if the device's class is ready for multi-phase
807 static ResettableTrFunction device_get_transitional_reset(Object *obj)
809 DeviceClass *dc = DEVICE_GET_CLASS(obj);
810 if (dc->reset != device_phases_reset) {
812 * dc->reset has been overridden by a subclass,
813 * the device is not ready for multi phase yet.
815 return device_transitional_reset;
817 return NULL;
820 static void device_class_init(ObjectClass *class, void *data)
822 DeviceClass *dc = DEVICE_CLASS(class);
823 VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
824 ResettableClass *rc = RESETTABLE_CLASS(class);
826 class->unparent = device_unparent;
828 /* by default all devices were considered as hotpluggable,
829 * so with intent to check it in generic qdev_unplug() /
830 * device_set_realized() functions make every device
831 * hotpluggable. Devices that shouldn't be hotpluggable,
832 * should override it in their class_init()
834 dc->hotpluggable = true;
835 dc->user_creatable = true;
836 vc->get_id = device_vmstate_if_get_id;
837 rc->get_state = device_get_reset_state;
838 rc->child_foreach = device_reset_child_foreach;
841 * @device_phases_reset is put as the default reset method below, allowing
842 * to do the multi-phase transition from base classes to leaf classes. It
843 * allows a legacy-reset Device class to extend a multi-phases-reset
844 * Device class for the following reason:
845 * + If a base class B has been moved to multi-phase, then it does not
846 * override this default reset method and may have defined phase methods.
847 * + A child class C (extending class B) which uses
848 * device_class_set_parent_reset() (or similar means) to override the
849 * reset method will still work as expected. @device_phases_reset function
850 * will be registered as the parent reset method and effectively call
851 * parent reset phases.
853 dc->reset = device_phases_reset;
854 rc->get_transitional_function = device_get_transitional_reset;
856 object_class_property_add_bool(class, "realized",
857 device_get_realized, device_set_realized);
858 object_class_property_add_bool(class, "hotpluggable",
859 device_get_hotpluggable, NULL);
860 object_class_property_add_bool(class, "hotplugged",
861 device_get_hotplugged, NULL);
862 object_class_property_add_link(class, "parent_bus", TYPE_BUS,
863 offsetof(DeviceState, parent_bus), NULL, 0);
866 void device_class_set_parent_reset(DeviceClass *dc,
867 DeviceReset dev_reset,
868 DeviceReset *parent_reset)
870 *parent_reset = dc->reset;
871 dc->reset = dev_reset;
874 void device_class_set_parent_realize(DeviceClass *dc,
875 DeviceRealize dev_realize,
876 DeviceRealize *parent_realize)
878 *parent_realize = dc->realize;
879 dc->realize = dev_realize;
882 void device_class_set_parent_unrealize(DeviceClass *dc,
883 DeviceUnrealize dev_unrealize,
884 DeviceUnrealize *parent_unrealize)
886 *parent_unrealize = dc->unrealize;
887 dc->unrealize = dev_unrealize;
890 void device_legacy_reset(DeviceState *dev)
892 DeviceClass *klass = DEVICE_GET_CLASS(dev);
894 trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));
895 if (klass->reset) {
896 klass->reset(dev);
900 Object *qdev_get_machine(void)
902 static Object *dev;
904 if (dev == NULL) {
905 dev = container_get(object_get_root(), "/machine");
908 return dev;
911 static MachineInitPhase machine_phase;
913 bool phase_check(MachineInitPhase phase)
915 return machine_phase >= phase;
918 void phase_advance(MachineInitPhase phase)
920 assert(machine_phase == phase - 1);
921 machine_phase = phase;
924 static const TypeInfo device_type_info = {
925 .name = TYPE_DEVICE,
926 .parent = TYPE_OBJECT,
927 .instance_size = sizeof(DeviceState),
928 .instance_init = device_initfn,
929 .instance_post_init = device_post_init,
930 .instance_finalize = device_finalize,
931 .class_base_init = device_class_base_init,
932 .class_init = device_class_init,
933 .abstract = true,
934 .class_size = sizeof(DeviceClass),
935 .interfaces = (InterfaceInfo[]) {
936 { TYPE_VMSTATE_IF },
937 { TYPE_RESETTABLE_INTERFACE },
942 static void qdev_register_types(void)
944 type_register_static(&device_type_info);
947 type_init(qdev_register_types)