xref: /openbmc/qemu/hw/core/qdev-properties.c (revision 7ed854af1401d62be9b232d4b67d8a75418e96b2)
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 "qapi/qmp/qerror.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 
13 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
14                                   Error **errp)
15 {
16     if (dev->id) {
17         error_setg(errp, "Attempt to set property '%s' on device '%s' "
18                    "(type '%s') after it was realized", name, dev->id,
19                    object_get_typename(OBJECT(dev)));
20     } else {
21         error_setg(errp, "Attempt to set property '%s' on anonymous device "
22                    "(type '%s') after it was realized", name,
23                    object_get_typename(OBJECT(dev)));
24     }
25 }
26 
27 void qdev_prop_allow_set_link_before_realize(const Object *obj,
28                                              const char *name,
29                                              Object *val, Error **errp)
30 {
31     DeviceState *dev = DEVICE(obj);
32 
33     if (dev->realized) {
34         error_setg(errp, "Attempt to set link property '%s' on device '%s' "
35                    "(type '%s') after it was realized",
36                    name, dev->id, object_get_typename(obj));
37     }
38 }
39 
40 void *qdev_get_prop_ptr(Object *obj, Property *prop)
41 {
42     void *ptr = obj;
43     ptr += prop->offset;
44     return ptr;
45 }
46 
47 static void field_prop_get(Object *obj, Visitor *v, const char *name,
48                            void *opaque, Error **errp)
49 {
50     Property *prop = opaque;
51     return prop->info->get(obj, v, name, opaque, errp);
52 }
53 
54 /**
55  * field_prop_getter: Return getter function to be used for property
56  *
57  * Return value can be NULL if @info has no getter function.
58  */
59 static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
60 {
61     return info->get ? field_prop_get : NULL;
62 }
63 
64 static void field_prop_set(Object *obj, Visitor *v, const char *name,
65                            void *opaque, Error **errp)
66 {
67     Property *prop = opaque;
68     return prop->info->set(obj, v, name, opaque, errp);
69 }
70 
71 /**
72  * field_prop_setter: Return setter function to be used for property
73  *
74  * Return value can be NULL if @info has not setter function.
75  */
76 static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
77 {
78     return info->set ? field_prop_set : NULL;
79 }
80 
81 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
82                             void *opaque, Error **errp)
83 {
84     Property *prop = opaque;
85     int *ptr = qdev_get_prop_ptr(obj, prop);
86 
87     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
88 }
89 
90 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
91                             void *opaque, Error **errp)
92 {
93     DeviceState *dev = DEVICE(obj);
94     Property *prop = opaque;
95     int *ptr = qdev_get_prop_ptr(obj, prop);
96 
97     if (dev->realized) {
98         qdev_prop_set_after_realize(dev, name, errp);
99         return;
100     }
101 
102     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
103 }
104 
105 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
106                                           const Property *prop)
107 {
108     object_property_set_default_str(op,
109         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
110 }
111 
112 const PropertyInfo qdev_prop_enum = {
113     .name  = "enum",
114     .get   = qdev_propinfo_get_enum,
115     .set   = qdev_propinfo_set_enum,
116     .set_default_value = qdev_propinfo_set_default_value_enum,
117 };
118 
119 /* Bit */
120 
121 static uint32_t qdev_get_prop_mask(Property *prop)
122 {
123     assert(prop->info == &qdev_prop_bit);
124     return 0x1 << prop->bitnr;
125 }
126 
127 static void bit_prop_set(Object *obj, Property *props, bool val)
128 {
129     uint32_t *p = qdev_get_prop_ptr(obj, props);
130     uint32_t mask = qdev_get_prop_mask(props);
131     if (val) {
132         *p |= mask;
133     } else {
134         *p &= ~mask;
135     }
136 }
137 
138 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
139                          void *opaque, Error **errp)
140 {
141     Property *prop = opaque;
142     uint32_t *p = qdev_get_prop_ptr(obj, prop);
143     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
144 
145     visit_type_bool(v, name, &value, errp);
146 }
147 
148 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
149                          void *opaque, Error **errp)
150 {
151     DeviceState *dev = DEVICE(obj);
152     Property *prop = opaque;
153     bool value;
154 
155     if (dev->realized) {
156         qdev_prop_set_after_realize(dev, name, errp);
157         return;
158     }
159 
160     if (!visit_type_bool(v, name, &value, errp)) {
161         return;
162     }
163     bit_prop_set(obj, prop, value);
164 }
165 
166 static void set_default_value_bool(ObjectProperty *op, const Property *prop)
167 {
168     object_property_set_default_bool(op, prop->defval.u);
169 }
170 
171 const PropertyInfo qdev_prop_bit = {
172     .name  = "bool",
173     .description = "on/off",
174     .get   = prop_get_bit,
175     .set   = prop_set_bit,
176     .set_default_value = set_default_value_bool,
177 };
178 
179 /* Bit64 */
180 
181 static uint64_t qdev_get_prop_mask64(Property *prop)
182 {
183     assert(prop->info == &qdev_prop_bit64);
184     return 0x1ull << prop->bitnr;
185 }
186 
187 static void bit64_prop_set(Object *obj, Property *props, bool val)
188 {
189     uint64_t *p = qdev_get_prop_ptr(obj, props);
190     uint64_t mask = qdev_get_prop_mask64(props);
191     if (val) {
192         *p |= mask;
193     } else {
194         *p &= ~mask;
195     }
196 }
197 
198 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
199                            void *opaque, Error **errp)
200 {
201     Property *prop = opaque;
202     uint64_t *p = qdev_get_prop_ptr(obj, prop);
203     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
204 
205     visit_type_bool(v, name, &value, errp);
206 }
207 
208 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
209                            void *opaque, Error **errp)
210 {
211     DeviceState *dev = DEVICE(obj);
212     Property *prop = opaque;
213     bool value;
214 
215     if (dev->realized) {
216         qdev_prop_set_after_realize(dev, name, errp);
217         return;
218     }
219 
220     if (!visit_type_bool(v, name, &value, errp)) {
221         return;
222     }
223     bit64_prop_set(obj, prop, value);
224 }
225 
226 const PropertyInfo qdev_prop_bit64 = {
227     .name  = "bool",
228     .description = "on/off",
229     .get   = prop_get_bit64,
230     .set   = prop_set_bit64,
231     .set_default_value = set_default_value_bool,
232 };
233 
234 /* --- bool --- */
235 
236 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
237                      Error **errp)
238 {
239     Property *prop = opaque;
240     bool *ptr = qdev_get_prop_ptr(obj, prop);
241 
242     visit_type_bool(v, name, ptr, errp);
243 }
244 
245 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
246                      Error **errp)
247 {
248     DeviceState *dev = DEVICE(obj);
249     Property *prop = opaque;
250     bool *ptr = qdev_get_prop_ptr(obj, prop);
251 
252     if (dev->realized) {
253         qdev_prop_set_after_realize(dev, name, errp);
254         return;
255     }
256 
257     visit_type_bool(v, name, ptr, errp);
258 }
259 
260 const PropertyInfo qdev_prop_bool = {
261     .name  = "bool",
262     .get   = get_bool,
263     .set   = set_bool,
264     .set_default_value = set_default_value_bool,
265 };
266 
267 /* --- 8bit integer --- */
268 
269 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
270                       Error **errp)
271 {
272     Property *prop = opaque;
273     uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
274 
275     visit_type_uint8(v, name, ptr, errp);
276 }
277 
278 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
279                       Error **errp)
280 {
281     DeviceState *dev = DEVICE(obj);
282     Property *prop = opaque;
283     uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
284 
285     if (dev->realized) {
286         qdev_prop_set_after_realize(dev, name, errp);
287         return;
288     }
289 
290     visit_type_uint8(v, name, ptr, errp);
291 }
292 
293 void qdev_propinfo_set_default_value_int(ObjectProperty *op,
294                                          const Property *prop)
295 {
296     object_property_set_default_int(op, prop->defval.i);
297 }
298 
299 void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
300                                           const Property *prop)
301 {
302     object_property_set_default_uint(op, prop->defval.u);
303 }
304 
305 const PropertyInfo qdev_prop_uint8 = {
306     .name  = "uint8",
307     .get   = get_uint8,
308     .set   = set_uint8,
309     .set_default_value = qdev_propinfo_set_default_value_uint,
310 };
311 
312 /* --- 16bit integer --- */
313 
314 static void get_uint16(Object *obj, Visitor *v, const char *name,
315                        void *opaque, Error **errp)
316 {
317     Property *prop = opaque;
318     uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
319 
320     visit_type_uint16(v, name, ptr, errp);
321 }
322 
323 static void set_uint16(Object *obj, Visitor *v, const char *name,
324                        void *opaque, Error **errp)
325 {
326     DeviceState *dev = DEVICE(obj);
327     Property *prop = opaque;
328     uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
329 
330     if (dev->realized) {
331         qdev_prop_set_after_realize(dev, name, errp);
332         return;
333     }
334 
335     visit_type_uint16(v, name, ptr, errp);
336 }
337 
338 const PropertyInfo qdev_prop_uint16 = {
339     .name  = "uint16",
340     .get   = get_uint16,
341     .set   = set_uint16,
342     .set_default_value = qdev_propinfo_set_default_value_uint,
343 };
344 
345 /* --- 32bit integer --- */
346 
347 static void get_uint32(Object *obj, Visitor *v, const char *name,
348                        void *opaque, Error **errp)
349 {
350     Property *prop = opaque;
351     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
352 
353     visit_type_uint32(v, name, ptr, errp);
354 }
355 
356 static void set_uint32(Object *obj, Visitor *v, const char *name,
357                        void *opaque, Error **errp)
358 {
359     DeviceState *dev = DEVICE(obj);
360     Property *prop = opaque;
361     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
362 
363     if (dev->realized) {
364         qdev_prop_set_after_realize(dev, name, errp);
365         return;
366     }
367 
368     visit_type_uint32(v, name, ptr, errp);
369 }
370 
371 void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
372                              void *opaque, Error **errp)
373 {
374     Property *prop = opaque;
375     int32_t *ptr = qdev_get_prop_ptr(obj, prop);
376 
377     visit_type_int32(v, name, ptr, errp);
378 }
379 
380 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
381                       Error **errp)
382 {
383     DeviceState *dev = DEVICE(obj);
384     Property *prop = opaque;
385     int32_t *ptr = qdev_get_prop_ptr(obj, prop);
386 
387     if (dev->realized) {
388         qdev_prop_set_after_realize(dev, name, errp);
389         return;
390     }
391 
392     visit_type_int32(v, name, ptr, errp);
393 }
394 
395 const PropertyInfo qdev_prop_uint32 = {
396     .name  = "uint32",
397     .get   = get_uint32,
398     .set   = set_uint32,
399     .set_default_value = qdev_propinfo_set_default_value_uint,
400 };
401 
402 const PropertyInfo qdev_prop_int32 = {
403     .name  = "int32",
404     .get   = qdev_propinfo_get_int32,
405     .set   = set_int32,
406     .set_default_value = qdev_propinfo_set_default_value_int,
407 };
408 
409 /* --- 64bit integer --- */
410 
411 static void get_uint64(Object *obj, Visitor *v, const char *name,
412                        void *opaque, Error **errp)
413 {
414     Property *prop = opaque;
415     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
416 
417     visit_type_uint64(v, name, ptr, errp);
418 }
419 
420 static void set_uint64(Object *obj, Visitor *v, const char *name,
421                        void *opaque, Error **errp)
422 {
423     DeviceState *dev = DEVICE(obj);
424     Property *prop = opaque;
425     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
426 
427     if (dev->realized) {
428         qdev_prop_set_after_realize(dev, name, errp);
429         return;
430     }
431 
432     visit_type_uint64(v, name, ptr, errp);
433 }
434 
435 static void get_int64(Object *obj, Visitor *v, const char *name,
436                       void *opaque, Error **errp)
437 {
438     Property *prop = opaque;
439     int64_t *ptr = qdev_get_prop_ptr(obj, prop);
440 
441     visit_type_int64(v, name, ptr, errp);
442 }
443 
444 static void set_int64(Object *obj, Visitor *v, const char *name,
445                       void *opaque, Error **errp)
446 {
447     DeviceState *dev = DEVICE(obj);
448     Property *prop = opaque;
449     int64_t *ptr = qdev_get_prop_ptr(obj, prop);
450 
451     if (dev->realized) {
452         qdev_prop_set_after_realize(dev, name, errp);
453         return;
454     }
455 
456     visit_type_int64(v, name, ptr, errp);
457 }
458 
459 const PropertyInfo qdev_prop_uint64 = {
460     .name  = "uint64",
461     .get   = get_uint64,
462     .set   = set_uint64,
463     .set_default_value = qdev_propinfo_set_default_value_uint,
464 };
465 
466 const PropertyInfo qdev_prop_int64 = {
467     .name  = "int64",
468     .get   = get_int64,
469     .set   = set_int64,
470     .set_default_value = qdev_propinfo_set_default_value_int,
471 };
472 
473 /* --- string --- */
474 
475 static void release_string(Object *obj, const char *name, void *opaque)
476 {
477     Property *prop = opaque;
478     g_free(*(char **)qdev_get_prop_ptr(obj, prop));
479 }
480 
481 static void get_string(Object *obj, Visitor *v, const char *name,
482                        void *opaque, Error **errp)
483 {
484     Property *prop = opaque;
485     char **ptr = qdev_get_prop_ptr(obj, prop);
486 
487     if (!*ptr) {
488         char *str = (char *)"";
489         visit_type_str(v, name, &str, errp);
490     } else {
491         visit_type_str(v, name, ptr, errp);
492     }
493 }
494 
495 static void set_string(Object *obj, Visitor *v, const char *name,
496                        void *opaque, Error **errp)
497 {
498     DeviceState *dev = DEVICE(obj);
499     Property *prop = opaque;
500     char **ptr = qdev_get_prop_ptr(obj, prop);
501     char *str;
502 
503     if (dev->realized) {
504         qdev_prop_set_after_realize(dev, name, errp);
505         return;
506     }
507 
508     if (!visit_type_str(v, name, &str, errp)) {
509         return;
510     }
511     g_free(*ptr);
512     *ptr = str;
513 }
514 
515 const PropertyInfo qdev_prop_string = {
516     .name  = "str",
517     .release = release_string,
518     .get   = get_string,
519     .set   = set_string,
520 };
521 
522 /* --- on/off/auto --- */
523 
524 const PropertyInfo qdev_prop_on_off_auto = {
525     .name = "OnOffAuto",
526     .description = "on/off/auto",
527     .enum_table = &OnOffAuto_lookup,
528     .get = qdev_propinfo_get_enum,
529     .set = qdev_propinfo_set_enum,
530     .set_default_value = qdev_propinfo_set_default_value_enum,
531 };
532 
533 /* --- 32bit unsigned int 'size' type --- */
534 
535 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
536                               void *opaque, Error **errp)
537 {
538     Property *prop = opaque;
539     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
540     uint64_t value = *ptr;
541 
542     visit_type_size(v, name, &value, errp);
543 }
544 
545 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
546                        Error **errp)
547 {
548     DeviceState *dev = DEVICE(obj);
549     Property *prop = opaque;
550     uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
551     uint64_t value;
552 
553     if (dev->realized) {
554         qdev_prop_set_after_realize(dev, name, errp);
555         return;
556     }
557 
558     if (!visit_type_size(v, name, &value, errp)) {
559         return;
560     }
561 
562     if (value > UINT32_MAX) {
563         error_setg(errp,
564                    "Property %s.%s doesn't take value %" PRIu64
565                    " (maximum: %u)",
566                    object_get_typename(obj), name, value, UINT32_MAX);
567         return;
568     }
569 
570     *ptr = value;
571 }
572 
573 const PropertyInfo qdev_prop_size32 = {
574     .name  = "size",
575     .get = qdev_propinfo_get_size32,
576     .set = set_size32,
577     .set_default_value = qdev_propinfo_set_default_value_uint,
578 };
579 
580 /* --- support for array properties --- */
581 
582 /* Used as an opaque for the object properties we add for each
583  * array element. Note that the struct Property must be first
584  * in the struct so that a pointer to this works as the opaque
585  * for the underlying element's property hooks as well as for
586  * our own release callback.
587  */
588 typedef struct {
589     struct Property prop;
590     char *propname;
591     ObjectPropertyRelease *release;
592 } ArrayElementProperty;
593 
594 /* object property release callback for array element properties:
595  * we call the underlying element's property release hook, and
596  * then free the memory we allocated when we added the property.
597  */
598 static void array_element_release(Object *obj, const char *name, void *opaque)
599 {
600     ArrayElementProperty *p = opaque;
601     if (p->release) {
602         p->release(obj, name, opaque);
603     }
604     g_free(p->propname);
605     g_free(p);
606 }
607 
608 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
609                               void *opaque, Error **errp)
610 {
611     /* Setter for the property which defines the length of a
612      * variable-sized property array. As well as actually setting the
613      * array-length field in the device struct, we have to create the
614      * array itself and dynamically add the corresponding properties.
615      */
616     DeviceState *dev = DEVICE(obj);
617     Property *prop = opaque;
618     uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
619     void **arrayptr = (void *)dev + prop->arrayoffset;
620     void *eltptr;
621     const char *arrayname;
622     int i;
623 
624     if (dev->realized) {
625         qdev_prop_set_after_realize(dev, name, errp);
626         return;
627     }
628     if (*alenptr) {
629         error_setg(errp, "array size property %s may not be set more than once",
630                    name);
631         return;
632     }
633     if (!visit_type_uint32(v, name, alenptr, errp)) {
634         return;
635     }
636     if (!*alenptr) {
637         return;
638     }
639 
640     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
641      * strip it off so we can get the name of the array itself.
642      */
643     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
644                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
645     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
646 
647     /* Note that it is the responsibility of the individual device's deinit
648      * to free the array proper.
649      */
650     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
651     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
652         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
653         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
654         arrayprop->release = prop->arrayinfo->release;
655         arrayprop->propname = propname;
656         arrayprop->prop.info = prop->arrayinfo;
657         arrayprop->prop.name = propname;
658         /* This ugly piece of pointer arithmetic sets up the offset so
659          * that when the underlying get/set hooks call qdev_get_prop_ptr
660          * they get the right answer despite the array element not actually
661          * being inside the device struct.
662          */
663         arrayprop->prop.offset = eltptr - (void *)dev;
664         assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr);
665         object_property_add(obj, propname,
666                             arrayprop->prop.info->name,
667                             field_prop_getter(arrayprop->prop.info),
668                             field_prop_setter(arrayprop->prop.info),
669                             array_element_release,
670                             arrayprop);
671     }
672 }
673 
674 const PropertyInfo qdev_prop_arraylen = {
675     .name = "uint32",
676     .get = get_uint32,
677     .set = set_prop_arraylen,
678     .set_default_value = qdev_propinfo_set_default_value_uint,
679 };
680 
681 /* --- public helpers --- */
682 
683 static Property *qdev_prop_walk(Property *props, const char *name)
684 {
685     if (!props) {
686         return NULL;
687     }
688     while (props->name) {
689         if (strcmp(props->name, name) == 0) {
690             return props;
691         }
692         props++;
693     }
694     return NULL;
695 }
696 
697 static Property *qdev_prop_find(DeviceState *dev, const char *name)
698 {
699     ObjectClass *class;
700     Property *prop;
701 
702     /* device properties */
703     class = object_get_class(OBJECT(dev));
704     do {
705         prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
706         if (prop) {
707             return prop;
708         }
709         class = object_class_get_parent(class);
710     } while (class != object_class_by_name(TYPE_DEVICE));
711 
712     return NULL;
713 }
714 
715 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
716                                     const char *name, const char *value)
717 {
718     switch (ret) {
719     case -EEXIST:
720         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
721                   object_get_typename(obj), name, value);
722         break;
723     default:
724     case -EINVAL:
725         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
726                    object_get_typename(obj), name, value);
727         break;
728     case -ENOENT:
729         error_setg(errp, "Property '%s.%s' can't find value '%s'",
730                   object_get_typename(obj), name, value);
731         break;
732     case 0:
733         break;
734     }
735 }
736 
737 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
738 {
739     object_property_set_bool(OBJECT(dev), name, value, &error_abort);
740 }
741 
742 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
743 {
744     object_property_set_int(OBJECT(dev), name, value, &error_abort);
745 }
746 
747 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
748 {
749     object_property_set_int(OBJECT(dev), name, value, &error_abort);
750 }
751 
752 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
753 {
754     object_property_set_int(OBJECT(dev), name, value, &error_abort);
755 }
756 
757 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
758 {
759     object_property_set_int(OBJECT(dev), name, value, &error_abort);
760 }
761 
762 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
763 {
764     object_property_set_int(OBJECT(dev), name, value, &error_abort);
765 }
766 
767 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
768 {
769     object_property_set_str(OBJECT(dev), name, value, &error_abort);
770 }
771 
772 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
773 {
774     Property *prop;
775 
776     prop = qdev_prop_find(dev, name);
777     object_property_set_str(OBJECT(dev), name,
778                             qapi_enum_lookup(prop->info->enum_table, value),
779                             &error_abort);
780 }
781 
782 static GPtrArray *global_props(void)
783 {
784     static GPtrArray *gp;
785 
786     if (!gp) {
787         gp = g_ptr_array_new();
788     }
789 
790     return gp;
791 }
792 
793 void qdev_prop_register_global(GlobalProperty *prop)
794 {
795     g_ptr_array_add(global_props(), prop);
796 }
797 
798 const GlobalProperty *qdev_find_global_prop(Object *obj,
799                                             const char *name)
800 {
801     GPtrArray *props = global_props();
802     const GlobalProperty *p;
803     int i;
804 
805     for (i = 0; i < props->len; i++) {
806         p = g_ptr_array_index(props, i);
807         if (object_dynamic_cast(obj, p->driver)
808             && !strcmp(p->property, name)) {
809             return p;
810         }
811     }
812     return NULL;
813 }
814 
815 int qdev_prop_check_globals(void)
816 {
817     int i, ret = 0;
818 
819     for (i = 0; i < global_props()->len; i++) {
820         GlobalProperty *prop;
821         ObjectClass *oc;
822         DeviceClass *dc;
823 
824         prop = g_ptr_array_index(global_props(), i);
825         if (prop->used) {
826             continue;
827         }
828         oc = object_class_by_name(prop->driver);
829         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
830         if (!oc) {
831             warn_report("global %s.%s has invalid class name",
832                         prop->driver, prop->property);
833             ret = 1;
834             continue;
835         }
836         dc = DEVICE_CLASS(oc);
837         if (!dc->hotpluggable && !prop->used) {
838             warn_report("global %s.%s=%s not used",
839                         prop->driver, prop->property, prop->value);
840             ret = 1;
841             continue;
842         }
843     }
844     return ret;
845 }
846 
847 void qdev_prop_set_globals(DeviceState *dev)
848 {
849     object_apply_global_props(OBJECT(dev), global_props(),
850                               dev->hotplugged ? NULL : &error_fatal);
851 }
852 
853 /* --- 64bit unsigned int 'size' type --- */
854 
855 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
856                      Error **errp)
857 {
858     Property *prop = opaque;
859     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
860 
861     visit_type_size(v, name, ptr, errp);
862 }
863 
864 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
865                      Error **errp)
866 {
867     DeviceState *dev = DEVICE(obj);
868     Property *prop = opaque;
869     uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
870 
871     if (dev->realized) {
872         qdev_prop_set_after_realize(dev, name, errp);
873         return;
874     }
875 
876     visit_type_size(v, name, ptr, errp);
877 }
878 
879 const PropertyInfo qdev_prop_size = {
880     .name  = "size",
881     .get = get_size,
882     .set = set_size,
883     .set_default_value = qdev_propinfo_set_default_value_uint,
884 };
885 
886 /* --- object link property --- */
887 
888 static void create_link_property(ObjectClass *oc, const char *name,
889                                  Property *prop)
890 {
891     object_class_property_add_link(oc, name, prop->link_type,
892                                    prop->offset,
893                                    qdev_prop_allow_set_link_before_realize,
894                                    OBJ_PROP_LINK_STRONG);
895 }
896 
897 const PropertyInfo qdev_prop_link = {
898     .name = "link",
899     .create = create_link_property,
900 };
901 
902 void qdev_property_add_static(DeviceState *dev, Property *prop)
903 {
904     Object *obj = OBJECT(dev);
905     ObjectProperty *op;
906 
907     assert(!prop->info->create);
908 
909     op = object_property_add(obj, prop->name, prop->info->name,
910                              field_prop_getter(prop->info),
911                              field_prop_setter(prop->info),
912                              prop->info->release,
913                              prop);
914 
915     object_property_set_description(obj, prop->name,
916                                     prop->info->description);
917 
918     if (prop->set_default) {
919         prop->info->set_default_value(op, prop);
920         if (op->init) {
921             op->init(obj, op);
922         }
923     }
924 }
925 
926 static void qdev_class_add_property(DeviceClass *klass, const char *name,
927                                     Property *prop)
928 {
929     ObjectClass *oc = OBJECT_CLASS(klass);
930 
931     if (prop->info->create) {
932         prop->info->create(oc, name, prop);
933     } else {
934         ObjectProperty *op;
935 
936         op = object_class_property_add(oc,
937                                        name, prop->info->name,
938                                        field_prop_getter(prop->info),
939                                        field_prop_setter(prop->info),
940                                        prop->info->release,
941                                        prop);
942         if (prop->set_default) {
943             prop->info->set_default_value(op, prop);
944         }
945     }
946     object_class_property_set_description(oc, name,
947                                           prop->info->description);
948 }
949 
950 /**
951  * Legacy property handling
952  */
953 
954 static void qdev_get_legacy_property(Object *obj, Visitor *v,
955                                      const char *name, void *opaque,
956                                      Error **errp)
957 {
958     Property *prop = opaque;
959 
960     char buffer[1024];
961     char *ptr = buffer;
962 
963     prop->info->print(obj, prop, buffer, sizeof(buffer));
964     visit_type_str(v, name, &ptr, errp);
965 }
966 
967 /**
968  * qdev_class_add_legacy_property:
969  * @dev: Device to add the property to.
970  * @prop: The qdev property definition.
971  *
972  * Add a legacy QOM property to @dev for qdev property @prop.
973  *
974  * Legacy properties are string versions of QOM properties.  The format of
975  * the string depends on the property type.  Legacy properties are only
976  * needed for "info qtree".
977  *
978  * Do not use this in new code!  QOM Properties added through this interface
979  * will be given names in the "legacy" namespace.
980  */
981 static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
982 {
983     g_autofree char *name = NULL;
984 
985     /* Register pointer properties as legacy properties */
986     if (!prop->info->print && prop->info->get) {
987         return;
988     }
989 
990     name = g_strdup_printf("legacy-%s", prop->name);
991     object_class_property_add(OBJECT_CLASS(dc), name, "str",
992         prop->info->print ? qdev_get_legacy_property : prop->info->get,
993         NULL, NULL, prop);
994 }
995 
996 void device_class_set_props(DeviceClass *dc, Property *props)
997 {
998     Property *prop;
999 
1000     dc->props_ = props;
1001     for (prop = props; prop && prop->name; prop++) {
1002         qdev_class_add_legacy_property(dc, prop);
1003         qdev_class_add_property(dc, prop->name, prop);
1004     }
1005 }
1006 
1007 void qdev_alias_all_properties(DeviceState *target, Object *source)
1008 {
1009     ObjectClass *class;
1010     Property *prop;
1011 
1012     class = object_get_class(OBJECT(target));
1013     do {
1014         DeviceClass *dc = DEVICE_CLASS(class);
1015 
1016         for (prop = dc->props_; prop && prop->name; prop++) {
1017             object_property_add_alias(source, prop->name,
1018                                       OBJECT(target), prop->name);
1019         }
1020         class = object_class_get_parent(class);
1021     } while (class != object_class_by_name(TYPE_DEVICE));
1022 }
1023