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 DeviceState
*qdev_device_add(const char *cmdline
)
113 char driver
[32], path
[128] = "";
114 char tag
[32], value
[256];
115 const char *params
= NULL
;
118 if (1 != sscanf(cmdline
, "%32[^,],%n", driver
, &n
)) {
119 fprintf(stderr
, "device parse error: \"%s\"\n", cmdline
);
122 if (strcmp(driver
, "?") == 0) {
123 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
124 fprintf(stderr
, "name \"%s\", bus %s\n", info
->name
, info
->bus_info
->name
);
129 params
= cmdline
+ n
;
130 get_param_value(path
, sizeof(path
), "bus", params
);
132 info
= qdev_find_info(NULL
, driver
);
134 fprintf(stderr
, "Device \"%s\" not found. Try -device '?' for a list.\n",
139 fprintf(stderr
, "device \"%s\" can't be added via command line\n",
145 bus
= qbus_find(path
);
148 qdev
= qdev_create(bus
, driver
);
150 bus
= qbus_find_recursive(main_system_bus
, NULL
, info
->bus_info
);
153 qdev
= qdev_create(bus
, driver
);
158 if (2 != sscanf(params
, "%31[^=]=%255[^,]%n", tag
, value
, &n
)) {
159 fprintf(stderr
, "parse error at \"%s\"\n", params
);
163 if (params
[0] == ',')
165 if (strcmp(tag
, "bus") == 0)
167 if (strcmp(tag
, "id") == 0) {
168 qdev
->id
= qemu_strdup(value
);
171 if (-1 == qdev_prop_parse(qdev
, tag
, value
)) {
172 fprintf(stderr
, "can't set property \"%s\" to \"%s\" for \"%s\"\n",
182 /* Initialize a device. Device properties should be set before calling
183 this function. IRQs and MMIO regions should be connected/mapped after
184 calling this function. */
185 void qdev_init(DeviceState
*dev
)
187 dev
->info
->init(dev
, dev
->info
);
190 /* Unlink device from bus and free the structure. */
191 void qdev_free(DeviceState
*dev
)
193 LIST_REMOVE(dev
, sibling
);
198 /* Get a character (serial) device interface. */
199 CharDriverState
*qdev_init_chardev(DeviceState
*dev
)
201 static int next_serial
;
202 static int next_virtconsole
;
203 /* FIXME: This is a nasty hack that needs to go away. */
204 if (strncmp(dev
->info
->name
, "virtio", 6) == 0) {
205 return virtcon_hds
[next_virtconsole
++];
207 return serial_hds
[next_serial
++];
211 BusState
*qdev_get_parent_bus(DeviceState
*dev
)
213 return dev
->parent_bus
;
216 void qdev_init_gpio_in(DeviceState
*dev
, qemu_irq_handler handler
, int n
)
218 assert(dev
->num_gpio_in
== 0);
219 dev
->num_gpio_in
= n
;
220 dev
->gpio_in
= qemu_allocate_irqs(handler
, dev
, n
);
223 void qdev_init_gpio_out(DeviceState
*dev
, qemu_irq
*pins
, int n
)
225 assert(dev
->num_gpio_out
== 0);
226 dev
->num_gpio_out
= n
;
227 dev
->gpio_out
= pins
;
230 qemu_irq
qdev_get_gpio_in(DeviceState
*dev
, int n
)
232 assert(n
>= 0 && n
< dev
->num_gpio_in
);
233 return dev
->gpio_in
[n
];
236 void qdev_connect_gpio_out(DeviceState
* dev
, int n
, qemu_irq pin
)
238 assert(n
>= 0 && n
< dev
->num_gpio_out
);
239 dev
->gpio_out
[n
] = pin
;
242 VLANClientState
*qdev_get_vlan_client(DeviceState
*dev
,
243 NetCanReceive
*can_receive
,
245 NetReceiveIOV
*receive_iov
,
249 NICInfo
*nd
= dev
->nd
;
251 nd
->vc
= qemu_new_vlan_client(nd
->vlan
, nd
->model
, nd
->name
, can_receive
,
252 receive
, receive_iov
, cleanup
, opaque
);
257 void qdev_get_macaddr(DeviceState
*dev
, uint8_t *macaddr
)
259 memcpy(macaddr
, dev
->nd
->macaddr
, 6);
262 static int next_block_unit
[IF_COUNT
];
264 /* Get a block device. This should only be used for single-drive devices
265 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
267 BlockDriverState
*qdev_init_bdrv(DeviceState
*dev
, BlockInterfaceType type
)
269 int unit
= next_block_unit
[type
]++;
272 dinfo
= drive_get(type
, 0, unit
);
273 return dinfo
? dinfo
->bdrv
: NULL
;
276 BusState
*qdev_get_child_bus(DeviceState
*dev
, const char *name
)
280 LIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
281 if (strcmp(name
, bus
->name
) == 0) {
288 static int next_scsi_bus
;
290 /* Create a scsi bus, and attach devices to it. */
291 /* TODO: Actually create a scsi bus for hotplug to use. */
292 void scsi_bus_new(DeviceState
*host
, SCSIAttachFn attach
)
294 int bus
= next_scsi_bus
++;
298 for (unit
= 0; unit
< MAX_SCSI_DEVS
; unit
++) {
299 dinfo
= drive_get(IF_SCSI
, bus
, unit
);
303 attach(host
, dinfo
->bdrv
, unit
);
307 static BusState
*qbus_find_recursive(BusState
*bus
, const char *name
,
311 BusState
*child
, *ret
;
314 if (name
&& (strcmp(bus
->name
, name
) != 0)) {
317 if (info
&& (bus
->info
!= info
)) {
324 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
325 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
326 ret
= qbus_find_recursive(child
, name
, info
);
335 static void qbus_list_bus(DeviceState
*dev
, char *dest
, int len
)
338 const char *sep
= " ";
341 pos
+= snprintf(dest
+pos
, len
-pos
,"child busses at \"%s\":",
342 dev
->id
? dev
->id
: dev
->info
->name
);
343 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
344 pos
+= snprintf(dest
+pos
, len
-pos
, "%s\"%s\"", sep
, child
->name
);
349 static void qbus_list_dev(BusState
*bus
, char *dest
, int len
)
352 const char *sep
= " ";
355 pos
+= snprintf(dest
+pos
, len
-pos
, "devices at \"%s\":",
357 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
358 pos
+= snprintf(dest
+pos
, len
-pos
, "%s\"%s\"",
359 sep
, dev
->info
->name
);
361 pos
+= snprintf(dest
+pos
, len
-pos
, "/\"%s\"", dev
->id
);
366 static BusState
*qbus_find_bus(DeviceState
*dev
, char *elem
)
370 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
371 if (strcmp(child
->name
, elem
) == 0) {
378 static DeviceState
*qbus_find_dev(BusState
*bus
, char *elem
)
383 * try to match in order:
384 * (1) instance id, if present
386 * (3) driver alias, if present
388 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
389 if (dev
->id
&& strcmp(dev
->id
, elem
) == 0) {
393 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
394 if (strcmp(dev
->info
->name
, elem
) == 0) {
398 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
399 if (dev
->info
->alias
&& strcmp(dev
->info
->alias
, elem
) == 0) {
406 static BusState
*qbus_find(const char *path
)
410 char elem
[128], msg
[256];
413 /* find start element */
414 if (path
[0] == '/') {
415 bus
= main_system_bus
;
418 if (sscanf(path
, "%127[^/]%n", elem
, &len
) != 1) {
419 fprintf(stderr
, "path parse error (\"%s\")\n", path
);
422 bus
= qbus_find_recursive(main_system_bus
, elem
, NULL
);
424 fprintf(stderr
, "bus \"%s\" not found\n", elem
);
431 if (path
[pos
] == '\0') {
437 if (sscanf(path
+pos
, "/%127[^/]%n", elem
, &len
) != 1) {
438 fprintf(stderr
, "path parse error (\"%s\" pos %d)\n", path
, pos
);
442 dev
= qbus_find_dev(bus
, elem
);
444 qbus_list_dev(bus
, msg
, sizeof(msg
));
445 fprintf(stderr
, "device \"%s\" not found\n%s\n", elem
, msg
);
448 if (path
[pos
] == '\0') {
449 /* last specified element is a device. If it has exactly
450 * one child bus accept it nevertheless */
451 switch (dev
->num_child_bus
) {
453 fprintf(stderr
, "device has no child bus (%s)\n", path
);
456 return LIST_FIRST(&dev
->child_bus
);
458 qbus_list_bus(dev
, msg
, sizeof(msg
));
459 fprintf(stderr
, "device has multiple child busses (%s)\n%s\n",
466 if (sscanf(path
+pos
, "/%127[^/]%n", elem
, &len
) != 1) {
467 fprintf(stderr
, "path parse error (\"%s\" pos %d)\n", path
, pos
);
471 bus
= qbus_find_bus(dev
, elem
);
473 qbus_list_bus(dev
, msg
, sizeof(msg
));
474 fprintf(stderr
, "child bus \"%s\" not found\n%s\n", elem
, msg
);
480 BusState
*qbus_create(BusInfo
*info
, DeviceState
*parent
, const char *name
)
486 bus
= qemu_mallocz(info
->size
);
488 bus
->parent
= parent
;
491 /* use supplied name */
492 bus
->name
= qemu_strdup(name
);
493 } else if (parent
&& parent
->id
) {
494 /* parent device has id -> use it for bus name */
495 len
= strlen(parent
->id
) + 16;
496 buf
= qemu_malloc(len
);
497 snprintf(buf
, len
, "%s.%d", parent
->id
, parent
->num_child_bus
);
500 /* no id -> use lowercase bus type for bus name */
501 len
= strlen(info
->name
) + 16;
502 buf
= qemu_malloc(len
);
503 len
= snprintf(buf
, len
, "%s.%d", info
->name
,
504 parent
? parent
->num_child_bus
: 0);
505 for (i
= 0; i
< len
; i
++)
506 buf
[i
] = tolower(buf
[i
]);
510 LIST_INIT(&bus
->children
);
512 LIST_INSERT_HEAD(&parent
->child_bus
, bus
, sibling
);
513 parent
->num_child_bus
++;
518 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
519 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
);
521 static void qdev_print_props(Monitor
*mon
, DeviceState
*dev
, Property
*props
,
522 const char *prefix
, int indent
)
528 while (props
->name
) {
529 if (props
->info
->print
) {
530 props
->info
->print(dev
, props
, buf
, sizeof(buf
));
531 qdev_printf("%s-prop: %s = %s\n", prefix
, props
->name
, buf
);
537 static void qdev_print(Monitor
*mon
, DeviceState
*dev
, int indent
)
540 qdev_printf("dev: %s, id \"%s\"\n", dev
->info
->name
,
541 dev
->id
? dev
->id
: "");
543 if (dev
->num_gpio_in
) {
544 qdev_printf("gpio-in %d\n", dev
->num_gpio_in
);
546 if (dev
->num_gpio_out
) {
547 qdev_printf("gpio-out %d\n", dev
->num_gpio_out
);
549 qdev_print_props(mon
, dev
, dev
->info
->props
, "dev", indent
);
550 qdev_print_props(mon
, dev
, dev
->parent_bus
->info
->props
, "bus", indent
);
551 if (dev
->parent_bus
->info
->print_dev
)
552 dev
->parent_bus
->info
->print_dev(mon
, dev
, indent
);
553 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
554 qbus_print(mon
, child
, indent
);
558 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
)
560 struct DeviceState
*dev
;
562 qdev_printf("bus: %s\n", bus
->name
);
564 qdev_printf("type %s\n", bus
->info
->name
);
565 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
566 qdev_print(mon
, dev
, indent
);
571 void do_info_qtree(Monitor
*mon
)
574 qbus_print(mon
, main_system_bus
, 0);