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