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