]> git.proxmox.com Git - mirror_qemu.git/blame - hw/qdev-properties.c
Add a pc-0.11 machine type and make the pc type an alias
[mirror_qemu.git] / hw / qdev-properties.c
CommitLineData
ee6847d1
GH
1#include "qdev.h"
2
3void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
4{
5 void *ptr = dev;
6 ptr += prop->offset;
7 return ptr;
8}
9
10/* --- 16bit integer --- */
11
12static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
13{
14 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
15 const char *fmt;
16
17 /* accept both hex and decimal */
18 fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx16 : "%" PRIu16;
19 if (sscanf(str, fmt, ptr) != 1)
20 return -1;
21 return 0;
22}
23
24static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
25{
26 uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
27 return snprintf(dest, len, "%" PRIu16, *ptr);
28}
29
30PropertyInfo qdev_prop_uint16 = {
31 .name = "uint16",
32 .type = PROP_TYPE_UINT16,
33 .size = sizeof(uint16_t),
34 .parse = parse_uint16,
35 .print = print_uint16,
36};
37
38/* --- 32bit integer --- */
39
40static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
41{
42 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
43 const char *fmt;
44
45 /* accept both hex and decimal */
46 fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx32 : "%" PRIu32;
47 if (sscanf(str, fmt, ptr) != 1)
48 return -1;
49 return 0;
50}
51
52static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
53{
54 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
55 return snprintf(dest, len, "%" PRIu32, *ptr);
56}
57
58PropertyInfo qdev_prop_uint32 = {
59 .name = "uint32",
60 .type = PROP_TYPE_UINT32,
61 .size = sizeof(uint32_t),
62 .parse = parse_uint32,
63 .print = print_uint32,
64};
65
66/* --- 32bit hex value --- */
67
68static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
69{
70 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
71
72 if (sscanf(str, "%" PRIx32, ptr) != 1)
73 return -1;
74 return 0;
75}
76
77static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
78{
79 uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
80 return snprintf(dest, len, "0x%" PRIx32, *ptr);
81}
82
83PropertyInfo qdev_prop_hex32 = {
84 .name = "hex32",
85 .type = PROP_TYPE_UINT32,
86 .size = sizeof(uint32_t),
87 .parse = parse_hex32,
88 .print = print_hex32,
89};
90
5a053d1f
BS
91/* --- 64bit integer --- */
92
93static int parse_uint64(DeviceState *dev, Property *prop, const char *str)
94{
95 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
96 const char *fmt;
97
98 /* accept both hex and decimal */
99 fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx64 : "%" PRIu64;
100 if (sscanf(str, fmt, ptr) != 1)
101 return -1;
102 return 0;
103}
104
105static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len)
106{
107 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
108 return snprintf(dest, len, "%" PRIu64, *ptr);
109}
110
111PropertyInfo qdev_prop_uint64 = {
112 .name = "uint64",
113 .type = PROP_TYPE_UINT64,
114 .size = sizeof(uint64_t),
115 .parse = parse_uint64,
116 .print = print_uint64,
117};
118
119/* --- 64bit hex value --- */
120
121static int parse_hex64(DeviceState *dev, Property *prop, const char *str)
122{
123 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
124
125 if (sscanf(str, "%" PRIx64, ptr) != 1)
126 return -1;
127 return 0;
128}
129
130static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
131{
132 uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
133 return snprintf(dest, len, "0x%" PRIx64, *ptr);
134}
135
136PropertyInfo qdev_prop_hex64 = {
137 .name = "hex64",
138 .type = PROP_TYPE_UINT64,
139 .size = sizeof(uint64_t),
140 .parse = parse_hex64,
141 .print = print_hex64,
142};
143
ee6847d1
GH
144/* --- pointer --- */
145
146static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len)
147{
148 void **ptr = qdev_get_prop_ptr(dev, prop);
149 return snprintf(dest, len, "<%p>", *ptr);
150}
151
152PropertyInfo qdev_prop_ptr = {
153 .name = "ptr",
154 .type = PROP_TYPE_PTR,
155 .size = sizeof(void*),
156 .print = print_ptr,
157};
158
159/* --- mac address --- */
160
161/*
162 * accepted syntax versions:
163 * 01:02:03:04:05:06
164 * 01-02-03-04-05-06
165 */
166static int parse_mac(DeviceState *dev, Property *prop, const char *str)
167{
168 uint8_t *mac = qdev_get_prop_ptr(dev, prop);
169 int i, pos;
170 char *p;
171
172 for (i = 0, pos = 0; i < 6; i++, pos += 3) {
88e150a5 173 if (!qemu_isxdigit(str[pos]))
ee6847d1 174 return -1;
88e150a5 175 if (!qemu_isxdigit(str[pos+1]))
ee6847d1
GH
176 return -1;
177 if (i == 5 && str[pos+2] != '\0')
178 return -1;
179 if (str[pos+2] != ':' && str[pos+2] != '-')
180 return -1;
181 mac[i] = strtol(str+pos, &p, 16);
182 }
183 return 0;
184}
185
186static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
187{
188 uint8_t *mac = qdev_get_prop_ptr(dev, prop);
189 return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
190 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
191}
192
193PropertyInfo qdev_prop_macaddr = {
194 .name = "mac-addr",
195 .type = PROP_TYPE_MACADDR,
196 .size = 6,
197 .parse = parse_mac,
198 .print = print_mac,
199};
200
201/* --- public helpers --- */
202
203static Property *qdev_prop_walk(Property *props, const char *name)
204{
205 if (!props)
206 return NULL;
207 while (props->name) {
208 if (strcmp(props->name, name) == 0)
209 return props;
210 props++;
211 }
212 return NULL;
213}
214
215static Property *qdev_prop_find(DeviceState *dev, const char *name)
216{
217 Property *prop;
218
219 /* device properties */
220 prop = qdev_prop_walk(dev->info->props, name);
221 if (prop)
222 return prop;
223
224 /* bus properties */
225 prop = qdev_prop_walk(dev->parent_bus->info->props, name);
226 if (prop)
227 return prop;
228
229 return NULL;
230}
231
232int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
233{
234 Property *prop;
235
236 prop = qdev_prop_find(dev, name);
237 if (!prop) {
238 fprintf(stderr, "property \"%s.%s\" not found\n",
239 dev->info->name, name);
240 return -1;
241 }
242 if (!prop->info->parse) {
243 fprintf(stderr, "property \"%s.%s\" has no parser\n",
244 dev->info->name, name);
245 return -1;
246 }
247 return prop->info->parse(dev, prop, value);
248}
249
250void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
251{
252 Property *prop;
253 void *dst;
254
255 prop = qdev_prop_find(dev, name);
256 if (!prop) {
257 fprintf(stderr, "%s: property \"%s.%s\" not found\n",
258 __FUNCTION__, dev->info->name, name);
259 abort();
260 }
261 if (prop->info->type != type) {
262 fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
263 __FUNCTION__, dev->info->name, name);
264 abort();
265 }
266 dst = qdev_get_prop_ptr(dev, prop);
267 memcpy(dst, src, prop->info->size);
268}
269
270void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
271{
272 qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
273}
274
275void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
276{
277 qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
278}
279
5a053d1f
BS
280void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
281{
282 qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
283}
284
ee6847d1
GH
285void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
286{
287 qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
288}
289
290void qdev_prop_set_defaults(DeviceState *dev, Property *props)
291{
292 char *dst;
293
294 if (!props)
295 return;
296 while (props->name) {
297 if (props->defval) {
298 dst = qdev_get_prop_ptr(dev, props);
299 memcpy(dst, props->defval, props->info->size);
300 }
301 props++;
302 }
303}
304
b6b61144
GH
305static CompatProperty *compat_props;
306
307void qdev_prop_register_compat(CompatProperty *props)
308{
309 compat_props = props;
310}
311
312void qdev_prop_set_compat(DeviceState *dev)
313{
314 CompatProperty *prop;
315
316 if (!compat_props) {
317 return;
318 }
319 for (prop = compat_props; prop->driver != NULL; prop++) {
320 if (strcmp(dev->info->name, prop->driver) != 0) {
321 continue;
322 }
323 if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
324 abort();
325 }
326 }
327}