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
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
));
44 info
->next
= device_info_list
;
45 device_info_list
= info
;
48 static DeviceInfo
*qdev_find_info(BusInfo
*bus_info
, const char *name
)
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
)
56 if (strcmp(info
->name
, name
) != 0)
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
)
67 if (strcmp(info
->alias
, name
) != 0)
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
)
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
);
91 hw_error("Unknown device '%s' for bus '%s'\n", name
, bus
->info
->name
);
94 dev
= qemu_mallocz(info
->size
);
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
);
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
);
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
++];
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
,
167 NetReceiveIOV
*receive_iov
,
171 NICInfo
*nd
= dev
->nd
;
173 nd
->vc
= qemu_new_vlan_client(nd
->vlan
, nd
->model
, nd
->name
, can_receive
,
174 receive
, receive_iov
, cleanup
, opaque
);
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
189 BlockDriverState
*qdev_init_bdrv(DeviceState
*dev
, BlockInterfaceType type
)
191 int unit
= next_block_unit
[type
]++;
194 index
= drive_get_index(type
, 0, unit
);
198 return drives_table
[index
].bdrv
;
201 BusState
*qdev_get_child_bus(DeviceState
*dev
, const char *name
)
205 LIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
206 if (strcmp(name
, bus
->name
) == 0) {
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
++;
223 for (unit
= 0; unit
< MAX_SCSI_DEVS
; unit
++) {
224 index
= drive_get_index(IF_SCSI
, bus
, unit
);
228 attach(host
, drives_table
[index
].bdrv
, unit
);
232 BusState
*qbus_create(BusInfo
*info
, DeviceState
*parent
, const char *name
)
236 bus
= qemu_mallocz(info
->size
);
238 bus
->parent
= parent
;
239 bus
->name
= qemu_strdup(name
);
240 LIST_INIT(&bus
->children
);
242 LIST_INSERT_HEAD(&parent
->child_bus
, bus
, sibling
);
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
)
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
);
266 static void qdev_print(Monitor
*mon
, DeviceState
*dev
, int indent
)
269 qdev_printf("dev: %s, id \"%s\"\n", dev
->info
->name
,
270 dev
->id
? dev
->id
: "");
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
);
293 qdev_printf("type %s\n", bus
->info
->name
);
294 LIST_FOREACH(dev
, &bus
->children
, sibling
) {
295 qdev_print(mon
, dev
, indent
);
300 void do_info_qtree(Monitor
*mon
)
303 qbus_print(mon
, main_system_bus
, 0);