qdev: bus walker + qdev_device_add()
[qemu.git] / hw / qdev.c
blob97a9665424dbd42d7dba9924dfc5e6fdce3d9571
1 /*
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
26 this API directly. */
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "monitor.h"
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,
39 const BusInfo *info);
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));
46 assert(!info->next);
48 info->next = device_info_list;
49 device_info_list = info;
52 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
54 DeviceInfo *info;
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)
59 continue;
60 if (strcmp(info->name, name) != 0)
61 continue;
62 return info;
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)
68 continue;
69 if (!info->alias)
70 continue;
71 if (strcmp(info->alias, name) != 0)
72 continue;
73 return info;
75 return NULL;
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)
83 DeviceInfo *info;
84 DeviceState *dev;
86 if (!bus) {
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);
94 if (!info) {
95 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
98 dev = qemu_mallocz(info->size);
99 dev->info = info;
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);
105 return dev;
108 DeviceState *qdev_device_add(const char *cmdline)
110 DeviceInfo *info;
111 DeviceState *qdev;
112 BusState *bus;
113 char driver[32], path[128] = "";
114 char tag[32], value[256];
115 const char *params = NULL;
116 int n = 0;
118 if (1 != sscanf(cmdline, "%32[^,],%n", driver, &n)) {
119 fprintf(stderr, "device parse error: \"%s\"\n", cmdline);
120 return NULL;
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);
126 return NULL;
128 if (n) {
129 params = cmdline + n;
130 get_param_value(path, sizeof(path), "bus", params);
132 info = qdev_find_info(NULL, driver);
133 if (!info) {
134 fprintf(stderr, "Device \"%s\" not found. Try -device '?' for a list.\n",
135 driver);
136 return NULL;
138 if (info->no_user) {
139 fprintf(stderr, "device \"%s\" can't be added via command line\n",
140 info->name);
141 return NULL;
144 if (strlen(path)) {
145 bus = qbus_find(path);
146 if (!bus)
147 return NULL;
148 qdev = qdev_create(bus, driver);
149 } else {
150 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
151 if (!bus)
152 return NULL;
153 qdev = qdev_create(bus, driver);
156 if (params) {
157 while (params[0]) {
158 if (2 != sscanf(params, "%31[^=]=%255[^,]%n", tag, value, &n)) {
159 fprintf(stderr, "parse error at \"%s\"\n", params);
160 break;
162 params += n;
163 if (params[0] == ',')
164 params++;
165 if (strcmp(tag, "bus") == 0)
166 continue;
167 if (strcmp(tag, "id") == 0) {
168 qdev->id = qemu_strdup(value);
169 continue;
171 if (-1 == qdev_prop_parse(qdev, tag, value)) {
172 fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n",
173 tag, value, driver);
178 qdev_init(qdev);
179 return qdev;
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);
194 qemu_free(dev->id);
195 qemu_free(dev);
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++];
206 } else {
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,
244 NetReceive *receive,
245 NetReceiveIOV *receive_iov,
246 NetCleanup *cleanup,
247 void *opaque)
249 NICInfo *nd = dev->nd;
250 assert(nd);
251 nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
252 receive, receive_iov, cleanup, opaque);
253 return nd->vc;
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
266 appropriate bus. */
267 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
269 int unit = next_block_unit[type]++;
270 int index;
272 index = drive_get_index(type, 0, unit);
273 if (index == -1) {
274 return NULL;
276 return drives_table[index].bdrv;
279 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
281 BusState *bus;
283 LIST_FOREACH(bus, &dev->child_bus, sibling) {
284 if (strcmp(name, bus->name) == 0) {
285 return bus;
288 return NULL;
291 static int next_scsi_bus;
293 /* Create a scsi bus, and attach devices to it. */
294 /* TODO: Actually create a scsi bus for hotplug to use. */
295 void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
297 int bus = next_scsi_bus++;
298 int unit;
299 int index;
301 for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
302 index = drive_get_index(IF_SCSI, bus, unit);
303 if (index == -1) {
304 continue;
306 attach(host, drives_table[index].bdrv, unit);
310 static BusState *qbus_find_recursive(BusState *bus, const char *name,
311 const BusInfo *info)
313 DeviceState *dev;
314 BusState *child, *ret;
315 int match = 1;
317 if (name && (strcmp(bus->name, name) != 0)) {
318 match = 0;
320 if (info && (bus->info != info)) {
321 match = 0;
323 if (match) {
324 return bus;
327 LIST_FOREACH(dev, &bus->children, sibling) {
328 LIST_FOREACH(child, &dev->child_bus, sibling) {
329 ret = qbus_find_recursive(child, name, info);
330 if (ret) {
331 return ret;
335 return NULL;
338 static void qbus_list_bus(DeviceState *dev, char *dest, int len)
340 BusState *child;
341 const char *sep = " ";
342 int pos = 0;
344 pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
345 dev->id ? dev->id : dev->info->name);
346 LIST_FOREACH(child, &dev->child_bus, sibling) {
347 pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
348 sep = ", ";
352 static void qbus_list_dev(BusState *bus, char *dest, int len)
354 DeviceState *dev;
355 const char *sep = " ";
356 int pos = 0;
358 pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
359 bus->name);
360 LIST_FOREACH(dev, &bus->children, sibling) {
361 pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
362 sep, dev->info->name);
363 if (dev->id)
364 pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
365 sep = ", ";
369 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
371 BusState *child;
373 LIST_FOREACH(child, &dev->child_bus, sibling) {
374 if (strcmp(child->name, elem) == 0) {
375 return child;
378 return NULL;
381 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
383 DeviceState *dev;
386 * try to match in order:
387 * (1) instance id, if present
388 * (2) driver name
389 * (3) driver alias, if present
391 LIST_FOREACH(dev, &bus->children, sibling) {
392 if (dev->id && strcmp(dev->id, elem) == 0) {
393 return dev;
396 LIST_FOREACH(dev, &bus->children, sibling) {
397 if (strcmp(dev->info->name, elem) == 0) {
398 return dev;
401 LIST_FOREACH(dev, &bus->children, sibling) {
402 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
403 return dev;
406 return NULL;
409 static BusState *qbus_find(const char *path)
411 DeviceState *dev;
412 BusState *bus;
413 char elem[128], msg[256];
414 int pos, len;
416 /* find start element */
417 if (path[0] == '/') {
418 bus = main_system_bus;
419 pos = 0;
420 } else {
421 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
422 fprintf(stderr, "path parse error (\"%s\")\n", path);
423 return NULL;
425 bus = qbus_find_recursive(main_system_bus, elem, NULL);
426 if (!bus) {
427 fprintf(stderr, "bus \"%s\" not found\n", elem);
428 return NULL;
430 pos = len;
433 for (;;) {
434 if (path[pos] == '\0') {
435 /* we are done */
436 return bus;
439 /* find device */
440 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
441 fprintf(stderr, "path parse error (\"%s\" pos %d)\n", path, pos);
442 return NULL;
444 pos += len;
445 dev = qbus_find_dev(bus, elem);
446 if (!dev) {
447 qbus_list_dev(bus, msg, sizeof(msg));
448 fprintf(stderr, "device \"%s\" not found\n%s\n", elem, msg);
449 return NULL;
451 if (path[pos] == '\0') {
452 /* last specified element is a device. If it has exactly
453 * one child bus accept it nevertheless */
454 switch (dev->num_child_bus) {
455 case 0:
456 fprintf(stderr, "device has no child bus (%s)\n", path);
457 return NULL;
458 case 1:
459 return LIST_FIRST(&dev->child_bus);
460 default:
461 qbus_list_bus(dev, msg, sizeof(msg));
462 fprintf(stderr, "device has multiple child busses (%s)\n%s\n",
463 path, msg);
464 return NULL;
468 /* find bus */
469 if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
470 fprintf(stderr, "path parse error (\"%s\" pos %d)\n", path, pos);
471 return NULL;
473 pos += len;
474 bus = qbus_find_bus(dev, elem);
475 if (!bus) {
476 qbus_list_bus(dev, msg, sizeof(msg));
477 fprintf(stderr, "child bus \"%s\" not found\n%s\n", elem, msg);
478 return NULL;
483 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
485 BusState *bus;
486 char *buf;
487 int i,len;
489 bus = qemu_mallocz(info->size);
490 bus->info = info;
491 bus->parent = parent;
493 if (name) {
494 /* use supplied name */
495 bus->name = qemu_strdup(name);
496 } else if (parent && parent->id) {
497 /* parent device has id -> use it for bus name */
498 len = strlen(parent->id) + 16;
499 buf = qemu_malloc(len);
500 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
501 bus->name = buf;
502 } else {
503 /* no id -> use lowercase bus type for bus name */
504 len = strlen(info->name) + 16;
505 buf = qemu_malloc(len);
506 len = snprintf(buf, len, "%s.%d", info->name,
507 parent ? parent->num_child_bus : 0);
508 for (i = 0; i < len; i++)
509 buf[i] = tolower(buf[i]);
510 bus->name = buf;
513 LIST_INIT(&bus->children);
514 if (parent) {
515 LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
516 parent->num_child_bus++;
518 return bus;
521 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
522 static void qbus_print(Monitor *mon, BusState *bus, int indent);
524 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
525 const char *prefix, int indent)
527 char buf[64];
529 if (!props)
530 return;
531 while (props->name) {
532 if (props->info->print) {
533 props->info->print(dev, props, buf, sizeof(buf));
534 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
536 props++;
540 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
542 BusState *child;
543 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
544 dev->id ? dev->id : "");
545 indent += 2;
546 if (dev->num_gpio_in) {
547 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
549 if (dev->num_gpio_out) {
550 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
552 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
553 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
554 if (dev->parent_bus->info->print_dev)
555 dev->parent_bus->info->print_dev(mon, dev, indent);
556 LIST_FOREACH(child, &dev->child_bus, sibling) {
557 qbus_print(mon, child, indent);
561 static void qbus_print(Monitor *mon, BusState *bus, int indent)
563 struct DeviceState *dev;
565 qdev_printf("bus: %s\n", bus->name);
566 indent += 2;
567 qdev_printf("type %s\n", bus->info->name);
568 LIST_FOREACH(dev, &bus->children, sibling) {
569 qdev_print(mon, dev, indent);
572 #undef qdev_printf
574 void do_info_qtree(Monitor *mon)
576 if (main_system_bus)
577 qbus_print(mon, main_system_bus, 0);