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
)
113 ret
= snprintf(dest
+pos
, len
-pos
, "name \"%s\", bus %s",
114 info
->name
, info
->bus_info
->name
);
115 pos
+= MIN(len
-pos
,ret
);
117 ret
= snprintf(dest
+pos
, len
-pos
, ", alias \"%s\"", info
->alias
);
118 pos
+= MIN(len
-pos
,ret
);
121 ret
= snprintf(dest
+pos
, len
-pos
, ", desc \"%s\"", info
->desc
);
122 pos
+= MIN(len
-pos
,ret
);
125 ret
= snprintf(dest
+pos
, len
-pos
, ", no-user");
126 pos
+= MIN(len
-pos
,ret
);
131 static int set_property(const char *name
, const char *value
, void *opaque
)
133 DeviceState
*dev
= opaque
;
135 if (strcmp(name
, "driver") == 0)
137 if (strcmp(name
, "bus") == 0)
140 if (-1 == qdev_prop_parse(dev
, name
, value
)) {
141 fprintf(stderr
, "can't set property \"%s\" to \"%s\" for \"%s\"\n",
142 name
, value
, dev
->info
->name
);
148 DeviceState
*qdev_device_add(QemuOpts
*opts
)
150 const char *driver
, *path
, *id
;
155 driver
= qemu_opt_get(opts
, "driver");
157 fprintf(stderr
, "-device: no driver specified\n");
160 if (strcmp(driver
, "?") == 0) {
162 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
163 qdev_print_devinfo(info
, msg
, sizeof(msg
));
164 fprintf(stderr
, "%s\n", msg
);
170 info
= qdev_find_info(NULL
, driver
);
172 fprintf(stderr
, "Device \"%s\" not found. Try -device '?' for a list.\n",
177 fprintf(stderr
, "device \"%s\" can't be added via command line\n",
183 path
= qemu_opt_get(opts
, "bus");
185 bus
= qbus_find(path
);
187 bus
= qbus_find_recursive(main_system_bus
, NULL
, info
->bus_info
);
192 /* create device, set properties */
193 qdev
= qdev_create(bus
, driver
);
194 id
= qemu_opts_id(opts
);
198 if (qemu_opt_foreach(opts
, set_property
, qdev
, 1) != 0) {
206 /* Initialize a device. Device properties should be set before calling
207 this function. IRQs and MMIO regions should be connected/mapped after
208 calling this function. */
209 void qdev_init(DeviceState
*dev
)
211 dev
->info
->init(dev
, dev
->info
);
214 /* Unlink device from bus and free the structure. */
215 void qdev_free(DeviceState
*dev
)
217 LIST_REMOVE(dev
, sibling
);
221 /* Get a character (serial) device interface. */
222 CharDriverState
*qdev_init_chardev(DeviceState
*dev
)
224 static int next_serial
;
225 static int next_virtconsole
;
226 /* FIXME: This is a nasty hack that needs to go away. */
227 if (strncmp(dev
->info
->name
, "virtio", 6) == 0) {
228 return virtcon_hds
[next_virtconsole
++];
230 return serial_hds
[next_serial
++];
234 BusState
*qdev_get_parent_bus(DeviceState
*dev
)
236 return dev
->parent_bus
;
239 void qdev_init_gpio_in(DeviceState
*dev
, qemu_irq_handler handler
, int n
)
241 assert(dev
->num_gpio_in
== 0);
242 dev
->num_gpio_in
= n
;
243 dev
->gpio_in
= qemu_allocate_irqs(handler
, dev
, n
);
246 void qdev_init_gpio_out(DeviceState
*dev
, qemu_irq
*pins
, int n
)
248 assert(dev
->num_gpio_out
== 0);
249 dev
->num_gpio_out
= n
;
250 dev
->gpio_out
= pins
;
253 qemu_irq
qdev_get_gpio_in(DeviceState
*dev
, int n
)
255 assert(n
>= 0 && n
< dev
->num_gpio_in
);
256 return dev
->gpio_in
[n
];
259 void qdev_connect_gpio_out(DeviceState
* dev
, int n
, qemu_irq pin
)
261 assert(n
>= 0 && n
< dev
->num_gpio_out
);
262 dev
->gpio_out
[n
] = pin
;
265 VLANClientState
*qdev_get_vlan_client(DeviceState
*dev
,
266 NetCanReceive
*can_receive
,
268 NetReceiveIOV
*receive_iov
,
272 NICInfo
*nd
= dev
->nd
;
274 nd
->vc
= qemu_new_vlan_client(nd
->vlan
, nd
->model
, nd
->name
, can_receive
,
275 receive
, receive_iov
, cleanup
, opaque
);
280 void qdev_get_macaddr(DeviceState
*dev
, uint8_t *macaddr
)
282 memcpy(macaddr
, dev
->nd
->macaddr
, 6);
285 static int next_block_unit
[IF_COUNT
];
287 /* Get a block device. This should only be used for single-drive devices
288 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
290 BlockDriverState
*qdev_init_bdrv(DeviceState
*dev
, BlockInterfaceType type
)
292 int unit
= next_block_unit
[type
]++;
295 dinfo
= drive_get(type
, 0, unit
);
296 return dinfo
? dinfo
->bdrv
: NULL
;
299 BusState
*qdev_get_child_bus(DeviceState
*dev
, const char *name
)
303 LIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
304 if (strcmp(name
, bus
->name
) == 0) {
311 static int next_scsi_bus
;
313 /* Create a scsi bus, and attach devices to it. */
314 /* TODO: Actually create a scsi bus for hotplug to use. */
315 void scsi_bus_new(DeviceState
*host
, SCSIAttachFn attach
)
317 int bus
= next_scsi_bus
++;
321 for (unit
= 0; unit
< MAX_SCSI_DEVS
; unit
++) {
322 dinfo
= drive_get(IF_SCSI
, bus
, unit
);
326 attach(host
, dinfo
->bdrv
, unit
);
330 static BusState
*qbus_find_recursive(BusState
*bus
, const char *name
,
334 BusState
*child
, *ret
;
337 if (name
&& (strcmp(bus
->name
, name
) != 0)) {
340 if (info
&& (bus
->info
!= info
)) {
347 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
348 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
349 ret
= qbus_find_recursive(child
, name
, info
);
358 static void qbus_list_bus(DeviceState
*dev
, char *dest
, int len
)
361 const char *sep
= " ";
364 pos
+= snprintf(dest
+pos
, len
-pos
,"child busses at \"%s\":",
365 dev
->id
? dev
->id
: dev
->info
->name
);
366 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
367 pos
+= snprintf(dest
+pos
, len
-pos
, "%s\"%s\"", sep
, child
->name
);
372 static void qbus_list_dev(BusState
*bus
, char *dest
, int len
)
375 const char *sep
= " ";
378 pos
+= snprintf(dest
+pos
, len
-pos
, "devices at \"%s\":",
380 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
381 pos
+= snprintf(dest
+pos
, len
-pos
, "%s\"%s\"",
382 sep
, dev
->info
->name
);
384 pos
+= snprintf(dest
+pos
, len
-pos
, "/\"%s\"", dev
->id
);
389 static BusState
*qbus_find_bus(DeviceState
*dev
, char *elem
)
393 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
394 if (strcmp(child
->name
, elem
) == 0) {
401 static DeviceState
*qbus_find_dev(BusState
*bus
, char *elem
)
406 * try to match in order:
407 * (1) instance id, if present
409 * (3) driver alias, if present
411 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
412 if (dev
->id
&& strcmp(dev
->id
, elem
) == 0) {
416 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
417 if (strcmp(dev
->info
->name
, elem
) == 0) {
421 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
422 if (dev
->info
->alias
&& strcmp(dev
->info
->alias
, elem
) == 0) {
429 static BusState
*qbus_find(const char *path
)
433 char elem
[128], msg
[256];
436 /* find start element */
437 if (path
[0] == '/') {
438 bus
= main_system_bus
;
441 if (sscanf(path
, "%127[^/]%n", elem
, &len
) != 1) {
442 fprintf(stderr
, "path parse error (\"%s\")\n", path
);
445 bus
= qbus_find_recursive(main_system_bus
, elem
, NULL
);
447 fprintf(stderr
, "bus \"%s\" not found\n", elem
);
454 if (path
[pos
] == '\0') {
460 if (sscanf(path
+pos
, "/%127[^/]%n", elem
, &len
) != 1) {
461 fprintf(stderr
, "path parse error (\"%s\" pos %d)\n", path
, pos
);
465 dev
= qbus_find_dev(bus
, elem
);
467 qbus_list_dev(bus
, msg
, sizeof(msg
));
468 fprintf(stderr
, "device \"%s\" not found\n%s\n", elem
, msg
);
471 if (path
[pos
] == '\0') {
472 /* last specified element is a device. If it has exactly
473 * one child bus accept it nevertheless */
474 switch (dev
->num_child_bus
) {
476 fprintf(stderr
, "device has no child bus (%s)\n", path
);
479 return LIST_FIRST(&dev
->child_bus
);
481 qbus_list_bus(dev
, msg
, sizeof(msg
));
482 fprintf(stderr
, "device has multiple child busses (%s)\n%s\n",
489 if (sscanf(path
+pos
, "/%127[^/]%n", elem
, &len
) != 1) {
490 fprintf(stderr
, "path parse error (\"%s\" pos %d)\n", path
, pos
);
494 bus
= qbus_find_bus(dev
, elem
);
496 qbus_list_bus(dev
, msg
, sizeof(msg
));
497 fprintf(stderr
, "child bus \"%s\" not found\n%s\n", elem
, msg
);
503 BusState
*qbus_create(BusInfo
*info
, DeviceState
*parent
, const char *name
)
509 bus
= qemu_mallocz(info
->size
);
511 bus
->parent
= parent
;
514 /* use supplied name */
515 bus
->name
= qemu_strdup(name
);
516 } else if (parent
&& parent
->id
) {
517 /* parent device has id -> use it for bus name */
518 len
= strlen(parent
->id
) + 16;
519 buf
= qemu_malloc(len
);
520 snprintf(buf
, len
, "%s.%d", parent
->id
, parent
->num_child_bus
);
523 /* no id -> use lowercase bus type for bus name */
524 len
= strlen(info
->name
) + 16;
525 buf
= qemu_malloc(len
);
526 len
= snprintf(buf
, len
, "%s.%d", info
->name
,
527 parent
? parent
->num_child_bus
: 0);
528 for (i
= 0; i
< len
; i
++)
529 buf
[i
] = qemu_tolower(buf
[i
]);
533 LIST_INIT(&bus
->children
);
535 LIST_INSERT_HEAD(&parent
->child_bus
, bus
, sibling
);
536 parent
->num_child_bus
++;
541 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
542 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
);
544 static void qdev_print_props(Monitor
*mon
, DeviceState
*dev
, Property
*props
,
545 const char *prefix
, int indent
)
551 while (props
->name
) {
552 if (props
->info
->print
) {
553 props
->info
->print(dev
, props
, buf
, sizeof(buf
));
554 qdev_printf("%s-prop: %s = %s\n", prefix
, props
->name
, buf
);
560 static void qdev_print(Monitor
*mon
, DeviceState
*dev
, int indent
)
563 qdev_printf("dev: %s, id \"%s\"\n", dev
->info
->name
,
564 dev
->id
? dev
->id
: "");
566 if (dev
->num_gpio_in
) {
567 qdev_printf("gpio-in %d\n", dev
->num_gpio_in
);
569 if (dev
->num_gpio_out
) {
570 qdev_printf("gpio-out %d\n", dev
->num_gpio_out
);
572 qdev_print_props(mon
, dev
, dev
->info
->props
, "dev", indent
);
573 qdev_print_props(mon
, dev
, dev
->parent_bus
->info
->props
, "bus", indent
);
574 if (dev
->parent_bus
->info
->print_dev
)
575 dev
->parent_bus
->info
->print_dev(mon
, dev
, indent
);
576 LIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
577 qbus_print(mon
, child
, indent
);
581 static void qbus_print(Monitor
*mon
, BusState
*bus
, int indent
)
583 struct DeviceState
*dev
;
585 qdev_printf("bus: %s\n", bus
->name
);
587 qdev_printf("type %s\n", bus
->info
->name
);
588 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
589 qdev_print(mon
, dev
, indent
);
594 void do_info_qtree(Monitor
*mon
)
597 qbus_print(mon
, main_system_bus
, 0);
600 void do_info_qdm(Monitor
*mon
)
605 for (info
= device_info_list
; info
!= NULL
; info
= info
->next
) {
606 qdev_print_devinfo(info
, msg
, sizeof(msg
));
607 monitor_printf(mon
, "%s\n", msg
);