xref: /openbmc/qemu/hw/core/qdev-properties.c (revision 856dfd8a)
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/ctype.h"
8 #include "qemu/error-report.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 GPtrArray *global_props(void)
1178 {
1179     static GPtrArray *gp;
1180 
1181     if (!gp) {
1182         gp = g_ptr_array_new();
1183     }
1184 
1185     return gp;
1186 }
1187 
1188 void qdev_prop_register_global(GlobalProperty *prop)
1189 {
1190     g_ptr_array_add(global_props(), prop);
1191 }
1192 
1193 int qdev_prop_check_globals(void)
1194 {
1195     int i, ret = 0;
1196 
1197     for (i = 0; i < global_props()->len; i++) {
1198         GlobalProperty *prop;
1199         ObjectClass *oc;
1200         DeviceClass *dc;
1201 
1202         prop = g_ptr_array_index(global_props(), i);
1203         if (prop->used) {
1204             continue;
1205         }
1206         oc = object_class_by_name(prop->driver);
1207         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1208         if (!oc) {
1209             warn_report("global %s.%s has invalid class name",
1210                         prop->driver, prop->property);
1211             ret = 1;
1212             continue;
1213         }
1214         dc = DEVICE_CLASS(oc);
1215         if (!dc->hotpluggable && !prop->used) {
1216             warn_report("global %s.%s=%s not used",
1217                         prop->driver, prop->property, prop->value);
1218             ret = 1;
1219             continue;
1220         }
1221     }
1222     return ret;
1223 }
1224 
1225 void qdev_prop_set_globals(DeviceState *dev)
1226 {
1227     object_apply_global_props(OBJECT(dev), global_props(),
1228                               dev->hotplugged ? NULL : &error_fatal);
1229 }
1230 
1231 /* --- 64bit unsigned int 'size' type --- */
1232 
1233 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1234                      Error **errp)
1235 {
1236     DeviceState *dev = DEVICE(obj);
1237     Property *prop = opaque;
1238     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1239 
1240     visit_type_size(v, name, ptr, errp);
1241 }
1242 
1243 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1244                      Error **errp)
1245 {
1246     DeviceState *dev = DEVICE(obj);
1247     Property *prop = opaque;
1248     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1249 
1250     visit_type_size(v, name, ptr, errp);
1251 }
1252 
1253 const PropertyInfo qdev_prop_size = {
1254     .name  = "size",
1255     .get = get_size,
1256     .set = set_size,
1257     .set_default_value = set_default_value_uint,
1258 };
1259 
1260 /* --- object link property --- */
1261 
1262 static void create_link_property(Object *obj, Property *prop, Error **errp)
1263 {
1264     Object **child = qdev_get_prop_ptr(DEVICE(obj), prop);
1265 
1266     object_property_add_link(obj, prop->name, prop->link_type,
1267                              child,
1268                              qdev_prop_allow_set_link_before_realize,
1269                              OBJ_PROP_LINK_STRONG,
1270                              errp);
1271 }
1272 
1273 const PropertyInfo qdev_prop_link = {
1274     .name = "link",
1275     .create = create_link_property,
1276 };
1277 
1278 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */
1279 
1280 const PropertyInfo qdev_prop_off_auto_pcibar = {
1281     .name = "OffAutoPCIBAR",
1282     .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
1283     .enum_table = &OffAutoPCIBAR_lookup,
1284     .get = get_enum,
1285     .set = set_enum,
1286     .set_default_value = set_default_value_enum,
1287 };
1288 
1289 /* --- PCIELinkSpeed 2_5/5/8/16 -- */
1290 
1291 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1292                                    void *opaque, Error **errp)
1293 {
1294     DeviceState *dev = DEVICE(obj);
1295     Property *prop = opaque;
1296     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1297     int speed;
1298 
1299     switch (*p) {
1300     case QEMU_PCI_EXP_LNK_2_5GT:
1301         speed = PCIE_LINK_SPEED_2_5;
1302         break;
1303     case QEMU_PCI_EXP_LNK_5GT:
1304         speed = PCIE_LINK_SPEED_5;
1305         break;
1306     case QEMU_PCI_EXP_LNK_8GT:
1307         speed = PCIE_LINK_SPEED_8;
1308         break;
1309     case QEMU_PCI_EXP_LNK_16GT:
1310         speed = PCIE_LINK_SPEED_16;
1311         break;
1312     default:
1313         /* Unreachable */
1314         abort();
1315     }
1316 
1317     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp);
1318 }
1319 
1320 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1321                                    void *opaque, Error **errp)
1322 {
1323     DeviceState *dev = DEVICE(obj);
1324     Property *prop = opaque;
1325     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1326     int speed;
1327     Error *local_err = NULL;
1328 
1329     if (dev->realized) {
1330         qdev_prop_set_after_realize(dev, name, errp);
1331         return;
1332     }
1333 
1334     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, &local_err);
1335     if (local_err) {
1336         error_propagate(errp, local_err);
1337         return;
1338     }
1339 
1340     switch (speed) {
1341     case PCIE_LINK_SPEED_2_5:
1342         *p = QEMU_PCI_EXP_LNK_2_5GT;
1343         break;
1344     case PCIE_LINK_SPEED_5:
1345         *p = QEMU_PCI_EXP_LNK_5GT;
1346         break;
1347     case PCIE_LINK_SPEED_8:
1348         *p = QEMU_PCI_EXP_LNK_8GT;
1349         break;
1350     case PCIE_LINK_SPEED_16:
1351         *p = QEMU_PCI_EXP_LNK_16GT;
1352         break;
1353     default:
1354         /* Unreachable */
1355         abort();
1356     }
1357 }
1358 
1359 const PropertyInfo qdev_prop_pcie_link_speed = {
1360     .name = "PCIELinkSpeed",
1361     .description = "2_5/5/8/16",
1362     .enum_table = &PCIELinkSpeed_lookup,
1363     .get = get_prop_pcielinkspeed,
1364     .set = set_prop_pcielinkspeed,
1365     .set_default_value = set_default_value_enum,
1366 };
1367 
1368 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
1369 
1370 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1371                                    void *opaque, Error **errp)
1372 {
1373     DeviceState *dev = DEVICE(obj);
1374     Property *prop = opaque;
1375     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1376     int width;
1377 
1378     switch (*p) {
1379     case QEMU_PCI_EXP_LNK_X1:
1380         width = PCIE_LINK_WIDTH_1;
1381         break;
1382     case QEMU_PCI_EXP_LNK_X2:
1383         width = PCIE_LINK_WIDTH_2;
1384         break;
1385     case QEMU_PCI_EXP_LNK_X4:
1386         width = PCIE_LINK_WIDTH_4;
1387         break;
1388     case QEMU_PCI_EXP_LNK_X8:
1389         width = PCIE_LINK_WIDTH_8;
1390         break;
1391     case QEMU_PCI_EXP_LNK_X12:
1392         width = PCIE_LINK_WIDTH_12;
1393         break;
1394     case QEMU_PCI_EXP_LNK_X16:
1395         width = PCIE_LINK_WIDTH_16;
1396         break;
1397     case QEMU_PCI_EXP_LNK_X32:
1398         width = PCIE_LINK_WIDTH_32;
1399         break;
1400     default:
1401         /* Unreachable */
1402         abort();
1403     }
1404 
1405     visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp);
1406 }
1407 
1408 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1409                                    void *opaque, Error **errp)
1410 {
1411     DeviceState *dev = DEVICE(obj);
1412     Property *prop = opaque;
1413     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1414     int width;
1415     Error *local_err = NULL;
1416 
1417     if (dev->realized) {
1418         qdev_prop_set_after_realize(dev, name, errp);
1419         return;
1420     }
1421 
1422     visit_type_enum(v, prop->name, &width, prop->info->enum_table, &local_err);
1423     if (local_err) {
1424         error_propagate(errp, local_err);
1425         return;
1426     }
1427 
1428     switch (width) {
1429     case PCIE_LINK_WIDTH_1:
1430         *p = QEMU_PCI_EXP_LNK_X1;
1431         break;
1432     case PCIE_LINK_WIDTH_2:
1433         *p = QEMU_PCI_EXP_LNK_X2;
1434         break;
1435     case PCIE_LINK_WIDTH_4:
1436         *p = QEMU_PCI_EXP_LNK_X4;
1437         break;
1438     case PCIE_LINK_WIDTH_8:
1439         *p = QEMU_PCI_EXP_LNK_X8;
1440         break;
1441     case PCIE_LINK_WIDTH_12:
1442         *p = QEMU_PCI_EXP_LNK_X12;
1443         break;
1444     case PCIE_LINK_WIDTH_16:
1445         *p = QEMU_PCI_EXP_LNK_X16;
1446         break;
1447     case PCIE_LINK_WIDTH_32:
1448         *p = QEMU_PCI_EXP_LNK_X32;
1449         break;
1450     default:
1451         /* Unreachable */
1452         abort();
1453     }
1454 }
1455 
1456 const PropertyInfo qdev_prop_pcie_link_width = {
1457     .name = "PCIELinkWidth",
1458     .description = "1/2/4/8/12/16/32",
1459     .enum_table = &PCIELinkWidth_lookup,
1460     .get = get_prop_pcielinkwidth,
1461     .set = set_prop_pcielinkwidth,
1462     .set_default_value = set_default_value_enum,
1463 };
1464