2 * Dynamic device configuration and creation.
4 * Copyright (c) 2009 CodeSourcery
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 /* The theory here is that it should be possible to create a machine without
21 knowledge of specific devices. Historically board init routines have
22 passed a bunch of arguments to each device, requiring the board know
23 exactly which device it is dealing with. This file provides an abstract
24 API for device configuration and initialization. Devices will generally
25 inherit from a particular bus (e.g. PCI or I2C) rather than
33 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
34 static BusState
*main_system_bus
;
36 static DeviceInfo
*device_info_list
;
38 static BusState
*qbus_find_recursive(BusState
*bus
, const char *name
,
40 static BusState
*qbus_find(const char *path
);
42 /* Register a new device type. */
43 void qdev_register(DeviceInfo
*info
)
45 assert(info
->size
>= sizeof(DeviceState
));
48 info
->next
= device_info_list
;
49 device_info_list
= info
;
52 static DeviceInfo
*qdev_find_info(BusInfo
*bus_info
, const char *name
)
56 /* first check device names */
57 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
58 if (bus_info
&& info
->bus_info
!= bus_info
)
60 if (strcmp(info
->name
, name
) != 0)
65 /* failing that check the aliases */
66 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
67 if (bus_info
&& info
->bus_info
!= bus_info
)
71 if (strcmp(info
->alias
, name
) != 0)
78 /* Create a new device. This only initializes the device state structure
79 and allows properties to be set. qdev_init should be called to
80 initialize the actual device emulation. */
81 DeviceState
*qdev_create(BusState
*bus
, const char *name
)
87 if (!main_system_bus
) {
88 main_system_bus
= qbus_create(&system_bus_info
, NULL
, "main-system-bus");
90 bus
= main_system_bus
;
93 info
= qdev_find_info(bus
->info
, name
);
95 hw_error("Unknown device '%s' for bus '%s'\n", name
, bus
->info
->name
);
98 dev
= qemu_mallocz(info
->size
);
100 dev
->parent_bus
= bus
;
101 qdev_prop_set_defaults(dev
, dev
->info
->props
);
102 qdev_prop_set_defaults(dev
, dev
->parent_bus
->info
->props
);
103 qdev_prop_set_compat(dev
);
104 LIST_INSERT_HEAD(&bus
->children
, dev
, sibling
);
108 static int qdev_print_devinfo(DeviceInfo
*info
, char *dest
, int len
)
112 pos
+= snprintf(dest
+pos
, len
-pos
, "name \"%s\", bus %s",
113 info
->name
, info
->bus_info
->name
);
115 pos
+= snprintf(dest
+pos
, len
-pos
, ", alias \"%s\"", info
->alias
);
117 pos
+= snprintf(dest
+pos
, len
-pos
, ", desc \"%s\"", info
->desc
);
119 pos
+= snprintf(dest
+pos
, len
-pos
, ", no-user");
123 static int set_property(const char *name
, const char *value
, void *opaque
)
125 DeviceState
*dev
= opaque
;
127 if (strcmp(name
, "driver") == 0)
129 if (strcmp(name
, "bus") == 0)
132 if (-1 == qdev_prop_parse(dev
, name
, value
)) {
133 fprintf(stderr
, "can't set property \"%s\" to \"%s\" for \"%s\"\n",
134 name
, value
, dev
->info
->name
);
140 DeviceState
*qdev_device_add(QemuOpts
*opts
)
142 const char *driver
, *path
, *id
;
147 driver
= qemu_opt_get(opts
, "driver");
149 fprintf(stderr
, "-device: no driver specified\n");
152 if (strcmp(driver
, "?") == 0) {
154 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
155 qdev_print_devinfo(info
, msg
, sizeof(msg
));
156 fprintf(stderr
, "%s\n", msg
);
162 info
= qdev_find_info(NULL
, driver
);
164 fprintf(stderr
, "Device \"%s\" not found. Try -device '?' for a list.\n",
169 fprintf(stderr
, "device \"%s\" can't be added via command line\n",
175 path
= qemu_opt_get(opts
, "bus");
177 bus
= qbus_find(path
);
179 bus
= qbus_find_recursive(main_system_bus
, NULL
, info
->bus_info
);
184 /* create device, set properties */
185 qdev
= qdev_create(bus
, driver
);
186 id
= qemu_opts_id(opts
);
190 if (qemu_opt_foreach(opts
, set_property
, qdev
, 1) != 0) {
198 /* Initialize a device. Device properties should be set before calling
199 this function. IRQs and MMIO regions should be connected/mapped after
200 calling this function. */
201 void qdev_init(DeviceState
*dev
)
203 dev
->info
->init(dev
, dev
->info
);
206 /* Unlink device from bus and free the structure. */
207 void qdev_free(DeviceState
*dev
)
209 LIST_REMOVE(dev
, sibling
);
213 /* Get a character (serial) device interface. */
214 CharDriverState
*qdev_init_chardev(DeviceState
*dev
)
216 static int next_serial
;
217 static int next_virtconsole
;
218 /* FIXME: This is a nasty hack that needs to go away. */
219 if (strncmp(dev
->info
->name
, "virtio", 6) == 0) {
220 return virtcon_hds
[next_virtconsole
++];
222 return serial_hds
[next_serial
++];
226 BusState
*qdev_get_parent_bus(DeviceState
*dev
)
228 return dev
->parent_bus
;
231 void qdev_init_gpio_in(DeviceState
*dev
, qemu_irq_handler handler
, int n
)
233 assert(dev
->num_gpio_in
== 0);
234 dev
->num_gpio_in
= n
;
235 dev
->gpio_in
= qemu_allocate_irqs(handler
, dev
, n
);
238 void qdev_init_gpio_out(DeviceState
*dev
, qemu_irq
*pins
, int n
)
240 assert(dev
->num_gpio_out
== 0);
241 dev
->num_gpio_out
= n
;
242 dev
->gpio_out
= pins
;
245 qemu_irq
qdev_get_gpio_in(DeviceState
*dev
, int n
)
247 assert(n
>= 0 && n
< dev
->num_gpio_in
);
248 return dev
->gpio_in
[n
];
251 void qdev_connect_gpio_out(DeviceState
* dev
, int n
, qemu_irq pin
)
253 assert(n
>= 0 && n
< dev
->num_gpio_out
);
254 dev
->gpio_out
[n
] = pin
;
257 VLANClientState
*qdev_get_vlan_client(DeviceState
*dev
,
258 NetCanReceive
*can_receive
,
260 NetReceiveIOV
*receive_iov
,
264 NICInfo
*nd
= dev
->nd
;
266 nd
->vc
= qemu_new_vlan_client(nd
->vlan
, nd
->model
, nd
->name
, can_receive
,
267 receive
, receive_iov
, cleanup
, opaque
);
272 void qdev_get_macaddr(DeviceState
*dev
, uint8_t *macaddr
)
274 memcpy(macaddr
, dev
->nd
->macaddr
, 6);
277 static int next_block_unit
[IF_COUNT
];
279 /* Get a block device. This should only be used for single-drive devices
280 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
282 BlockDriverState
*qdev_init_bdrv(DeviceState
*dev
, BlockInterfaceType type
)
284 int unit
= next_block_unit
[type
]++;
287 dinfo
= drive_get(type
, 0, unit
);
288 return dinfo
? dinfo
->bdrv
: NULL
;
291 BusState
*qdev_get_child_bus(DeviceState
*dev
, const char *name
)
295 LIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
296 if (strcmp(name
, bus
->name
) == 0) {
303 static int next_scsi_bus
;
305 /* Create a scsi bus, and attach devices to it. */
306 /* TODO: Actually create a scsi bus for hotplug to use. */
307 void scsi_bus_new(DeviceState
*host
, SCSIAttachFn attach
)
309 int bus
= next_scsi_bus
++;
313 for (unit
= 0; unit
< MAX_SCSI_DEVS
; unit
++) {
314 dinfo
= drive_get(IF_SCSI
, bus
, unit
);
318 attach(host
, dinfo
->bdrv
, unit
);
322 static BusState
*qbus_find_recursive(BusState
*bus
, const char *name
,
326 BusState
*child
, *ret
;
329 if (name
&& (strcmp(bus
->name
, name
) != 0)) {
332 if (info
&& (bus
->info
!= info
)) {
339 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
340 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
341 ret
= qbus_find_recursive(child
, name
, info
);
350 static void qbus_list_bus(DeviceState
*dev
, char *dest
, int len
)
353 const char *sep
= " ";
356 pos
+= snprintf(dest
+pos
, len
-pos
,"child busses at \"%s\":",
357 dev
->id
? dev
->id
: dev
->info
->name
);
358 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
359 pos
+= snprintf(dest
+pos
, len
-pos
, "%s\"%s\"", sep
, child
->name
);
364 static void qbus_list_dev(BusState
*bus
, char *dest
, int len
)
367 const char *sep
= " ";
370 pos
+= snprintf(dest
+pos
, len
-pos
, "devices at \"%s\":",
372 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
373 pos
+= snprintf(dest
+pos
, len
-pos
, "%s\"%s\"",
374 sep
, dev
->info
->name
);
376 pos
+= snprintf(dest
+pos
, len
-pos
, "/\"%s\"", dev
->id
);
381 static BusState
*qbus_find_bus(DeviceState
*dev
, char *elem
)
385 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
386 if (strcmp(child
->name
, elem
) == 0) {
393 static DeviceState
*qbus_find_dev(BusState
*bus
, char *elem
)
398 * try to match in order:
399 * (1) instance id, if present
401 * (3) driver alias, if present
403 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
404 if (dev
->id
&& strcmp(dev
->id
, elem
) == 0) {
408 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
409 if (strcmp(dev
->info
->name
, elem
) == 0) {
413 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
414 if (dev
->info
->alias
&& strcmp(dev
->info
->alias
, elem
) == 0) {
421 static BusState
*qbus_find(const char *path
)
425 char elem
[128], msg
[256];
428 /* find start element */
429 if (path
[0] == '/') {
430 bus
= main_system_bus
;
433 if (sscanf(path
, "%127[^/]%n", elem
, &len
) != 1) {
434 fprintf(stderr
, "path parse error (\"%s\")\n", path
);
437 bus
= qbus_find_recursive(main_system_bus
, elem
, NULL
);
439 fprintf(stderr
, "bus \"%s\" not found\n", elem
);
446 if (path
[pos
] == '\0') {
452 if (sscanf(path
+pos
, "/%127[^/]%n", elem
, &len
) != 1) {
453 fprintf(stderr
, "path parse error (\"%s\" pos %d)\n", path
, pos
);
457 dev
= qbus_find_dev(bus
, elem
);
459 qbus_list_dev(bus
, msg
, sizeof(msg
));
460 fprintf(stderr
, "device \"%s\" not found\n%s\n", elem
, msg
);
463 if (path
[pos
] == '\0') {
464 /* last specified element is a device. If it has exactly
465 * one child bus accept it nevertheless */
466 switch (dev
->num_child_bus
) {
468 fprintf(stderr
, "device has no child bus (%s)\n", path
);
471 return LIST_FIRST(&dev
->child_bus
);
473 qbus_list_bus(dev
, msg
, sizeof(msg
));
474 fprintf(stderr
, "device has multiple child busses (%s)\n%s\n",
481 if (sscanf(path
+pos
, "/%127[^/]%n", elem
, &len
) != 1) {
482 fprintf(stderr
, "path parse error (\"%s\" pos %d)\n", path
, pos
);
486 bus
= qbus_find_bus(dev
, elem
);
488 qbus_list_bus(dev
, msg
, sizeof(msg
));
489 fprintf(stderr
, "child bus \"%s\" not found\n%s\n", elem
, msg
);
495 BusState
*qbus_create(BusInfo
*info
, DeviceState
*parent
, const char *name
)
501 bus
= qemu_mallocz(info
->size
);
503 bus
->parent
= parent
;
506 /* use supplied name */
507 bus
->name
= qemu_strdup(name
);
508 } else if (parent
&& parent
->id
) {
509 /* parent device has id -> use it for bus name */
510 len
= strlen(parent
->id
) + 16;
511 buf
= qemu_malloc(len
);
512 snprintf(buf
, len
, "%s.%d", parent
->id
, parent
->num_child_bus
);
515 /* no id -> use lowercase bus type for bus name */
516 len
= strlen(info
->name
) + 16;
517 buf
= qemu_malloc(len
);
518 len
= snprintf(buf
, len
, "%s.%d", info
->name
,
519 parent
? parent
->num_child_bus
: 0);
520 for (i
= 0; i
< len
; i
++)
521 buf
[i
] = qemu_tolower(buf
[i
]);
525 LIST_INIT(&bus
->children
);
527 LIST_INSERT_HEAD(&parent
->child_bus
, bus
, sibling
);
528 parent
->num_child_bus
++;
533 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
534 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
);
536 static void qdev_print_props(Monitor
*mon
, DeviceState
*dev
, Property
*props
,
537 const char *prefix
, int indent
)
543 while (props
->name
) {
544 if (props
->info
->print
) {
545 props
->info
->print(dev
, props
, buf
, sizeof(buf
));
546 qdev_printf("%s-prop: %s = %s\n", prefix
, props
->name
, buf
);
552 static void qdev_print(Monitor
*mon
, DeviceState
*dev
, int indent
)
555 qdev_printf("dev: %s, id \"%s\"\n", dev
->info
->name
,
556 dev
->id
? dev
->id
: "");
558 if (dev
->num_gpio_in
) {
559 qdev_printf("gpio-in %d\n", dev
->num_gpio_in
);
561 if (dev
->num_gpio_out
) {
562 qdev_printf("gpio-out %d\n", dev
->num_gpio_out
);
564 qdev_print_props(mon
, dev
, dev
->info
->props
, "dev", indent
);
565 qdev_print_props(mon
, dev
, dev
->parent_bus
->info
->props
, "bus", indent
);
566 if (dev
->parent_bus
->info
->print_dev
)
567 dev
->parent_bus
->info
->print_dev(mon
, dev
, indent
);
568 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
569 qbus_print(mon
, child
, indent
);
573 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
)
575 struct DeviceState
*dev
;
577 qdev_printf("bus: %s\n", bus
->name
);
579 qdev_printf("type %s\n", bus
->info
->name
);
580 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
581 qdev_print(mon
, dev
, indent
);
586 void do_info_qtree(Monitor
*mon
)
589 qbus_print(mon
, main_system_bus
, 0);
592 void do_info_qdrv(Monitor
*mon
)
597 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
598 qdev_print_devinfo(info
, msg
, sizeof(msg
));
599 monitor_printf(mon
, "%s\n", msg
);