1 #include "qemu/osdep.h"
2 #include "hw/qdev-properties.h"
3 #include "qapi/error.h"
4 #include "qapi/qapi-types-misc.h"
5 #include "qobject/qlist.h"
6 #include "qemu/ctype.h"
7 #include "qemu/error-report.h"
8 #include "qapi/visitor.h"
9 #include "qemu/units.h"
10 #include "qemu/cutils.h"
11 #include "qdev-prop-internal.h"
12 #include "qom/qom-qobject.h"
14 void qdev_prop_set_after_realize(DeviceState
*dev
, const char *name
,
18 error_setg(errp
, "Attempt to set property '%s' on device '%s' "
19 "(type '%s') after it was realized", name
, dev
->id
,
20 object_get_typename(OBJECT(dev
)));
22 error_setg(errp
, "Attempt to set property '%s' on anonymous device "
23 "(type '%s') after it was realized", name
,
24 object_get_typename(OBJECT(dev
)));
28 /* returns: true if property is allowed to be set, false otherwise */
29 static bool qdev_prop_allow_set(Object
*obj
, const char *name
,
30 const PropertyInfo
*info
, Error
**errp
)
32 DeviceState
*dev
= DEVICE(obj
);
34 if (dev
->realized
&& !info
->realized_set_allowed
) {
35 qdev_prop_set_after_realize(dev
, name
, errp
);
41 void qdev_prop_allow_set_link_before_realize(const Object
*obj
,
43 Object
*val
, Error
**errp
)
45 DeviceState
*dev
= DEVICE(obj
);
48 error_setg(errp
, "Attempt to set link property '%s' on device '%s' "
49 "(type '%s') after it was realized",
50 name
, dev
->id
, object_get_typename(obj
));
54 void *object_field_prop_ptr(Object
*obj
, const Property
*prop
)
61 static void field_prop_get(Object
*obj
, Visitor
*v
, const char *name
,
62 void *opaque
, Error
**errp
)
64 const Property
*prop
= opaque
;
65 return prop
->info
->get(obj
, v
, name
, opaque
, errp
);
69 * field_prop_getter: Return getter function to be used for property
71 * Return value can be NULL if @info has no getter function.
73 static ObjectPropertyAccessor
*field_prop_getter(const PropertyInfo
*info
)
75 return info
->get
? field_prop_get
: NULL
;
78 static void field_prop_set(Object
*obj
, Visitor
*v
, const char *name
,
79 void *opaque
, Error
**errp
)
81 const Property
*prop
= opaque
;
83 if (!qdev_prop_allow_set(obj
, name
, prop
->info
, errp
)) {
87 return prop
->info
->set(obj
, v
, name
, opaque
, errp
);
91 * field_prop_setter: Return setter function to be used for property
93 * Return value can be NULL if @info has not setter function.
95 static ObjectPropertyAccessor
*field_prop_setter(const PropertyInfo
*info
)
97 return info
->set
? field_prop_set
: NULL
;
100 void qdev_propinfo_get_enum(Object
*obj
, Visitor
*v
, const char *name
,
101 void *opaque
, Error
**errp
)
103 const Property
*prop
= opaque
;
104 int *ptr
= object_field_prop_ptr(obj
, prop
);
106 visit_type_enum(v
, name
, ptr
, prop
->info
->enum_table
, errp
);
109 void qdev_propinfo_set_enum(Object
*obj
, Visitor
*v
, const char *name
,
110 void *opaque
, Error
**errp
)
112 const Property
*prop
= opaque
;
113 int *ptr
= object_field_prop_ptr(obj
, prop
);
115 visit_type_enum(v
, name
, ptr
, prop
->info
->enum_table
, errp
);
118 void qdev_propinfo_set_default_value_enum(ObjectProperty
*op
,
119 const Property
*prop
)
121 object_property_set_default_str(op
,
122 qapi_enum_lookup(prop
->info
->enum_table
, prop
->defval
.i
));
127 static uint32_t qdev_get_prop_mask(const Property
*prop
)
129 assert(prop
->info
== &qdev_prop_bit
);
130 return 0x1 << prop
->bitnr
;
133 static void bit_prop_set(Object
*obj
, const Property
*props
, bool val
)
135 uint32_t *p
= object_field_prop_ptr(obj
, props
);
136 uint32_t mask
= qdev_get_prop_mask(props
);
144 static void prop_get_bit(Object
*obj
, Visitor
*v
, const char *name
,
145 void *opaque
, Error
**errp
)
147 const Property
*prop
= opaque
;
148 uint32_t *p
= object_field_prop_ptr(obj
, prop
);
149 bool value
= (*p
& qdev_get_prop_mask(prop
)) != 0;
151 visit_type_bool(v
, name
, &value
, errp
);
154 static void prop_set_bit(Object
*obj
, Visitor
*v
, const char *name
,
155 void *opaque
, Error
**errp
)
157 const Property
*prop
= opaque
;
160 if (!visit_type_bool(v
, name
, &value
, errp
)) {
163 bit_prop_set(obj
, prop
, value
);
166 static void set_default_value_bool(ObjectProperty
*op
, const Property
*prop
)
168 object_property_set_default_bool(op
, prop
->defval
.u
);
171 const PropertyInfo qdev_prop_bit
= {
173 .description
= "on/off",
176 .set_default_value
= set_default_value_bool
,
181 static uint64_t qdev_get_prop_mask64(const Property
*prop
)
183 assert(prop
->info
== &qdev_prop_bit64
);
184 return 0x1ull
<< prop
->bitnr
;
187 static void bit64_prop_set(Object
*obj
, const Property
*props
, bool val
)
189 uint64_t *p
= object_field_prop_ptr(obj
, props
);
190 uint64_t mask
= qdev_get_prop_mask64(props
);
198 static void prop_get_bit64(Object
*obj
, Visitor
*v
, const char *name
,
199 void *opaque
, Error
**errp
)
201 const Property
*prop
= opaque
;
202 uint64_t *p
= object_field_prop_ptr(obj
, prop
);
203 bool value
= (*p
& qdev_get_prop_mask64(prop
)) != 0;
205 visit_type_bool(v
, name
, &value
, errp
);
208 static void prop_set_bit64(Object
*obj
, Visitor
*v
, const char *name
,
209 void *opaque
, Error
**errp
)
211 const Property
*prop
= opaque
;
214 if (!visit_type_bool(v
, name
, &value
, errp
)) {
217 bit64_prop_set(obj
, prop
, value
);
220 const PropertyInfo qdev_prop_bit64
= {
222 .description
= "on/off",
223 .get
= prop_get_bit64
,
224 .set
= prop_set_bit64
,
225 .set_default_value
= set_default_value_bool
,
230 static void get_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
233 const Property
*prop
= opaque
;
234 bool *ptr
= object_field_prop_ptr(obj
, prop
);
236 visit_type_bool(v
, name
, ptr
, errp
);
239 static void set_bool(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
242 const Property
*prop
= opaque
;
243 bool *ptr
= object_field_prop_ptr(obj
, prop
);
245 visit_type_bool(v
, name
, ptr
, errp
);
248 const PropertyInfo qdev_prop_bool
= {
250 .description
= "on/off",
253 .set_default_value
= set_default_value_bool
,
256 /* --- 8bit integer --- */
258 static void get_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
261 const Property
*prop
= opaque
;
262 uint8_t *ptr
= object_field_prop_ptr(obj
, prop
);
264 visit_type_uint8(v
, name
, ptr
, errp
);
267 static void set_uint8(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
270 const Property
*prop
= opaque
;
271 uint8_t *ptr
= object_field_prop_ptr(obj
, prop
);
273 visit_type_uint8(v
, name
, ptr
, errp
);
276 void qdev_propinfo_set_default_value_int(ObjectProperty
*op
,
277 const Property
*prop
)
279 object_property_set_default_int(op
, prop
->defval
.i
);
282 void qdev_propinfo_set_default_value_uint(ObjectProperty
*op
,
283 const Property
*prop
)
285 object_property_set_default_uint(op
, prop
->defval
.u
);
288 const PropertyInfo qdev_prop_uint8
= {
292 .set_default_value
= qdev_propinfo_set_default_value_uint
,
295 /* --- 16bit integer --- */
297 static void get_uint16(Object
*obj
, Visitor
*v
, const char *name
,
298 void *opaque
, Error
**errp
)
300 const Property
*prop
= opaque
;
301 uint16_t *ptr
= object_field_prop_ptr(obj
, prop
);
303 visit_type_uint16(v
, name
, ptr
, errp
);
306 static void set_uint16(Object
*obj
, Visitor
*v
, const char *name
,
307 void *opaque
, Error
**errp
)
309 const Property
*prop
= opaque
;
310 uint16_t *ptr
= object_field_prop_ptr(obj
, prop
);
312 visit_type_uint16(v
, name
, ptr
, errp
);
315 const PropertyInfo qdev_prop_uint16
= {
319 .set_default_value
= qdev_propinfo_set_default_value_uint
,
322 /* --- 32bit integer --- */
324 static void get_uint32(Object
*obj
, Visitor
*v
, const char *name
,
325 void *opaque
, Error
**errp
)
327 const Property
*prop
= opaque
;
328 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
330 visit_type_uint32(v
, name
, ptr
, errp
);
333 static void set_uint32(Object
*obj
, Visitor
*v
, const char *name
,
334 void *opaque
, Error
**errp
)
336 const Property
*prop
= opaque
;
337 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
339 visit_type_uint32(v
, name
, ptr
, errp
);
342 void qdev_propinfo_get_int32(Object
*obj
, Visitor
*v
, const char *name
,
343 void *opaque
, Error
**errp
)
345 const Property
*prop
= opaque
;
346 int32_t *ptr
= object_field_prop_ptr(obj
, prop
);
348 visit_type_int32(v
, name
, ptr
, errp
);
351 static void set_int32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
354 const Property
*prop
= opaque
;
355 int32_t *ptr
= object_field_prop_ptr(obj
, prop
);
357 visit_type_int32(v
, name
, ptr
, errp
);
360 const PropertyInfo qdev_prop_uint32
= {
364 .set_default_value
= qdev_propinfo_set_default_value_uint
,
367 const PropertyInfo qdev_prop_int32
= {
369 .get
= qdev_propinfo_get_int32
,
371 .set_default_value
= qdev_propinfo_set_default_value_int
,
374 /* --- 64bit integer --- */
376 static void get_uint64(Object
*obj
, Visitor
*v
, const char *name
,
377 void *opaque
, Error
**errp
)
379 const Property
*prop
= opaque
;
380 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
382 visit_type_uint64(v
, name
, ptr
, errp
);
385 static void set_uint64(Object
*obj
, Visitor
*v
, const char *name
,
386 void *opaque
, Error
**errp
)
388 const Property
*prop
= opaque
;
389 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
391 visit_type_uint64(v
, name
, ptr
, errp
);
394 static void get_int64(Object
*obj
, Visitor
*v
, const char *name
,
395 void *opaque
, Error
**errp
)
397 const Property
*prop
= opaque
;
398 int64_t *ptr
= object_field_prop_ptr(obj
, prop
);
400 visit_type_int64(v
, name
, ptr
, errp
);
403 static void set_int64(Object
*obj
, Visitor
*v
, const char *name
,
404 void *opaque
, Error
**errp
)
406 const Property
*prop
= opaque
;
407 int64_t *ptr
= object_field_prop_ptr(obj
, prop
);
409 visit_type_int64(v
, name
, ptr
, errp
);
412 const PropertyInfo qdev_prop_uint64
= {
416 .set_default_value
= qdev_propinfo_set_default_value_uint
,
419 const PropertyInfo qdev_prop_int64
= {
423 .set_default_value
= qdev_propinfo_set_default_value_int
,
426 static void set_uint64_checkmask(Object
*obj
, Visitor
*v
, const char *name
,
427 void *opaque
, Error
**errp
)
429 const Property
*prop
= opaque
;
430 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
432 visit_type_uint64(v
, name
, ptr
, errp
);
433 if (*ptr
& ~prop
->bitmask
) {
434 error_setg(errp
, "Property value for '%s' has bits outside mask '0x%" PRIx64
"'",
435 name
, prop
->bitmask
);
439 const PropertyInfo qdev_prop_uint64_checkmask
= {
442 .set
= set_uint64_checkmask
,
445 /* --- pointer-size integer --- */
447 static void get_usize(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
450 const Property
*prop
= opaque
;
452 #if HOST_LONG_BITS == 32
453 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
454 visit_type_uint32(v
, name
, ptr
, errp
);
456 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
457 visit_type_uint64(v
, name
, ptr
, errp
);
461 static void set_usize(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
464 const Property
*prop
= opaque
;
466 #if HOST_LONG_BITS == 32
467 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
468 visit_type_uint32(v
, name
, ptr
, errp
);
470 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
471 visit_type_uint64(v
, name
, ptr
, errp
);
475 const PropertyInfo qdev_prop_usize
= {
479 .set_default_value
= qdev_propinfo_set_default_value_uint
,
484 static void release_string(Object
*obj
, const char *name
, void *opaque
)
486 const Property
*prop
= opaque
;
487 g_free(*(char **)object_field_prop_ptr(obj
, prop
));
490 static void get_string(Object
*obj
, Visitor
*v
, const char *name
,
491 void *opaque
, Error
**errp
)
493 const Property
*prop
= opaque
;
494 char **ptr
= object_field_prop_ptr(obj
, prop
);
497 char *str
= (char *)"";
498 visit_type_str(v
, name
, &str
, errp
);
500 visit_type_str(v
, name
, ptr
, errp
);
504 static void set_string(Object
*obj
, Visitor
*v
, const char *name
,
505 void *opaque
, Error
**errp
)
507 const Property
*prop
= opaque
;
508 char **ptr
= object_field_prop_ptr(obj
, prop
);
511 if (!visit_type_str(v
, name
, &str
, errp
)) {
518 const PropertyInfo qdev_prop_string
= {
520 .release
= release_string
,
525 /* --- on/off/auto --- */
527 const PropertyInfo qdev_prop_on_off_auto
= {
529 .description
= "on/off/auto",
530 .enum_table
= &OnOffAuto_lookup
,
531 .get
= qdev_propinfo_get_enum
,
532 .set
= qdev_propinfo_set_enum
,
533 .set_default_value
= qdev_propinfo_set_default_value_enum
,
536 /* --- 32bit unsigned int 'size' type --- */
538 void qdev_propinfo_get_size32(Object
*obj
, Visitor
*v
, const char *name
,
539 void *opaque
, Error
**errp
)
541 const Property
*prop
= opaque
;
542 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
543 uint64_t value
= *ptr
;
545 visit_type_size(v
, name
, &value
, errp
);
548 static void set_size32(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
551 const Property
*prop
= opaque
;
552 uint32_t *ptr
= object_field_prop_ptr(obj
, prop
);
555 if (!visit_type_size(v
, name
, &value
, errp
)) {
559 if (value
> UINT32_MAX
) {
561 "Property %s.%s doesn't take value %" PRIu64
563 object_get_typename(obj
), name
, value
, UINT32_MAX
);
570 const PropertyInfo qdev_prop_size32
= {
572 .get
= qdev_propinfo_get_size32
,
574 .set_default_value
= qdev_propinfo_set_default_value_uint
,
577 /* --- support for array properties --- */
579 typedef struct ArrayElementList ArrayElementList
;
581 struct ArrayElementList
{
582 ArrayElementList
*next
;
587 * Given an array property @parent_prop in @obj, return a Property for a
588 * specific element of the array. Arrays are backed by an uint32_t length field
589 * and an element array. @elem points at an element in this element array.
591 static Property
array_elem_prop(Object
*obj
, const Property
*parent_prop
,
592 const char *name
, char *elem
)
595 .info
= parent_prop
->arrayinfo
,
598 * This ugly piece of pointer arithmetic sets up the offset so
599 * that when the underlying release hook calls qdev_get_prop_ptr
600 * they get the right answer despite the array element not actually
601 * being inside the device struct.
603 .offset
= (uintptr_t)elem
- (uintptr_t)obj
,
608 * Object property release callback for array properties: We call the
609 * underlying element's property release hook for each element.
611 * Note that it is the responsibility of the individual device's deinit
612 * to free the array proper.
614 static void release_prop_array(Object
*obj
, const char *name
, void *opaque
)
616 const Property
*prop
= opaque
;
617 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
618 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
619 char *elem
= *arrayptr
;
622 if (!prop
->arrayinfo
->release
) {
626 for (i
= 0; i
< *alenptr
; i
++) {
627 Property elem_prop
= array_elem_prop(obj
, prop
, name
, elem
);
628 prop
->arrayinfo
->release(obj
, NULL
, &elem_prop
);
629 elem
+= prop
->arrayfieldsize
;
634 * Setter for an array property. This sets both the array length (which
635 * is technically the property field in the object) and the array itself
636 * (a pointer to which is stored in the additional field described by
637 * prop->arrayoffset).
639 static void set_prop_array(Object
*obj
, Visitor
*v
, const char *name
,
640 void *opaque
, Error
**errp
)
643 const Property
*prop
= opaque
;
644 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
645 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
646 ArrayElementList
*list
, *elem
, *next
;
647 const size_t size
= sizeof(*list
);
652 error_setg(errp
, "array size property %s may not be set more than once",
657 if (!visit_start_list(v
, name
, (GenericList
**) &list
, size
, errp
)) {
661 /* Read the whole input into a temporary list */
666 elem
->value
= g_malloc0(prop
->arrayfieldsize
);
667 elem_prop
= array_elem_prop(obj
, prop
, name
, elem
->value
);
668 prop
->arrayinfo
->set(obj
, v
, NULL
, &elem_prop
, errp
);
673 if (*alenptr
== INT_MAX
) {
674 error_setg(errp
, "array is too big");
678 elem
= (ArrayElementList
*) visit_next_list(v
, (GenericList
*) elem
,
682 ok
= visit_check_list(v
, errp
);
684 visit_end_list(v
, (void**) &list
);
687 for (elem
= list
; elem
; elem
= next
) {
688 Property elem_prop
= array_elem_prop(obj
, prop
, name
,
690 if (prop
->arrayinfo
->release
) {
691 prop
->arrayinfo
->release(obj
, NULL
, &elem_prop
);
701 * Now that we know how big the array has to be, move the data over to a
702 * linear array and free the temporary list.
704 *arrayptr
= g_malloc_n(*alenptr
, prop
->arrayfieldsize
);
706 for (elem
= list
; elem
; elem
= next
) {
707 memcpy(elemptr
, elem
->value
, prop
->arrayfieldsize
);
708 elemptr
+= prop
->arrayfieldsize
;
715 static void get_prop_array(Object
*obj
, Visitor
*v
, const char *name
,
716 void *opaque
, Error
**errp
)
719 const Property
*prop
= opaque
;
720 uint32_t *alenptr
= object_field_prop_ptr(obj
, prop
);
721 void **arrayptr
= (void *)obj
+ prop
->arrayoffset
;
722 char *elemptr
= *arrayptr
;
723 ArrayElementList
*list
= NULL
, *elem
;
724 ArrayElementList
**tail
= &list
;
725 const size_t size
= sizeof(*list
);
729 /* At least the string output visitor needs a real list */
730 for (i
= 0; i
< *alenptr
; i
++) {
731 elem
= g_new0(ArrayElementList
, 1);
732 elem
->value
= elemptr
;
733 elemptr
+= prop
->arrayfieldsize
;
739 if (!visit_start_list(v
, name
, (GenericList
**) &list
, size
, errp
)) {
745 Property elem_prop
= array_elem_prop(obj
, prop
, name
, elem
->value
);
746 prop
->arrayinfo
->get(obj
, v
, NULL
, &elem_prop
, errp
);
750 elem
= (ArrayElementList
*) visit_next_list(v
, (GenericList
*) elem
,
754 /* visit_check_list() can only fail for input visitors */
755 ok
= visit_check_list(v
, errp
);
759 visit_end_list(v
, (void**) &list
);
768 static void default_prop_array(ObjectProperty
*op
, const Property
*prop
)
770 object_property_set_default_list(op
);
773 const PropertyInfo qdev_prop_array
= {
775 .get
= get_prop_array
,
776 .set
= set_prop_array
,
777 .release
= release_prop_array
,
778 .set_default_value
= default_prop_array
,
781 /* --- public helpers --- */
783 static const Property
*qdev_prop_walk(DeviceClass
*cls
, const char *name
)
785 for (int i
= 0, n
= cls
->props_count_
; i
< n
; ++i
) {
786 const Property
*prop
= &cls
->props_
[i
];
787 if (strcmp(prop
->name
, name
) == 0) {
794 static const Property
*qdev_prop_find(DeviceState
*dev
, const char *name
)
797 const Property
*prop
;
799 /* device properties */
800 class = object_get_class(OBJECT(dev
));
802 prop
= qdev_prop_walk(DEVICE_CLASS(class), name
);
806 class = object_class_get_parent(class);
807 } while (class != object_class_by_name(TYPE_DEVICE
));
812 void error_set_from_qdev_prop_error(Error
**errp
, int ret
, Object
*obj
,
813 const char *name
, const char *value
)
817 error_setg(errp
, "Property '%s.%s' can't take value '%s', it's in use",
818 object_get_typename(obj
), name
, value
);
822 error_setg(errp
, "Property '%s.%s' doesn't take value '%s'",
823 object_get_typename(obj
), name
, value
);
826 error_setg(errp
, "Property '%s.%s' can't find value '%s'",
827 object_get_typename(obj
), name
, value
);
834 void qdev_prop_set_bit(DeviceState
*dev
, const char *name
, bool value
)
836 object_property_set_bool(OBJECT(dev
), name
, value
, &error_abort
);
839 void qdev_prop_set_uint8(DeviceState
*dev
, const char *name
, uint8_t value
)
841 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
844 void qdev_prop_set_uint16(DeviceState
*dev
, const char *name
, uint16_t value
)
846 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
849 void qdev_prop_set_uint32(DeviceState
*dev
, const char *name
, uint32_t value
)
851 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
854 void qdev_prop_set_int32(DeviceState
*dev
, const char *name
, int32_t value
)
856 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
859 void qdev_prop_set_uint64(DeviceState
*dev
, const char *name
, uint64_t value
)
861 object_property_set_int(OBJECT(dev
), name
, value
, &error_abort
);
864 void qdev_prop_set_string(DeviceState
*dev
, const char *name
, const char *value
)
866 object_property_set_str(OBJECT(dev
), name
, value
, &error_abort
);
869 void qdev_prop_set_enum(DeviceState
*dev
, const char *name
, int value
)
871 const Property
*prop
;
873 prop
= qdev_prop_find(dev
, name
);
874 object_property_set_str(OBJECT(dev
), name
,
875 qapi_enum_lookup(prop
->info
->enum_table
, value
),
879 void qdev_prop_set_array(DeviceState
*dev
, const char *name
, QList
*values
)
881 object_property_set_qobject(OBJECT(dev
), name
, QOBJECT(values
),
883 qobject_unref(values
);
886 static GPtrArray
*global_props(void)
888 static GPtrArray
*gp
;
891 gp
= g_ptr_array_new();
897 void qdev_prop_register_global(GlobalProperty
*prop
)
899 g_ptr_array_add(global_props(), prop
);
902 const GlobalProperty
*qdev_find_global_prop(Object
*obj
,
905 GPtrArray
*props
= global_props();
906 const GlobalProperty
*p
;
909 for (i
= 0; i
< props
->len
; i
++) {
910 p
= g_ptr_array_index(props
, i
);
911 if (object_dynamic_cast(obj
, p
->driver
)
912 && !strcmp(p
->property
, name
)) {
919 int qdev_prop_check_globals(void)
923 for (i
= 0; i
< global_props()->len
; i
++) {
924 GlobalProperty
*prop
;
928 prop
= g_ptr_array_index(global_props(), i
);
932 oc
= object_class_by_name(prop
->driver
);
933 oc
= object_class_dynamic_cast(oc
, TYPE_DEVICE
);
935 warn_report("global %s.%s has invalid class name",
936 prop
->driver
, prop
->property
);
940 dc
= DEVICE_CLASS(oc
);
941 if (!dc
->hotpluggable
&& !prop
->used
) {
942 warn_report("global %s.%s=%s not used",
943 prop
->driver
, prop
->property
, prop
->value
);
951 void qdev_prop_set_globals(DeviceState
*dev
)
953 object_apply_global_props(OBJECT(dev
), global_props(),
954 dev
->hotplugged
? NULL
: &error_fatal
);
957 /* --- 64bit unsigned int 'size' type --- */
959 static void get_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
962 const Property
*prop
= opaque
;
963 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
965 visit_type_size(v
, name
, ptr
, errp
);
968 static void set_size(Object
*obj
, Visitor
*v
, const char *name
, void *opaque
,
971 const Property
*prop
= opaque
;
972 uint64_t *ptr
= object_field_prop_ptr(obj
, prop
);
974 visit_type_size(v
, name
, ptr
, errp
);
977 const PropertyInfo qdev_prop_size
= {
981 .set_default_value
= qdev_propinfo_set_default_value_uint
,
984 /* --- object link property --- */
986 static ObjectProperty
*create_link_property(ObjectClass
*oc
, const char *name
,
987 const Property
*prop
)
989 return object_class_property_add_link(oc
, name
, prop
->link_type
,
991 qdev_prop_allow_set_link_before_realize
,
992 OBJ_PROP_LINK_STRONG
);
995 const PropertyInfo qdev_prop_link
= {
997 .create
= create_link_property
,
1000 void qdev_property_add_static(DeviceState
*dev
, const Property
*prop
)
1002 Object
*obj
= OBJECT(dev
);
1005 assert(!prop
->info
->create
);
1007 op
= object_property_add(obj
, prop
->name
, prop
->info
->type
,
1008 field_prop_getter(prop
->info
),
1009 field_prop_setter(prop
->info
),
1010 prop
->info
->release
,
1013 object_property_set_description(obj
, prop
->name
,
1014 prop
->info
->description
);
1016 if (prop
->set_default
) {
1017 prop
->info
->set_default_value(op
, prop
);
1024 static void qdev_class_add_property(DeviceClass
*klass
, const char *name
,
1025 const Property
*prop
)
1027 ObjectClass
*oc
= OBJECT_CLASS(klass
);
1030 if (prop
->info
->create
) {
1031 op
= prop
->info
->create(oc
, name
, prop
);
1033 op
= object_class_property_add(oc
,
1034 name
, prop
->info
->type
,
1035 field_prop_getter(prop
->info
),
1036 field_prop_setter(prop
->info
),
1037 prop
->info
->release
,
1040 if (prop
->set_default
) {
1041 prop
->info
->set_default_value(op
, prop
);
1043 object_class_property_set_description(oc
, name
, prop
->info
->description
);
1047 * Legacy property handling
1050 static void qdev_get_legacy_property(Object
*obj
, Visitor
*v
,
1051 const char *name
, void *opaque
,
1054 const Property
*prop
= opaque
;
1059 prop
->info
->print(obj
, prop
, buffer
, sizeof(buffer
));
1060 visit_type_str(v
, name
, &ptr
, errp
);
1064 * qdev_class_add_legacy_property:
1065 * @dev: Device to add the property to.
1066 * @prop: The qdev property definition.
1068 * Add a legacy QOM property to @dev for qdev property @prop.
1070 * Legacy properties are string versions of QOM properties. The format of
1071 * the string depends on the property type. Legacy properties are only
1072 * needed for "info qtree".
1074 * Do not use this in new code! QOM Properties added through this interface
1075 * will be given names in the "legacy" namespace.
1077 static void qdev_class_add_legacy_property(DeviceClass
*dc
, const Property
*prop
)
1079 g_autofree
char *name
= NULL
;
1081 /* Register pointer properties as legacy properties */
1082 if (!prop
->info
->print
&& prop
->info
->get
) {
1086 name
= g_strdup_printf("legacy-%s", prop
->name
);
1087 object_class_property_add(OBJECT_CLASS(dc
), name
, "str",
1088 prop
->info
->print
? qdev_get_legacy_property
: prop
->info
->get
,
1089 NULL
, NULL
, (Property
*)prop
);
1092 void device_class_set_props_n(DeviceClass
*dc
, const Property
*props
, size_t n
)
1094 /* We used a hole in DeviceClass because that's still a lot. */
1095 assert(n
<= UINT16_MAX
);
1099 dc
->props_count_
= n
;
1101 for (size_t i
= 0; i
< n
; ++i
) {
1102 const Property
*prop
= &props
[i
];
1104 qdev_class_add_legacy_property(dc
, prop
);
1105 qdev_class_add_property(dc
, prop
->name
, prop
);
1109 void qdev_alias_all_properties(DeviceState
*target
, Object
*source
)
1112 ObjectPropertyIterator iter
;
1113 ObjectProperty
*prop
;
1115 class = object_get_class(OBJECT(target
));
1117 object_class_property_iter_init(&iter
, class);
1118 while ((prop
= object_property_iter_next(&iter
))) {
1119 if (object_property_find(source
, prop
->name
)) {
1120 continue; /* skip duplicate properties */
1123 object_property_add_alias(source
, prop
->name
,
1124 OBJECT(target
), prop
->name
);