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