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