]> Git Repo - qemu.git/blob - hw/qdev.c
qom: move properties from qdev to object
[qemu.git] / hw / qdev.c
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
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
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
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31
32 int qdev_hotplug = 0;
33 static bool qdev_hot_added = false;
34 static bool qdev_hot_removed = false;
35
36 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
37 static BusState *main_system_bus;
38 static void main_system_bus_create(void);
39
40 /* Register a new device type.  */
41 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
42 {
43     DeviceClass *dc = DEVICE_GET_CLASS(dev);
44     return dc->vmsd;
45 }
46
47 BusInfo *qdev_get_bus_info(DeviceState *dev)
48 {
49     DeviceClass *dc = DEVICE_GET_CLASS(dev);
50     return dc->bus_info;
51 }
52
53 Property *qdev_get_props(DeviceState *dev)
54 {
55     DeviceClass *dc = DEVICE_GET_CLASS(dev);
56     return dc->props;
57 }
58
59 const char *qdev_fw_name(DeviceState *dev)
60 {
61     DeviceClass *dc = DEVICE_GET_CLASS(dev);
62
63     if (dc->fw_name) {
64         return dc->fw_name;
65     }
66
67     return object_get_typename(OBJECT(dev));
68 }
69
70 bool qdev_exists(const char *name)
71 {
72     return !!object_class_by_name(name);
73 }
74
75 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
76                                      Error **errp);
77
78 void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
79 {
80     Property *prop;
81
82     if (qdev_hotplug) {
83         assert(bus->allow_hotplug);
84     }
85
86     dev->parent_bus = bus;
87     QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
88
89     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
90     for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
91         qdev_property_add_legacy(dev, prop, NULL);
92         qdev_property_add_static(dev, prop, NULL);
93     }
94 }
95
96 /* Create a new device.  This only initializes the device state structure
97    and allows properties to be set.  qdev_init should be called to
98    initialize the actual device emulation.  */
99 DeviceState *qdev_create(BusState *bus, const char *name)
100 {
101     DeviceState *dev;
102
103     dev = qdev_try_create(bus, name);
104     if (!dev) {
105         if (bus) {
106             hw_error("Unknown device '%s' for bus '%s'\n", name,
107                      bus->info->name);
108         } else {
109             hw_error("Unknown device '%s' for default sysbus\n", name);
110         }
111     }
112
113     return dev;
114 }
115
116 DeviceState *qdev_try_create(BusState *bus, const char *name)
117 {
118     DeviceState *dev;
119
120     dev = DEVICE(object_new(name));
121     if (!dev) {
122         return NULL;
123     }
124
125     if (!bus) {
126         bus = sysbus_get_default();
127     }
128
129     qdev_set_parent_bus(dev, bus);
130     qdev_prop_set_globals(dev);
131
132     return dev;
133 }
134
135 /* Initialize a device.  Device properties should be set before calling
136    this function.  IRQs and MMIO regions should be connected/mapped after
137    calling this function.
138    On failure, destroy the device and return negative value.
139    Return 0 on success.  */
140 int qdev_init(DeviceState *dev)
141 {
142     DeviceClass *dc = DEVICE_GET_CLASS(dev);
143     int rc;
144
145     assert(dev->state == DEV_STATE_CREATED);
146
147     rc = dc->init(dev);
148     if (rc < 0) {
149         qdev_free(dev);
150         return rc;
151     }
152     if (qdev_get_vmsd(dev)) {
153         vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
154                                        dev->instance_id_alias,
155                                        dev->alias_required_for_version);
156     }
157     dev->state = DEV_STATE_INITIALIZED;
158     if (dev->hotplugged) {
159         device_reset(dev);
160     }
161     return 0;
162 }
163
164 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
165                                  int required_for_version)
166 {
167     assert(dev->state == DEV_STATE_CREATED);
168     dev->instance_id_alias = alias_id;
169     dev->alias_required_for_version = required_for_version;
170 }
171
172 int qdev_unplug(DeviceState *dev)
173 {
174     DeviceClass *dc = DEVICE_GET_CLASS(dev);
175
176     if (!dev->parent_bus->allow_hotplug) {
177         qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
178         return -1;
179     }
180     assert(dc->unplug != NULL);
181
182     qdev_hot_removed = true;
183
184     return dc->unplug(dev);
185 }
186
187 static int qdev_reset_one(DeviceState *dev, void *opaque)
188 {
189     device_reset(dev);
190
191     return 0;
192 }
193
194 BusState *sysbus_get_default(void)
195 {
196     if (!main_system_bus) {
197         main_system_bus_create();
198     }
199     return main_system_bus;
200 }
201
202 static int qbus_reset_one(BusState *bus, void *opaque)
203 {
204     if (bus->info->reset) {
205         return bus->info->reset(bus);
206     }
207     return 0;
208 }
209
210 void qdev_reset_all(DeviceState *dev)
211 {
212     qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
213 }
214
215 void qbus_reset_all_fn(void *opaque)
216 {
217     BusState *bus = opaque;
218     qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
219 }
220
221 /* can be used as ->unplug() callback for the simple cases */
222 int qdev_simple_unplug_cb(DeviceState *dev)
223 {
224     /* just zap it */
225     object_unparent(OBJECT(dev));
226     qdev_free(dev);
227     return 0;
228 }
229
230
231 /* Like qdev_init(), but terminate program via error_report() instead of
232    returning an error value.  This is okay during machine creation.
233    Don't use for hotplug, because there callers need to recover from
234    failure.  Exception: if you know the device's init() callback can't
235    fail, then qdev_init_nofail() can't fail either, and is therefore
236    usable even then.  But relying on the device implementation that
237    way is somewhat unclean, and best avoided.  */
238 void qdev_init_nofail(DeviceState *dev)
239 {
240     if (qdev_init(dev) < 0) {
241         error_report("Initialization of device %s failed",
242                      object_get_typename(OBJECT(dev)));
243         exit(1);
244     }
245 }
246
247 /* Unlink device from bus and free the structure.  */
248 void qdev_free(DeviceState *dev)
249 {
250     BusState *bus;
251     Property *prop;
252     DeviceClass *dc = DEVICE_GET_CLASS(dev);
253
254     if (dev->state == DEV_STATE_INITIALIZED) {
255         while (dev->num_child_bus) {
256             bus = QLIST_FIRST(&dev->child_bus);
257             qbus_free(bus);
258         }
259         if (qdev_get_vmsd(dev)) {
260             vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
261         }
262         if (dc->exit) {
263             dc->exit(dev);
264         }
265         if (dev->opts) {
266             qemu_opts_del(dev->opts);
267         }
268     }
269     QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
270     for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
271         if (prop->info->free) {
272             prop->info->free(dev, prop);
273         }
274     }
275     object_delete(OBJECT(dev));
276 }
277
278 void qdev_machine_creation_done(void)
279 {
280     /*
281      * ok, initial machine setup is done, starting from now we can
282      * only create hotpluggable devices
283      */
284     qdev_hotplug = 1;
285 }
286
287 bool qdev_machine_modified(void)
288 {
289     return qdev_hot_added || qdev_hot_removed;
290 }
291
292 BusState *qdev_get_parent_bus(DeviceState *dev)
293 {
294     return dev->parent_bus;
295 }
296
297 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
298 {
299     assert(dev->num_gpio_in == 0);
300     dev->num_gpio_in = n;
301     dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
302 }
303
304 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
305 {
306     assert(dev->num_gpio_out == 0);
307     dev->num_gpio_out = n;
308     dev->gpio_out = pins;
309 }
310
311 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
312 {
313     assert(n >= 0 && n < dev->num_gpio_in);
314     return dev->gpio_in[n];
315 }
316
317 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
318 {
319     assert(n >= 0 && n < dev->num_gpio_out);
320     dev->gpio_out[n] = pin;
321 }
322
323 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
324 {
325     qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
326     if (nd->vlan)
327         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
328     if (nd->netdev)
329         qdev_prop_set_netdev(dev, "netdev", nd->netdev);
330     if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
331         qdev_prop_exists(dev, "vectors")) {
332         qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
333     }
334     nd->instantiated = 1;
335 }
336
337 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
338 {
339     BusState *bus;
340
341     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
342         if (strcmp(name, bus->name) == 0) {
343             return bus;
344         }
345     }
346     return NULL;
347 }
348
349 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
350                        qbus_walkerfn *busfn, void *opaque)
351 {
352     DeviceState *dev;
353     int err;
354
355     if (busfn) {
356         err = busfn(bus, opaque);
357         if (err) {
358             return err;
359         }
360     }
361
362     QTAILQ_FOREACH(dev, &bus->children, sibling) {
363         err = qdev_walk_children(dev, devfn, busfn, opaque);
364         if (err < 0) {
365             return err;
366         }
367     }
368
369     return 0;
370 }
371
372 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
373                        qbus_walkerfn *busfn, void *opaque)
374 {
375     BusState *bus;
376     int err;
377
378     if (devfn) {
379         err = devfn(dev, opaque);
380         if (err) {
381             return err;
382         }
383     }
384
385     QLIST_FOREACH(bus, &dev->child_bus, sibling) {
386         err = qbus_walk_children(bus, devfn, busfn, opaque);
387         if (err < 0) {
388             return err;
389         }
390     }
391
392     return 0;
393 }
394
395 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
396 {
397     DeviceState *dev, *ret;
398     BusState *child;
399
400     QTAILQ_FOREACH(dev, &bus->children, sibling) {
401         if (dev->id && strcmp(dev->id, id) == 0)
402             return dev;
403         QLIST_FOREACH(child, &dev->child_bus, sibling) {
404             ret = qdev_find_recursive(child, id);
405             if (ret) {
406                 return ret;
407             }
408         }
409     }
410     return NULL;
411 }
412
413 void qbus_create_inplace(BusState *bus, BusInfo *info,
414                          DeviceState *parent, const char *name)
415 {
416     char *buf;
417     int i,len;
418
419     bus->info = info;
420     bus->parent = parent;
421
422     if (name) {
423         /* use supplied name */
424         bus->name = g_strdup(name);
425     } else if (parent && parent->id) {
426         /* parent device has id -> use it for bus name */
427         len = strlen(parent->id) + 16;
428         buf = g_malloc(len);
429         snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
430         bus->name = buf;
431     } else {
432         /* no id -> use lowercase bus type for bus name */
433         len = strlen(info->name) + 16;
434         buf = g_malloc(len);
435         len = snprintf(buf, len, "%s.%d", info->name,
436                        parent ? parent->num_child_bus : 0);
437         for (i = 0; i < len; i++)
438             buf[i] = qemu_tolower(buf[i]);
439         bus->name = buf;
440     }
441
442     QTAILQ_INIT(&bus->children);
443     if (parent) {
444         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
445         parent->num_child_bus++;
446     } else if (bus != main_system_bus) {
447         /* TODO: once all bus devices are qdevified,
448            only reset handler for main_system_bus should be registered here. */
449         qemu_register_reset(qbus_reset_all_fn, bus);
450     }
451 }
452
453 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
454 {
455     BusState *bus;
456
457     bus = g_malloc0(info->size);
458     bus->qdev_allocated = 1;
459     qbus_create_inplace(bus, info, parent, name);
460     return bus;
461 }
462
463 static void main_system_bus_create(void)
464 {
465     /* assign main_system_bus before qbus_create_inplace()
466      * in order to make "if (bus != main_system_bus)" work */
467     main_system_bus = g_malloc0(system_bus_info.size);
468     main_system_bus->qdev_allocated = 1;
469     qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
470                         "main-system-bus");
471 }
472
473 void qbus_free(BusState *bus)
474 {
475     DeviceState *dev;
476
477     while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
478         qdev_free(dev);
479     }
480     if (bus->parent) {
481         QLIST_REMOVE(bus, sibling);
482         bus->parent->num_child_bus--;
483     } else {
484         assert(bus != main_system_bus); /* main_system_bus is never freed */
485         qemu_unregister_reset(qbus_reset_all_fn, bus);
486     }
487     g_free((void*)bus->name);
488     if (bus->qdev_allocated) {
489         g_free(bus);
490     }
491 }
492
493 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
494 {
495     int l = 0;
496
497     if (dev && dev->parent_bus) {
498         char *d;
499         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
500         if (dev->parent_bus->info->get_fw_dev_path) {
501             d = dev->parent_bus->info->get_fw_dev_path(dev);
502             l += snprintf(p + l, size - l, "%s", d);
503             g_free(d);
504         } else {
505             l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
506         }
507     }
508     l += snprintf(p + l , size - l, "/");
509
510     return l;
511 }
512
513 char* qdev_get_fw_dev_path(DeviceState *dev)
514 {
515     char path[128];
516     int l;
517
518     l = qdev_get_fw_dev_path_helper(dev, path, 128);
519
520     path[l-1] = '\0';
521
522     return strdup(path);
523 }
524
525 static char *qdev_get_type(Object *obj, Error **errp)
526 {
527     return g_strdup(object_get_typename(obj));
528 }
529
530 /**
531  * Legacy property handling
532  */
533
534 static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
535                                      const char *name, Error **errp)
536 {
537     DeviceState *dev = DEVICE(obj);
538     Property *prop = opaque;
539
540     char buffer[1024];
541     char *ptr = buffer;
542
543     prop->info->print(dev, prop, buffer, sizeof(buffer));
544     visit_type_str(v, &ptr, name, errp);
545 }
546
547 static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
548                                      const char *name, Error **errp)
549 {
550     DeviceState *dev = DEVICE(obj);
551     Property *prop = opaque;
552     Error *local_err = NULL;
553     char *ptr = NULL;
554     int ret;
555
556     if (dev->state != DEV_STATE_CREATED) {
557         error_set(errp, QERR_PERMISSION_DENIED);
558         return;
559     }
560
561     visit_type_str(v, &ptr, name, &local_err);
562     if (local_err) {
563         error_propagate(errp, local_err);
564         return;
565     }
566
567     ret = prop->info->parse(dev, prop, ptr);
568     error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
569     g_free(ptr);
570 }
571
572 /**
573  * @qdev_add_legacy_property - adds a legacy property
574  *
575  * Do not use this is new code!  Properties added through this interface will
576  * be given names and types in the "legacy" namespace.
577  *
578  * Legacy properties are always processed as strings.  The format of the string
579  * depends on the property type.
580  */
581 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
582                               Error **errp)
583 {
584     gchar *name, *type;
585
586     name = g_strdup_printf("legacy-%s", prop->name);
587     type = g_strdup_printf("legacy<%s>",
588                            prop->info->legacy_name ?: prop->info->name);
589
590     object_property_add(OBJECT(dev), name, type,
591                         prop->info->print ? qdev_get_legacy_property : NULL,
592                         prop->info->parse ? qdev_set_legacy_property : NULL,
593                         NULL,
594                         prop, errp);
595
596     g_free(type);
597     g_free(name);
598 }
599
600 /**
601  * @qdev_property_add_static - add a @Property to a device.
602  *
603  * Static properties access data in a struct.  The actual type of the
604  * property and the field depends on the property type.
605  */
606 void qdev_property_add_static(DeviceState *dev, Property *prop,
607                               Error **errp)
608 {
609     object_property_add(OBJECT(dev), prop->name, prop->info->name,
610                         prop->info->get, prop->info->set,
611                         NULL,
612                         prop, errp);
613 }
614
615 static void device_initfn(Object *obj)
616 {
617     DeviceState *dev = DEVICE(obj);
618     Property *prop;
619
620     if (qdev_hotplug) {
621         dev->hotplugged = 1;
622         qdev_hot_added = true;
623     }
624
625     dev->instance_id_alias = -1;
626     dev->state = DEV_STATE_CREATED;
627
628     qdev_prop_set_defaults(dev, qdev_get_props(dev));
629     for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
630         qdev_property_add_legacy(dev, prop, NULL);
631         qdev_property_add_static(dev, prop, NULL);
632     }
633
634     object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
635 }
636
637 void device_reset(DeviceState *dev)
638 {
639     DeviceClass *klass = DEVICE_GET_CLASS(dev);
640
641     if (klass->reset) {
642         klass->reset(dev);
643     }
644 }
645
646 static TypeInfo device_type_info = {
647     .name = TYPE_DEVICE,
648     .parent = TYPE_OBJECT,
649     .instance_size = sizeof(DeviceState),
650     .instance_init = device_initfn,
651     .abstract = true,
652     .class_size = sizeof(DeviceClass),
653 };
654
655 static void init_qdev(void)
656 {
657     type_register_static(&device_type_info);
658 }
659
660 device_init(init_qdev);
This page took 0.062308 seconds and 4 git commands to generate.