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