5 void *qdev_get_prop_ptr(DeviceState
*dev
, Property
*prop
)
12 /* --- 8bit integer --- */
14 static int parse_uint8(DeviceState
*dev
, Property
*prop
, const char *str
)
16 uint8_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
19 /* accept both hex and decimal */
20 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx8
: "%" PRIu8
;
21 if (sscanf(str
, fmt
, ptr
) != 1)
26 static int print_uint8(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
28 uint8_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
29 return snprintf(dest
, len
, "%" PRIu8
, *ptr
);
32 PropertyInfo qdev_prop_uint8
= {
34 .type
= PROP_TYPE_UINT8
,
35 .size
= sizeof(uint8_t),
40 /* --- 16bit integer --- */
42 static int parse_uint16(DeviceState
*dev
, Property
*prop
, const char *str
)
44 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
47 /* accept both hex and decimal */
48 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx16
: "%" PRIu16
;
49 if (sscanf(str
, fmt
, ptr
) != 1)
54 static int print_uint16(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
56 uint16_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
57 return snprintf(dest
, len
, "%" PRIu16
, *ptr
);
60 PropertyInfo qdev_prop_uint16
= {
62 .type
= PROP_TYPE_UINT16
,
63 .size
= sizeof(uint16_t),
64 .parse
= parse_uint16
,
65 .print
= print_uint16
,
68 /* --- 32bit integer --- */
70 static int parse_uint32(DeviceState
*dev
, Property
*prop
, const char *str
)
72 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
75 /* accept both hex and decimal */
76 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx32
: "%" PRIu32
;
77 if (sscanf(str
, fmt
, ptr
) != 1)
82 static int print_uint32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
84 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
85 return snprintf(dest
, len
, "%" PRIu32
, *ptr
);
88 PropertyInfo qdev_prop_uint32
= {
90 .type
= PROP_TYPE_UINT32
,
91 .size
= sizeof(uint32_t),
92 .parse
= parse_uint32
,
93 .print
= print_uint32
,
96 static int parse_int32(DeviceState
*dev
, Property
*prop
, const char *str
)
98 int32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
100 if (sscanf(str
, "%" PRId32
, ptr
) != 1)
105 static int print_int32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
107 int32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
108 return snprintf(dest
, len
, "%" PRId32
, *ptr
);
111 PropertyInfo qdev_prop_int32
= {
113 .type
= PROP_TYPE_INT32
,
114 .size
= sizeof(int32_t),
115 .parse
= parse_int32
,
116 .print
= print_int32
,
119 /* --- 32bit hex value --- */
121 static int parse_hex32(DeviceState
*dev
, Property
*prop
, const char *str
)
123 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
125 if (sscanf(str
, "%" PRIx32
, ptr
) != 1)
130 static int print_hex32(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
132 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
133 return snprintf(dest
, len
, "0x%" PRIx32
, *ptr
);
136 PropertyInfo qdev_prop_hex32
= {
138 .type
= PROP_TYPE_UINT32
,
139 .size
= sizeof(uint32_t),
140 .parse
= parse_hex32
,
141 .print
= print_hex32
,
144 /* --- 64bit integer --- */
146 static int parse_uint64(DeviceState
*dev
, Property
*prop
, const char *str
)
148 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
151 /* accept both hex and decimal */
152 fmt
= strncasecmp(str
, "0x",2) == 0 ? "%" PRIx64
: "%" PRIu64
;
153 if (sscanf(str
, fmt
, ptr
) != 1)
158 static int print_uint64(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
160 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
161 return snprintf(dest
, len
, "%" PRIu64
, *ptr
);
164 PropertyInfo qdev_prop_uint64
= {
166 .type
= PROP_TYPE_UINT64
,
167 .size
= sizeof(uint64_t),
168 .parse
= parse_uint64
,
169 .print
= print_uint64
,
172 /* --- 64bit hex value --- */
174 static int parse_hex64(DeviceState
*dev
, Property
*prop
, const char *str
)
176 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
178 if (sscanf(str
, "%" PRIx64
, ptr
) != 1)
183 static int print_hex64(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
185 uint64_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
186 return snprintf(dest
, len
, "0x%" PRIx64
, *ptr
);
189 PropertyInfo qdev_prop_hex64
= {
191 .type
= PROP_TYPE_UINT64
,
192 .size
= sizeof(uint64_t),
193 .parse
= parse_hex64
,
194 .print
= print_hex64
,
199 static int parse_string(DeviceState
*dev
, Property
*prop
, const char *str
)
201 char **ptr
= qdev_get_prop_ptr(dev
, prop
);
205 *ptr
= qemu_strdup(str
);
209 static int print_string(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
211 char **ptr
= qdev_get_prop_ptr(dev
, prop
);
213 return snprintf(dest
, len
, "<null>");
214 return snprintf(dest
, len
, "\"%s\"", *ptr
);
217 PropertyInfo qdev_prop_string
= {
219 .type
= PROP_TYPE_STRING
,
220 .size
= sizeof(char*),
221 .parse
= parse_string
,
222 .print
= print_string
,
227 static int parse_drive(DeviceState
*dev
, Property
*prop
, const char *str
)
229 DriveInfo
**ptr
= qdev_get_prop_ptr(dev
, prop
);
231 *ptr
= drive_get_by_id(str
);
237 static int print_drive(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
239 DriveInfo
**ptr
= qdev_get_prop_ptr(dev
, prop
);
240 return snprintf(dest
, len
, "%s", (*ptr
) ? (*ptr
)->id
: "<null>");
243 PropertyInfo qdev_prop_drive
= {
245 .type
= PROP_TYPE_DRIVE
,
246 .size
= sizeof(DriveInfo
*),
247 .parse
= parse_drive
,
248 .print
= print_drive
,
251 /* --- character device --- */
253 static int parse_chr(DeviceState
*dev
, Property
*prop
, const char *str
)
255 CharDriverState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
257 *ptr
= qemu_chr_find(str
);
263 static int print_chr(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
265 CharDriverState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
267 if (*ptr
&& (*ptr
)->label
) {
268 return snprintf(dest
, len
, "%s", (*ptr
)->label
);
270 return snprintf(dest
, len
, "<null>");
274 PropertyInfo qdev_prop_chr
= {
276 .type
= PROP_TYPE_CHR
,
277 .size
= sizeof(CharDriverState
*),
282 /* --- netdev device --- */
284 static int parse_netdev(DeviceState
*dev
, Property
*prop
, const char *str
)
286 VLANClientState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
288 *ptr
= qemu_find_netdev(str
);
294 static int print_netdev(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
296 VLANClientState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
298 if (*ptr
&& (*ptr
)->name
) {
299 return snprintf(dest
, len
, "%s", (*ptr
)->name
);
301 return snprintf(dest
, len
, "<null>");
305 PropertyInfo qdev_prop_netdev
= {
307 .type
= PROP_TYPE_NETDEV
,
308 .size
= sizeof(VLANClientState
*),
309 .parse
= parse_netdev
,
310 .print
= print_netdev
,
315 static int parse_vlan(DeviceState
*dev
, Property
*prop
, const char *str
)
317 VLANState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
320 if (sscanf(str
, "%d", &id
) != 1)
322 *ptr
= qemu_find_vlan(id
, 1);
328 static int print_vlan(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
330 VLANState
**ptr
= qdev_get_prop_ptr(dev
, prop
);
333 return snprintf(dest
, len
, "%d", (*ptr
)->id
);
335 return snprintf(dest
, len
, "<null>");
339 PropertyInfo qdev_prop_vlan
= {
341 .type
= PROP_TYPE_VLAN
,
342 .size
= sizeof(VLANClientState
*),
347 /* --- pointer --- */
349 static int print_ptr(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
351 void **ptr
= qdev_get_prop_ptr(dev
, prop
);
352 return snprintf(dest
, len
, "<%p>", *ptr
);
355 PropertyInfo qdev_prop_ptr
= {
357 .type
= PROP_TYPE_PTR
,
358 .size
= sizeof(void*),
362 /* --- mac address --- */
365 * accepted syntax versions:
369 static int parse_mac(DeviceState
*dev
, Property
*prop
, const char *str
)
371 MACAddr
*mac
= qdev_get_prop_ptr(dev
, prop
);
375 for (i
= 0, pos
= 0; i
< 6; i
++, pos
+= 3) {
376 if (!qemu_isxdigit(str
[pos
]))
378 if (!qemu_isxdigit(str
[pos
+1]))
381 if (str
[pos
+2] != '\0')
384 if (str
[pos
+2] != ':' && str
[pos
+2] != '-')
387 mac
->a
[i
] = strtol(str
+pos
, &p
, 16);
392 static int print_mac(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
394 MACAddr
*mac
= qdev_get_prop_ptr(dev
, prop
);
396 return snprintf(dest
, len
, "%02x:%02x:%02x:%02x:%02x:%02x",
397 mac
->a
[0], mac
->a
[1], mac
->a
[2],
398 mac
->a
[3], mac
->a
[4], mac
->a
[5]);
401 PropertyInfo qdev_prop_macaddr
= {
403 .type
= PROP_TYPE_MACADDR
,
404 .size
= sizeof(MACAddr
),
409 /* --- pci address --- */
412 * bus-local address, i.e. "$slot" or "$slot.$fn"
414 static int parse_pci_devfn(DeviceState
*dev
, Property
*prop
, const char *str
)
416 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
417 unsigned int slot
, fn
, n
;
419 if (sscanf(str
, "%x.%x%n", &slot
, &fn
, &n
) != 2) {
421 if (sscanf(str
, "%x%n", &slot
, &n
) != 1) {
429 *ptr
= slot
<< 3 | fn
;
433 static int print_pci_devfn(DeviceState
*dev
, Property
*prop
, char *dest
, size_t len
)
435 uint32_t *ptr
= qdev_get_prop_ptr(dev
, prop
);
438 return snprintf(dest
, len
, "<unset>");
440 return snprintf(dest
, len
, "%02x.%x", *ptr
>> 3, *ptr
& 7);
444 PropertyInfo qdev_prop_pci_devfn
= {
446 .type
= PROP_TYPE_UINT32
,
447 .size
= sizeof(uint32_t),
448 .parse
= parse_pci_devfn
,
449 .print
= print_pci_devfn
,
452 /* --- public helpers --- */
454 static Property
*qdev_prop_walk(Property
*props
, const char *name
)
458 while (props
->name
) {
459 if (strcmp(props
->name
, name
) == 0)
466 static Property
*qdev_prop_find(DeviceState
*dev
, const char *name
)
470 /* device properties */
471 prop
= qdev_prop_walk(dev
->info
->props
, name
);
476 prop
= qdev_prop_walk(dev
->parent_bus
->info
->props
, name
);
483 int qdev_prop_exists(DeviceState
*dev
, const char *name
)
485 return qdev_prop_find(dev
, name
) ? true : false;
488 int qdev_prop_parse(DeviceState
*dev
, const char *name
, const char *value
)
492 prop
= qdev_prop_find(dev
, name
);
494 fprintf(stderr
, "property \"%s.%s\" not found\n",
495 dev
->info
->name
, name
);
498 if (!prop
->info
->parse
) {
499 fprintf(stderr
, "property \"%s.%s\" has no parser\n",
500 dev
->info
->name
, name
);
503 if (prop
->info
->parse(dev
, prop
, value
) != 0) {
504 fprintf(stderr
, "property \"%s.%s\": failed to parse \"%s\"\n",
505 dev
->info
->name
, name
, value
);
511 void qdev_prop_set(DeviceState
*dev
, const char *name
, void *src
, enum PropertyType type
)
516 prop
= qdev_prop_find(dev
, name
);
518 fprintf(stderr
, "%s: property \"%s.%s\" not found\n",
519 __FUNCTION__
, dev
->info
->name
, name
);
522 if (prop
->info
->type
!= type
) {
523 fprintf(stderr
, "%s: property \"%s.%s\" type mismatch\n",
524 __FUNCTION__
, dev
->info
->name
, name
);
527 dst
= qdev_get_prop_ptr(dev
, prop
);
528 memcpy(dst
, src
, prop
->info
->size
);
531 void qdev_prop_set_uint8(DeviceState
*dev
, const char *name
, uint8_t value
)
533 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT8
);
536 void qdev_prop_set_uint16(DeviceState
*dev
, const char *name
, uint16_t value
)
538 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT16
);
541 void qdev_prop_set_uint32(DeviceState
*dev
, const char *name
, uint32_t value
)
543 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT32
);
546 void qdev_prop_set_int32(DeviceState
*dev
, const char *name
, int32_t value
)
548 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_INT32
);
551 void qdev_prop_set_uint64(DeviceState
*dev
, const char *name
, uint64_t value
)
553 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_UINT64
);
556 void qdev_prop_set_drive(DeviceState
*dev
, const char *name
, DriveInfo
*value
)
558 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_DRIVE
);
561 void qdev_prop_set_chr(DeviceState
*dev
, const char *name
, CharDriverState
*value
)
563 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_CHR
);
566 void qdev_prop_set_netdev(DeviceState
*dev
, const char *name
, VLANClientState
*value
)
568 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_NETDEV
);
571 void qdev_prop_set_vlan(DeviceState
*dev
, const char *name
, VLANState
*value
)
573 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_VLAN
);
576 void qdev_prop_set_macaddr(DeviceState
*dev
, const char *name
, uint8_t *value
)
578 qdev_prop_set(dev
, name
, value
, PROP_TYPE_MACADDR
);
581 void qdev_prop_set_ptr(DeviceState
*dev
, const char *name
, void *value
)
583 qdev_prop_set(dev
, name
, &value
, PROP_TYPE_PTR
);
586 void qdev_prop_set_defaults(DeviceState
*dev
, Property
*props
)
592 while (props
->name
) {
594 dst
= qdev_get_prop_ptr(dev
, props
);
595 memcpy(dst
, props
->defval
, props
->info
->size
);
601 static QTAILQ_HEAD(, GlobalProperty
) global_props
= QTAILQ_HEAD_INITIALIZER(global_props
);
603 void qdev_prop_register_global(GlobalProperty
*prop
)
605 QTAILQ_INSERT_TAIL(&global_props
, prop
, next
);
608 void qdev_prop_register_global_list(GlobalProperty
*props
)
612 for (i
= 0; props
[i
].driver
!= NULL
; i
++) {
613 qdev_prop_register_global(props
+i
);
617 void qdev_prop_set_globals(DeviceState
*dev
)
619 GlobalProperty
*prop
;
621 QTAILQ_FOREACH(prop
, &global_props
, next
) {
622 if (strcmp(dev
->info
->name
, prop
->driver
) != 0 &&
623 strcmp(dev
->info
->bus_info
->name
, prop
->driver
) != 0) {
626 if (qdev_prop_parse(dev
, prop
->property
, prop
->value
) != 0) {