Revision ee6847d1 hw/qdev.c
b/hw/qdev.c | ||
---|---|---|
30 | 30 |
#include "sysemu.h" |
31 | 31 |
#include "monitor.h" |
32 | 32 |
|
33 |
struct DeviceProperty { |
|
34 |
const char *name; |
|
35 |
DevicePropType type; |
|
36 |
union { |
|
37 |
uint64_t i; |
|
38 |
void *ptr; |
|
39 |
} value; |
|
40 |
DeviceProperty *next; |
|
41 |
}; |
|
42 |
|
|
43 | 33 |
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */ |
44 | 34 |
static BusState *main_system_bus; |
45 | 35 |
extern struct BusInfo system_bus_info; |
... | ... | |
85 | 75 |
dev = qemu_mallocz(info->size); |
86 | 76 |
dev->info = info; |
87 | 77 |
dev->parent_bus = bus; |
78 |
qdev_prop_set_defaults(dev, dev->info->props); |
|
79 |
qdev_prop_set_defaults(dev, dev->parent_bus->info->props); |
|
88 | 80 |
LIST_INSERT_HEAD(&bus->children, dev, sibling); |
89 | 81 |
return dev; |
90 | 82 |
} |
... | ... | |
104 | 96 |
free(dev); |
105 | 97 |
} |
106 | 98 |
|
107 |
static DeviceProperty *create_prop(DeviceState *dev, const char *name, |
|
108 |
DevicePropType type) |
|
109 |
{ |
|
110 |
DeviceProperty *prop; |
|
111 |
|
|
112 |
/* TODO: Check for duplicate properties. */ |
|
113 |
prop = qemu_mallocz(sizeof(*prop)); |
|
114 |
prop->name = qemu_strdup(name); |
|
115 |
prop->type = type; |
|
116 |
prop->next = dev->props; |
|
117 |
dev->props = prop; |
|
118 |
|
|
119 |
return prop; |
|
120 |
} |
|
121 |
|
|
122 |
void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value) |
|
123 |
{ |
|
124 |
DeviceProperty *prop; |
|
125 |
|
|
126 |
prop = create_prop(dev, name, PROP_TYPE_INT); |
|
127 |
prop->value.i = value; |
|
128 |
} |
|
129 |
|
|
130 |
void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value) |
|
131 |
{ |
|
132 |
DeviceProperty *prop; |
|
133 |
|
|
134 |
prop = create_prop(dev, name, PROP_TYPE_DEV); |
|
135 |
prop->value.ptr = value; |
|
136 |
} |
|
137 |
|
|
138 |
void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value) |
|
139 |
{ |
|
140 |
DeviceProperty *prop; |
|
141 |
|
|
142 |
prop = create_prop(dev, name, PROP_TYPE_PTR); |
|
143 |
prop->value.ptr = value; |
|
144 |
} |
|
145 |
|
|
146 |
void qdev_set_netdev(DeviceState *dev, NICInfo *nd) |
|
147 |
{ |
|
148 |
assert(!dev->nd); |
|
149 |
dev->nd = nd; |
|
150 |
} |
|
151 |
|
|
152 |
|
|
153 | 99 |
/* Get a character (serial) device interface. */ |
154 | 100 |
CharDriverState *qdev_init_chardev(DeviceState *dev) |
155 | 101 |
{ |
... | ... | |
168 | 114 |
return dev->parent_bus; |
169 | 115 |
} |
170 | 116 |
|
171 |
static DeviceProperty *find_prop(DeviceState *dev, const char *name, |
|
172 |
DevicePropType type) |
|
173 |
{ |
|
174 |
DeviceProperty *prop; |
|
175 |
|
|
176 |
for (prop = dev->props; prop; prop = prop->next) { |
|
177 |
if (strcmp(prop->name, name) == 0) { |
|
178 |
assert (prop->type == type); |
|
179 |
return prop; |
|
180 |
} |
|
181 |
} |
|
182 |
return NULL; |
|
183 |
} |
|
184 |
|
|
185 |
uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def) |
|
186 |
{ |
|
187 |
DeviceProperty *prop; |
|
188 |
|
|
189 |
prop = find_prop(dev, name, PROP_TYPE_INT); |
|
190 |
if (!prop) { |
|
191 |
return def; |
|
192 |
} |
|
193 |
|
|
194 |
return prop->value.i; |
|
195 |
} |
|
196 |
|
|
197 |
void *qdev_get_prop_ptr(DeviceState *dev, const char *name) |
|
198 |
{ |
|
199 |
DeviceProperty *prop; |
|
200 |
|
|
201 |
prop = find_prop(dev, name, PROP_TYPE_PTR); |
|
202 |
assert(prop); |
|
203 |
return prop->value.ptr; |
|
204 |
} |
|
205 |
|
|
206 |
DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name) |
|
207 |
{ |
|
208 |
DeviceProperty *prop; |
|
209 |
|
|
210 |
prop = find_prop(dev, name, PROP_TYPE_DEV); |
|
211 |
if (!prop) { |
|
212 |
return NULL; |
|
213 |
} |
|
214 |
return prop->value.ptr; |
|
215 |
} |
|
216 |
|
|
217 | 117 |
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) |
218 | 118 |
{ |
219 | 119 |
assert(dev->num_gpio_in == 0); |
... | ... | |
326 | 226 |
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__) |
327 | 227 |
static void qbus_print(Monitor *mon, BusState *bus, int indent); |
328 | 228 |
|
229 |
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props, |
|
230 |
const char *prefix, int indent) |
|
231 |
{ |
|
232 |
char buf[64]; |
|
233 |
|
|
234 |
if (!props) |
|
235 |
return; |
|
236 |
while (props->name) { |
|
237 |
if (props->info->print) { |
|
238 |
props->info->print(dev, props, buf, sizeof(buf)); |
|
239 |
qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf); |
|
240 |
} |
|
241 |
props++; |
|
242 |
} |
|
243 |
} |
|
244 |
|
|
329 | 245 |
static void qdev_print(Monitor *mon, DeviceState *dev, int indent) |
330 | 246 |
{ |
331 |
DeviceProperty *prop; |
|
332 | 247 |
BusState *child; |
333 | 248 |
qdev_printf("dev: %s\n", dev->info->name); |
334 | 249 |
indent += 2; |
... | ... | |
338 | 253 |
if (dev->num_gpio_out) { |
339 | 254 |
qdev_printf("gpio-out %d\n", dev->num_gpio_out); |
340 | 255 |
} |
341 |
for (prop = dev->props; prop; prop = prop->next) { |
|
342 |
switch (prop->type) { |
|
343 |
case PROP_TYPE_INT: |
|
344 |
qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name, |
|
345 |
prop->value.i); |
|
346 |
break; |
|
347 |
case PROP_TYPE_PTR: |
|
348 |
qdev_printf("prop-ptr %s\n", prop->name); |
|
349 |
break; |
|
350 |
case PROP_TYPE_DEV: |
|
351 |
qdev_printf("prop-dev %s %s\n", prop->name, |
|
352 |
((DeviceState *)prop->value.ptr)->info->name); |
|
353 |
break; |
|
354 |
default: |
|
355 |
qdev_printf("prop-unknown%d %s\n", prop->type, prop->name); |
|
356 |
break; |
|
357 |
} |
|
358 |
} |
|
256 |
qdev_print_props(mon, dev, dev->info->props, "dev", indent); |
|
257 |
qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent); |
|
359 | 258 |
if (dev->parent_bus->info->print_dev) |
360 | 259 |
dev->parent_bus->info->print_dev(mon, dev, indent); |
361 | 260 |
LIST_FOREACH(child, &dev->child_bus, sibling) { |
Also available in: Unified diff