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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
19 */
20
21 /* The theory here is that it should be possible to create a machine without
22 knowledge of specific devices. Historically board init routines have
23 passed a bunch of arguments to each device, requiring the board know
24 exactly which device it is dealing with. This file provides an abstract
25 API for device configuration and initialization. Devices will generally
26 inherit from a particular bus (e.g. PCI or I2C) rather than
27 this API directly. */
28
29 #include "net/net.h"
30 #include "hw/qdev.h"
31 #include "sysemu/sysemu.h"
32 #include "monitor/monitor.h"
33 #include "sysemu/blockdev.h"
34
35 struct DeviceProperty {
36 const char *name;
37 DevicePropType type;
38 union {
39 uint64_t i;
40 void *ptr;
41 } value;
42 DeviceProperty *next;
43 };
44
45 struct DeviceType {
46 DeviceInfo *info;
47 DeviceType *next;
48 };
49
50 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
51 static BusState *main_system_bus;
52
53 static DeviceType *device_type_list;
54
55 /* Register a new device type. */
qdev_register(DeviceInfo * info)56 void qdev_register(DeviceInfo *info)
57 {
58 DeviceType *t;
59
60 assert(info->size >= sizeof(DeviceState));
61
62 t = g_malloc0(sizeof(DeviceType));
63 t->next = device_type_list;
64 device_type_list = t;
65 t->info = info;
66 }
67
68 /* Create a new device. This only initializes the device state structure
69 and allows properties to be set. qdev_init should be called to
70 initialize the actual device emulation. */
qdev_create(BusState * bus,const char * name)71 DeviceState *qdev_create(BusState *bus, const char *name)
72 {
73 DeviceType *t;
74 DeviceState *dev;
75
76 for (t = device_type_list; t; t = t->next) {
77 if (strcmp(t->info->name, name) == 0) {
78 break;
79 }
80 }
81 if (!t) {
82 hw_error("Unknown device '%s'\n", name);
83 }
84
85 dev = g_malloc0(t->info->size);
86 dev->type = t;
87
88 if (!bus) {
89 /* ???: This assumes system busses have no additional state. */
90 if (!main_system_bus) {
91 main_system_bus = qbus_create(BUS_TYPE_SYSTEM, sizeof(BusState),
92 NULL, "main-system-bus");
93 }
94 bus = main_system_bus;
95 }
96 if (t->info->bus_type != bus->type) {
97 /* TODO: Print bus type names. */
98 hw_error("Device '%s' on wrong bus type (%d/%d)", name,
99 t->info->bus_type, bus->type);
100 }
101 dev->parent_bus = bus;
102 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
103 return dev;
104 }
105
qdev_device_help(QemuOpts * opts)106 int qdev_device_help(QemuOpts *opts)
107 {
108 #ifdef CONFIG_ANDROID /* Not ready yet, will remove when we properly integrate upstream qdev */
109 return 0;
110 #else
111 const char *driver;
112 DeviceInfo *info;
113 Property *prop;
114
115 driver = qemu_opt_get(opts, "driver");
116 if (driver && !strcmp(driver, "?")) {
117 for (info = device_info_list; info != NULL; info = info->next) {
118 if (info->no_user) {
119 continue; /* not available, don't show */
120 }
121 qdev_print_devinfo(info);
122 }
123 return 1;
124 }
125
126 if (!qemu_opt_get(opts, "?")) {
127 return 0;
128 }
129
130 info = qdev_find_info(NULL, driver);
131 if (!info) {
132 return 0;
133 }
134
135 for (prop = info->props; prop && prop->name; prop++) {
136 /*
137 * TODO Properties without a parser are just for dirty hacks.
138 * qdev_prop_ptr is the only such PropertyInfo. It's marked
139 * for removal. This conditional should be removed along with
140 * it.
141 */
142 if (!prop->info->parse) {
143 continue; /* no way to set it, don't show */
144 }
145 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
146 }
147 return 1;
148 #endif
149 }
150
qdev_device_add(QemuOpts * opts)151 DeviceState *qdev_device_add(QemuOpts *opts)
152 {
153 #ifdef CONFIG_ANDROID /* Not ready yet */
154 return NULL;
155 #else
156 const char *driver, *path, *id;
157 DeviceInfo *info;
158 DeviceState *qdev;
159 BusState *bus;
160
161 driver = qemu_opt_get(opts, "driver");
162 if (!driver) {
163 qerror_report(QERR_MISSING_PARAMETER, "driver");
164 return NULL;
165 }
166
167 /* find driver */
168 info = qdev_find_info(NULL, driver);
169 if (!info || info->no_user) {
170 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
171 error_printf_unless_qmp("Try with argument '?' for a list.\n");
172 return NULL;
173 }
174
175 /* find bus */
176 path = qemu_opt_get(opts, "bus");
177 if (path != NULL) {
178 bus = qbus_find(path);
179 if (!bus) {
180 return NULL;
181 }
182 if (bus->info != info->bus_info) {
183 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
184 driver, bus->info->name);
185 return NULL;
186 }
187 } else {
188 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
189 if (!bus) {
190 qerror_report(QERR_NO_BUS_FOR_DEVICE,
191 info->name, info->bus_info->name);
192 return NULL;
193 }
194 }
195 if (qdev_hotplug && !bus->allow_hotplug) {
196 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
197 return NULL;
198 }
199
200 /* create device, set properties */
201 qdev = qdev_create_from_info(bus, info);
202 id = qemu_opts_id(opts);
203 if (id) {
204 qdev->id = id;
205 }
206 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
207 qdev_free(qdev);
208 return NULL;
209 }
210 if (qdev_init(qdev) < 0) {
211 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
212 return NULL;
213 }
214 qdev->opts = opts;
215 return qdev;
216 #endif
217 }
218
219 /* Initialize a device. Device properties should be set before calling
220 this function. IRQs and MMIO regions should be connected/mapped after
221 calling this function. */
qdev_init(DeviceState * dev)222 void qdev_init(DeviceState *dev)
223 {
224 dev->type->info->init(dev, dev->type->info);
225 }
226
227 /* Unlink device from bus and free the structure. */
qdev_free(DeviceState * dev)228 void qdev_free(DeviceState *dev)
229 {
230 QLIST_REMOVE(dev, sibling);
231 g_free(dev);
232 }
233
create_prop(DeviceState * dev,const char * name,DevicePropType type)234 static DeviceProperty *create_prop(DeviceState *dev, const char *name,
235 DevicePropType type)
236 {
237 DeviceProperty *prop;
238
239 /* TODO: Check for duplicate properties. */
240 prop = g_malloc0(sizeof(*prop));
241 prop->name = g_strdup(name);
242 prop->type = type;
243 prop->next = dev->props;
244 dev->props = prop;
245
246 return prop;
247 }
248
qdev_set_prop_int(DeviceState * dev,const char * name,uint64_t value)249 void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value)
250 {
251 DeviceProperty *prop;
252
253 prop = create_prop(dev, name, PROP_TYPE_INT);
254 prop->value.i = value;
255 }
256
qdev_set_prop_dev(DeviceState * dev,const char * name,DeviceState * value)257 void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value)
258 {
259 DeviceProperty *prop;
260
261 prop = create_prop(dev, name, PROP_TYPE_DEV);
262 prop->value.ptr = value;
263 }
264
qdev_set_prop_ptr(DeviceState * dev,const char * name,void * value)265 void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value)
266 {
267 DeviceProperty *prop;
268
269 prop = create_prop(dev, name, PROP_TYPE_PTR);
270 prop->value.ptr = value;
271 }
272
qdev_set_netdev(DeviceState * dev,NICInfo * nd)273 void qdev_set_netdev(DeviceState *dev, NICInfo *nd)
274 {
275 assert(!dev->nd);
276 dev->nd = nd;
277 }
278
279
280 /* Get a character (serial) device interface. */
qdev_init_chardev(DeviceState * dev)281 CharDriverState *qdev_init_chardev(DeviceState *dev)
282 {
283 static int next_serial;
284 static int next_virtconsole;
285 /* FIXME: This is a nasty hack that needs to go away. */
286 if (strncmp(dev->type->info->name, "virtio", 6) == 0) {
287 return virtcon_hds[next_virtconsole++];
288 } else {
289 return serial_hds[next_serial++];
290 }
291 }
292
qdev_get_parent_bus(DeviceState * dev)293 BusState *qdev_get_parent_bus(DeviceState *dev)
294 {
295 return dev->parent_bus;
296 }
297
find_prop(DeviceState * dev,const char * name,DevicePropType type)298 static DeviceProperty *find_prop(DeviceState *dev, const char *name,
299 DevicePropType type)
300 {
301 DeviceProperty *prop;
302
303 for (prop = dev->props; prop; prop = prop->next) {
304 if (strcmp(prop->name, name) == 0) {
305 assert (prop->type == type);
306 return prop;
307 }
308 }
309 return NULL;
310 }
311
qdev_get_prop_int(DeviceState * dev,const char * name,uint64_t def)312 uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def)
313 {
314 DeviceProperty *prop;
315
316 prop = find_prop(dev, name, PROP_TYPE_INT);
317 if (!prop) {
318 return def;
319 }
320
321 return prop->value.i;
322 }
323
qdev_get_prop_ptr(DeviceState * dev,const char * name)324 void *qdev_get_prop_ptr(DeviceState *dev, const char *name)
325 {
326 DeviceProperty *prop;
327
328 prop = find_prop(dev, name, PROP_TYPE_PTR);
329 assert(prop);
330 return prop->value.ptr;
331 }
332
qdev_get_prop_dev(DeviceState * dev,const char * name)333 DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name)
334 {
335 DeviceProperty *prop;
336
337 prop = find_prop(dev, name, PROP_TYPE_DEV);
338 if (!prop) {
339 return NULL;
340 }
341 return prop->value.ptr;
342 }
343
qdev_init_gpio_in(DeviceState * dev,qemu_irq_handler handler,int n)344 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
345 {
346 assert(dev->num_gpio_in == 0);
347 dev->num_gpio_in = n;
348 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
349 }
350
qdev_init_gpio_out(DeviceState * dev,qemu_irq * pins,int n)351 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
352 {
353 assert(dev->num_gpio_out == 0);
354 dev->num_gpio_out = n;
355 dev->gpio_out = pins;
356 }
357
qdev_get_gpio_in(DeviceState * dev,int n)358 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
359 {
360 assert(n >= 0 && n < dev->num_gpio_in);
361 return dev->gpio_in[n];
362 }
363
qdev_connect_gpio_out(DeviceState * dev,int n,qemu_irq pin)364 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
365 {
366 assert(n >= 0 && n < dev->num_gpio_out);
367 dev->gpio_out[n] = pin;
368 }
369
qdev_get_vlan_client(DeviceState * dev,NetCanReceive * can_receive,NetReceive * receive,NetReceiveIOV * receive_iov,NetCleanup * cleanup,void * opaque)370 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
371 NetCanReceive *can_receive,
372 NetReceive *receive,
373 NetReceiveIOV *receive_iov,
374 NetCleanup *cleanup,
375 void *opaque)
376 {
377 NICInfo *nd = dev->nd;
378 assert(nd);
379 return qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
380 receive, receive_iov, cleanup, opaque);
381 }
382
383
qdev_get_macaddr(DeviceState * dev,uint8_t * macaddr)384 void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
385 {
386 memcpy(macaddr, dev->nd->macaddr, 6);
387 }
388
389 static int next_block_unit[IF_COUNT];
390
391 /* Get a block device. This should only be used for single-drive devices
392 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
393 appropriate bus. */
qdev_init_bdrv(DeviceState * dev,BlockInterfaceType type)394 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
395 {
396 int unit = next_block_unit[type]++;
397 DriveInfo* info;
398
399 info = drive_get(type, 0, unit);
400 if (info == NULL) {
401 return NULL;
402 }
403 return info->bdrv;
404 }
405
qdev_get_child_bus(DeviceState * dev,const char * name)406 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
407 {
408 BusState *bus;
409
410 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
411 if (strcmp(name, bus->name) == 0) {
412 return bus;
413 }
414 }
415 return NULL;
416 }
417
418 static int next_scsi_bus;
419
420 /* Create a scsi bus, and attach devices to it. */
421 /* TODO: Actually create a scsi bus for hotplug to use. */
scsi_bus_new(DeviceState * host,SCSIAttachFn attach)422 void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
423 {
424 int bus = next_scsi_bus++;
425 int unit;
426 DriveInfo* info;
427
428 for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
429 info = drive_get(IF_SCSI, bus, unit);
430 if (info == NULL) {
431 continue;
432 }
433 attach(host, info->bdrv, unit);
434 }
435 }
436
qbus_create(BusType type,size_t size,DeviceState * parent,const char * name)437 BusState *qbus_create(BusType type, size_t size,
438 DeviceState *parent, const char *name)
439 {
440 BusState *bus;
441
442 bus = g_malloc0(size);
443 bus->type = type;
444 bus->parent = parent;
445 bus->name = g_strdup(name);
446 QLIST_INIT(&bus->children);
447 if (parent) {
448 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
449 }
450 return bus;
451 }
452
453 static const char *bus_type_names[] = {
454 [ BUS_TYPE_SYSTEM ] = "System",
455 [ BUS_TYPE_PCI ] = "PCI",
456 [ BUS_TYPE_SCSI ] = "SCSI",
457 [ BUS_TYPE_I2C ] = "I2C",
458 [ BUS_TYPE_SSI ] = "SSI",
459 };
460
461 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
462 static void qbus_print(Monitor *mon, BusState *bus, int indent);
463
qdev_print(Monitor * mon,DeviceState * dev,int indent)464 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
465 {
466 DeviceProperty *prop;
467 BusState *child;
468 qdev_printf("dev: %s\n", dev->type->info->name);
469 indent += 2;
470 if (dev->num_gpio_in) {
471 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
472 }
473 if (dev->num_gpio_out) {
474 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
475 }
476 for (prop = dev->props; prop; prop = prop->next) {
477 switch (prop->type) {
478 case PROP_TYPE_INT:
479 qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name,
480 prop->value.i);
481 break;
482 case PROP_TYPE_PTR:
483 qdev_printf("prop-ptr %s\n", prop->name);
484 break;
485 case PROP_TYPE_DEV:
486 qdev_printf("prop-dev %s %s\n", prop->name,
487 ((DeviceState *)prop->value.ptr)->type->info->name);
488 break;
489 default:
490 qdev_printf("prop-unknown%d %s\n", prop->type, prop->name);
491 break;
492 }
493 }
494 switch (dev->parent_bus->type) {
495 case BUS_TYPE_SYSTEM:
496 sysbus_dev_print(mon, dev, indent);
497 break;
498 default:
499 break;
500 }
501 QLIST_FOREACH(child, &dev->child_bus, sibling) {
502 qbus_print(mon, child, indent);
503 }
504 }
505
qbus_print(Monitor * mon,BusState * bus,int indent)506 static void qbus_print(Monitor *mon, BusState *bus, int indent)
507 {
508 struct DeviceState *dev;
509
510 qdev_printf("bus: %s\n", bus->name);
511 indent += 2;
512 qdev_printf("type %s\n", bus_type_names[bus->type]);
513 QLIST_FOREACH(dev, &bus->children, sibling) {
514 qdev_print(mon, dev, indent);
515 }
516 }
517 #undef qdev_printf
518
do_info_qtree(Monitor * mon)519 void do_info_qtree(Monitor *mon)
520 {
521 if (main_system_bus)
522 qbus_print(mon, main_system_bus, 0);
523 }
524
qdev_get_dev_path(DeviceState * dev)525 char *qdev_get_dev_path(DeviceState *dev)
526 {
527 // TODO(digit): Implement this properly.
528 return NULL;
529 }
530
531