]> git.proxmox.com Git - mirror_qemu.git/blame - hw/core/qdev.c
hw/intc/arm_gicv3_kvm: Reset GICv3 cpu interface registers
[mirror_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"
83c9f4ca 29#include "hw/qdev.h"
6b1566cb 30#include "hw/fw-path-provider.h"
9c17d615 31#include "sysemu/sysemu.h"
b4a42f81 32#include "qapi/qmp/qerror.h"
7b1b5d19 33#include "qapi/visitor.h"
0402a5d6 34#include "qapi/qmp/qjson.h"
d49b6836 35#include "qemu/error-report.h"
0ee4de6c 36#include "hw/hotplug.h"
b7454548 37#include "hw/boards.h"
7474f1be 38#include "hw/sysbus.h"
24b699fb 39#include "qapi-event.h"
aae9460e 40
ee46d8a5 41int qdev_hotplug = 0;
0ac8ef71
AW
42static bool qdev_hot_added = false;
43static bool qdev_hot_removed = false;
3418bd25 44
4be9f0d1
AL
45const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
46{
6e008585
AL
47 DeviceClass *dc = DEVICE_GET_CLASS(dev);
48 return dc->vmsd;
4be9f0d1
AL
49}
50
4be9f0d1
AL
51const char *qdev_fw_name(DeviceState *dev)
52{
6e008585 53 DeviceClass *dc = DEVICE_GET_CLASS(dev);
4be9f0d1 54
6e008585
AL
55 if (dc->fw_name) {
56 return dc->fw_name;
4be9f0d1
AL
57 }
58
59 return object_get_typename(OBJECT(dev));
60}
61
0866aca1 62static void bus_remove_child(BusState *bus, DeviceState *child)
0c17542d 63{
0866aca1
AL
64 BusChild *kid;
65
66 QTAILQ_FOREACH(kid, &bus->children, sibling) {
67 if (kid->child == child) {
68 char name[32];
69
70 snprintf(name, sizeof(name), "child[%d]", kid->index);
71 QTAILQ_REMOVE(&bus->children, kid, sibling);
9d127820
PB
72
73 /* This gives back ownership of kid->child back to us. */
0866aca1 74 object_property_del(OBJECT(bus), name, NULL);
9d127820 75 object_unref(OBJECT(kid->child));
0866aca1
AL
76 g_free(kid);
77 return;
78 }
79 }
80}
81
82static void bus_add_child(BusState *bus, DeviceState *child)
83{
84 char name[32];
85 BusChild *kid = g_malloc0(sizeof(*kid));
0c17542d 86
0866aca1
AL
87 kid->index = bus->max_index++;
88 kid->child = child;
9d127820 89 object_ref(OBJECT(kid->child));
a5296ca9 90
0866aca1
AL
91 QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
92
9d127820 93 /* This transfers ownership of kid->child to the property. */
0866aca1
AL
94 snprintf(name, sizeof(name), "child[%d]", kid->index);
95 object_property_add_link(OBJECT(bus), name,
96 object_get_typename(OBJECT(child)),
39f72ef9
SH
97 (Object **)&kid->child,
98 NULL, /* read-only property */
99 0, /* return ownership on prop deletion */
100 NULL);
0866aca1
AL
101}
102
103void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
104{
9fbe6127 105 dev->parent_bus = bus;
62d7ba66 106 object_ref(OBJECT(bus));
0866aca1 107 bus_add_child(bus, dev);
0c17542d
MA
108}
109
0210afe6
MA
110/* Create a new device. This only initializes the device state
111 structure and allows properties to be set. The device still needs
112 to be realized. See qdev-core.h. */
02e2da45 113DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
114{
115 DeviceState *dev;
116
117 dev = qdev_try_create(bus, name);
118 if (!dev) {
e92714c7 119 if (bus) {
312fd5f2 120 error_report("Unknown device '%s' for bus '%s'", name,
23e3fbec 121 object_get_typename(OBJECT(bus)));
e92714c7 122 } else {
312fd5f2 123 error_report("Unknown device '%s' for default sysbus", name);
e92714c7 124 }
01ed1d52 125 abort();
0bcdeda7
BS
126 }
127
128 return dev;
129}
130
da57febf 131DeviceState *qdev_try_create(BusState *bus, const char *type)
aae9460e 132{
9fbe6127
AL
133 DeviceState *dev;
134
da57febf 135 if (object_class_by_name(type) == NULL) {
4ed658ca
AF
136 return NULL;
137 }
da57febf 138 dev = DEVICE(object_new(type));
9fbe6127
AL
139 if (!dev) {
140 return NULL;
141 }
142
10c4c98a 143 if (!bus) {
7474f1be
PM
144 /* Assert that the device really is a SysBusDevice before
145 * we put it onto the sysbus. Non-sysbus devices which aren't
146 * being put onto a bus should be created with object_new(TYPE_FOO),
147 * not qdev_create(NULL, TYPE_FOO).
148 */
149 g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
68694897 150 bus = sysbus_get_default();
10c4c98a
GH
151 }
152
9fbe6127 153 qdev_set_parent_bus(dev, bus);
b09995ae 154 object_unref(OBJECT(dev));
9fbe6127 155 return dev;
aae9460e
PB
156}
157
707ff800
PD
158static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
159 = QTAILQ_HEAD_INITIALIZER(device_listeners);
160
161enum ListenerDirection { Forward, Reverse };
162
163#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
164 do { \
165 DeviceListener *_listener; \
166 \
167 switch (_direction) { \
168 case Forward: \
169 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
170 if (_listener->_callback) { \
171 _listener->_callback(_listener, ##_args); \
172 } \
173 } \
174 break; \
175 case Reverse: \
176 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
177 device_listeners, link) { \
178 if (_listener->_callback) { \
179 _listener->_callback(_listener, ##_args); \
180 } \
181 } \
182 break; \
183 default: \
184 abort(); \
185 } \
186 } while (0)
187
188static int device_listener_add(DeviceState *dev, void *opaque)
189{
190 DEVICE_LISTENER_CALL(realize, Forward, dev);
191
192 return 0;
193}
194
195void device_listener_register(DeviceListener *listener)
196{
197 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
198
199 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
200 NULL, NULL);
201}
202
203void device_listener_unregister(DeviceListener *listener)
204{
205 QTAILQ_REMOVE(&device_listeners, listener, link);
206}
207
a7737e44 208static void device_realize(DeviceState *dev, Error **errp)
249d4172
AF
209{
210 DeviceClass *dc = DEVICE_GET_CLASS(dev);
da57febf 211
249d4172
AF
212 if (dc->init) {
213 int rc = dc->init(dev);
214 if (rc < 0) {
a7737e44 215 error_setg(errp, "Device initialization failed.");
249d4172
AF
216 return;
217 }
5ab28c83 218 }
02e2da45
PB
219}
220
fe6c2117
AF
221static void device_unrealize(DeviceState *dev, Error **errp)
222{
223 DeviceClass *dc = DEVICE_GET_CLASS(dev);
224
225 if (dc->exit) {
226 int rc = dc->exit(dev);
227 if (rc < 0) {
228 error_setg(errp, "Device exit failed.");
229 return;
230 }
231 }
232}
233
4d2ffa08
JK
234void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
235 int required_for_version)
236{
7983c8a3 237 assert(!dev->realized);
4d2ffa08
JK
238 dev->instance_id_alias = alias_id;
239 dev->alias_required_for_version = required_for_version;
240}
241
c06b2ffb 242HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
7716b8ca
IM
243{
244 HotplugHandler *hotplug_ctrl = NULL;
245
246 if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
247 hotplug_ctrl = dev->parent_bus->hotplug_handler;
248 } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
249 MachineState *machine = MACHINE(qdev_get_machine());
250 MachineClass *mc = MACHINE_GET_CLASS(machine);
251
252 if (mc->get_hotplug_handler) {
253 hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
254 }
255 }
256 return hotplug_ctrl;
257}
258
56f9107e 259void qdev_unplug(DeviceState *dev, Error **errp)
3418bd25 260{
6e008585 261 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca
IM
262 HotplugHandler *hotplug_ctrl;
263 HotplugHandlerClass *hdc;
6e008585 264
39b888bd 265 if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
c6bd8c70 266 error_setg(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
56f9107e 267 return;
3418bd25 268 }
593831de 269
1a37eca1 270 if (!dc->hotpluggable) {
c6bd8c70
MA
271 error_setg(errp, QERR_DEVICE_NO_HOTPLUG,
272 object_get_typename(OBJECT(dev)));
1a37eca1
IM
273 return;
274 }
275
0ac8ef71
AW
276 qdev_hot_removed = true;
277
7716b8ca
IM
278 hotplug_ctrl = qdev_get_hotplug_handler(dev);
279 /* hotpluggable device MUST have HotplugHandler, if it doesn't
280 * then something is very wrong with it */
281 g_assert(hotplug_ctrl);
282
283 /* If device supports async unplug just request it to be done,
284 * otherwise just remove it synchronously */
285 hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
286 if (hdc->unplug_request) {
287 hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
5e954943 288 } else {
7716b8ca 289 hotplug_handler_unplug(hotplug_ctrl, dev, errp);
56f9107e 290 }
3418bd25
GH
291}
292
ec990eb6
AL
293static int qdev_reset_one(DeviceState *dev, void *opaque)
294{
94afdadc 295 device_reset(dev);
ec990eb6
AL
296
297 return 0;
298}
299
b4694b7c
IY
300static int qbus_reset_one(BusState *bus, void *opaque)
301{
0d936928
AL
302 BusClass *bc = BUS_GET_CLASS(bus);
303 if (bc->reset) {
dcc20931 304 bc->reset(bus);
b4694b7c
IY
305 }
306 return 0;
307}
308
5af0a04b
IY
309void qdev_reset_all(DeviceState *dev)
310{
dcc20931 311 qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
312}
313
ff8de075
DH
314void qdev_reset_all_fn(void *opaque)
315{
316 qdev_reset_all(DEVICE(opaque));
317}
318
d0508c36
PB
319void qbus_reset_all(BusState *bus)
320{
dcc20931 321 qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
322}
323
80376c3f
IY
324void qbus_reset_all_fn(void *opaque)
325{
326 BusState *bus = opaque;
d0508c36 327 qbus_reset_all(bus);
80376c3f
IY
328}
329
3418bd25 330/* can be used as ->unplug() callback for the simple cases */
014176f9
IM
331void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
332 DeviceState *dev, Error **errp)
333{
2d9a982f
IM
334 /* just zap it */
335 object_unparent(OBJECT(dev));
014176f9 336}
3b29a101 337
0210afe6
MA
338/*
339 * Realize @dev.
340 * Device properties should be set before calling this function. IRQs
341 * and MMIO regions should be connected/mapped after calling this
342 * function.
343 * On failure, report an error with error_report() and terminate the
344 * program. This is okay during machine creation. Don't use for
345 * hotplug, because there callers need to recover from failure.
346 * Exception: if you know the device's init() callback can't fail,
347 * then qdev_init_nofail() can't fail either, and is therefore usable
348 * even then. But relying on the device implementation that way is
349 * somewhat unclean, and best avoided.
350 */
e23a1b33
MA
351void qdev_init_nofail(DeviceState *dev)
352{
c4bacafb 353 Error *err = NULL;
7de3abe5 354
c4bacafb
MA
355 assert(!dev->realized);
356
0d4104e5 357 object_ref(OBJECT(dev));
c4bacafb
MA
358 object_property_set_bool(OBJECT(dev), true, "realized", &err);
359 if (err) {
c29b77f9
MA
360 error_reportf_err(err, "Initialization of device %s failed: ",
361 object_get_typename(OBJECT(dev)));
bd6c9a61
MA
362 exit(1);
363 }
0d4104e5 364 object_unref(OBJECT(dev));
e23a1b33
MA
365}
366
3418bd25
GH
367void qdev_machine_creation_done(void)
368{
369 /*
370 * ok, initial machine setup is done, starting from now we can
371 * only create hotpluggable devices
372 */
373 qdev_hotplug = 1;
374}
375
0ac8ef71
AW
376bool qdev_machine_modified(void)
377{
378 return qdev_hot_added || qdev_hot_removed;
379}
380
02e2da45 381BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 382{
02e2da45 383 return dev->parent_bus;
aae9460e
PB
384}
385
a5f54290
PC
386static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
387 const char *name)
388{
389 NamedGPIOList *ngl;
390
391 QLIST_FOREACH(ngl, &dev->gpios, node) {
392 /* NULL is a valid and matchable name, otherwise do a normal
393 * strcmp match.
394 */
395 if ((!ngl->name && !name) ||
396 (name && ngl->name && strcmp(name, ngl->name) == 0)) {
397 return ngl;
398 }
399 }
400
401 ngl = g_malloc0(sizeof(*ngl));
402 ngl->name = g_strdup(name);
403 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
404 return ngl;
405}
406
407void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler,
408 const char *name, int n)
409{
a69bef1c 410 int i;
a5f54290
PC
411 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
412
b235a71f 413 assert(gpio_list->num_out == 0 || !name);
a5f54290
PC
414 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
415 dev, n);
a69bef1c 416
6c76b377
PF
417 if (!name) {
418 name = "unnamed-gpio-in";
419 }
a69bef1c 420 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
6c76b377
PF
421 gchar *propname = g_strdup_printf("%s[%u]", name, i);
422
a69bef1c
PC
423 object_property_add_child(OBJECT(dev), propname,
424 OBJECT(gpio_list->in[i]), &error_abort);
6c76b377 425 g_free(propname);
a69bef1c 426 }
a69bef1c 427
a5f54290
PC
428 gpio_list->num_in += n;
429}
430
aae9460e
PB
431void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
432{
a5f54290
PC
433 qdev_init_gpio_in_named(dev, handler, NULL, n);
434}
435
436void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
437 const char *name, int n)
438{
688b057a 439 int i;
a5f54290
PC
440 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
441
b235a71f 442 assert(gpio_list->num_in == 0 || !name);
688b057a 443
6c76b377
PF
444 if (!name) {
445 name = "unnamed-gpio-out";
446 }
447 memset(pins, 0, sizeof(*pins) * n);
688b057a 448 for (i = 0; i < n; ++i) {
6c76b377
PF
449 gchar *propname = g_strdup_printf("%s[%u]", name,
450 gpio_list->num_out + i);
451
688b057a
PC
452 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
453 (Object **)&pins[i],
454 object_property_allow_set_link,
455 OBJ_PROP_LINK_UNREF_ON_RELEASE,
456 &error_abort);
6c76b377 457 g_free(propname);
688b057a 458 }
6c76b377 459 gpio_list->num_out += n;
aae9460e
PB
460}
461
462void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
463{
a5f54290
PC
464 qdev_init_gpio_out_named(dev, pins, NULL, n);
465}
466
467qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
468{
469 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
470
471 assert(n >= 0 && n < gpio_list->num_in);
472 return gpio_list->in[n];
aae9460e
PB
473}
474
475qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
476{
a5f54290
PC
477 return qdev_get_gpio_in_named(dev, NULL, n);
478}
479
480void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
481 qemu_irq pin)
482{
02757df2
PC
483 char *propname = g_strdup_printf("%s[%d]",
484 name ? name : "unnamed-gpio-out", n);
485 if (pin) {
486 /* We need a name for object_property_set_link to work. If the
487 * object has a parent, object_property_add_child will come back
488 * with an error without doing anything. If it has none, it will
489 * never fail. So we can just call it with a NULL Error pointer.
490 */
88950eef
AF
491 object_property_add_child(container_get(qdev_get_machine(),
492 "/unattached"),
493 "non-qdev-gpio[*]", OBJECT(pin), NULL);
02757df2
PC
494 }
495 object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
496 g_free(propname);
aae9460e
PB
497}
498
b7973186
AG
499qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
500{
501 char *propname = g_strdup_printf("%s[%d]",
502 name ? name : "unnamed-gpio-out", n);
503
504 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
505 NULL);
506
507 return ret;
508}
509
67cc32eb 510/* disconnect a GPIO output, returning the disconnected input (if any) */
0c24db2b
PC
511
512static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
513 const char *name, int n)
514{
515 char *propname = g_strdup_printf("%s[%d]",
516 name ? name : "unnamed-gpio-out", n);
517
518 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
519 NULL);
520 if (ret) {
521 object_property_set_link(OBJECT(dev), NULL, propname, NULL);
522 }
523 g_free(propname);
524 return ret;
525}
a5f54290 526
0c24db2b
PC
527qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
528 const char *name, int n)
529{
530 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
531 qdev_connect_gpio_out_named(dev, name, n, icpt);
532 return disconnected;
aae9460e
PB
533}
534
535void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
536{
a5f54290 537 qdev_connect_gpio_out_named(dev, NULL, n, pin);
aae9460e
PB
538}
539
17a96a14
PC
540void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
541 const char *name)
542{
543 int i;
544 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
545
546 for (i = 0; i < ngl->num_in; i++) {
547 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
548 char *propname = g_strdup_printf("%s[%d]", nm, i);
549
550 object_property_add_alias(OBJECT(container), propname,
551 OBJECT(dev), propname,
552 &error_abort);
6bc5cf92 553 g_free(propname);
17a96a14
PC
554 }
555 for (i = 0; i < ngl->num_out; i++) {
556 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
557 char *propname = g_strdup_printf("%s[%d]", nm, i);
558
559 object_property_add_alias(OBJECT(container), propname,
560 OBJECT(dev), propname,
561 &error_abort);
6bc5cf92 562 g_free(propname);
17a96a14
PC
563 }
564 QLIST_REMOVE(ngl, node);
565 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
566}
567
02e2da45 568BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 569{
02e2da45 570 BusState *bus;
f698c8ba
PC
571 Object *child = object_resolve_path_component(OBJECT(dev), name);
572
573 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
574 if (bus) {
575 return bus;
576 }
4d6ae674 577
72cf2d4f 578 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 579 if (strcmp(name, bus->name) == 0) {
02e2da45 580 return bus;
4d6ae674
PB
581 }
582 }
583 return NULL;
584}
585
0293214b
PB
586int qdev_walk_children(DeviceState *dev,
587 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
588 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
589 void *opaque)
81699d8a
AL
590{
591 BusState *bus;
592 int err;
593
0293214b
PB
594 if (pre_devfn) {
595 err = pre_devfn(dev, opaque);
81699d8a
AL
596 if (err) {
597 return err;
598 }
599 }
600
601 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
602 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
603 post_devfn, post_busfn, opaque);
81699d8a
AL
604 if (err < 0) {
605 return err;
606 }
607 }
608
0293214b
PB
609 if (post_devfn) {
610 err = post_devfn(dev, opaque);
611 if (err) {
612 return err;
613 }
614 }
615
81699d8a
AL
616 return 0;
617}
618
a2ee6b4f 619DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 620{
0866aca1
AL
621 BusChild *kid;
622 DeviceState *ret;
3418bd25
GH
623 BusState *child;
624
0866aca1
AL
625 QTAILQ_FOREACH(kid, &bus->children, sibling) {
626 DeviceState *dev = kid->child;
627
628 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 629 return dev;
0866aca1
AL
630 }
631
3418bd25
GH
632 QLIST_FOREACH(child, &dev->child_bus, sibling) {
633 ret = qdev_find_recursive(child, id);
634 if (ret) {
635 return ret;
636 }
637 }
638 }
639 return NULL;
640}
641
0d936928
AL
642static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
643{
644 BusClass *bc = BUS_GET_CLASS(bus);
645
646 if (bc->get_fw_dev_path) {
647 return bc->get_fw_dev_path(dev);
131ec1bd 648 }
0d936928
AL
649
650 return NULL;
131ec1bd
GH
651}
652
6b1566cb
PB
653static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
654{
655 Object *obj = OBJECT(dev);
656 char *d = NULL;
657
658 while (!d && obj->parent) {
659 obj = obj->parent;
660 d = fw_path_provider_try_get_dev_path(obj, bus, dev);
661 }
662 return d;
663}
664
0be63901
GA
665char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev)
666{
667 Object *obj = OBJECT(dev);
668
669 return fw_path_provider_try_get_dev_path(obj, bus, dev);
670}
671
1ca4d09a
GN
672static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
673{
674 int l = 0;
675
676 if (dev && dev->parent_bus) {
677 char *d;
678 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
6b1566cb
PB
679 d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev);
680 if (!d) {
681 d = bus_get_fw_dev_path(dev->parent_bus, dev);
682 }
0d936928 683 if (d) {
1ca4d09a 684 l += snprintf(p + l, size - l, "%s", d);
7267c094 685 g_free(d);
1ca4d09a 686 } else {
bbfa18fc 687 return l;
1ca4d09a
GN
688 }
689 }
690 l += snprintf(p + l , size - l, "/");
691
692 return l;
693}
694
695char* qdev_get_fw_dev_path(DeviceState *dev)
696{
697 char path[128];
698 int l;
699
700 l = qdev_get_fw_dev_path_helper(dev, path, 128);
701
702 path[l-1] = '\0';
703
a5cf8262 704 return g_strdup(path);
1ca4d09a 705}
85ed303b 706
09e5ab63 707char *qdev_get_dev_path(DeviceState *dev)
85ed303b 708{
0d936928 709 BusClass *bc;
09e5ab63
AL
710
711 if (!dev || !dev->parent_bus) {
712 return NULL;
713 }
714
0d936928
AL
715 bc = BUS_GET_CLASS(dev->parent_bus);
716 if (bc->get_dev_path) {
717 return bc->get_dev_path(dev);
09e5ab63
AL
718 }
719
720 return NULL;
44677ded 721}
a5296ca9
AL
722
723/**
724 * Legacy property handling
725 */
726
d7bce999
EB
727static void qdev_get_legacy_property(Object *obj, Visitor *v,
728 const char *name, void *opaque,
729 Error **errp)
a5296ca9 730{
57c9fafe 731 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
732 Property *prop = opaque;
733
e3cb6ba6
PB
734 char buffer[1024];
735 char *ptr = buffer;
a5296ca9 736
e3cb6ba6 737 prop->info->print(dev, prop, buffer, sizeof(buffer));
51e72bc1 738 visit_type_str(v, name, &ptr, errp);
a5296ca9
AL
739}
740
a5296ca9 741/**
d9d8d452
C
742 * qdev_property_add_legacy:
743 * @dev: Device to add the property to.
744 * @prop: The qdev property definition.
745 * @errp: location to store error information.
746 *
747 * Add a legacy QOM property to @dev for qdev property @prop.
748 * On error, store error in @errp.
a5296ca9 749 *
d9d8d452
C
750 * Legacy properties are string versions of QOM properties. The format of
751 * the string depends on the property type. Legacy properties are only
752 * needed for "info qtree".
a5296ca9 753 *
d9d8d452
C
754 * Do not use this is new code! QOM Properties added through this interface
755 * will be given names in the "legacy" namespace.
a5296ca9 756 */
f5a014d2
SW
757static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
758 Error **errp)
a5296ca9 759{
7ce7ffe0 760 gchar *name;
a5296ca9 761
f3be016d 762 /* Register pointer properties as legacy properties */
03ff7770 763 if (!prop->info->print && prop->info->get) {
68ee3569
PB
764 return;
765 }
f3be016d 766
ca2cc788 767 name = g_strdup_printf("legacy-%s", prop->name);
7ce7ffe0 768 object_property_add(OBJECT(dev), name, "str",
68ee3569 769 prop->info->print ? qdev_get_legacy_property : prop->info->get,
03ff7770 770 NULL,
57c9fafe
AL
771 NULL,
772 prop, errp);
a5296ca9 773
ca2cc788
PB
774 g_free(name);
775}
776
777/**
d9d8d452
C
778 * qdev_property_add_static:
779 * @dev: Device to add the property to.
780 * @prop: The qdev property definition.
781 * @errp: location to store error information.
ca2cc788 782 *
d9d8d452
C
783 * Add a static QOM property to @dev for qdev property @prop.
784 * On error, store error in @errp. Static properties access data in a struct.
785 * The type of the QOM property is derived from prop->info.
ca2cc788
PB
786 */
787void qdev_property_add_static(DeviceState *dev, Property *prop,
788 Error **errp)
789{
fdae245f
PB
790 Error *local_err = NULL;
791 Object *obj = OBJECT(dev);
792
d822979b
PB
793 /*
794 * TODO qdev_prop_ptr does not have getters or setters. It must
795 * go now that it can be replaced with links. The test should be
796 * removed along with it: all static properties are read/write.
797 */
798 if (!prop->info->get && !prop->info->set) {
799 return;
800 }
801
fdae245f 802 object_property_add(obj, prop->name, prop->info->name,
57c9fafe 803 prop->info->get, prop->info->set,
dd0ba250 804 prop->info->release,
fdae245f
PB
805 prop, &local_err);
806
807 if (local_err) {
808 error_propagate(errp, local_err);
809 return;
810 }
b8c9cd5c
GA
811
812 object_property_set_description(obj, prop->name,
813 prop->info->description,
814 &error_abort);
815
fdae245f
PB
816 if (prop->qtype == QTYPE_NONE) {
817 return;
818 }
819
820 if (prop->qtype == QTYPE_QBOOL) {
5433a0a8 821 object_property_set_bool(obj, prop->defval, prop->name, &error_abort);
fdae245f
PB
822 } else if (prop->info->enum_table) {
823 object_property_set_str(obj, prop->info->enum_table[prop->defval],
5433a0a8 824 prop->name, &error_abort);
fdae245f 825 } else if (prop->qtype == QTYPE_QINT) {
5433a0a8 826 object_property_set_int(obj, prop->defval, prop->name, &error_abort);
fdae245f 827 }
6a146eba 828}
1de81d28 829
67cc7e0a
SH
830/* @qdev_alias_all_properties - Add alias properties to the source object for
831 * all qdev properties on the target DeviceState.
832 */
833void qdev_alias_all_properties(DeviceState *target, Object *source)
834{
835 ObjectClass *class;
836 Property *prop;
837
838 class = object_get_class(OBJECT(target));
839 do {
840 DeviceClass *dc = DEVICE_CLASS(class);
841
842 for (prop = dc->props; prop && prop->name; prop++) {
843 object_property_add_alias(source, prop->name,
844 OBJECT(target), prop->name,
845 &error_abort);
846 }
847 class = object_class_get_parent(class);
848 } while (class != object_class_by_name(TYPE_DEVICE));
849}
850
4cae4d5a 851static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
66e56b13
ZG
852{
853 GSList **list = opaque;
09d56017
JL
854 DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
855 TYPE_DEVICE);
856
857 if (dev == NULL) {
858 return 0;
859 }
66e56b13
ZG
860
861 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
862 *list = g_slist_append(*list, dev);
863 }
864
66e56b13
ZG
865 return 0;
866}
867
4cae4d5a
MA
868GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
869{
870 GSList *list = NULL;
871
872 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
873
874 return list;
875}
876
a7737e44 877static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
878{
879 DeviceState *dev = DEVICE(obj);
880 return dev->realized;
881}
882
a7737e44 883static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
884{
885 DeviceState *dev = DEVICE(obj);
886 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 887 HotplugHandler *hotplug_ctrl;
5c21ce77 888 BusState *bus;
249d4172 889 Error *local_err = NULL;
69382d8b
IM
890 bool unattached_parent = false;
891 static int unattached_count;
249d4172 892
1a37eca1 893 if (dev->hotplugged && !dc->hotpluggable) {
c6bd8c70 894 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
895 return;
896 }
897
249d4172 898 if (value && !dev->realized) {
d578029e 899 if (!obj->parent) {
249d4172
AF
900 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
901
902 object_property_add_child(container_get(qdev_get_machine(),
903 "/unattached"),
d578029e 904 name, obj, &error_abort);
69382d8b 905 unattached_parent = true;
249d4172
AF
906 g_free(name);
907 }
908
41346263
IM
909 hotplug_ctrl = qdev_get_hotplug_handler(dev);
910 if (hotplug_ctrl) {
911 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
912 if (local_err != NULL) {
913 goto fail;
914 }
915 }
916
a7ddba52
IM
917 if (dc->realize) {
918 dc->realize(dev, &local_err);
919 }
920
1d45a705
GA
921 if (local_err != NULL) {
922 goto fail;
923 }
924
707ff800
PD
925 DEVICE_LISTENER_CALL(realize, Forward, dev);
926
7716b8ca
IM
927 if (hotplug_ctrl) {
928 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
5e954943
IM
929 }
930
1d45a705
GA
931 if (local_err != NULL) {
932 goto post_realize_fail;
933 }
934
935 if (qdev_get_vmsd(dev)) {
67980031
DDAG
936 if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
937 dev->instance_id_alias,
938 dev->alias_required_for_version,
939 &local_err) < 0) {
940 goto post_realize_fail;
941 }
249d4172 942 }
1d45a705
GA
943
944 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
945 object_property_set_bool(OBJECT(bus), true, "realized",
5c21ce77 946 &local_err);
1d45a705
GA
947 if (local_err != NULL) {
948 goto child_realize_fail;
5c21ce77
BD
949 }
950 }
1d45a705 951 if (dev->hotplugged) {
249d4172
AF
952 device_reset(dev);
953 }
352e8da7 954 dev->pending_deleted_event = false;
249d4172 955 } else if (!value && dev->realized) {
cd4520ad 956 Error **local_errp = NULL;
5c21ce77 957 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
cd4520ad 958 local_errp = local_err ? NULL : &local_err;
5c21ce77 959 object_property_set_bool(OBJECT(bus), false, "realized",
cd4520ad 960 local_errp);
5c21ce77 961 }
cd4520ad 962 if (qdev_get_vmsd(dev)) {
fe6c2117
AF
963 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
964 }
cd4520ad
GA
965 if (dc->unrealize) {
966 local_errp = local_err ? NULL : &local_err;
967 dc->unrealize(dev, local_errp);
249d4172 968 }
352e8da7 969 dev->pending_deleted_event = true;
707ff800 970 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
c7f8d0f3 971 }
249d4172 972
c7f8d0f3
XG
973 if (local_err != NULL) {
974 goto fail;
249d4172
AF
975 }
976
c7f8d0f3 977 dev->realized = value;
1d45a705
GA
978 return;
979
980child_realize_fail:
981 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
982 object_property_set_bool(OBJECT(bus), false, "realized",
983 NULL);
984 }
985
986 if (qdev_get_vmsd(dev)) {
987 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
988 }
989
990post_realize_fail:
991 if (dc->unrealize) {
992 dc->unrealize(dev, NULL);
993 }
994
995fail:
996 error_propagate(errp, local_err);
69382d8b
IM
997 if (unattached_parent) {
998 object_unparent(OBJECT(dev));
999 unattached_count--;
1000 }
249d4172
AF
1001}
1002
a7737e44 1003static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
1004{
1005 DeviceClass *dc = DEVICE_GET_CLASS(obj);
1006 DeviceState *dev = DEVICE(obj);
1007
2b81b35f 1008 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 1009 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
1010}
1011
d012ffc1
IM
1012static bool device_get_hotplugged(Object *obj, Error **err)
1013{
1014 DeviceState *dev = DEVICE(obj);
1015
1016 return dev->hotplugged;
1017}
1018
1019static void device_set_hotplugged(Object *obj, bool value, Error **err)
1020{
1021 DeviceState *dev = DEVICE(obj);
1022
1023 dev->hotplugged = value;
1024}
1025
9674bfe4
AL
1026static void device_initfn(Object *obj)
1027{
1028 DeviceState *dev = DEVICE(obj);
bce54474 1029 ObjectClass *class;
9674bfe4
AL
1030 Property *prop;
1031
1032 if (qdev_hotplug) {
1033 dev->hotplugged = 1;
1034 qdev_hot_added = true;
1035 }
1036
1037 dev->instance_id_alias = -1;
7983c8a3 1038 dev->realized = false;
9674bfe4 1039
249d4172
AF
1040 object_property_add_bool(obj, "realized",
1041 device_get_realized, device_set_realized, NULL);
1a37eca1
IM
1042 object_property_add_bool(obj, "hotpluggable",
1043 device_get_hotpluggable, NULL, NULL);
d012ffc1
IM
1044 object_property_add_bool(obj, "hotplugged",
1045 device_get_hotplugged, device_set_hotplugged,
1046 &error_abort);
249d4172 1047
bce54474
PB
1048 class = object_get_class(OBJECT(dev));
1049 do {
1050 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
5433a0a8
PC
1051 qdev_property_add_legacy(dev, prop, &error_abort);
1052 qdev_property_add_static(dev, prop, &error_abort);
bce54474 1053 }
bce54474
PB
1054 class = object_class_get_parent(class);
1055 } while (class != object_class_by_name(TYPE_DEVICE));
9674bfe4 1056
f968fc68 1057 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
39f72ef9 1058 (Object **)&dev->parent_bus, NULL, 0,
9561fda8 1059 &error_abort);
a5f54290 1060 QLIST_INIT(&dev->gpios);
9674bfe4
AL
1061}
1062
99a0b036
EH
1063static void device_post_init(Object *obj)
1064{
25f8dd96 1065 qdev_prop_set_globals(DEVICE(obj));
99a0b036
EH
1066}
1067
60adba37
AL
1068/* Unlink device from bus and free the structure. */
1069static void device_finalize(Object *obj)
1070{
a5f54290
PC
1071 NamedGPIOList *ngl, *next;
1072
60adba37 1073 DeviceState *dev = DEVICE(obj);
a5f54290
PC
1074
1075 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
1076 QLIST_REMOVE(ngl, node);
f173d57a 1077 qemu_free_irqs(ngl->in, ngl->num_in);
a5f54290
PC
1078 g_free(ngl->name);
1079 g_free(ngl);
1080 /* ngl->out irqs are owned by the other end and should not be freed
1081 * here
1082 */
1083 }
60adba37
AL
1084}
1085
bce54474
PB
1086static void device_class_base_init(ObjectClass *class, void *data)
1087{
1088 DeviceClass *klass = DEVICE_CLASS(class);
1089
1090 /* We explicitly look up properties in the superclasses,
1091 * so do not propagate them to the subclasses.
1092 */
1093 klass->props = NULL;
60adba37
AL
1094}
1095
5d5b24d0 1096static void device_unparent(Object *obj)
667d22d1
PB
1097{
1098 DeviceState *dev = DEVICE(obj);
06f7f2bb 1099 BusState *bus;
667d22d1 1100
5c21ce77
BD
1101 if (dev->realized) {
1102 object_property_set_bool(obj, false, "realized", NULL);
1103 }
06f7f2bb
PB
1104 while (dev->num_child_bus) {
1105 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 1106 object_unparent(OBJECT(bus));
06f7f2bb 1107 }
06f7f2bb 1108 if (dev->parent_bus) {
5d5b24d0 1109 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
1110 object_unref(OBJECT(dev->parent_bus));
1111 dev->parent_bus = NULL;
5d5b24d0 1112 }
0402a5d6 1113
b1ee5829 1114 /* Only send event if the device had been completely realized */
352e8da7 1115 if (dev->pending_deleted_event) {
b1ee5829
AL
1116 gchar *path = object_get_canonical_path(OBJECT(dev));
1117
24b699fb 1118 qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort);
b1ee5829 1119 g_free(path);
0402a5d6 1120 }
abed886e
PB
1121
1122 qemu_opts_del(dev->opts);
1123 dev->opts = NULL;
667d22d1
PB
1124}
1125
1126static void device_class_init(ObjectClass *class, void *data)
1127{
249d4172
AF
1128 DeviceClass *dc = DEVICE_CLASS(class);
1129
5d5b24d0 1130 class->unparent = device_unparent;
249d4172 1131 dc->realize = device_realize;
fe6c2117 1132 dc->unrealize = device_unrealize;
267a3264
IM
1133
1134 /* by default all devices were considered as hotpluggable,
1135 * so with intent to check it in generic qdev_unplug() /
1136 * device_set_realized() functions make every device
1137 * hotpluggable. Devices that shouldn't be hotpluggable,
1138 * should override it in their class_init()
1139 */
1140 dc->hotpluggable = true;
667d22d1
PB
1141}
1142
94afdadc
AL
1143void device_reset(DeviceState *dev)
1144{
1145 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1146
1147 if (klass->reset) {
1148 klass->reset(dev);
1149 }
1150}
1151
f05f6b4a
PB
1152Object *qdev_get_machine(void)
1153{
1154 static Object *dev;
1155
1156 if (dev == NULL) {
dfe47e70 1157 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
1158 }
1159
1160 return dev;
1161}
1162
8c43a6f0 1163static const TypeInfo device_type_info = {
32fea402
AL
1164 .name = TYPE_DEVICE,
1165 .parent = TYPE_OBJECT,
1166 .instance_size = sizeof(DeviceState),
9674bfe4 1167 .instance_init = device_initfn,
99a0b036 1168 .instance_post_init = device_post_init,
60adba37 1169 .instance_finalize = device_finalize,
bce54474 1170 .class_base_init = device_class_base_init,
667d22d1 1171 .class_init = device_class_init,
32fea402
AL
1172 .abstract = true,
1173 .class_size = sizeof(DeviceClass),
1174};
1175
83f7d43a 1176static void qdev_register_types(void)
32fea402
AL
1177{
1178 type_register_static(&device_type_info);
1179}
1180
83f7d43a 1181type_init(qdev_register_types)