Statistics
| Branch: | Revision:

root / hw / qdev.c @ c4470b25

History | View | Annotate | Download (16.6 kB)

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, see <http://www.gnu.org/licenses/>.
18
 */
19

    
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.  */
27

    
28
#include "net.h"
29
#include "qdev.h"
30
#include "sysemu.h"
31
#include "monitor.h"
32

    
33
/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
34
static BusState *main_system_bus;
35

    
36
static DeviceInfo *device_info_list;
37

    
38
static BusState *qbus_find_recursive(BusState *bus, const char *name,
39
                                     const BusInfo *info);
40
static BusState *qbus_find(const char *path);
41

    
42
/* Register a new device type.  */
43
void qdev_register(DeviceInfo *info)
44
{
45
    assert(info->size >= sizeof(DeviceState));
46
    assert(!info->next);
47

    
48
    info->next = device_info_list;
49
    device_info_list = info;
50
}
51

    
52
static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
53
{
54
    DeviceInfo *info;
55

    
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;
63
    }
64

    
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;
74
    }
75
    return NULL;
76
}
77

    
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)
82
{
83
    DeviceInfo *info;
84
    DeviceState *dev;
85

    
86
    if (!bus) {
87
        if (!main_system_bus) {
88
            main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
89
        }
90
        bus = main_system_bus;
91
    }
92

    
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);
96
    }
97

    
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;
106
}
107

    
108
static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
109
{
110
    int pos = 0;
111

    
112
    pos += snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
113
                    info->name, info->bus_info->name);
114
    if (info->alias)
115
        pos += snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
116
    if (info->desc)
117
        pos += snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
118
    if (info->no_user)
119
        pos += snprintf(dest+pos, len-pos, ", no-user");
120
    return pos;
121
}
122

    
123
static int set_property(const char *name, const char *value, void *opaque)
124
{
125
    DeviceState *dev = opaque;
126

    
127
    if (strcmp(name, "driver") == 0)
128
        return 0;
129
    if (strcmp(name, "bus") == 0)
130
        return 0;
131

    
132
    if (-1 == qdev_prop_parse(dev, name, value)) {
133
        fprintf(stderr, "can't set property \"%s\" to \"%s\" for \"%s\"\n",
134
                name, value, dev->info->name);
135
        return -1;
136
    }
137
    return 0;
138
}
139

    
140
DeviceState *qdev_device_add(QemuOpts *opts)
141
{
142
    const char *driver, *path, *id;
143
    DeviceInfo *info;
144
    DeviceState *qdev;
145
    BusState *bus;
146

    
147
    driver = qemu_opt_get(opts, "driver");
148
    if (!driver) {
149
        fprintf(stderr, "-device: no driver specified\n");
150
        return NULL;
151
    }
152
    if (strcmp(driver, "?") == 0) {
153
        char msg[256];
154
        for (info = device_info_list; info != NULL; info = info->next) {
155
            qdev_print_devinfo(info, msg, sizeof(msg));
156
            fprintf(stderr, "%s\n", msg);
157
        }
158
        return NULL;
159
    }
160

    
161
    /* find driver */
162
    info = qdev_find_info(NULL, driver);
163
    if (!info) {
164
        fprintf(stderr, "Device \"%s\" not found.  Try -device '?' for a list.\n",
165
                driver);
166
        return NULL;
167
    }
168
    if (info->no_user) {
169
        fprintf(stderr, "device \"%s\" can't be added via command line\n",
170
                info->name);
171
        return NULL;
172
    }
173

    
174
    /* find bus */
175
    path = qemu_opt_get(opts, "bus");
176
    if (path != NULL) {
177
        bus = qbus_find(path);
178
    } else {
179
        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
180
    }
181
    if (!bus)
182
        return NULL;
183

    
184
    /* create device, set properties */
185
    qdev = qdev_create(bus, driver);
186
    id = qemu_opts_id(opts);
187
    if (id) {
188
        qdev->id = id;
189
    }
190
    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
191
        qdev_free(qdev);
192
        return NULL;
193
    }
194
    qdev_init(qdev);
195
    return qdev;
196
}
197

    
198
/* Initialize a device.  Device properties should be set before calling
199
   this function.  IRQs and MMIO regions should be connected/mapped after
200
   calling this function.  */
201
void qdev_init(DeviceState *dev)
202
{
203
    dev->info->init(dev, dev->info);
204
}
205

    
206
/* Unlink device from bus and free the structure.  */
207
void qdev_free(DeviceState *dev)
208
{
209
    LIST_REMOVE(dev, sibling);
210
    qemu_free(dev);
211
}
212

    
213
/* Get a character (serial) device interface.  */
214
CharDriverState *qdev_init_chardev(DeviceState *dev)
215
{
216
    static int next_serial;
217
    static int next_virtconsole;
218
    /* FIXME: This is a nasty hack that needs to go away.  */
219
    if (strncmp(dev->info->name, "virtio", 6) == 0) {
220
        return virtcon_hds[next_virtconsole++];
221
    } else {
222
        return serial_hds[next_serial++];
223
    }
224
}
225

    
226
BusState *qdev_get_parent_bus(DeviceState *dev)
227
{
228
    return dev->parent_bus;
229
}
230

    
231
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
232
{
233
    assert(dev->num_gpio_in == 0);
234
    dev->num_gpio_in = n;
235
    dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
236
}
237

    
238
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
239
{
240
    assert(dev->num_gpio_out == 0);
241
    dev->num_gpio_out = n;
242
    dev->gpio_out = pins;
243
}
244

    
245
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
246
{
247
    assert(n >= 0 && n < dev->num_gpio_in);
248
    return dev->gpio_in[n];
249
}
250

    
251
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
252
{
253
    assert(n >= 0 && n < dev->num_gpio_out);
254
    dev->gpio_out[n] = pin;
255
}
256

    
257
VLANClientState *qdev_get_vlan_client(DeviceState *dev,
258
                                      NetCanReceive *can_receive,
259
                                      NetReceive *receive,
260
                                      NetReceiveIOV *receive_iov,
261
                                      NetCleanup *cleanup,
262
                                      void *opaque)
263
{
264
    NICInfo *nd = dev->nd;
265
    assert(nd);
266
    nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
267
                                  receive, receive_iov, cleanup, opaque);
268
    return nd->vc;
269
}
270

    
271

    
272
void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
273
{
274
    memcpy(macaddr, dev->nd->macaddr, 6);
275
}
276

    
277
static int next_block_unit[IF_COUNT];
278

    
279
/* Get a block device.  This should only be used for single-drive devices
280
   (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
281
   appropriate bus.  */
282
BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
283
{
284
    int unit = next_block_unit[type]++;
285
    DriveInfo *dinfo;
286

    
287
    dinfo = drive_get(type, 0, unit);
288
    return dinfo ? dinfo->bdrv : NULL;
289
}
290

    
291
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
292
{
293
    BusState *bus;
294

    
295
    LIST_FOREACH(bus, &dev->child_bus, sibling) {
296
        if (strcmp(name, bus->name) == 0) {
297
            return bus;
298
        }
299
    }
300
    return NULL;
301
}
302

    
303
static int next_scsi_bus;
304

    
305
/* Create a scsi bus, and attach devices to it.  */
306
/* TODO: Actually create a scsi bus for hotplug to use.  */
307
void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
308
{
309
   int bus = next_scsi_bus++;
310
   int unit;
311
   DriveInfo *dinfo;
312

    
313
   for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
314
       dinfo = drive_get(IF_SCSI, bus, unit);
315
       if (!dinfo) {
316
           continue;
317
       }
318
       attach(host, dinfo->bdrv, unit);
319
   }
320
}
321

    
322
static BusState *qbus_find_recursive(BusState *bus, const char *name,
323
                                     const BusInfo *info)
324
{
325
    DeviceState *dev;
326
    BusState *child, *ret;
327
    int match = 1;
328

    
329
    if (name && (strcmp(bus->name, name) != 0)) {
330
        match = 0;
331
    }
332
    if (info && (bus->info != info)) {
333
        match = 0;
334
    }
335
    if (match) {
336
        return bus;
337
    }
338

    
339
    LIST_FOREACH(dev, &bus->children, sibling) {
340
        LIST_FOREACH(child, &dev->child_bus, sibling) {
341
            ret = qbus_find_recursive(child, name, info);
342
            if (ret) {
343
                return ret;
344
            }
345
        }
346
    }
347
    return NULL;
348
}
349

    
350
static void qbus_list_bus(DeviceState *dev, char *dest, int len)
351
{
352
    BusState *child;
353
    const char *sep = " ";
354
    int pos = 0;
355

    
356
    pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
357
                    dev->id ? dev->id : dev->info->name);
358
    LIST_FOREACH(child, &dev->child_bus, sibling) {
359
        pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
360
        sep = ", ";
361
    }
362
}
363

    
364
static void qbus_list_dev(BusState *bus, char *dest, int len)
365
{
366
    DeviceState *dev;
367
    const char *sep = " ";
368
    int pos = 0;
369

    
370
    pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
371
                    bus->name);
372
    LIST_FOREACH(dev, &bus->children, sibling) {
373
        pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
374
                        sep, dev->info->name);
375
        if (dev->id)
376
            pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
377
        sep = ", ";
378
    }
379
}
380

    
381
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
382
{
383
    BusState *child;
384

    
385
    LIST_FOREACH(child, &dev->child_bus, sibling) {
386
        if (strcmp(child->name, elem) == 0) {
387
            return child;
388
        }
389
    }
390
    return NULL;
391
}
392

    
393
static DeviceState *qbus_find_dev(BusState *bus, char *elem)
394
{
395
    DeviceState *dev;
396

    
397
    /*
398
     * try to match in order:
399
     *   (1) instance id, if present
400
     *   (2) driver name
401
     *   (3) driver alias, if present
402
     */
403
    LIST_FOREACH(dev, &bus->children, sibling) {
404
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
405
            return dev;
406
        }
407
    }
408
    LIST_FOREACH(dev, &bus->children, sibling) {
409
        if (strcmp(dev->info->name, elem) == 0) {
410
            return dev;
411
        }
412
    }
413
    LIST_FOREACH(dev, &bus->children, sibling) {
414
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
415
            return dev;
416
        }
417
    }
418
    return NULL;
419
}
420

    
421
static BusState *qbus_find(const char *path)
422
{
423
    DeviceState *dev;
424
    BusState *bus;
425
    char elem[128], msg[256];
426
    int pos, len;
427

    
428
    /* find start element */
429
    if (path[0] == '/') {
430
        bus = main_system_bus;
431
        pos = 0;
432
    } else {
433
        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
434
            fprintf(stderr, "path parse error (\"%s\")\n", path);
435
            return NULL;
436
        }
437
        bus = qbus_find_recursive(main_system_bus, elem, NULL);
438
        if (!bus) {
439
            fprintf(stderr, "bus \"%s\" not found\n", elem);
440
            return NULL;
441
        }
442
        pos = len;
443
    }
444

    
445
    for (;;) {
446
        if (path[pos] == '\0') {
447
            /* we are done */
448
            return bus;
449
        }
450

    
451
        /* find device */
452
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
453
            fprintf(stderr, "path parse error (\"%s\" pos %d)\n", path, pos);
454
            return NULL;
455
        }
456
        pos += len;
457
        dev = qbus_find_dev(bus, elem);
458
        if (!dev) {
459
            qbus_list_dev(bus, msg, sizeof(msg));
460
            fprintf(stderr, "device \"%s\" not found\n%s\n", elem, msg);
461
            return NULL;
462
        }
463
        if (path[pos] == '\0') {
464
            /* last specified element is a device.  If it has exactly
465
             * one child bus accept it nevertheless */
466
            switch (dev->num_child_bus) {
467
            case 0:
468
                fprintf(stderr, "device has no child bus (%s)\n", path);
469
                return NULL;
470
            case 1:
471
                return LIST_FIRST(&dev->child_bus);
472
            default:
473
                qbus_list_bus(dev, msg, sizeof(msg));
474
                fprintf(stderr, "device has multiple child busses (%s)\n%s\n",
475
                        path, msg);
476
                return NULL;
477
            }
478
        }
479

    
480
        /* find bus */
481
        if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
482
            fprintf(stderr, "path parse error (\"%s\" pos %d)\n", path, pos);
483
            return NULL;
484
        }
485
        pos += len;
486
        bus = qbus_find_bus(dev, elem);
487
        if (!bus) {
488
            qbus_list_bus(dev, msg, sizeof(msg));
489
            fprintf(stderr, "child bus \"%s\" not found\n%s\n", elem, msg);
490
            return NULL;
491
        }
492
    }
493
}
494

    
495
BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
496
{
497
    BusState *bus;
498
    char *buf;
499
    int i,len;
500

    
501
    bus = qemu_mallocz(info->size);
502
    bus->info = info;
503
    bus->parent = parent;
504

    
505
    if (name) {
506
        /* use supplied name */
507
        bus->name = qemu_strdup(name);
508
    } else if (parent && parent->id) {
509
        /* parent device has id -> use it for bus name */
510
        len = strlen(parent->id) + 16;
511
        buf = qemu_malloc(len);
512
        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
513
        bus->name = buf;
514
    } else {
515
        /* no id -> use lowercase bus type for bus name */
516
        len = strlen(info->name) + 16;
517
        buf = qemu_malloc(len);
518
        len = snprintf(buf, len, "%s.%d", info->name,
519
                       parent ? parent->num_child_bus : 0);
520
        for (i = 0; i < len; i++)
521
            buf[i] = qemu_tolower(buf[i]);
522
        bus->name = buf;
523
    }
524

    
525
    LIST_INIT(&bus->children);
526
    if (parent) {
527
        LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
528
        parent->num_child_bus++;
529
    }
530
    return bus;
531
}
532

    
533
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
534
static void qbus_print(Monitor *mon, BusState *bus, int indent);
535

    
536
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
537
                             const char *prefix, int indent)
538
{
539
    char buf[64];
540

    
541
    if (!props)
542
        return;
543
    while (props->name) {
544
        if (props->info->print) {
545
            props->info->print(dev, props, buf, sizeof(buf));
546
            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
547
        }
548
        props++;
549
    }
550
}
551

    
552
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
553
{
554
    BusState *child;
555
    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
556
                dev->id ? dev->id : "");
557
    indent += 2;
558
    if (dev->num_gpio_in) {
559
        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
560
    }
561
    if (dev->num_gpio_out) {
562
        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
563
    }
564
    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
565
    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
566
    if (dev->parent_bus->info->print_dev)
567
        dev->parent_bus->info->print_dev(mon, dev, indent);
568
    LIST_FOREACH(child, &dev->child_bus, sibling) {
569
        qbus_print(mon, child, indent);
570
    }
571
}
572

    
573
static void qbus_print(Monitor *mon, BusState *bus, int indent)
574
{
575
    struct DeviceState *dev;
576

    
577
    qdev_printf("bus: %s\n", bus->name);
578
    indent += 2;
579
    qdev_printf("type %s\n", bus->info->name);
580
    LIST_FOREACH(dev, &bus->children, sibling) {
581
        qdev_print(mon, dev, indent);
582
    }
583
}
584
#undef qdev_printf
585

    
586
void do_info_qtree(Monitor *mon)
587
{
588
    if (main_system_bus)
589
        qbus_print(mon, main_system_bus, 0);
590
}
591

    
592
void do_info_qdrv(Monitor *mon)
593
{
594
    DeviceInfo *info;
595
    char msg[256];
596

    
597
    for (info = device_info_list; info != NULL; info = info->next) {
598
        qdev_print_devinfo(info, msg, sizeof(msg));
599
        monitor_printf(mon, "%s\n", msg);
600
    }
601
}