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