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