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.h"
30#include "qdev.h"
31#include "sysemu.h"
32#include "monitor.h"
33#include "blockdev.h"
34
35struct DeviceProperty {
36    const char *name;
37    DevicePropType type;
38    union {
39        uint64_t i;
40        void *ptr;
41    } value;
42    DeviceProperty *next;
43};
44
45struct DeviceType {
46    DeviceInfo *info;
47    DeviceType *next;
48};
49
50/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
51static BusState *main_system_bus;
52
53static DeviceType *device_type_list;
54
55/* Register a new device type.  */
56void qdev_register(DeviceInfo *info)
57{
58    DeviceType *t;
59
60    assert(info->size >= sizeof(DeviceState));
61
62    t = qemu_mallocz(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.  */
71DeviceState *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 = qemu_mallocz(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
106int 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
151DeviceState *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.  */
222void 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.  */
228void qdev_free(DeviceState *dev)
229{
230    QLIST_REMOVE(dev, sibling);
231    qemu_free(dev);
232}
233
234static DeviceProperty *create_prop(DeviceState *dev, const char *name,
235                                   DevicePropType type)
236{
237    DeviceProperty *prop;
238
239    /* TODO: Check for duplicate properties.  */
240    prop = qemu_mallocz(sizeof(*prop));
241    prop->name = qemu_strdup(name);
242    prop->type = type;
243    prop->next = dev->props;
244    dev->props = prop;
245
246    return prop;
247}
248
249void 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
257void 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
265void 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
273void 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.  */
281CharDriverState *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
293BusState *qdev_get_parent_bus(DeviceState *dev)
294{
295    return dev->parent_bus;
296}
297
298static 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
312uint64_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
324void *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
333DeviceState *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
344void 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
351void 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
358qemu_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
364void 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
370VLANClientState *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
384void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
385{
386    memcpy(macaddr, dev->nd->macaddr, 6);
387}
388
389static 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.  */
394BlockDriverState *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
406BusState *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
418static 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.  */
422void 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
437BusState *qbus_create(BusType type, size_t size,
438                      DeviceState *parent, const char *name)
439{
440    BusState *bus;
441
442    bus = qemu_mallocz(size);
443    bus->type = type;
444    bus->parent = parent;
445    bus->name = qemu_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
453static 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__)
462static void qbus_print(Monitor *mon, BusState *bus, int indent);
463
464static 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
506static 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
519void do_info_qtree(Monitor *mon)
520{
521    if (main_system_bus)
522        qbus_print(mon, main_system_bus, 0);
523}
524