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