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