xref: /openbmc/qemu/hw/core/qdev-properties.c (revision 979a8902)
1 #include "qemu/osdep.h"
2 #include "net/net.h"
3 #include "hw/qdev-properties.h"
4 #include "qapi/error.h"
5 #include "hw/pci/pci.h"
6 #include "qapi/qapi-types-block.h"
7 #include "qapi/qapi-types-misc.h"
8 #include "qapi/qmp/qerror.h"
9 #include "qemu/ctype.h"
10 #include "qemu/error-report.h"
11 #include "hw/block/block.h"
12 #include "net/hub.h"
13 #include "qapi/visitor.h"
14 #include "chardev/char.h"
15 #include "qemu/uuid.h"
16 
17 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
18                                   Error **errp)
19 {
20     if (dev->id) {
21         error_setg(errp, "Attempt to set property '%s' on device '%s' "
22                    "(type '%s') after it was realized", name, dev->id,
23                    object_get_typename(OBJECT(dev)));
24     } else {
25         error_setg(errp, "Attempt to set property '%s' on anonymous device "
26                    "(type '%s') after it was realized", name,
27                    object_get_typename(OBJECT(dev)));
28     }
29 }
30 
31 void qdev_prop_allow_set_link_before_realize(const Object *obj,
32                                              const char *name,
33                                              Object *val, Error **errp)
34 {
35     DeviceState *dev = DEVICE(obj);
36 
37     if (dev->realized) {
38         error_setg(errp, "Attempt to set link property '%s' on device '%s' "
39                    "(type '%s') after it was realized",
40                    name, dev->id, object_get_typename(obj));
41     }
42 }
43 
44 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
45 {
46     void *ptr = dev;
47     ptr += prop->offset;
48     return ptr;
49 }
50 
51 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
52                      Error **errp)
53 {
54     DeviceState *dev = DEVICE(obj);
55     Property *prop = opaque;
56     int *ptr = qdev_get_prop_ptr(dev, prop);
57 
58     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
59 }
60 
61 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
62                      Error **errp)
63 {
64     DeviceState *dev = DEVICE(obj);
65     Property *prop = opaque;
66     int *ptr = qdev_get_prop_ptr(dev, prop);
67 
68     if (dev->realized) {
69         qdev_prop_set_after_realize(dev, name, errp);
70         return;
71     }
72 
73     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
74 }
75 
76 static void set_default_value_enum(ObjectProperty *op, const Property *prop)
77 {
78     object_property_set_default_str(op,
79         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
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(ObjectProperty *op, const Property *prop)
134 {
135     object_property_set_default_bool(op, prop->defval.u);
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(ObjectProperty *op, const Property *prop)
267 {
268     object_property_set_default_int(op, prop->defval.i);
269 }
270 
271 static void set_default_value_uint(ObjectProperty *op, const Property *prop)
272 {
273     object_property_set_default_uint(op, prop->defval.u);
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 /* --- mac address --- */
503 
504 /*
505  * accepted syntax versions:
506  *   01:02:03:04:05:06
507  *   01-02-03-04-05-06
508  */
509 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
510                     Error **errp)
511 {
512     DeviceState *dev = DEVICE(obj);
513     Property *prop = opaque;
514     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
515     char buffer[2 * 6 + 5 + 1];
516     char *p = buffer;
517 
518     snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
519              mac->a[0], mac->a[1], mac->a[2],
520              mac->a[3], mac->a[4], mac->a[5]);
521 
522     visit_type_str(v, name, &p, errp);
523 }
524 
525 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
526                     Error **errp)
527 {
528     DeviceState *dev = DEVICE(obj);
529     Property *prop = opaque;
530     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
531     Error *local_err = NULL;
532     int i, pos;
533     char *str, *p;
534 
535     if (dev->realized) {
536         qdev_prop_set_after_realize(dev, name, errp);
537         return;
538     }
539 
540     visit_type_str(v, name, &str, &local_err);
541     if (local_err) {
542         error_propagate(errp, local_err);
543         return;
544     }
545 
546     for (i = 0, pos = 0; i < 6; i++, pos += 3) {
547         if (!qemu_isxdigit(str[pos])) {
548             goto inval;
549         }
550         if (!qemu_isxdigit(str[pos+1])) {
551             goto inval;
552         }
553         if (i == 5) {
554             if (str[pos+2] != '\0') {
555                 goto inval;
556             }
557         } else {
558             if (str[pos+2] != ':' && str[pos+2] != '-') {
559                 goto inval;
560             }
561         }
562         mac->a[i] = strtol(str+pos, &p, 16);
563     }
564     g_free(str);
565     return;
566 
567 inval:
568     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
569     g_free(str);
570 }
571 
572 const PropertyInfo qdev_prop_macaddr = {
573     .name  = "str",
574     .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
575     .get   = get_mac,
576     .set   = set_mac,
577 };
578 
579 /* --- on/off/auto --- */
580 
581 const PropertyInfo qdev_prop_on_off_auto = {
582     .name = "OnOffAuto",
583     .description = "on/off/auto",
584     .enum_table = &OnOffAuto_lookup,
585     .get = get_enum,
586     .set = set_enum,
587     .set_default_value = set_default_value_enum,
588 };
589 
590 /* --- lost tick policy --- */
591 
592 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
593 
594 const PropertyInfo qdev_prop_losttickpolicy = {
595     .name  = "LostTickPolicy",
596     .enum_table  = &LostTickPolicy_lookup,
597     .get   = get_enum,
598     .set   = set_enum,
599     .set_default_value = set_default_value_enum,
600 };
601 
602 /* --- Block device error handling policy --- */
603 
604 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
605 
606 const PropertyInfo qdev_prop_blockdev_on_error = {
607     .name = "BlockdevOnError",
608     .description = "Error handling policy, "
609                    "report/ignore/enospc/stop/auto",
610     .enum_table = &BlockdevOnError_lookup,
611     .get = get_enum,
612     .set = set_enum,
613     .set_default_value = set_default_value_enum,
614 };
615 
616 /* --- BIOS CHS translation */
617 
618 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
619 
620 const PropertyInfo qdev_prop_bios_chs_trans = {
621     .name = "BiosAtaTranslation",
622     .description = "Logical CHS translation algorithm, "
623                    "auto/none/lba/large/rechs",
624     .enum_table = &BiosAtaTranslation_lookup,
625     .get = get_enum,
626     .set = set_enum,
627     .set_default_value = set_default_value_enum,
628 };
629 
630 /* --- FDC default drive types */
631 
632 const PropertyInfo qdev_prop_fdc_drive_type = {
633     .name = "FdcDriveType",
634     .description = "FDC drive type, "
635                    "144/288/120/none/auto",
636     .enum_table = &FloppyDriveType_lookup,
637     .get = get_enum,
638     .set = set_enum,
639     .set_default_value = set_default_value_enum,
640 };
641 
642 /* --- pci address --- */
643 
644 /*
645  * bus-local address, i.e. "$slot" or "$slot.$fn"
646  */
647 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
648                           void *opaque, Error **errp)
649 {
650     DeviceState *dev = DEVICE(obj);
651     Property *prop = opaque;
652     int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
653     unsigned int slot, fn, n;
654     Error *local_err = NULL;
655     char *str;
656 
657     if (dev->realized) {
658         qdev_prop_set_after_realize(dev, name, errp);
659         return;
660     }
661 
662     visit_type_str(v, name, &str, &local_err);
663     if (local_err) {
664         error_free(local_err);
665         local_err = NULL;
666         visit_type_int32(v, name, &value, &local_err);
667         if (local_err) {
668             error_propagate(errp, local_err);
669         } else if (value < -1 || value > 255) {
670             error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
671                        name ? name : "null", "pci_devfn");
672         } else {
673             *ptr = value;
674         }
675         return;
676     }
677 
678     if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
679         fn = 0;
680         if (sscanf(str, "%x%n", &slot, &n) != 1) {
681             goto invalid;
682         }
683     }
684     if (str[n] != '\0' || fn > 7 || slot > 31) {
685         goto invalid;
686     }
687     *ptr = slot << 3 | fn;
688     g_free(str);
689     return;
690 
691 invalid:
692     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
693     g_free(str);
694 }
695 
696 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
697                            size_t len)
698 {
699     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
700 
701     if (*ptr == -1) {
702         return snprintf(dest, len, "<unset>");
703     } else {
704         return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
705     }
706 }
707 
708 const PropertyInfo qdev_prop_pci_devfn = {
709     .name  = "int32",
710     .description = "Slot and optional function number, example: 06.0 or 06",
711     .print = print_pci_devfn,
712     .get   = get_int32,
713     .set   = set_pci_devfn,
714     .set_default_value = set_default_value_int,
715 };
716 
717 /* --- blocksize --- */
718 
719 static void set_blocksize(Object *obj, Visitor *v, const char *name,
720                           void *opaque, Error **errp)
721 {
722     DeviceState *dev = DEVICE(obj);
723     Property *prop = opaque;
724     uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
725     Error *local_err = NULL;
726     const int64_t min = 512;
727     const int64_t max = 32768;
728 
729     if (dev->realized) {
730         qdev_prop_set_after_realize(dev, name, errp);
731         return;
732     }
733 
734     visit_type_uint16(v, name, &value, &local_err);
735     if (local_err) {
736         error_propagate(errp, local_err);
737         return;
738     }
739     /* value of 0 means "unset" */
740     if (value && (value < min || value > max)) {
741         error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
742                    dev->id ? : "", name, (int64_t)value, min, max);
743         return;
744     }
745 
746     /* We rely on power-of-2 blocksizes for bitmasks */
747     if ((value & (value - 1)) != 0) {
748         error_setg(errp,
749                   "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
750                   dev->id ?: "", name, (int64_t)value);
751         return;
752     }
753 
754     *ptr = value;
755 }
756 
757 const PropertyInfo qdev_prop_blocksize = {
758     .name  = "uint16",
759     .description = "A power of two between 512 and 32768",
760     .get   = get_uint16,
761     .set   = set_blocksize,
762     .set_default_value = set_default_value_uint,
763 };
764 
765 /* --- pci host address --- */
766 
767 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
768                                  void *opaque, Error **errp)
769 {
770     DeviceState *dev = DEVICE(obj);
771     Property *prop = opaque;
772     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
773     char buffer[] = "ffff:ff:ff.f";
774     char *p = buffer;
775     int rc = 0;
776 
777     /*
778      * Catch "invalid" device reference from vfio-pci and allow the
779      * default buffer representing the non-existent device to be used.
780      */
781     if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
782         rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
783                       addr->domain, addr->bus, addr->slot, addr->function);
784         assert(rc == sizeof(buffer) - 1);
785     }
786 
787     visit_type_str(v, name, &p, errp);
788 }
789 
790 /*
791  * Parse [<domain>:]<bus>:<slot>.<func>
792  *   if <domain> is not supplied, it's assumed to be 0.
793  */
794 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
795                                  void *opaque, Error **errp)
796 {
797     DeviceState *dev = DEVICE(obj);
798     Property *prop = opaque;
799     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
800     Error *local_err = NULL;
801     char *str, *p;
802     char *e;
803     unsigned long val;
804     unsigned long dom = 0, bus = 0;
805     unsigned int slot = 0, func = 0;
806 
807     if (dev->realized) {
808         qdev_prop_set_after_realize(dev, name, errp);
809         return;
810     }
811 
812     visit_type_str(v, name, &str, &local_err);
813     if (local_err) {
814         error_propagate(errp, local_err);
815         return;
816     }
817 
818     p = str;
819     val = strtoul(p, &e, 16);
820     if (e == p || *e != ':') {
821         goto inval;
822     }
823     bus = val;
824 
825     p = e + 1;
826     val = strtoul(p, &e, 16);
827     if (e == p) {
828         goto inval;
829     }
830     if (*e == ':') {
831         dom = bus;
832         bus = val;
833         p = e + 1;
834         val = strtoul(p, &e, 16);
835         if (e == p) {
836             goto inval;
837         }
838     }
839     slot = val;
840 
841     if (*e != '.') {
842         goto inval;
843     }
844     p = e + 1;
845     val = strtoul(p, &e, 10);
846     if (e == p) {
847         goto inval;
848     }
849     func = val;
850 
851     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
852         goto inval;
853     }
854 
855     if (*e) {
856         goto inval;
857     }
858 
859     addr->domain = dom;
860     addr->bus = bus;
861     addr->slot = slot;
862     addr->function = func;
863 
864     g_free(str);
865     return;
866 
867 inval:
868     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
869     g_free(str);
870 }
871 
872 const PropertyInfo qdev_prop_pci_host_devaddr = {
873     .name = "str",
874     .description = "Address (bus/device/function) of "
875                    "the host device, example: 04:10.0",
876     .get = get_pci_host_devaddr,
877     .set = set_pci_host_devaddr,
878 };
879 
880 /* --- UUID --- */
881 
882 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
883                      Error **errp)
884 {
885     DeviceState *dev = DEVICE(obj);
886     Property *prop = opaque;
887     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
888     char buffer[UUID_FMT_LEN + 1];
889     char *p = buffer;
890 
891     qemu_uuid_unparse(uuid, buffer);
892 
893     visit_type_str(v, name, &p, errp);
894 }
895 
896 #define UUID_VALUE_AUTO        "auto"
897 
898 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
899                     Error **errp)
900 {
901     DeviceState *dev = DEVICE(obj);
902     Property *prop = opaque;
903     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
904     Error *local_err = NULL;
905     char *str;
906 
907     if (dev->realized) {
908         qdev_prop_set_after_realize(dev, name, errp);
909         return;
910     }
911 
912     visit_type_str(v, name, &str, &local_err);
913     if (local_err) {
914         error_propagate(errp, local_err);
915         return;
916     }
917 
918     if (!strcmp(str, UUID_VALUE_AUTO)) {
919         qemu_uuid_generate(uuid);
920     } else if (qemu_uuid_parse(str, uuid) < 0) {
921         error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
922     }
923     g_free(str);
924 }
925 
926 static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
927 {
928     object_property_set_default_str(op, UUID_VALUE_AUTO);
929 }
930 
931 const PropertyInfo qdev_prop_uuid = {
932     .name  = "str",
933     .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
934         "\" for random value (default)",
935     .get   = get_uuid,
936     .set   = set_uuid,
937     .set_default_value = set_default_uuid_auto,
938 };
939 
940 /* --- support for array properties --- */
941 
942 /* Used as an opaque for the object properties we add for each
943  * array element. Note that the struct Property must be first
944  * in the struct so that a pointer to this works as the opaque
945  * for the underlying element's property hooks as well as for
946  * our own release callback.
947  */
948 typedef struct {
949     struct Property prop;
950     char *propname;
951     ObjectPropertyRelease *release;
952 } ArrayElementProperty;
953 
954 /* object property release callback for array element properties:
955  * we call the underlying element's property release hook, and
956  * then free the memory we allocated when we added the property.
957  */
958 static void array_element_release(Object *obj, const char *name, void *opaque)
959 {
960     ArrayElementProperty *p = opaque;
961     if (p->release) {
962         p->release(obj, name, opaque);
963     }
964     g_free(p->propname);
965     g_free(p);
966 }
967 
968 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
969                               void *opaque, Error **errp)
970 {
971     /* Setter for the property which defines the length of a
972      * variable-sized property array. As well as actually setting the
973      * array-length field in the device struct, we have to create the
974      * array itself and dynamically add the corresponding properties.
975      */
976     DeviceState *dev = DEVICE(obj);
977     Property *prop = opaque;
978     uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
979     void **arrayptr = (void *)dev + prop->arrayoffset;
980     Error *local_err = NULL;
981     void *eltptr;
982     const char *arrayname;
983     int i;
984 
985     if (dev->realized) {
986         qdev_prop_set_after_realize(dev, name, errp);
987         return;
988     }
989     if (*alenptr) {
990         error_setg(errp, "array size property %s may not be set more than once",
991                    name);
992         return;
993     }
994     visit_type_uint32(v, name, alenptr, &local_err);
995     if (local_err) {
996         error_propagate(errp, local_err);
997         return;
998     }
999     if (!*alenptr) {
1000         return;
1001     }
1002 
1003     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
1004      * strip it off so we can get the name of the array itself.
1005      */
1006     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
1007                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
1008     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
1009 
1010     /* Note that it is the responsibility of the individual device's deinit
1011      * to free the array proper.
1012      */
1013     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
1014     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
1015         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
1016         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
1017         arrayprop->release = prop->arrayinfo->release;
1018         arrayprop->propname = propname;
1019         arrayprop->prop.info = prop->arrayinfo;
1020         arrayprop->prop.name = propname;
1021         /* This ugly piece of pointer arithmetic sets up the offset so
1022          * that when the underlying get/set hooks call qdev_get_prop_ptr
1023          * they get the right answer despite the array element not actually
1024          * being inside the device struct.
1025          */
1026         arrayprop->prop.offset = eltptr - (void *)dev;
1027         assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
1028         object_property_add(obj, propname,
1029                             arrayprop->prop.info->name,
1030                             arrayprop->prop.info->get,
1031                             arrayprop->prop.info->set,
1032                             array_element_release,
1033                             arrayprop, &local_err);
1034         if (local_err) {
1035             error_propagate(errp, local_err);
1036             return;
1037         }
1038     }
1039 }
1040 
1041 const PropertyInfo qdev_prop_arraylen = {
1042     .name = "uint32",
1043     .get = get_uint32,
1044     .set = set_prop_arraylen,
1045     .set_default_value = set_default_value_uint,
1046 };
1047 
1048 /* --- public helpers --- */
1049 
1050 static Property *qdev_prop_walk(Property *props, const char *name)
1051 {
1052     if (!props) {
1053         return NULL;
1054     }
1055     while (props->name) {
1056         if (strcmp(props->name, name) == 0) {
1057             return props;
1058         }
1059         props++;
1060     }
1061     return NULL;
1062 }
1063 
1064 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1065 {
1066     ObjectClass *class;
1067     Property *prop;
1068 
1069     /* device properties */
1070     class = object_get_class(OBJECT(dev));
1071     do {
1072         prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
1073         if (prop) {
1074             return prop;
1075         }
1076         class = object_class_get_parent(class);
1077     } while (class != object_class_by_name(TYPE_DEVICE));
1078 
1079     return NULL;
1080 }
1081 
1082 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1083                                     Property *prop, const char *value)
1084 {
1085     switch (ret) {
1086     case -EEXIST:
1087         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
1088                   object_get_typename(OBJECT(dev)), prop->name, value);
1089         break;
1090     default:
1091     case -EINVAL:
1092         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
1093                    object_get_typename(OBJECT(dev)), prop->name, value);
1094         break;
1095     case -ENOENT:
1096         error_setg(errp, "Property '%s.%s' can't find value '%s'",
1097                   object_get_typename(OBJECT(dev)), prop->name, value);
1098         break;
1099     case 0:
1100         break;
1101     }
1102 }
1103 
1104 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1105 {
1106     object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1107 }
1108 
1109 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1110 {
1111     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1112 }
1113 
1114 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1115 {
1116     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1117 }
1118 
1119 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1120 {
1121     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1122 }
1123 
1124 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1125 {
1126     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1127 }
1128 
1129 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1130 {
1131     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1132 }
1133 
1134 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1135 {
1136     object_property_set_str(OBJECT(dev), value, name, &error_abort);
1137 }
1138 
1139 void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
1140                            const uint8_t *value)
1141 {
1142     char str[2 * 6 + 5 + 1];
1143     snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1144              value[0], value[1], value[2], value[3], value[4], value[5]);
1145 
1146     object_property_set_str(OBJECT(dev), str, name, &error_abort);
1147 }
1148 
1149 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1150 {
1151     Property *prop;
1152 
1153     prop = qdev_prop_find(dev, name);
1154     object_property_set_str(OBJECT(dev),
1155                             qapi_enum_lookup(prop->info->enum_table, value),
1156                             name, &error_abort);
1157 }
1158 
1159 static GPtrArray *global_props(void)
1160 {
1161     static GPtrArray *gp;
1162 
1163     if (!gp) {
1164         gp = g_ptr_array_new();
1165     }
1166 
1167     return gp;
1168 }
1169 
1170 void qdev_prop_register_global(GlobalProperty *prop)
1171 {
1172     g_ptr_array_add(global_props(), prop);
1173 }
1174 
1175 int qdev_prop_check_globals(void)
1176 {
1177     int i, ret = 0;
1178 
1179     for (i = 0; i < global_props()->len; i++) {
1180         GlobalProperty *prop;
1181         ObjectClass *oc;
1182         DeviceClass *dc;
1183 
1184         prop = g_ptr_array_index(global_props(), i);
1185         if (prop->used) {
1186             continue;
1187         }
1188         oc = object_class_by_name(prop->driver);
1189         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1190         if (!oc) {
1191             warn_report("global %s.%s has invalid class name",
1192                         prop->driver, prop->property);
1193             ret = 1;
1194             continue;
1195         }
1196         dc = DEVICE_CLASS(oc);
1197         if (!dc->hotpluggable && !prop->used) {
1198             warn_report("global %s.%s=%s not used",
1199                         prop->driver, prop->property, prop->value);
1200             ret = 1;
1201             continue;
1202         }
1203     }
1204     return ret;
1205 }
1206 
1207 void qdev_prop_set_globals(DeviceState *dev)
1208 {
1209     object_apply_global_props(OBJECT(dev), global_props(),
1210                               dev->hotplugged ? NULL : &error_fatal);
1211 }
1212 
1213 /* --- 64bit unsigned int 'size' type --- */
1214 
1215 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1216                      Error **errp)
1217 {
1218     DeviceState *dev = DEVICE(obj);
1219     Property *prop = opaque;
1220     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1221 
1222     visit_type_size(v, name, ptr, errp);
1223 }
1224 
1225 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1226                      Error **errp)
1227 {
1228     DeviceState *dev = DEVICE(obj);
1229     Property *prop = opaque;
1230     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1231 
1232     visit_type_size(v, name, ptr, errp);
1233 }
1234 
1235 const PropertyInfo qdev_prop_size = {
1236     .name  = "size",
1237     .get = get_size,
1238     .set = set_size,
1239     .set_default_value = set_default_value_uint,
1240 };
1241 
1242 /* --- object link property --- */
1243 
1244 static void create_link_property(ObjectClass *oc, Property *prop, Error **errp)
1245 {
1246     object_class_property_add_link(oc, prop->name, prop->link_type,
1247                                    prop->offset,
1248                                    qdev_prop_allow_set_link_before_realize,
1249                                    OBJ_PROP_LINK_STRONG,
1250                                    errp);
1251 }
1252 
1253 const PropertyInfo qdev_prop_link = {
1254     .name = "link",
1255     .create = create_link_property,
1256 };
1257 
1258 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */
1259 
1260 const PropertyInfo qdev_prop_off_auto_pcibar = {
1261     .name = "OffAutoPCIBAR",
1262     .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
1263     .enum_table = &OffAutoPCIBAR_lookup,
1264     .get = get_enum,
1265     .set = set_enum,
1266     .set_default_value = set_default_value_enum,
1267 };
1268 
1269 /* --- PCIELinkSpeed 2_5/5/8/16 -- */
1270 
1271 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1272                                    void *opaque, Error **errp)
1273 {
1274     DeviceState *dev = DEVICE(obj);
1275     Property *prop = opaque;
1276     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1277     int speed;
1278 
1279     switch (*p) {
1280     case QEMU_PCI_EXP_LNK_2_5GT:
1281         speed = PCIE_LINK_SPEED_2_5;
1282         break;
1283     case QEMU_PCI_EXP_LNK_5GT:
1284         speed = PCIE_LINK_SPEED_5;
1285         break;
1286     case QEMU_PCI_EXP_LNK_8GT:
1287         speed = PCIE_LINK_SPEED_8;
1288         break;
1289     case QEMU_PCI_EXP_LNK_16GT:
1290         speed = PCIE_LINK_SPEED_16;
1291         break;
1292     default:
1293         /* Unreachable */
1294         abort();
1295     }
1296 
1297     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp);
1298 }
1299 
1300 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1301                                    void *opaque, Error **errp)
1302 {
1303     DeviceState *dev = DEVICE(obj);
1304     Property *prop = opaque;
1305     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1306     int speed;
1307     Error *local_err = NULL;
1308 
1309     if (dev->realized) {
1310         qdev_prop_set_after_realize(dev, name, errp);
1311         return;
1312     }
1313 
1314     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, &local_err);
1315     if (local_err) {
1316         error_propagate(errp, local_err);
1317         return;
1318     }
1319 
1320     switch (speed) {
1321     case PCIE_LINK_SPEED_2_5:
1322         *p = QEMU_PCI_EXP_LNK_2_5GT;
1323         break;
1324     case PCIE_LINK_SPEED_5:
1325         *p = QEMU_PCI_EXP_LNK_5GT;
1326         break;
1327     case PCIE_LINK_SPEED_8:
1328         *p = QEMU_PCI_EXP_LNK_8GT;
1329         break;
1330     case PCIE_LINK_SPEED_16:
1331         *p = QEMU_PCI_EXP_LNK_16GT;
1332         break;
1333     default:
1334         /* Unreachable */
1335         abort();
1336     }
1337 }
1338 
1339 const PropertyInfo qdev_prop_pcie_link_speed = {
1340     .name = "PCIELinkSpeed",
1341     .description = "2_5/5/8/16",
1342     .enum_table = &PCIELinkSpeed_lookup,
1343     .get = get_prop_pcielinkspeed,
1344     .set = set_prop_pcielinkspeed,
1345     .set_default_value = set_default_value_enum,
1346 };
1347 
1348 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
1349 
1350 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1351                                    void *opaque, Error **errp)
1352 {
1353     DeviceState *dev = DEVICE(obj);
1354     Property *prop = opaque;
1355     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1356     int width;
1357 
1358     switch (*p) {
1359     case QEMU_PCI_EXP_LNK_X1:
1360         width = PCIE_LINK_WIDTH_1;
1361         break;
1362     case QEMU_PCI_EXP_LNK_X2:
1363         width = PCIE_LINK_WIDTH_2;
1364         break;
1365     case QEMU_PCI_EXP_LNK_X4:
1366         width = PCIE_LINK_WIDTH_4;
1367         break;
1368     case QEMU_PCI_EXP_LNK_X8:
1369         width = PCIE_LINK_WIDTH_8;
1370         break;
1371     case QEMU_PCI_EXP_LNK_X12:
1372         width = PCIE_LINK_WIDTH_12;
1373         break;
1374     case QEMU_PCI_EXP_LNK_X16:
1375         width = PCIE_LINK_WIDTH_16;
1376         break;
1377     case QEMU_PCI_EXP_LNK_X32:
1378         width = PCIE_LINK_WIDTH_32;
1379         break;
1380     default:
1381         /* Unreachable */
1382         abort();
1383     }
1384 
1385     visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp);
1386 }
1387 
1388 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1389                                    void *opaque, Error **errp)
1390 {
1391     DeviceState *dev = DEVICE(obj);
1392     Property *prop = opaque;
1393     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1394     int width;
1395     Error *local_err = NULL;
1396 
1397     if (dev->realized) {
1398         qdev_prop_set_after_realize(dev, name, errp);
1399         return;
1400     }
1401 
1402     visit_type_enum(v, prop->name, &width, prop->info->enum_table, &local_err);
1403     if (local_err) {
1404         error_propagate(errp, local_err);
1405         return;
1406     }
1407 
1408     switch (width) {
1409     case PCIE_LINK_WIDTH_1:
1410         *p = QEMU_PCI_EXP_LNK_X1;
1411         break;
1412     case PCIE_LINK_WIDTH_2:
1413         *p = QEMU_PCI_EXP_LNK_X2;
1414         break;
1415     case PCIE_LINK_WIDTH_4:
1416         *p = QEMU_PCI_EXP_LNK_X4;
1417         break;
1418     case PCIE_LINK_WIDTH_8:
1419         *p = QEMU_PCI_EXP_LNK_X8;
1420         break;
1421     case PCIE_LINK_WIDTH_12:
1422         *p = QEMU_PCI_EXP_LNK_X12;
1423         break;
1424     case PCIE_LINK_WIDTH_16:
1425         *p = QEMU_PCI_EXP_LNK_X16;
1426         break;
1427     case PCIE_LINK_WIDTH_32:
1428         *p = QEMU_PCI_EXP_LNK_X32;
1429         break;
1430     default:
1431         /* Unreachable */
1432         abort();
1433     }
1434 }
1435 
1436 const PropertyInfo qdev_prop_pcie_link_width = {
1437     .name = "PCIELinkWidth",
1438     .description = "1/2/4/8/12/16/32",
1439     .enum_table = &PCIELinkWidth_lookup,
1440     .get = get_prop_pcielinkwidth,
1441     .set = set_prop_pcielinkwidth,
1442     .set_default_value = set_default_value_enum,
1443 };
1444