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