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