]> Git Repo - qemu.git/blame - hw/core/qdev.c
spapr_numa: create a vcpu associativity helper
[qemu.git] / hw / core / qdev.c
CommitLineData
aae9460e
PB
1/*
2 * Dynamic device configuration and creation.
3 *
4 * Copyright (c) 2009 CodeSourcery
5 *
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 of the License, or (at your option) any later version.
10 *
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.
15 *
16 * You should have received a copy of the GNU Lesser General Public
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
aae9460e
PB
18 */
19
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. */
27
18c86e2b 28#include "qemu/osdep.h"
e688df6b 29#include "qapi/error.h"
c577ff62 30#include "qapi/qapi-events-qdev.h"
b4a42f81 31#include "qapi/qmp/qerror.h"
7b1b5d19 32#include "qapi/visitor.h"
d49b6836 33#include "qemu/error-report.h"
922a01a0 34#include "qemu/option.h"
0ee4de6c 35#include "hw/hotplug.h"
64552b6b 36#include "hw/irq.h"
a27bd6c7 37#include "hw/qdev-properties.h"
b7454548 38#include "hw/boards.h"
7474f1be 39#include "hw/sysbus.h"
0e6934f2 40#include "hw/qdev-clock.h"
d6454270 41#include "migration/vmstate.h"
70804c83 42#include "trace.h"
aae9460e 43
9bed84c1 44bool qdev_hotplug = false;
0ac8ef71 45static bool qdev_hot_added = false;
21def24a 46bool qdev_hot_removed = false;
3418bd25 47
4be9f0d1
AL
48const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
49{
6e008585
AL
50 DeviceClass *dc = DEVICE_GET_CLASS(dev);
51 return dc->vmsd;
4be9f0d1
AL
52}
53
0866aca1 54static void bus_remove_child(BusState *bus, DeviceState *child)
0c17542d 55{
0866aca1
AL
56 BusChild *kid;
57
58 QTAILQ_FOREACH(kid, &bus->children, sibling) {
59 if (kid->child == child) {
60 char name[32];
61
62 snprintf(name, sizeof(name), "child[%d]", kid->index);
63 QTAILQ_REMOVE(&bus->children, kid, sibling);
9d127820 64
12b2e9f3
TK
65 bus->num_children--;
66
9d127820 67 /* This gives back ownership of kid->child back to us. */
df4fe0b2 68 object_property_del(OBJECT(bus), name);
9d127820 69 object_unref(OBJECT(kid->child));
0866aca1
AL
70 g_free(kid);
71 return;
72 }
73 }
74}
75
76static void bus_add_child(BusState *bus, DeviceState *child)
77{
78 char name[32];
79 BusChild *kid = g_malloc0(sizeof(*kid));
0c17542d 80
12b2e9f3 81 bus->num_children++;
0866aca1
AL
82 kid->index = bus->max_index++;
83 kid->child = child;
9d127820 84 object_ref(OBJECT(kid->child));
a5296ca9 85
0866aca1
AL
86 QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
87
9d127820 88 /* This transfers ownership of kid->child to the property. */
0866aca1
AL
89 snprintf(name, sizeof(name), "child[%d]", kid->index);
90 object_property_add_link(OBJECT(bus), name,
91 object_get_typename(OBJECT(child)),
39f72ef9
SH
92 (Object **)&kid->child,
93 NULL, /* read-only property */
d2623129 94 0);
0866aca1
AL
95}
96
97void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
98{
a7c3a4f9 99 BusState *old_parent_bus = dev->parent_bus;
81cb0573
MA
100 DeviceClass *dc = DEVICE_GET_CLASS(dev);
101
102 assert(dc->bus_type && object_dynamic_cast(OBJECT(bus), dc->bus_type));
91c968ac 103
a7c3a4f9 104 if (old_parent_bus) {
70804c83 105 trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)),
a7c3a4f9 106 old_parent_bus, object_get_typename(OBJECT(old_parent_bus)),
70804c83
DH
107 OBJECT(bus), object_get_typename(OBJECT(bus)));
108 /*
109 * Keep a reference to the device while it's not plugged into
91c968ac
PM
110 * any bus, to avoid it potentially evaporating when it is
111 * dereffed in bus_remove_child().
a7c3a4f9
DH
112 * Also keep the ref of the parent bus until the end, so that
113 * we can safely call resettable_change_parent() below.
91c968ac
PM
114 */
115 object_ref(OBJECT(dev));
116 bus_remove_child(dev->parent_bus, dev);
91c968ac 117 }
9fbe6127 118 dev->parent_bus = bus;
62d7ba66 119 object_ref(OBJECT(bus));
0866aca1 120 bus_add_child(bus, dev);
a7c3a4f9
DH
121 if (dev->realized) {
122 resettable_change_parent(OBJECT(dev), OBJECT(bus),
123 OBJECT(old_parent_bus));
124 }
125 if (old_parent_bus) {
126 object_unref(OBJECT(old_parent_bus));
91c968ac
PM
127 object_unref(OBJECT(dev));
128 }
0c17542d
MA
129}
130
9940b2cf
MA
131DeviceState *qdev_new(const char *name)
132{
7ab6e7fc
GH
133 if (!object_class_by_name(name)) {
134 module_load_qom_one(name);
135 }
9940b2cf
MA
136 return DEVICE(object_new(name));
137}
138
9940b2cf
MA
139DeviceState *qdev_try_new(const char *name)
140{
7ab6e7fc 141 if (!module_object_class_by_name(name)) {
9940b2cf
MA
142 return NULL;
143 }
9940b2cf
MA
144 return DEVICE(object_new(name));
145}
146
eae3eb3e 147static QTAILQ_HEAD(, DeviceListener) device_listeners
707ff800
PD
148 = QTAILQ_HEAD_INITIALIZER(device_listeners);
149
150enum ListenerDirection { Forward, Reverse };
151
152#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
153 do { \
154 DeviceListener *_listener; \
155 \
156 switch (_direction) { \
157 case Forward: \
158 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
159 if (_listener->_callback) { \
160 _listener->_callback(_listener, ##_args); \
161 } \
162 } \
163 break; \
164 case Reverse: \
165 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
eae3eb3e 166 link) { \
707ff800
PD
167 if (_listener->_callback) { \
168 _listener->_callback(_listener, ##_args); \
169 } \
170 } \
171 break; \
172 default: \
173 abort(); \
174 } \
175 } while (0)
176
177static int device_listener_add(DeviceState *dev, void *opaque)
178{
179 DEVICE_LISTENER_CALL(realize, Forward, dev);
180
181 return 0;
182}
183
184void device_listener_register(DeviceListener *listener)
185{
186 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
187
188 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
189 NULL, NULL);
190}
191
192void device_listener_unregister(DeviceListener *listener)
193{
194 QTAILQ_REMOVE(&device_listeners, listener, link);
195}
196
f3a85056
JF
197bool qdev_should_hide_device(QemuOpts *opts)
198{
199 int rc = -1;
200 DeviceListener *listener;
201
202 QTAILQ_FOREACH(listener, &device_listeners, link) {
203 if (listener->should_be_hidden) {
204 /*
205 * should_be_hidden_will return
206 * 1 if device matches opts and it should be hidden
207 * 0 if device matches opts and should not be hidden
208 * -1 if device doesn't match ops
209 */
210 rc = listener->should_be_hidden(listener, opts);
211 }
212
213 if (rc > 0) {
214 break;
215 }
216 }
217
218 return rc > 0;
219}
220
4d2ffa08
JK
221void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
222 int required_for_version)
223{
7983c8a3 224 assert(!dev->realized);
4d2ffa08
JK
225 dev->instance_id_alias = alias_id;
226 dev->alias_required_for_version = required_for_version;
227}
228
03fcbd9d
TH
229HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
230{
231 MachineState *machine;
232 MachineClass *mc;
233 Object *m_obj = qdev_get_machine();
234
235 if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
236 machine = MACHINE(m_obj);
237 mc = MACHINE_GET_CLASS(machine);
238 if (mc->get_hotplug_handler) {
239 return mc->get_hotplug_handler(machine, dev);
240 }
241 }
242
243 return NULL;
244}
245
d2321d31
PX
246bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
247{
248 MachineState *machine;
249 MachineClass *mc;
250 Object *m_obj = qdev_get_machine();
251
252 if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
253 machine = MACHINE(m_obj);
254 mc = MACHINE_GET_CLASS(machine);
255 if (mc->hotplug_allowed) {
256 return mc->hotplug_allowed(machine, dev, errp);
257 }
258 }
259
260 return true;
261}
262
14405c27
DH
263HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
264{
265 if (dev->parent_bus) {
266 return dev->parent_bus->hotplug_handler;
267 }
268 return NULL;
269}
270
c06b2ffb 271HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
7716b8ca 272{
17cc0128 273 HotplugHandler *hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
7716b8ca 274
17cc0128 275 if (hotplug_ctrl == NULL && dev->parent_bus) {
14405c27 276 hotplug_ctrl = qdev_get_bus_hotplug_handler(dev);
7716b8ca
IM
277 }
278 return hotplug_ctrl;
279}
280
70804c83
DH
281static int qdev_prereset(DeviceState *dev, void *opaque)
282{
283 trace_qdev_reset_tree(dev, object_get_typename(OBJECT(dev)));
284 return 0;
285}
286
287static int qbus_prereset(BusState *bus, void *opaque)
288{
289 trace_qbus_reset_tree(bus, object_get_typename(OBJECT(bus)));
290 return 0;
291}
292
ec990eb6
AL
293static int qdev_reset_one(DeviceState *dev, void *opaque)
294{
f703a04c 295 device_legacy_reset(dev);
ec990eb6
AL
296
297 return 0;
298}
299
b4694b7c
IY
300static int qbus_reset_one(BusState *bus, void *opaque)
301{
0d936928 302 BusClass *bc = BUS_GET_CLASS(bus);
70804c83 303 trace_qbus_reset(bus, object_get_typename(OBJECT(bus)));
0d936928 304 if (bc->reset) {
dcc20931 305 bc->reset(bus);
b4694b7c
IY
306 }
307 return 0;
308}
309
5af0a04b
IY
310void qdev_reset_all(DeviceState *dev)
311{
70804c83
DH
312 trace_qdev_reset_all(dev, object_get_typename(OBJECT(dev)));
313 qdev_walk_children(dev, qdev_prereset, qbus_prereset,
314 qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
315}
316
ff8de075
DH
317void qdev_reset_all_fn(void *opaque)
318{
319 qdev_reset_all(DEVICE(opaque));
320}
321
d0508c36
PB
322void qbus_reset_all(BusState *bus)
323{
70804c83
DH
324 trace_qbus_reset_all(bus, object_get_typename(OBJECT(bus)));
325 qbus_walk_children(bus, qdev_prereset, qbus_prereset,
326 qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
327}
328
80376c3f
IY
329void qbus_reset_all_fn(void *opaque)
330{
331 BusState *bus = opaque;
d0508c36 332 qbus_reset_all(bus);
80376c3f
IY
333}
334
abb89dbf
DH
335void device_cold_reset(DeviceState *dev)
336{
337 resettable_reset(OBJECT(dev), RESET_TYPE_COLD);
338}
339
c11256aa
DH
340bool device_is_in_reset(DeviceState *dev)
341{
342 return resettable_is_in_reset(OBJECT(dev));
343}
344
345static ResettableState *device_get_reset_state(Object *obj)
346{
347 DeviceState *dev = DEVICE(obj);
348 return &dev->reset;
349}
350
351static void device_reset_child_foreach(Object *obj, ResettableChildCallback cb,
352 void *opaque, ResetType type)
353{
354 DeviceState *dev = DEVICE(obj);
355 BusState *bus;
356
357 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
358 cb(OBJECT(bus), opaque, type);
359 }
360}
361
3418bd25 362/* can be used as ->unplug() callback for the simple cases */
014176f9
IM
363void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
364 DeviceState *dev, Error **errp)
365{
dc3edf8d 366 qdev_unrealize(dev);
014176f9 367}
3b29a101 368
9940b2cf
MA
369bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp)
370{
9940b2cf 371 assert(!dev->realized && !dev->parent_bus);
9940b2cf 372
510ef98d
MA
373 if (bus) {
374 qdev_set_parent_bus(dev, bus);
375 } else {
376 assert(!DEVICE_GET_CLASS(dev)->bus_type);
377 }
9940b2cf 378
f07ad48d 379 return object_property_set_bool(OBJECT(dev), "realized", true, errp);
9940b2cf
MA
380}
381
9940b2cf
MA
382bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp)
383{
384 bool ret;
385
386 ret = qdev_realize(dev, bus, errp);
387 object_unref(OBJECT(dev));
388 return ret;
389}
390
391void qdev_unrealize(DeviceState *dev)
392{
5325cc34 393 object_property_set_bool(OBJECT(dev), "realized", false, &error_abort);
9940b2cf
MA
394}
395
dfe8c79c
MA
396static int qdev_assert_realized_properly(Object *obj, void *opaque)
397{
398 DeviceState *dev = DEVICE(object_dynamic_cast(obj, TYPE_DEVICE));
399 DeviceClass *dc;
400
401 if (dev) {
402 dc = DEVICE_GET_CLASS(dev);
403 assert(dev->realized);
404 assert(dev->parent_bus || !dc->bus_type);
405 }
406 return 0;
407}
408
3418bd25
GH
409void qdev_machine_creation_done(void)
410{
411 /*
412 * ok, initial machine setup is done, starting from now we can
413 * only create hotpluggable devices
414 */
9bed84c1 415 qdev_hotplug = true;
dfe8c79c
MA
416
417 object_child_foreach_recursive(object_get_root(),
418 qdev_assert_realized_properly, NULL);
3418bd25
GH
419}
420
0ac8ef71
AW
421bool qdev_machine_modified(void)
422{
423 return qdev_hot_added || qdev_hot_removed;
424}
425
02e2da45 426BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 427{
02e2da45 428 return dev->parent_bus;
aae9460e
PB
429}
430
a5f54290
PC
431static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
432 const char *name)
433{
434 NamedGPIOList *ngl;
435
436 QLIST_FOREACH(ngl, &dev->gpios, node) {
3a87dde8
MAL
437 /* NULL is a valid and matchable name. */
438 if (g_strcmp0(name, ngl->name) == 0) {
a5f54290
PC
439 return ngl;
440 }
441 }
442
443 ngl = g_malloc0(sizeof(*ngl));
444 ngl->name = g_strdup(name);
445 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
446 return ngl;
447}
448
4a151677
PM
449void qdev_init_gpio_in_named_with_opaque(DeviceState *dev,
450 qemu_irq_handler handler,
451 void *opaque,
452 const char *name, int n)
a5f54290 453{
a69bef1c 454 int i;
a5f54290
PC
455 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
456
b235a71f 457 assert(gpio_list->num_out == 0 || !name);
a5f54290 458 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
4a151677 459 opaque, n);
a69bef1c 460
6c76b377
PF
461 if (!name) {
462 name = "unnamed-gpio-in";
463 }
a69bef1c 464 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
6c76b377
PF
465 gchar *propname = g_strdup_printf("%s[%u]", name, i);
466
a69bef1c 467 object_property_add_child(OBJECT(dev), propname,
d2623129 468 OBJECT(gpio_list->in[i]));
6c76b377 469 g_free(propname);
a69bef1c 470 }
a69bef1c 471
a5f54290
PC
472 gpio_list->num_in += n;
473}
474
aae9460e
PB
475void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
476{
a5f54290
PC
477 qdev_init_gpio_in_named(dev, handler, NULL, n);
478}
479
480void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
481 const char *name, int n)
482{
688b057a 483 int i;
a5f54290
PC
484 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
485
b235a71f 486 assert(gpio_list->num_in == 0 || !name);
688b057a 487
6c76b377
PF
488 if (!name) {
489 name = "unnamed-gpio-out";
490 }
491 memset(pins, 0, sizeof(*pins) * n);
688b057a 492 for (i = 0; i < n; ++i) {
6c76b377
PF
493 gchar *propname = g_strdup_printf("%s[%u]", name,
494 gpio_list->num_out + i);
495
688b057a
PC
496 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
497 (Object **)&pins[i],
498 object_property_allow_set_link,
d2623129 499 OBJ_PROP_LINK_STRONG);
6c76b377 500 g_free(propname);
688b057a 501 }
6c76b377 502 gpio_list->num_out += n;
aae9460e
PB
503}
504
505void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
506{
a5f54290
PC
507 qdev_init_gpio_out_named(dev, pins, NULL, n);
508}
509
510qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
511{
512 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
513
514 assert(n >= 0 && n < gpio_list->num_in);
515 return gpio_list->in[n];
aae9460e
PB
516}
517
518qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
519{
a5f54290
PC
520 return qdev_get_gpio_in_named(dev, NULL, n);
521}
522
523void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
524 qemu_irq pin)
525{
02757df2
PC
526 char *propname = g_strdup_printf("%s[%d]",
527 name ? name : "unnamed-gpio-out", n);
9f742c28
MA
528 if (pin && !OBJECT(pin)->parent) {
529 /* We need a name for object_property_set_link to work */
88950eef
AF
530 object_property_add_child(container_get(qdev_get_machine(),
531 "/unattached"),
d2623129 532 "non-qdev-gpio[*]", OBJECT(pin));
02757df2 533 }
5325cc34 534 object_property_set_link(OBJECT(dev), propname, OBJECT(pin), &error_abort);
02757df2 535 g_free(propname);
aae9460e
PB
536}
537
b7973186
AG
538qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
539{
2244f233 540 g_autofree char *propname = g_strdup_printf("%s[%d]",
b7973186
AG
541 name ? name : "unnamed-gpio-out", n);
542
543 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
544 NULL);
545
546 return ret;
547}
548
67cc32eb 549/* disconnect a GPIO output, returning the disconnected input (if any) */
0c24db2b
PC
550
551static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
552 const char *name, int n)
553{
554 char *propname = g_strdup_printf("%s[%d]",
555 name ? name : "unnamed-gpio-out", n);
556
557 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
558 NULL);
559 if (ret) {
5325cc34 560 object_property_set_link(OBJECT(dev), propname, NULL, NULL);
0c24db2b
PC
561 }
562 g_free(propname);
563 return ret;
564}
a5f54290 565
0c24db2b
PC
566qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
567 const char *name, int n)
568{
569 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
570 qdev_connect_gpio_out_named(dev, name, n, icpt);
571 return disconnected;
aae9460e
PB
572}
573
574void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
575{
a5f54290 576 qdev_connect_gpio_out_named(dev, NULL, n, pin);
aae9460e
PB
577}
578
17a96a14
PC
579void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
580 const char *name)
581{
582 int i;
583 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
584
585 for (i = 0; i < ngl->num_in; i++) {
586 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
587 char *propname = g_strdup_printf("%s[%d]", nm, i);
588
589 object_property_add_alias(OBJECT(container), propname,
d2623129 590 OBJECT(dev), propname);
6bc5cf92 591 g_free(propname);
17a96a14
PC
592 }
593 for (i = 0; i < ngl->num_out; i++) {
594 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
595 char *propname = g_strdup_printf("%s[%d]", nm, i);
596
597 object_property_add_alias(OBJECT(container), propname,
d2623129 598 OBJECT(dev), propname);
6bc5cf92 599 g_free(propname);
17a96a14
PC
600 }
601 QLIST_REMOVE(ngl, node);
602 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
603}
604
02e2da45 605BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 606{
02e2da45 607 BusState *bus;
f698c8ba
PC
608 Object *child = object_resolve_path_component(OBJECT(dev), name);
609
610 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
611 if (bus) {
612 return bus;
613 }
4d6ae674 614
72cf2d4f 615 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 616 if (strcmp(name, bus->name) == 0) {
02e2da45 617 return bus;
4d6ae674
PB
618 }
619 }
620 return NULL;
621}
622
0293214b
PB
623int qdev_walk_children(DeviceState *dev,
624 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
625 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
626 void *opaque)
81699d8a
AL
627{
628 BusState *bus;
629 int err;
630
0293214b
PB
631 if (pre_devfn) {
632 err = pre_devfn(dev, opaque);
81699d8a
AL
633 if (err) {
634 return err;
635 }
636 }
637
638 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
639 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
640 post_devfn, post_busfn, opaque);
81699d8a
AL
641 if (err < 0) {
642 return err;
643 }
644 }
645
0293214b
PB
646 if (post_devfn) {
647 err = post_devfn(dev, opaque);
648 if (err) {
649 return err;
650 }
651 }
652
81699d8a
AL
653 return 0;
654}
655
a2ee6b4f 656DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 657{
0866aca1
AL
658 BusChild *kid;
659 DeviceState *ret;
3418bd25
GH
660 BusState *child;
661
0866aca1
AL
662 QTAILQ_FOREACH(kid, &bus->children, sibling) {
663 DeviceState *dev = kid->child;
664
665 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 666 return dev;
0866aca1
AL
667 }
668
3418bd25
GH
669 QLIST_FOREACH(child, &dev->child_bus, sibling) {
670 ret = qdev_find_recursive(child, id);
671 if (ret) {
672 return ret;
673 }
674 }
675 }
676 return NULL;
677}
678
09e5ab63 679char *qdev_get_dev_path(DeviceState *dev)
85ed303b 680{
0d936928 681 BusClass *bc;
09e5ab63
AL
682
683 if (!dev || !dev->parent_bus) {
684 return NULL;
685 }
686
0d936928
AL
687 bc = BUS_GET_CLASS(dev->parent_bus);
688 if (bc->get_dev_path) {
689 return bc->get_dev_path(dev);
09e5ab63
AL
690 }
691
692 return NULL;
44677ded 693}
a5296ca9
AL
694
695/**
696 * Legacy property handling
697 */
698
d7bce999
EB
699static void qdev_get_legacy_property(Object *obj, Visitor *v,
700 const char *name, void *opaque,
701 Error **errp)
a5296ca9 702{
57c9fafe 703 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
704 Property *prop = opaque;
705
e3cb6ba6
PB
706 char buffer[1024];
707 char *ptr = buffer;
a5296ca9 708
e3cb6ba6 709 prop->info->print(dev, prop, buffer, sizeof(buffer));
51e72bc1 710 visit_type_str(v, name, &ptr, errp);
a5296ca9
AL
711}
712
a5296ca9 713/**
77b06bba 714 * qdev_class_add_legacy_property:
d9d8d452
C
715 * @dev: Device to add the property to.
716 * @prop: The qdev property definition.
d9d8d452
C
717 *
718 * Add a legacy QOM property to @dev for qdev property @prop.
a5296ca9 719 *
d9d8d452
C
720 * Legacy properties are string versions of QOM properties. The format of
721 * the string depends on the property type. Legacy properties are only
722 * needed for "info qtree".
a5296ca9 723 *
6871a0d0 724 * Do not use this in new code! QOM Properties added through this interface
d9d8d452 725 * will be given names in the "legacy" namespace.
a5296ca9 726 */
77b06bba 727static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
a5296ca9 728{
77b06bba 729 g_autofree char *name = NULL;
a5296ca9 730
f3be016d 731 /* Register pointer properties as legacy properties */
03ff7770 732 if (!prop->info->print && prop->info->get) {
68ee3569
PB
733 return;
734 }
f3be016d 735
ca2cc788 736 name = g_strdup_printf("legacy-%s", prop->name);
77b06bba
MAL
737 object_class_property_add(OBJECT_CLASS(dc), name, "str",
738 prop->info->print ? qdev_get_legacy_property : prop->info->get,
d2623129 739 NULL, NULL, prop);
ca2cc788
PB
740}
741
94d912d1 742void qdev_property_add_static(DeviceState *dev, Property *prop)
ca2cc788 743{
fdae245f 744 Object *obj = OBJECT(dev);
77b06bba 745 ObjectProperty *op;
fdae245f 746
77b06bba
MAL
747 assert(!prop->info->create);
748
749 op = object_property_add(obj, prop->name, prop->info->name,
750 prop->info->get, prop->info->set,
751 prop->info->release,
d2623129 752 prop);
b8c9cd5c
GA
753
754 object_property_set_description(obj, prop->name,
7eecec7d 755 prop->info->description);
b8c9cd5c 756
5cc56cc6 757 if (prop->set_default) {
77b06bba
MAL
758 prop->info->set_default_value(op, prop);
759 if (op->init) {
760 op->init(obj, op);
761 }
fdae245f 762 }
6a146eba 763}
1de81d28 764
77b06bba
MAL
765static void qdev_class_add_property(DeviceClass *klass, Property *prop)
766{
767 ObjectClass *oc = OBJECT_CLASS(klass);
768
769 if (prop->info->create) {
40c2281c 770 prop->info->create(oc, prop);
77b06bba
MAL
771 } else {
772 ObjectProperty *op;
773
774 op = object_class_property_add(oc,
775 prop->name, prop->info->name,
776 prop->info->get, prop->info->set,
777 prop->info->release,
d2623129 778 prop);
77b06bba
MAL
779 if (prop->set_default) {
780 prop->info->set_default_value(op, prop);
781 }
782 }
783 object_class_property_set_description(oc, prop->name,
7eecec7d 784 prop->info->description);
77b06bba
MAL
785}
786
67cc7e0a
SH
787void qdev_alias_all_properties(DeviceState *target, Object *source)
788{
789 ObjectClass *class;
790 Property *prop;
791
792 class = object_get_class(OBJECT(target));
793 do {
794 DeviceClass *dc = DEVICE_CLASS(class);
795
385d8f22 796 for (prop = dc->props_; prop && prop->name; prop++) {
67cc7e0a 797 object_property_add_alias(source, prop->name,
d2623129 798 OBJECT(target), prop->name);
67cc7e0a
SH
799 }
800 class = object_class_get_parent(class);
801 } while (class != object_class_by_name(TYPE_DEVICE));
802}
803
a7737e44 804static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
805{
806 DeviceState *dev = DEVICE(obj);
807 return dev->realized;
808}
809
40f03bd5 810static bool check_only_migratable(Object *obj, Error **errp)
1bfe5f05
JQ
811{
812 DeviceClass *dc = DEVICE_GET_CLASS(obj);
813
814 if (!vmstate_check_only_migratable(dc->vmsd)) {
40f03bd5 815 error_setg(errp, "Device %s is not migratable, but "
1bfe5f05
JQ
816 "--only-migratable was specified",
817 object_get_typename(obj));
818 return false;
819 }
820
821 return true;
822}
823
a7737e44 824static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
825{
826 DeviceState *dev = DEVICE(obj);
827 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 828 HotplugHandler *hotplug_ctrl;
5c21ce77 829 BusState *bus;
0e6934f2 830 NamedClockList *ncl;
249d4172 831 Error *local_err = NULL;
69382d8b
IM
832 bool unattached_parent = false;
833 static int unattached_count;
249d4172 834
1a37eca1 835 if (dev->hotplugged && !dc->hotpluggable) {
c6bd8c70 836 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
837 return;
838 }
839
249d4172 840 if (value && !dev->realized) {
a5f9b9df 841 if (!check_only_migratable(obj, errp)) {
7562f907
AA
842 goto fail;
843 }
844
d578029e 845 if (!obj->parent) {
249d4172
AF
846 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
847
848 object_property_add_child(container_get(qdev_get_machine(),
849 "/unattached"),
d2623129 850 name, obj);
69382d8b 851 unattached_parent = true;
249d4172
AF
852 g_free(name);
853 }
854
41346263
IM
855 hotplug_ctrl = qdev_get_hotplug_handler(dev);
856 if (hotplug_ctrl) {
857 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
858 if (local_err != NULL) {
859 goto fail;
860 }
861 }
862
a7ddba52
IM
863 if (dc->realize) {
864 dc->realize(dev, &local_err);
40f03bd5
VSO
865 if (local_err != NULL) {
866 goto fail;
867 }
1d45a705
GA
868 }
869
707ff800
PD
870 DEVICE_LISTENER_CALL(realize, Forward, dev);
871
04162f8f
MR
872 /*
873 * always free/re-initialize here since the value cannot be cleaned up
874 * in device_unrealize due to its usage later on in the unplug path
875 */
876 g_free(dev->canonical_path);
877 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
0e6934f2
DH
878 QLIST_FOREACH(ncl, &dev->clocks, node) {
879 if (ncl->alias) {
880 continue;
881 } else {
882 clock_setup_canonical_path(ncl->clock);
883 }
884 }
04162f8f 885
1d45a705 886 if (qdev_get_vmsd(dev)) {
3cad405b 887 if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
1df2c9a2
PX
888 VMSTATE_INSTANCE_ID_ANY,
889 qdev_get_vmsd(dev), dev,
67980031
DDAG
890 dev->instance_id_alias,
891 dev->alias_required_for_version,
892 &local_err) < 0) {
893 goto post_realize_fail;
894 }
249d4172 895 }
1d45a705 896
e755e127
DH
897 /*
898 * Clear the reset state, in case the object was previously unrealized
899 * with a dirty state.
900 */
901 resettable_state_clear(&dev->reset);
902
1d45a705 903 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
f1483b46 904 if (!qbus_realize(bus, errp)) {
1d45a705 905 goto child_realize_fail;
5c21ce77
BD
906 }
907 }
1d45a705 908 if (dev->hotplugged) {
e755e127
DH
909 /*
910 * Reset the device, as well as its subtree which, at this point,
911 * should be realized too.
912 */
913 resettable_assert_reset(OBJECT(dev), RESET_TYPE_COLD);
914 resettable_change_parent(OBJECT(dev), OBJECT(dev->parent_bus),
915 NULL);
916 resettable_release_reset(OBJECT(dev), RESET_TYPE_COLD);
249d4172 917 }
352e8da7 918 dev->pending_deleted_event = false;
25e89788
SH
919
920 if (hotplug_ctrl) {
8b5e6caf
IM
921 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
922 if (local_err != NULL) {
923 goto child_realize_fail;
924 }
925 }
926
249d4172 927 } else if (!value && dev->realized) {
5c21ce77 928 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
f1483b46 929 qbus_unrealize(bus);
5c21ce77 930 }
cd4520ad 931 if (qdev_get_vmsd(dev)) {
3cad405b 932 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
fe6c2117 933 }
cd4520ad 934 if (dc->unrealize) {
b69c3c21 935 dc->unrealize(dev);
249d4172 936 }
352e8da7 937 dev->pending_deleted_event = true;
707ff800 938 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
249d4172
AF
939 }
940
40f03bd5 941 assert(local_err == NULL);
c7f8d0f3 942 dev->realized = value;
1d45a705
GA
943 return;
944
945child_realize_fail:
946 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
f1483b46 947 qbus_unrealize(bus);
1d45a705
GA
948 }
949
950 if (qdev_get_vmsd(dev)) {
3cad405b 951 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
1d45a705
GA
952 }
953
954post_realize_fail:
04162f8f
MR
955 g_free(dev->canonical_path);
956 dev->canonical_path = NULL;
1d45a705 957 if (dc->unrealize) {
b69c3c21 958 dc->unrealize(dev);
1d45a705
GA
959 }
960
961fail:
962 error_propagate(errp, local_err);
69382d8b 963 if (unattached_parent) {
9940b2cf
MA
964 /*
965 * Beware, this doesn't just revert
966 * object_property_add_child(), it also runs bus_remove()!
967 */
69382d8b
IM
968 object_unparent(OBJECT(dev));
969 unattached_count--;
970 }
249d4172
AF
971}
972
a7737e44 973static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
974{
975 DeviceClass *dc = DEVICE_GET_CLASS(obj);
976 DeviceState *dev = DEVICE(obj);
977
2b81b35f 978 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 979 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
980}
981
40f03bd5 982static bool device_get_hotplugged(Object *obj, Error **errp)
d012ffc1
IM
983{
984 DeviceState *dev = DEVICE(obj);
985
986 return dev->hotplugged;
987}
988
9674bfe4
AL
989static void device_initfn(Object *obj)
990{
991 DeviceState *dev = DEVICE(obj);
9674bfe4
AL
992
993 if (qdev_hotplug) {
994 dev->hotplugged = 1;
995 qdev_hot_added = true;
996 }
997
998 dev->instance_id_alias = -1;
7983c8a3 999 dev->realized = false;
a1190ab6 1000 dev->allow_unplug_during_migration = false;
9674bfe4 1001
a5f54290 1002 QLIST_INIT(&dev->gpios);
0e6934f2 1003 QLIST_INIT(&dev->clocks);
9674bfe4
AL
1004}
1005
1c3994f6
MAL
1006static void device_post_init(Object *obj)
1007{
1a3ec8c1
MA
1008 /*
1009 * Note: ordered so that the user's global properties take
1010 * precedence.
1011 */
1c3994f6 1012 object_apply_compat_props(obj);
25f8dd96 1013 qdev_prop_set_globals(DEVICE(obj));
99a0b036
EH
1014}
1015
60adba37
AL
1016/* Unlink device from bus and free the structure. */
1017static void device_finalize(Object *obj)
1018{
a5f54290
PC
1019 NamedGPIOList *ngl, *next;
1020
60adba37 1021 DeviceState *dev = DEVICE(obj);
a5f54290
PC
1022
1023 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
1024 QLIST_REMOVE(ngl, node);
f173d57a 1025 qemu_free_irqs(ngl->in, ngl->num_in);
a5f54290
PC
1026 g_free(ngl->name);
1027 g_free(ngl);
1028 /* ngl->out irqs are owned by the other end and should not be freed
1029 * here
1030 */
1031 }
f7b879e0 1032
0e6934f2
DH
1033 qdev_finalize_clocklist(dev);
1034
f7b879e0
MR
1035 /* Only send event if the device had been completely realized */
1036 if (dev->pending_deleted_event) {
1037 g_assert(dev->canonical_path);
1038
3ab72385 1039 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path);
f7b879e0
MR
1040 g_free(dev->canonical_path);
1041 dev->canonical_path = NULL;
1042 }
1043
1044 qemu_opts_del(dev->opts);
60adba37
AL
1045}
1046
bce54474
PB
1047static void device_class_base_init(ObjectClass *class, void *data)
1048{
1049 DeviceClass *klass = DEVICE_CLASS(class);
1050
1051 /* We explicitly look up properties in the superclasses,
1052 * so do not propagate them to the subclasses.
1053 */
385d8f22 1054 klass->props_ = NULL;
60adba37
AL
1055}
1056
5d5b24d0 1057static void device_unparent(Object *obj)
667d22d1
PB
1058{
1059 DeviceState *dev = DEVICE(obj);
06f7f2bb 1060 BusState *bus;
667d22d1 1061
5c21ce77 1062 if (dev->realized) {
dc3edf8d 1063 qdev_unrealize(dev);
5c21ce77 1064 }
06f7f2bb
PB
1065 while (dev->num_child_bus) {
1066 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 1067 object_unparent(OBJECT(bus));
06f7f2bb 1068 }
06f7f2bb 1069 if (dev->parent_bus) {
5d5b24d0 1070 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
1071 object_unref(OBJECT(dev->parent_bus));
1072 dev->parent_bus = NULL;
5d5b24d0 1073 }
667d22d1
PB
1074}
1075
107b5969
MAL
1076static char *
1077device_vmstate_if_get_id(VMStateIf *obj)
1078{
1079 DeviceState *dev = DEVICE(obj);
1080
1081 return qdev_get_dev_path(dev);
1082}
1083
c11256aa
DH
1084/**
1085 * device_phases_reset:
1086 * Transition reset method for devices to allow moving
1087 * smoothly from legacy reset method to multi-phases
1088 */
1089static void device_phases_reset(DeviceState *dev)
1090{
1091 ResettableClass *rc = RESETTABLE_GET_CLASS(dev);
1092
1093 if (rc->phases.enter) {
1094 rc->phases.enter(OBJECT(dev), RESET_TYPE_COLD);
1095 }
1096 if (rc->phases.hold) {
1097 rc->phases.hold(OBJECT(dev));
1098 }
1099 if (rc->phases.exit) {
1100 rc->phases.exit(OBJECT(dev));
1101 }
1102}
1103
1104static void device_transitional_reset(Object *obj)
1105{
1106 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1107
1108 /*
1109 * This will call either @device_phases_reset (for multi-phases transitioned
1110 * devices) or a device's specific method for not-yet transitioned devices.
1111 * In both case, it does not reset children.
1112 */
1113 if (dc->reset) {
1114 dc->reset(DEVICE(obj));
1115 }
1116}
1117
1118/**
1119 * device_get_transitional_reset:
1120 * check if the device's class is ready for multi-phase
1121 */
1122static ResettableTrFunction device_get_transitional_reset(Object *obj)
1123{
1124 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1125 if (dc->reset != device_phases_reset) {
1126 /*
1127 * dc->reset has been overridden by a subclass,
1128 * the device is not ready for multi phase yet.
1129 */
1130 return device_transitional_reset;
1131 }
1132 return NULL;
1133}
1134
667d22d1
PB
1135static void device_class_init(ObjectClass *class, void *data)
1136{
249d4172 1137 DeviceClass *dc = DEVICE_CLASS(class);
107b5969 1138 VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
c11256aa 1139 ResettableClass *rc = RESETTABLE_CLASS(class);
249d4172 1140
5d5b24d0 1141 class->unparent = device_unparent;
267a3264
IM
1142
1143 /* by default all devices were considered as hotpluggable,
1144 * so with intent to check it in generic qdev_unplug() /
1145 * device_set_realized() functions make every device
1146 * hotpluggable. Devices that shouldn't be hotpluggable,
1147 * should override it in their class_init()
1148 */
1149 dc->hotpluggable = true;
e90f2a8c 1150 dc->user_creatable = true;
107b5969 1151 vc->get_id = device_vmstate_if_get_id;
c11256aa
DH
1152 rc->get_state = device_get_reset_state;
1153 rc->child_foreach = device_reset_child_foreach;
1154
1155 /*
1156 * @device_phases_reset is put as the default reset method below, allowing
1157 * to do the multi-phase transition from base classes to leaf classes. It
1158 * allows a legacy-reset Device class to extend a multi-phases-reset
1159 * Device class for the following reason:
1160 * + If a base class B has been moved to multi-phase, then it does not
1161 * override this default reset method and may have defined phase methods.
1162 * + A child class C (extending class B) which uses
1163 * device_class_set_parent_reset() (or similar means) to override the
1164 * reset method will still work as expected. @device_phases_reset function
1165 * will be registered as the parent reset method and effectively call
1166 * parent reset phases.
1167 */
1168 dc->reset = device_phases_reset;
1169 rc->get_transitional_function = device_get_transitional_reset;
c68fc935
MAL
1170
1171 object_class_property_add_bool(class, "realized",
d2623129 1172 device_get_realized, device_set_realized);
c68fc935 1173 object_class_property_add_bool(class, "hotpluggable",
d2623129 1174 device_get_hotpluggable, NULL);
c68fc935 1175 object_class_property_add_bool(class, "hotplugged",
d2623129 1176 device_get_hotplugged, NULL);
c68fc935 1177 object_class_property_add_link(class, "parent_bus", TYPE_BUS,
d2623129 1178 offsetof(DeviceState, parent_bus), NULL, 0);
667d22d1
PB
1179}
1180
4f67d30b
MAL
1181void device_class_set_props(DeviceClass *dc, Property *props)
1182{
77b06bba
MAL
1183 Property *prop;
1184
385d8f22 1185 dc->props_ = props;
77b06bba
MAL
1186 for (prop = props; prop && prop->name; prop++) {
1187 qdev_class_add_legacy_property(dc, prop);
1188 qdev_class_add_property(dc, prop);
1189 }
4f67d30b
MAL
1190}
1191
46795cf2
PMD
1192void device_class_set_parent_reset(DeviceClass *dc,
1193 DeviceReset dev_reset,
1194 DeviceReset *parent_reset)
1195{
1196 *parent_reset = dc->reset;
1197 dc->reset = dev_reset;
1198}
1199
1200void device_class_set_parent_realize(DeviceClass *dc,
1201 DeviceRealize dev_realize,
1202 DeviceRealize *parent_realize)
1203{
1204 *parent_realize = dc->realize;
1205 dc->realize = dev_realize;
1206}
1207
1208void device_class_set_parent_unrealize(DeviceClass *dc,
1209 DeviceUnrealize dev_unrealize,
1210 DeviceUnrealize *parent_unrealize)
1211{
1212 *parent_unrealize = dc->unrealize;
1213 dc->unrealize = dev_unrealize;
1214}
1215
f703a04c 1216void device_legacy_reset(DeviceState *dev)
94afdadc
AL
1217{
1218 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1219
70804c83 1220 trace_qdev_reset(dev, object_get_typename(OBJECT(dev)));
94afdadc
AL
1221 if (klass->reset) {
1222 klass->reset(dev);
1223 }
1224}
1225
f05f6b4a
PB
1226Object *qdev_get_machine(void)
1227{
1228 static Object *dev;
1229
1230 if (dev == NULL) {
dfe47e70 1231 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
1232 }
1233
1234 return dev;
1235}
1236
8c43a6f0 1237static const TypeInfo device_type_info = {
32fea402
AL
1238 .name = TYPE_DEVICE,
1239 .parent = TYPE_OBJECT,
1240 .instance_size = sizeof(DeviceState),
9674bfe4 1241 .instance_init = device_initfn,
99a0b036 1242 .instance_post_init = device_post_init,
60adba37 1243 .instance_finalize = device_finalize,
bce54474 1244 .class_base_init = device_class_base_init,
667d22d1 1245 .class_init = device_class_init,
32fea402
AL
1246 .abstract = true,
1247 .class_size = sizeof(DeviceClass),
107b5969
MAL
1248 .interfaces = (InterfaceInfo[]) {
1249 { TYPE_VMSTATE_IF },
c11256aa 1250 { TYPE_RESETTABLE_INTERFACE },
107b5969
MAL
1251 { }
1252 }
32fea402
AL
1253};
1254
83f7d43a 1255static void qdev_register_types(void)
32fea402
AL
1256{
1257 type_register_static(&device_type_info);
1258}
1259
83f7d43a 1260type_init(qdev_register_types)
This page took 1.163472 seconds and 4 git commands to generate.