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