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