Fix 32-bit overflow in parallels image support
[qemu-kvm/fedora.git] / hw / qdev.c
blobfaecc767af1517fc413243357fd247f524328374
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 /* Register a new device type. */
39 void qdev_register(DeviceInfo *info)
41 assert(info->size >= sizeof(DeviceState));
42 assert(!info->next);
44 info->next = device_info_list;
45 device_info_list = info;
48 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
50 DeviceInfo *info;
52 /* first check device names */
53 for (info = device_info_list; info != NULL; info = info->next) {
54 if (bus_info && info->bus_info != bus_info)
55 continue;
56 if (strcmp(info->name, name) != 0)
57 continue;
58 return info;
61 /* failing that check the aliases */
62 for (info = device_info_list; info != NULL; info = info->next) {
63 if (bus_info && info->bus_info != bus_info)
64 continue;
65 if (!info->alias)
66 continue;
67 if (strcmp(info->alias, name) != 0)
68 continue;
69 return info;
71 return NULL;
74 /* Create a new device. This only initializes the device state structure
75 and allows properties to be set. qdev_init should be called to
76 initialize the actual device emulation. */
77 DeviceState *qdev_create(BusState *bus, const char *name)
79 DeviceInfo *info;
80 DeviceState *dev;
82 if (!bus) {
83 if (!main_system_bus) {
84 main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
86 bus = main_system_bus;
89 info = qdev_find_info(bus->info, name);
90 if (!info) {
91 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
94 dev = qemu_mallocz(info->size);
95 dev->info = info;
96 dev->parent_bus = bus;
97 qdev_prop_set_defaults(dev, dev->info->props);
98 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
99 qdev_prop_set_compat(dev);
100 LIST_INSERT_HEAD(&bus->children, dev, sibling);
101 return dev;
104 /* Initialize a device. Device properties should be set before calling
105 this function. IRQs and MMIO regions should be connected/mapped after
106 calling this function. */
107 void qdev_init(DeviceState *dev)
109 dev->info->init(dev, dev->info);
112 /* Unlink device from bus and free the structure. */
113 void qdev_free(DeviceState *dev)
115 LIST_REMOVE(dev, sibling);
116 qemu_free(dev->id);
117 qemu_free(dev);
120 /* Get a character (serial) device interface. */
121 CharDriverState *qdev_init_chardev(DeviceState *dev)
123 static int next_serial;
124 static int next_virtconsole;
125 /* FIXME: This is a nasty hack that needs to go away. */
126 if (strncmp(dev->info->name, "virtio", 6) == 0) {
127 return virtcon_hds[next_virtconsole++];
128 } else {
129 return serial_hds[next_serial++];
133 BusState *qdev_get_parent_bus(DeviceState *dev)
135 return dev->parent_bus;
138 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
140 assert(dev->num_gpio_in == 0);
141 dev->num_gpio_in = n;
142 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
145 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
147 assert(dev->num_gpio_out == 0);
148 dev->num_gpio_out = n;
149 dev->gpio_out = pins;
152 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
154 assert(n >= 0 && n < dev->num_gpio_in);
155 return dev->gpio_in[n];
158 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
160 assert(n >= 0 && n < dev->num_gpio_out);
161 dev->gpio_out[n] = pin;
164 VLANClientState *qdev_get_vlan_client(DeviceState *dev,
165 NetCanReceive *can_receive,
166 NetReceive *receive,
167 NetReceiveIOV *receive_iov,
168 NetCleanup *cleanup,
169 void *opaque)
171 NICInfo *nd = dev->nd;
172 assert(nd);
173 nd->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, can_receive,
174 receive, receive_iov, cleanup, opaque);
175 return nd->vc;
179 void qdev_get_macaddr(DeviceState *dev, uint8_t *macaddr)
181 memcpy(macaddr, dev->nd->macaddr, 6);
184 static int next_block_unit[IF_COUNT];
186 /* Get a block device. This should only be used for single-drive devices
187 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
188 appropriate bus. */
189 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
191 int unit = next_block_unit[type]++;
192 int index;
194 index = drive_get_index(type, 0, unit);
195 if (index == -1) {
196 return NULL;
198 return drives_table[index].bdrv;
201 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
203 BusState *bus;
205 LIST_FOREACH(bus, &dev->child_bus, sibling) {
206 if (strcmp(name, bus->name) == 0) {
207 return bus;
210 return NULL;
213 static int next_scsi_bus;
215 /* Create a scsi bus, and attach devices to it. */
216 /* TODO: Actually create a scsi bus for hotplug to use. */
217 void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
219 int bus = next_scsi_bus++;
220 int unit;
221 int index;
223 for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
224 index = drive_get_index(IF_SCSI, bus, unit);
225 if (index == -1) {
226 continue;
228 attach(host, drives_table[index].bdrv, unit);
232 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
234 BusState *bus;
236 bus = qemu_mallocz(info->size);
237 bus->info = info;
238 bus->parent = parent;
239 bus->name = qemu_strdup(name);
240 LIST_INIT(&bus->children);
241 if (parent) {
242 LIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
244 return bus;
247 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
248 static void qbus_print(Monitor *mon, BusState *bus, int indent);
250 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
251 const char *prefix, int indent)
253 char buf[64];
255 if (!props)
256 return;
257 while (props->name) {
258 if (props->info->print) {
259 props->info->print(dev, props, buf, sizeof(buf));
260 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
262 props++;
266 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
268 BusState *child;
269 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
270 dev->id ? dev->id : "");
271 indent += 2;
272 if (dev->num_gpio_in) {
273 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
275 if (dev->num_gpio_out) {
276 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
278 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
279 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
280 if (dev->parent_bus->info->print_dev)
281 dev->parent_bus->info->print_dev(mon, dev, indent);
282 LIST_FOREACH(child, &dev->child_bus, sibling) {
283 qbus_print(mon, child, indent);
287 static void qbus_print(Monitor *mon, BusState *bus, int indent)
289 struct DeviceState *dev;
291 qdev_printf("bus: %s\n", bus->name);
292 indent += 2;
293 qdev_printf("type %s\n", bus->info->name);
294 LIST_FOREACH(dev, &bus->children, sibling) {
295 qdev_print(mon, dev, indent);
298 #undef qdev_printf
300 void do_info_qtree(Monitor *mon)
302 if (main_system_bus)
303 qbus_print(mon, main_system_bus, 0);