Home | History | Annotate | Download | only in core
      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.  */
     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.  */
     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 
    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 
    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.  */
    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.  */
    228 void qdev_free(DeviceState *dev)
    229 {
    230     QLIST_REMOVE(dev, sibling);
    231     g_free(dev);
    232 }
    233 
    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 
    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 
    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 
    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 
    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.  */
    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 
    293 BusState *qdev_get_parent_bus(DeviceState *dev)
    294 {
    295     return dev->parent_bus;
    296 }
    297 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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.  */
    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 
    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.  */
    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 
    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 
    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 
    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 
    519 void do_info_qtree(Monitor *mon)
    520 {
    521     if (main_system_bus)
    522         qbus_print(mon, main_system_bus, 0);
    523 }
    524 
    525 char *qdev_get_dev_path(DeviceState *dev)
    526 {
    527     // TODO(digit): Implement this properly.
    528     return NULL;
    529 }
    530 
    531