xref: /openbmc/qemu/hw/core/qdev-properties.c (revision a6977312)
1 #include "qemu/osdep.h"
2 #include "net/net.h"
3 #include "hw/qdev.h"
4 #include "qapi/error.h"
5 #include "hw/pci/pci.h"
6 #include "qapi/qmp/qerror.h"
7 #include "qemu/error-report.h"
8 #include "sysemu/block-backend.h"
9 #include "hw/block/block.h"
10 #include "net/hub.h"
11 #include "qapi/visitor.h"
12 #include "chardev/char.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 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
49                      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 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
59                      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 static void set_default_value_enum(Object *obj, const Property *prop)
74 {
75     object_property_set_str(obj, prop->info->enum_table[prop->defval.i],
76                             prop->name, &error_abort);
77 }
78 
79 /* Bit */
80 
81 static uint32_t qdev_get_prop_mask(Property *prop)
82 {
83     assert(prop->info == &qdev_prop_bit);
84     return 0x1 << prop->bitnr;
85 }
86 
87 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
88 {
89     uint32_t *p = qdev_get_prop_ptr(dev, props);
90     uint32_t mask = qdev_get_prop_mask(props);
91     if (val) {
92         *p |= mask;
93     } else {
94         *p &= ~mask;
95     }
96 }
97 
98 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
99                          void *opaque, Error **errp)
100 {
101     DeviceState *dev = DEVICE(obj);
102     Property *prop = opaque;
103     uint32_t *p = qdev_get_prop_ptr(dev, prop);
104     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
105 
106     visit_type_bool(v, name, &value, errp);
107 }
108 
109 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
110                          void *opaque, Error **errp)
111 {
112     DeviceState *dev = DEVICE(obj);
113     Property *prop = opaque;
114     Error *local_err = NULL;
115     bool value;
116 
117     if (dev->realized) {
118         qdev_prop_set_after_realize(dev, name, errp);
119         return;
120     }
121 
122     visit_type_bool(v, name, &value, &local_err);
123     if (local_err) {
124         error_propagate(errp, local_err);
125         return;
126     }
127     bit_prop_set(dev, prop, value);
128 }
129 
130 static void set_default_value_bool(Object *obj, const Property *prop)
131 {
132     object_property_set_bool(obj, prop->defval.u, prop->name, &error_abort);
133 }
134 
135 const PropertyInfo qdev_prop_bit = {
136     .name  = "bool",
137     .description = "on/off",
138     .get   = prop_get_bit,
139     .set   = prop_set_bit,
140     .set_default_value = set_default_value_bool,
141 };
142 
143 /* Bit64 */
144 
145 static uint64_t qdev_get_prop_mask64(Property *prop)
146 {
147     assert(prop->info == &qdev_prop_bit64);
148     return 0x1ull << prop->bitnr;
149 }
150 
151 static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
152 {
153     uint64_t *p = qdev_get_prop_ptr(dev, props);
154     uint64_t mask = qdev_get_prop_mask64(props);
155     if (val) {
156         *p |= mask;
157     } else {
158         *p &= ~mask;
159     }
160 }
161 
162 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
163                            void *opaque, Error **errp)
164 {
165     DeviceState *dev = DEVICE(obj);
166     Property *prop = opaque;
167     uint64_t *p = qdev_get_prop_ptr(dev, prop);
168     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
169 
170     visit_type_bool(v, name, &value, errp);
171 }
172 
173 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
174                            void *opaque, Error **errp)
175 {
176     DeviceState *dev = DEVICE(obj);
177     Property *prop = opaque;
178     Error *local_err = NULL;
179     bool value;
180 
181     if (dev->realized) {
182         qdev_prop_set_after_realize(dev, name, errp);
183         return;
184     }
185 
186     visit_type_bool(v, name, &value, &local_err);
187     if (local_err) {
188         error_propagate(errp, local_err);
189         return;
190     }
191     bit64_prop_set(dev, prop, value);
192 }
193 
194 const PropertyInfo qdev_prop_bit64 = {
195     .name  = "bool",
196     .description = "on/off",
197     .get   = prop_get_bit64,
198     .set   = prop_set_bit64,
199     .set_default_value = set_default_value_bool,
200 };
201 
202 /* --- bool --- */
203 
204 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
205                      Error **errp)
206 {
207     DeviceState *dev = DEVICE(obj);
208     Property *prop = opaque;
209     bool *ptr = qdev_get_prop_ptr(dev, prop);
210 
211     visit_type_bool(v, name, ptr, errp);
212 }
213 
214 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
215                      Error **errp)
216 {
217     DeviceState *dev = DEVICE(obj);
218     Property *prop = opaque;
219     bool *ptr = qdev_get_prop_ptr(dev, prop);
220 
221     if (dev->realized) {
222         qdev_prop_set_after_realize(dev, name, errp);
223         return;
224     }
225 
226     visit_type_bool(v, name, ptr, errp);
227 }
228 
229 const PropertyInfo qdev_prop_bool = {
230     .name  = "bool",
231     .get   = get_bool,
232     .set   = set_bool,
233     .set_default_value = set_default_value_bool,
234 };
235 
236 /* --- 8bit integer --- */
237 
238 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
239                       Error **errp)
240 {
241     DeviceState *dev = DEVICE(obj);
242     Property *prop = opaque;
243     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
244 
245     visit_type_uint8(v, name, ptr, errp);
246 }
247 
248 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
249                       Error **errp)
250 {
251     DeviceState *dev = DEVICE(obj);
252     Property *prop = opaque;
253     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
254 
255     if (dev->realized) {
256         qdev_prop_set_after_realize(dev, name, errp);
257         return;
258     }
259 
260     visit_type_uint8(v, name, ptr, errp);
261 }
262 
263 static void set_default_value_int(Object *obj, const Property *prop)
264 {
265     object_property_set_int(obj, prop->defval.i, prop->name, &error_abort);
266 }
267 
268 static void set_default_value_uint(Object *obj, const Property *prop)
269 {
270     object_property_set_uint(obj, prop->defval.u, prop->name, &error_abort);
271 }
272 
273 const PropertyInfo qdev_prop_uint8 = {
274     .name  = "uint8",
275     .get   = get_uint8,
276     .set   = set_uint8,
277     .set_default_value = set_default_value_uint,
278 };
279 
280 /* --- 16bit integer --- */
281 
282 static void get_uint16(Object *obj, Visitor *v, const char *name,
283                        void *opaque, Error **errp)
284 {
285     DeviceState *dev = DEVICE(obj);
286     Property *prop = opaque;
287     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
288 
289     visit_type_uint16(v, name, ptr, errp);
290 }
291 
292 static void set_uint16(Object *obj, Visitor *v, const char *name,
293                        void *opaque, Error **errp)
294 {
295     DeviceState *dev = DEVICE(obj);
296     Property *prop = opaque;
297     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
298 
299     if (dev->realized) {
300         qdev_prop_set_after_realize(dev, name, errp);
301         return;
302     }
303 
304     visit_type_uint16(v, name, ptr, errp);
305 }
306 
307 const PropertyInfo qdev_prop_uint16 = {
308     .name  = "uint16",
309     .get   = get_uint16,
310     .set   = set_uint16,
311     .set_default_value = set_default_value_uint,
312 };
313 
314 /* --- 32bit integer --- */
315 
316 static void get_uint32(Object *obj, Visitor *v, const char *name,
317                        void *opaque, Error **errp)
318 {
319     DeviceState *dev = DEVICE(obj);
320     Property *prop = opaque;
321     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
322 
323     visit_type_uint32(v, name, ptr, errp);
324 }
325 
326 static void set_uint32(Object *obj, Visitor *v, const char *name,
327                        void *opaque, Error **errp)
328 {
329     DeviceState *dev = DEVICE(obj);
330     Property *prop = opaque;
331     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
332 
333     if (dev->realized) {
334         qdev_prop_set_after_realize(dev, name, errp);
335         return;
336     }
337 
338     visit_type_uint32(v, name, ptr, errp);
339 }
340 
341 static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque,
342                       Error **errp)
343 {
344     DeviceState *dev = DEVICE(obj);
345     Property *prop = opaque;
346     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
347 
348     visit_type_int32(v, name, ptr, errp);
349 }
350 
351 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
352                       Error **errp)
353 {
354     DeviceState *dev = DEVICE(obj);
355     Property *prop = opaque;
356     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
357 
358     if (dev->realized) {
359         qdev_prop_set_after_realize(dev, name, errp);
360         return;
361     }
362 
363     visit_type_int32(v, name, ptr, errp);
364 }
365 
366 const PropertyInfo qdev_prop_uint32 = {
367     .name  = "uint32",
368     .get   = get_uint32,
369     .set   = set_uint32,
370     .set_default_value = set_default_value_uint,
371 };
372 
373 const PropertyInfo qdev_prop_int32 = {
374     .name  = "int32",
375     .get   = get_int32,
376     .set   = set_int32,
377     .set_default_value = set_default_value_int,
378 };
379 
380 /* --- 64bit integer --- */
381 
382 static void get_uint64(Object *obj, Visitor *v, const char *name,
383                        void *opaque, Error **errp)
384 {
385     DeviceState *dev = DEVICE(obj);
386     Property *prop = opaque;
387     uint64_t *ptr = qdev_get_prop_ptr(dev, 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     DeviceState *dev = DEVICE(obj);
396     Property *prop = opaque;
397     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
398 
399     if (dev->realized) {
400         qdev_prop_set_after_realize(dev, name, errp);
401         return;
402     }
403 
404     visit_type_uint64(v, name, ptr, errp);
405 }
406 
407 static void get_int64(Object *obj, Visitor *v, const char *name,
408                       void *opaque, Error **errp)
409 {
410     DeviceState *dev = DEVICE(obj);
411     Property *prop = opaque;
412     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
413 
414     visit_type_int64(v, name, ptr, errp);
415 }
416 
417 static void set_int64(Object *obj, Visitor *v, const char *name,
418                       void *opaque, Error **errp)
419 {
420     DeviceState *dev = DEVICE(obj);
421     Property *prop = opaque;
422     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
423 
424     if (dev->realized) {
425         qdev_prop_set_after_realize(dev, name, errp);
426         return;
427     }
428 
429     visit_type_int64(v, name, ptr, errp);
430 }
431 
432 const PropertyInfo qdev_prop_uint64 = {
433     .name  = "uint64",
434     .get   = get_uint64,
435     .set   = set_uint64,
436     .set_default_value = set_default_value_uint,
437 };
438 
439 const PropertyInfo qdev_prop_int64 = {
440     .name  = "int64",
441     .get   = get_int64,
442     .set   = set_int64,
443     .set_default_value = set_default_value_int,
444 };
445 
446 /* --- string --- */
447 
448 static void release_string(Object *obj, const char *name, void *opaque)
449 {
450     Property *prop = opaque;
451     g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
452 }
453 
454 static void get_string(Object *obj, Visitor *v, const char *name,
455                        void *opaque, Error **errp)
456 {
457     DeviceState *dev = DEVICE(obj);
458     Property *prop = opaque;
459     char **ptr = qdev_get_prop_ptr(dev, prop);
460 
461     if (!*ptr) {
462         char *str = (char *)"";
463         visit_type_str(v, name, &str, errp);
464     } else {
465         visit_type_str(v, name, ptr, errp);
466     }
467 }
468 
469 static void set_string(Object *obj, Visitor *v, const char *name,
470                        void *opaque, Error **errp)
471 {
472     DeviceState *dev = DEVICE(obj);
473     Property *prop = opaque;
474     char **ptr = qdev_get_prop_ptr(dev, prop);
475     Error *local_err = NULL;
476     char *str;
477 
478     if (dev->realized) {
479         qdev_prop_set_after_realize(dev, name, errp);
480         return;
481     }
482 
483     visit_type_str(v, name, &str, &local_err);
484     if (local_err) {
485         error_propagate(errp, local_err);
486         return;
487     }
488     g_free(*ptr);
489     *ptr = str;
490 }
491 
492 const PropertyInfo qdev_prop_string = {
493     .name  = "str",
494     .release = release_string,
495     .get   = get_string,
496     .set   = set_string,
497 };
498 
499 /* --- pointer --- */
500 
501 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
502 const PropertyInfo qdev_prop_ptr = {
503     .name  = "ptr",
504 };
505 
506 /* --- mac address --- */
507 
508 /*
509  * accepted syntax versions:
510  *   01:02:03:04:05:06
511  *   01-02-03-04-05-06
512  */
513 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
514                     Error **errp)
515 {
516     DeviceState *dev = DEVICE(obj);
517     Property *prop = opaque;
518     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
519     char buffer[2 * 6 + 5 + 1];
520     char *p = buffer;
521 
522     snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
523              mac->a[0], mac->a[1], mac->a[2],
524              mac->a[3], mac->a[4], mac->a[5]);
525 
526     visit_type_str(v, name, &p, errp);
527 }
528 
529 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
530                     Error **errp)
531 {
532     DeviceState *dev = DEVICE(obj);
533     Property *prop = opaque;
534     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
535     Error *local_err = NULL;
536     int i, pos;
537     char *str, *p;
538 
539     if (dev->realized) {
540         qdev_prop_set_after_realize(dev, name, errp);
541         return;
542     }
543 
544     visit_type_str(v, name, &str, &local_err);
545     if (local_err) {
546         error_propagate(errp, local_err);
547         return;
548     }
549 
550     for (i = 0, pos = 0; i < 6; i++, pos += 3) {
551         if (!qemu_isxdigit(str[pos])) {
552             goto inval;
553         }
554         if (!qemu_isxdigit(str[pos+1])) {
555             goto inval;
556         }
557         if (i == 5) {
558             if (str[pos+2] != '\0') {
559                 goto inval;
560             }
561         } else {
562             if (str[pos+2] != ':' && str[pos+2] != '-') {
563                 goto inval;
564             }
565         }
566         mac->a[i] = strtol(str+pos, &p, 16);
567     }
568     g_free(str);
569     return;
570 
571 inval:
572     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
573     g_free(str);
574 }
575 
576 const PropertyInfo qdev_prop_macaddr = {
577     .name  = "str",
578     .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
579     .get   = get_mac,
580     .set   = set_mac,
581 };
582 
583 /* --- on/off/auto --- */
584 
585 const PropertyInfo qdev_prop_on_off_auto = {
586     .name = "OnOffAuto",
587     .description = "on/off/auto",
588     .enum_table = OnOffAuto_lookup,
589     .get = get_enum,
590     .set = set_enum,
591     .set_default_value = set_default_value_enum,
592 };
593 
594 /* --- lost tick policy --- */
595 
596 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
597 
598 const PropertyInfo qdev_prop_losttickpolicy = {
599     .name  = "LostTickPolicy",
600     .enum_table  = LostTickPolicy_lookup,
601     .get   = get_enum,
602     .set   = set_enum,
603     .set_default_value = set_default_value_enum,
604 };
605 
606 /* --- Block device error handling policy --- */
607 
608 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
609 
610 const PropertyInfo qdev_prop_blockdev_on_error = {
611     .name = "BlockdevOnError",
612     .description = "Error handling policy, "
613                    "report/ignore/enospc/stop/auto",
614     .enum_table = BlockdevOnError_lookup,
615     .get = get_enum,
616     .set = set_enum,
617     .set_default_value = set_default_value_enum,
618 };
619 
620 /* --- BIOS CHS translation */
621 
622 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
623 
624 const PropertyInfo qdev_prop_bios_chs_trans = {
625     .name = "BiosAtaTranslation",
626     .description = "Logical CHS translation algorithm, "
627                    "auto/none/lba/large/rechs",
628     .enum_table = BiosAtaTranslation_lookup,
629     .get = get_enum,
630     .set = set_enum,
631     .set_default_value = set_default_value_enum,
632 };
633 
634 /* --- FDC default drive types */
635 
636 const PropertyInfo qdev_prop_fdc_drive_type = {
637     .name = "FdcDriveType",
638     .description = "FDC drive type, "
639                    "144/288/120/none/auto",
640     .enum_table = FloppyDriveType_lookup,
641     .get = get_enum,
642     .set = set_enum,
643     .set_default_value = set_default_value_enum,
644 };
645 
646 /* --- pci address --- */
647 
648 /*
649  * bus-local address, i.e. "$slot" or "$slot.$fn"
650  */
651 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
652                           void *opaque, Error **errp)
653 {
654     DeviceState *dev = DEVICE(obj);
655     Property *prop = opaque;
656     int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
657     unsigned int slot, fn, n;
658     Error *local_err = NULL;
659     char *str;
660 
661     if (dev->realized) {
662         qdev_prop_set_after_realize(dev, name, errp);
663         return;
664     }
665 
666     visit_type_str(v, name, &str, &local_err);
667     if (local_err) {
668         error_free(local_err);
669         local_err = NULL;
670         visit_type_int32(v, name, &value, &local_err);
671         if (local_err) {
672             error_propagate(errp, local_err);
673         } else if (value < -1 || value > 255) {
674             error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
675                        name ? name : "null", "pci_devfn");
676         } else {
677             *ptr = value;
678         }
679         return;
680     }
681 
682     if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
683         fn = 0;
684         if (sscanf(str, "%x%n", &slot, &n) != 1) {
685             goto invalid;
686         }
687     }
688     if (str[n] != '\0' || fn > 7 || slot > 31) {
689         goto invalid;
690     }
691     *ptr = slot << 3 | fn;
692     g_free(str);
693     return;
694 
695 invalid:
696     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
697     g_free(str);
698 }
699 
700 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
701                            size_t len)
702 {
703     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
704 
705     if (*ptr == -1) {
706         return snprintf(dest, len, "<unset>");
707     } else {
708         return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
709     }
710 }
711 
712 const PropertyInfo qdev_prop_pci_devfn = {
713     .name  = "int32",
714     .description = "Slot and optional function number, example: 06.0 or 06",
715     .print = print_pci_devfn,
716     .get   = get_int32,
717     .set   = set_pci_devfn,
718     .set_default_value = set_default_value_int,
719 };
720 
721 /* --- blocksize --- */
722 
723 static void set_blocksize(Object *obj, Visitor *v, const char *name,
724                           void *opaque, Error **errp)
725 {
726     DeviceState *dev = DEVICE(obj);
727     Property *prop = opaque;
728     uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
729     Error *local_err = NULL;
730     const int64_t min = 512;
731     const int64_t max = 32768;
732 
733     if (dev->realized) {
734         qdev_prop_set_after_realize(dev, name, errp);
735         return;
736     }
737 
738     visit_type_uint16(v, name, &value, &local_err);
739     if (local_err) {
740         error_propagate(errp, local_err);
741         return;
742     }
743     /* value of 0 means "unset" */
744     if (value && (value < min || value > max)) {
745         error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
746                    dev->id ? : "", name, (int64_t)value, min, max);
747         return;
748     }
749 
750     /* We rely on power-of-2 blocksizes for bitmasks */
751     if ((value & (value - 1)) != 0) {
752         error_setg(errp,
753                   "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
754                   dev->id ?: "", name, (int64_t)value);
755         return;
756     }
757 
758     *ptr = value;
759 }
760 
761 const PropertyInfo qdev_prop_blocksize = {
762     .name  = "uint16",
763     .description = "A power of two between 512 and 32768",
764     .get   = get_uint16,
765     .set   = set_blocksize,
766     .set_default_value = set_default_value_uint,
767 };
768 
769 /* --- pci host address --- */
770 
771 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
772                                  void *opaque, Error **errp)
773 {
774     DeviceState *dev = DEVICE(obj);
775     Property *prop = opaque;
776     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
777     char buffer[] = "ffff:ff:ff.f";
778     char *p = buffer;
779     int rc = 0;
780 
781     /*
782      * Catch "invalid" device reference from vfio-pci and allow the
783      * default buffer representing the non-existent device to be used.
784      */
785     if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
786         rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
787                       addr->domain, addr->bus, addr->slot, addr->function);
788         assert(rc == sizeof(buffer) - 1);
789     }
790 
791     visit_type_str(v, name, &p, errp);
792 }
793 
794 /*
795  * Parse [<domain>:]<bus>:<slot>.<func>
796  *   if <domain> is not supplied, it's assumed to be 0.
797  */
798 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
799                                  void *opaque, Error **errp)
800 {
801     DeviceState *dev = DEVICE(obj);
802     Property *prop = opaque;
803     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
804     Error *local_err = NULL;
805     char *str, *p;
806     char *e;
807     unsigned long val;
808     unsigned long dom = 0, bus = 0;
809     unsigned int slot = 0, func = 0;
810 
811     if (dev->realized) {
812         qdev_prop_set_after_realize(dev, name, errp);
813         return;
814     }
815 
816     visit_type_str(v, name, &str, &local_err);
817     if (local_err) {
818         error_propagate(errp, local_err);
819         return;
820     }
821 
822     p = str;
823     val = strtoul(p, &e, 16);
824     if (e == p || *e != ':') {
825         goto inval;
826     }
827     bus = val;
828 
829     p = e + 1;
830     val = strtoul(p, &e, 16);
831     if (e == p) {
832         goto inval;
833     }
834     if (*e == ':') {
835         dom = bus;
836         bus = val;
837         p = e + 1;
838         val = strtoul(p, &e, 16);
839         if (e == p) {
840             goto inval;
841         }
842     }
843     slot = val;
844 
845     if (*e != '.') {
846         goto inval;
847     }
848     p = e + 1;
849     val = strtoul(p, &e, 10);
850     if (e == p) {
851         goto inval;
852     }
853     func = val;
854 
855     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
856         goto inval;
857     }
858 
859     if (*e) {
860         goto inval;
861     }
862 
863     addr->domain = dom;
864     addr->bus = bus;
865     addr->slot = slot;
866     addr->function = func;
867 
868     g_free(str);
869     return;
870 
871 inval:
872     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
873     g_free(str);
874 }
875 
876 const PropertyInfo qdev_prop_pci_host_devaddr = {
877     .name = "str",
878     .description = "Address (bus/device/function) of "
879                    "the host device, example: 04:10.0",
880     .get = get_pci_host_devaddr,
881     .set = set_pci_host_devaddr,
882 };
883 
884 /* --- support for array properties --- */
885 
886 /* Used as an opaque for the object properties we add for each
887  * array element. Note that the struct Property must be first
888  * in the struct so that a pointer to this works as the opaque
889  * for the underlying element's property hooks as well as for
890  * our own release callback.
891  */
892 typedef struct {
893     struct Property prop;
894     char *propname;
895     ObjectPropertyRelease *release;
896 } ArrayElementProperty;
897 
898 /* object property release callback for array element properties:
899  * we call the underlying element's property release hook, and
900  * then free the memory we allocated when we added the property.
901  */
902 static void array_element_release(Object *obj, const char *name, void *opaque)
903 {
904     ArrayElementProperty *p = opaque;
905     if (p->release) {
906         p->release(obj, name, opaque);
907     }
908     g_free(p->propname);
909     g_free(p);
910 }
911 
912 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
913                               void *opaque, Error **errp)
914 {
915     /* Setter for the property which defines the length of a
916      * variable-sized property array. As well as actually setting the
917      * array-length field in the device struct, we have to create the
918      * array itself and dynamically add the corresponding properties.
919      */
920     DeviceState *dev = DEVICE(obj);
921     Property *prop = opaque;
922     uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
923     void **arrayptr = (void *)dev + prop->arrayoffset;
924     Error *local_err = NULL;
925     void *eltptr;
926     const char *arrayname;
927     int i;
928 
929     if (dev->realized) {
930         qdev_prop_set_after_realize(dev, name, errp);
931         return;
932     }
933     if (*alenptr) {
934         error_setg(errp, "array size property %s may not be set more than once",
935                    name);
936         return;
937     }
938     visit_type_uint32(v, name, alenptr, &local_err);
939     if (local_err) {
940         error_propagate(errp, local_err);
941         return;
942     }
943     if (!*alenptr) {
944         return;
945     }
946 
947     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
948      * strip it off so we can get the name of the array itself.
949      */
950     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
951                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
952     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
953 
954     /* Note that it is the responsibility of the individual device's deinit
955      * to free the array proper.
956      */
957     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
958     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
959         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
960         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
961         arrayprop->release = prop->arrayinfo->release;
962         arrayprop->propname = propname;
963         arrayprop->prop.info = prop->arrayinfo;
964         arrayprop->prop.name = propname;
965         /* This ugly piece of pointer arithmetic sets up the offset so
966          * that when the underlying get/set hooks call qdev_get_prop_ptr
967          * they get the right answer despite the array element not actually
968          * being inside the device struct.
969          */
970         arrayprop->prop.offset = eltptr - (void *)dev;
971         assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
972         object_property_add(obj, propname,
973                             arrayprop->prop.info->name,
974                             arrayprop->prop.info->get,
975                             arrayprop->prop.info->set,
976                             array_element_release,
977                             arrayprop, &local_err);
978         if (local_err) {
979             error_propagate(errp, local_err);
980             return;
981         }
982     }
983 }
984 
985 const PropertyInfo qdev_prop_arraylen = {
986     .name = "uint32",
987     .get = get_uint32,
988     .set = set_prop_arraylen,
989     .set_default_value = set_default_value_uint,
990 };
991 
992 /* --- public helpers --- */
993 
994 static Property *qdev_prop_walk(Property *props, const char *name)
995 {
996     if (!props) {
997         return NULL;
998     }
999     while (props->name) {
1000         if (strcmp(props->name, name) == 0) {
1001             return props;
1002         }
1003         props++;
1004     }
1005     return NULL;
1006 }
1007 
1008 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1009 {
1010     ObjectClass *class;
1011     Property *prop;
1012 
1013     /* device properties */
1014     class = object_get_class(OBJECT(dev));
1015     do {
1016         prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
1017         if (prop) {
1018             return prop;
1019         }
1020         class = object_class_get_parent(class);
1021     } while (class != object_class_by_name(TYPE_DEVICE));
1022 
1023     return NULL;
1024 }
1025 
1026 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1027                                     Property *prop, const char *value)
1028 {
1029     switch (ret) {
1030     case -EEXIST:
1031         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
1032                   object_get_typename(OBJECT(dev)), prop->name, value);
1033         break;
1034     default:
1035     case -EINVAL:
1036         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
1037                    object_get_typename(OBJECT(dev)), prop->name, value);
1038         break;
1039     case -ENOENT:
1040         error_setg(errp, "Property '%s.%s' can't find value '%s'",
1041                   object_get_typename(OBJECT(dev)), prop->name, value);
1042         break;
1043     case 0:
1044         break;
1045     }
1046 }
1047 
1048 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1049 {
1050     object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1051 }
1052 
1053 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1054 {
1055     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1056 }
1057 
1058 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1059 {
1060     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1061 }
1062 
1063 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1064 {
1065     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1066 }
1067 
1068 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1069 {
1070     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1071 }
1072 
1073 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1074 {
1075     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1076 }
1077 
1078 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1079 {
1080     object_property_set_str(OBJECT(dev), value, name, &error_abort);
1081 }
1082 
1083 void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
1084                            const uint8_t *value)
1085 {
1086     char str[2 * 6 + 5 + 1];
1087     snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1088              value[0], value[1], value[2], value[3], value[4], value[5]);
1089 
1090     object_property_set_str(OBJECT(dev), str, name, &error_abort);
1091 }
1092 
1093 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1094 {
1095     Property *prop;
1096 
1097     prop = qdev_prop_find(dev, name);
1098     object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1099                             name, &error_abort);
1100 }
1101 
1102 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1103 {
1104     Property *prop;
1105     void **ptr;
1106 
1107     prop = qdev_prop_find(dev, name);
1108     assert(prop && prop->info == &qdev_prop_ptr);
1109     ptr = qdev_get_prop_ptr(dev, prop);
1110     *ptr = value;
1111 }
1112 
1113 static GList *global_props;
1114 
1115 void qdev_prop_register_global(GlobalProperty *prop)
1116 {
1117     global_props = g_list_append(global_props, prop);
1118 }
1119 
1120 void register_compat_prop(const char *driver,
1121                           const char *property,
1122                           const char *value)
1123 {
1124     GlobalProperty *p = g_new0(GlobalProperty, 1);
1125 
1126     /* Any compat_props must never cause error */
1127     p->errp = &error_abort;
1128     p->driver = driver;
1129     p->property = property;
1130     p->value = value;
1131     qdev_prop_register_global(p);
1132 }
1133 
1134 void register_compat_props_array(GlobalProperty *prop)
1135 {
1136     for (; prop && prop->driver; prop++) {
1137         register_compat_prop(prop->driver, prop->property, prop->value);
1138     }
1139 }
1140 
1141 void qdev_prop_register_global_list(GlobalProperty *props)
1142 {
1143     int i;
1144 
1145     for (i = 0; props[i].driver != NULL; i++) {
1146         qdev_prop_register_global(props+i);
1147     }
1148 }
1149 
1150 int qdev_prop_check_globals(void)
1151 {
1152     GList *l;
1153     int ret = 0;
1154 
1155     for (l = global_props; l; l = l->next) {
1156         GlobalProperty *prop = l->data;
1157         ObjectClass *oc;
1158         DeviceClass *dc;
1159         if (prop->used) {
1160             continue;
1161         }
1162         if (!prop->user_provided) {
1163             continue;
1164         }
1165         oc = object_class_by_name(prop->driver);
1166         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1167         if (!oc) {
1168             warn_report("global %s.%s has invalid class name",
1169                         prop->driver, prop->property);
1170             ret = 1;
1171             continue;
1172         }
1173         dc = DEVICE_CLASS(oc);
1174         if (!dc->hotpluggable && !prop->used) {
1175             warn_report("global %s.%s=%s not used",
1176                         prop->driver, prop->property, prop->value);
1177             ret = 1;
1178             continue;
1179         }
1180     }
1181     return ret;
1182 }
1183 
1184 void qdev_prop_set_globals(DeviceState *dev)
1185 {
1186     GList *l;
1187 
1188     for (l = global_props; l; l = l->next) {
1189         GlobalProperty *prop = l->data;
1190         Error *err = NULL;
1191 
1192         if (object_dynamic_cast(OBJECT(dev), prop->driver) == NULL) {
1193             continue;
1194         }
1195         prop->used = true;
1196         object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
1197         if (err != NULL) {
1198             error_prepend(&err, "can't apply global %s.%s=%s: ",
1199                           prop->driver, prop->property, prop->value);
1200             if (!dev->hotplugged && prop->errp) {
1201                 error_propagate(prop->errp, err);
1202             } else {
1203                 assert(prop->user_provided);
1204                 warn_report_err(err);
1205             }
1206         }
1207     }
1208 }
1209 
1210 /* --- 64bit unsigned int 'size' type --- */
1211 
1212 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1213                      Error **errp)
1214 {
1215     DeviceState *dev = DEVICE(obj);
1216     Property *prop = opaque;
1217     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1218 
1219     visit_type_size(v, name, ptr, errp);
1220 }
1221 
1222 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1223                      Error **errp)
1224 {
1225     DeviceState *dev = DEVICE(obj);
1226     Property *prop = opaque;
1227     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1228 
1229     visit_type_size(v, name, ptr, errp);
1230 }
1231 
1232 const PropertyInfo qdev_prop_size = {
1233     .name  = "size",
1234     .get = get_size,
1235     .set = set_size,
1236     .set_default_value = set_default_value_uint,
1237 };
1238 
1239 /* --- object link property --- */
1240 
1241 static void create_link_property(Object *obj, Property *prop, Error **errp)
1242 {
1243     Object **child = qdev_get_prop_ptr(DEVICE(obj), prop);
1244 
1245     object_property_add_link(obj, prop->name, prop->link_type,
1246                              child,
1247                              qdev_prop_allow_set_link_before_realize,
1248                              OBJ_PROP_LINK_UNREF_ON_RELEASE,
1249                              errp);
1250 }
1251 
1252 const PropertyInfo qdev_prop_link = {
1253     .name = "link",
1254     .create = create_link_property,
1255 };
1256