xref: /openbmc/qemu/hw/core/qdev-properties.c (revision 4f44bbc5bba0858d34b1aa356397847696276546)
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 set_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;
740     Error *local_err = NULL;
741 
742     if (dev->realized) {
743         qdev_prop_set_after_realize(dev, name, errp);
744         return;
745     }
746 
747     visit_type_size(v, name, &value, &local_err);
748     if (local_err) {
749         error_propagate(errp, local_err);
750         return;
751     }
752 
753     if (value > UINT32_MAX) {
754         error_setg(errp,
755                    "Property %s.%s doesn't take value %" PRIu64
756                    " (maximum: %u)",
757                    dev->id ? : "", name, value, UINT32_MAX);
758         return;
759     }
760 
761     *ptr = value;
762 }
763 
764 const PropertyInfo qdev_prop_size32 = {
765     .name  = "size",
766     .get = get_uint32,
767     .set = set_size32,
768     .set_default_value = set_default_value_uint,
769 };
770 
771 /* --- blocksize --- */
772 
773 /* lower limit is sector size */
774 #define MIN_BLOCK_SIZE          512
775 #define MIN_BLOCK_SIZE_STR      "512 B"
776 /* upper limit is the max power of 2 that fits in uint16_t */
777 #define MAX_BLOCK_SIZE          (32 * KiB)
778 #define MAX_BLOCK_SIZE_STR      "32 KiB"
779 
780 static void set_blocksize(Object *obj, Visitor *v, const char *name,
781                           void *opaque, Error **errp)
782 {
783     DeviceState *dev = DEVICE(obj);
784     Property *prop = opaque;
785     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
786     uint64_t value;
787     Error *local_err = NULL;
788 
789     if (dev->realized) {
790         qdev_prop_set_after_realize(dev, name, errp);
791         return;
792     }
793 
794     visit_type_size(v, name, &value, &local_err);
795     if (local_err) {
796         error_propagate(errp, local_err);
797         return;
798     }
799     /* value of 0 means "unset" */
800     if (value && (value < MIN_BLOCK_SIZE || value > MAX_BLOCK_SIZE)) {
801         error_setg(errp,
802                    "Property %s.%s doesn't take value %" PRIu64
803                    " (minimum: " MIN_BLOCK_SIZE_STR
804                    ", maximum: " MAX_BLOCK_SIZE_STR ")",
805                    dev->id ? : "", name, value);
806         return;
807     }
808 
809     /* We rely on power-of-2 blocksizes for bitmasks */
810     if ((value & (value - 1)) != 0) {
811         error_setg(errp,
812                   "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
813                   dev->id ?: "", name, (int64_t)value);
814         return;
815     }
816 
817     *ptr = value;
818 }
819 
820 const PropertyInfo qdev_prop_blocksize = {
821     .name  = "size",
822     .description = "A power of two between " MIN_BLOCK_SIZE_STR
823                    " and " MAX_BLOCK_SIZE_STR,
824     .get   = get_uint32,
825     .set   = set_blocksize,
826     .set_default_value = set_default_value_uint,
827 };
828 
829 /* --- pci host address --- */
830 
831 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
832                                  void *opaque, Error **errp)
833 {
834     DeviceState *dev = DEVICE(obj);
835     Property *prop = opaque;
836     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
837     char buffer[] = "ffff:ff:ff.f";
838     char *p = buffer;
839     int rc = 0;
840 
841     /*
842      * Catch "invalid" device reference from vfio-pci and allow the
843      * default buffer representing the non-existent device to be used.
844      */
845     if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
846         rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
847                       addr->domain, addr->bus, addr->slot, addr->function);
848         assert(rc == sizeof(buffer) - 1);
849     }
850 
851     visit_type_str(v, name, &p, errp);
852 }
853 
854 /*
855  * Parse [<domain>:]<bus>:<slot>.<func>
856  *   if <domain> is not supplied, it's assumed to be 0.
857  */
858 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
859                                  void *opaque, Error **errp)
860 {
861     DeviceState *dev = DEVICE(obj);
862     Property *prop = opaque;
863     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
864     Error *local_err = NULL;
865     char *str, *p;
866     char *e;
867     unsigned long val;
868     unsigned long dom = 0, bus = 0;
869     unsigned int slot = 0, func = 0;
870 
871     if (dev->realized) {
872         qdev_prop_set_after_realize(dev, name, errp);
873         return;
874     }
875 
876     visit_type_str(v, name, &str, &local_err);
877     if (local_err) {
878         error_propagate(errp, local_err);
879         return;
880     }
881 
882     p = str;
883     val = strtoul(p, &e, 16);
884     if (e == p || *e != ':') {
885         goto inval;
886     }
887     bus = val;
888 
889     p = e + 1;
890     val = strtoul(p, &e, 16);
891     if (e == p) {
892         goto inval;
893     }
894     if (*e == ':') {
895         dom = bus;
896         bus = val;
897         p = e + 1;
898         val = strtoul(p, &e, 16);
899         if (e == p) {
900             goto inval;
901         }
902     }
903     slot = val;
904 
905     if (*e != '.') {
906         goto inval;
907     }
908     p = e + 1;
909     val = strtoul(p, &e, 10);
910     if (e == p) {
911         goto inval;
912     }
913     func = val;
914 
915     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
916         goto inval;
917     }
918 
919     if (*e) {
920         goto inval;
921     }
922 
923     addr->domain = dom;
924     addr->bus = bus;
925     addr->slot = slot;
926     addr->function = func;
927 
928     g_free(str);
929     return;
930 
931 inval:
932     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
933     g_free(str);
934 }
935 
936 const PropertyInfo qdev_prop_pci_host_devaddr = {
937     .name = "str",
938     .description = "Address (bus/device/function) of "
939                    "the host device, example: 04:10.0",
940     .get = get_pci_host_devaddr,
941     .set = set_pci_host_devaddr,
942 };
943 
944 /* --- UUID --- */
945 
946 static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
947                      Error **errp)
948 {
949     DeviceState *dev = DEVICE(obj);
950     Property *prop = opaque;
951     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
952     char buffer[UUID_FMT_LEN + 1];
953     char *p = buffer;
954 
955     qemu_uuid_unparse(uuid, buffer);
956 
957     visit_type_str(v, name, &p, errp);
958 }
959 
960 #define UUID_VALUE_AUTO        "auto"
961 
962 static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
963                     Error **errp)
964 {
965     DeviceState *dev = DEVICE(obj);
966     Property *prop = opaque;
967     QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
968     Error *local_err = NULL;
969     char *str;
970 
971     if (dev->realized) {
972         qdev_prop_set_after_realize(dev, name, errp);
973         return;
974     }
975 
976     visit_type_str(v, name, &str, &local_err);
977     if (local_err) {
978         error_propagate(errp, local_err);
979         return;
980     }
981 
982     if (!strcmp(str, UUID_VALUE_AUTO)) {
983         qemu_uuid_generate(uuid);
984     } else if (qemu_uuid_parse(str, uuid) < 0) {
985         error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
986     }
987     g_free(str);
988 }
989 
990 static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
991 {
992     object_property_set_default_str(op, UUID_VALUE_AUTO);
993 }
994 
995 const PropertyInfo qdev_prop_uuid = {
996     .name  = "str",
997     .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
998         "\" for random value (default)",
999     .get   = get_uuid,
1000     .set   = set_uuid,
1001     .set_default_value = set_default_uuid_auto,
1002 };
1003 
1004 /* --- support for array properties --- */
1005 
1006 /* Used as an opaque for the object properties we add for each
1007  * array element. Note that the struct Property must be first
1008  * in the struct so that a pointer to this works as the opaque
1009  * for the underlying element's property hooks as well as for
1010  * our own release callback.
1011  */
1012 typedef struct {
1013     struct Property prop;
1014     char *propname;
1015     ObjectPropertyRelease *release;
1016 } ArrayElementProperty;
1017 
1018 /* object property release callback for array element properties:
1019  * we call the underlying element's property release hook, and
1020  * then free the memory we allocated when we added the property.
1021  */
1022 static void array_element_release(Object *obj, const char *name, void *opaque)
1023 {
1024     ArrayElementProperty *p = opaque;
1025     if (p->release) {
1026         p->release(obj, name, opaque);
1027     }
1028     g_free(p->propname);
1029     g_free(p);
1030 }
1031 
1032 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
1033                               void *opaque, Error **errp)
1034 {
1035     /* Setter for the property which defines the length of a
1036      * variable-sized property array. As well as actually setting the
1037      * array-length field in the device struct, we have to create the
1038      * array itself and dynamically add the corresponding properties.
1039      */
1040     DeviceState *dev = DEVICE(obj);
1041     Property *prop = opaque;
1042     uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
1043     void **arrayptr = (void *)dev + prop->arrayoffset;
1044     Error *local_err = NULL;
1045     void *eltptr;
1046     const char *arrayname;
1047     int i;
1048 
1049     if (dev->realized) {
1050         qdev_prop_set_after_realize(dev, name, errp);
1051         return;
1052     }
1053     if (*alenptr) {
1054         error_setg(errp, "array size property %s may not be set more than once",
1055                    name);
1056         return;
1057     }
1058     visit_type_uint32(v, name, alenptr, &local_err);
1059     if (local_err) {
1060         error_propagate(errp, local_err);
1061         return;
1062     }
1063     if (!*alenptr) {
1064         return;
1065     }
1066 
1067     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
1068      * strip it off so we can get the name of the array itself.
1069      */
1070     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
1071                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
1072     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
1073 
1074     /* Note that it is the responsibility of the individual device's deinit
1075      * to free the array proper.
1076      */
1077     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
1078     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
1079         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
1080         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
1081         arrayprop->release = prop->arrayinfo->release;
1082         arrayprop->propname = propname;
1083         arrayprop->prop.info = prop->arrayinfo;
1084         arrayprop->prop.name = propname;
1085         /* This ugly piece of pointer arithmetic sets up the offset so
1086          * that when the underlying get/set hooks call qdev_get_prop_ptr
1087          * they get the right answer despite the array element not actually
1088          * being inside the device struct.
1089          */
1090         arrayprop->prop.offset = eltptr - (void *)dev;
1091         assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
1092         object_property_add(obj, propname,
1093                             arrayprop->prop.info->name,
1094                             arrayprop->prop.info->get,
1095                             arrayprop->prop.info->set,
1096                             array_element_release,
1097                             arrayprop);
1098     }
1099 }
1100 
1101 const PropertyInfo qdev_prop_arraylen = {
1102     .name = "uint32",
1103     .get = get_uint32,
1104     .set = set_prop_arraylen,
1105     .set_default_value = set_default_value_uint,
1106 };
1107 
1108 /* --- public helpers --- */
1109 
1110 static Property *qdev_prop_walk(Property *props, const char *name)
1111 {
1112     if (!props) {
1113         return NULL;
1114     }
1115     while (props->name) {
1116         if (strcmp(props->name, name) == 0) {
1117             return props;
1118         }
1119         props++;
1120     }
1121     return NULL;
1122 }
1123 
1124 static Property *qdev_prop_find(DeviceState *dev, const char *name)
1125 {
1126     ObjectClass *class;
1127     Property *prop;
1128 
1129     /* device properties */
1130     class = object_get_class(OBJECT(dev));
1131     do {
1132         prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
1133         if (prop) {
1134             return prop;
1135         }
1136         class = object_class_get_parent(class);
1137     } while (class != object_class_by_name(TYPE_DEVICE));
1138 
1139     return NULL;
1140 }
1141 
1142 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
1143                                     Property *prop, const char *value)
1144 {
1145     switch (ret) {
1146     case -EEXIST:
1147         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
1148                   object_get_typename(OBJECT(dev)), prop->name, value);
1149         break;
1150     default:
1151     case -EINVAL:
1152         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
1153                    object_get_typename(OBJECT(dev)), prop->name, value);
1154         break;
1155     case -ENOENT:
1156         error_setg(errp, "Property '%s.%s' can't find value '%s'",
1157                   object_get_typename(OBJECT(dev)), prop->name, value);
1158         break;
1159     case 0:
1160         break;
1161     }
1162 }
1163 
1164 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1165 {
1166     object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1167 }
1168 
1169 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1170 {
1171     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1172 }
1173 
1174 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1175 {
1176     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1177 }
1178 
1179 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1180 {
1181     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1182 }
1183 
1184 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1185 {
1186     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1187 }
1188 
1189 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1190 {
1191     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1192 }
1193 
1194 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1195 {
1196     object_property_set_str(OBJECT(dev), value, name, &error_abort);
1197 }
1198 
1199 void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
1200                            const uint8_t *value)
1201 {
1202     char str[2 * 6 + 5 + 1];
1203     snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1204              value[0], value[1], value[2], value[3], value[4], value[5]);
1205 
1206     object_property_set_str(OBJECT(dev), str, name, &error_abort);
1207 }
1208 
1209 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1210 {
1211     Property *prop;
1212 
1213     prop = qdev_prop_find(dev, name);
1214     object_property_set_str(OBJECT(dev),
1215                             qapi_enum_lookup(prop->info->enum_table, value),
1216                             name, &error_abort);
1217 }
1218 
1219 static GPtrArray *global_props(void)
1220 {
1221     static GPtrArray *gp;
1222 
1223     if (!gp) {
1224         gp = g_ptr_array_new();
1225     }
1226 
1227     return gp;
1228 }
1229 
1230 void qdev_prop_register_global(GlobalProperty *prop)
1231 {
1232     g_ptr_array_add(global_props(), prop);
1233 }
1234 
1235 int qdev_prop_check_globals(void)
1236 {
1237     int i, ret = 0;
1238 
1239     for (i = 0; i < global_props()->len; i++) {
1240         GlobalProperty *prop;
1241         ObjectClass *oc;
1242         DeviceClass *dc;
1243 
1244         prop = g_ptr_array_index(global_props(), i);
1245         if (prop->used) {
1246             continue;
1247         }
1248         oc = object_class_by_name(prop->driver);
1249         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1250         if (!oc) {
1251             warn_report("global %s.%s has invalid class name",
1252                         prop->driver, prop->property);
1253             ret = 1;
1254             continue;
1255         }
1256         dc = DEVICE_CLASS(oc);
1257         if (!dc->hotpluggable && !prop->used) {
1258             warn_report("global %s.%s=%s not used",
1259                         prop->driver, prop->property, prop->value);
1260             ret = 1;
1261             continue;
1262         }
1263     }
1264     return ret;
1265 }
1266 
1267 void qdev_prop_set_globals(DeviceState *dev)
1268 {
1269     object_apply_global_props(OBJECT(dev), global_props(),
1270                               dev->hotplugged ? NULL : &error_fatal);
1271 }
1272 
1273 /* --- 64bit unsigned int 'size' type --- */
1274 
1275 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1276                      Error **errp)
1277 {
1278     DeviceState *dev = DEVICE(obj);
1279     Property *prop = opaque;
1280     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1281 
1282     visit_type_size(v, name, ptr, errp);
1283 }
1284 
1285 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1286                      Error **errp)
1287 {
1288     DeviceState *dev = DEVICE(obj);
1289     Property *prop = opaque;
1290     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1291 
1292     visit_type_size(v, name, ptr, errp);
1293 }
1294 
1295 const PropertyInfo qdev_prop_size = {
1296     .name  = "size",
1297     .get = get_size,
1298     .set = set_size,
1299     .set_default_value = set_default_value_uint,
1300 };
1301 
1302 /* --- object link property --- */
1303 
1304 static void create_link_property(ObjectClass *oc, Property *prop)
1305 {
1306     object_class_property_add_link(oc, prop->name, prop->link_type,
1307                                    prop->offset,
1308                                    qdev_prop_allow_set_link_before_realize,
1309                                    OBJ_PROP_LINK_STRONG);
1310 }
1311 
1312 const PropertyInfo qdev_prop_link = {
1313     .name = "link",
1314     .create = create_link_property,
1315 };
1316 
1317 /* --- OffAutoPCIBAR off/auto/bar0/bar1/bar2/bar3/bar4/bar5 --- */
1318 
1319 const PropertyInfo qdev_prop_off_auto_pcibar = {
1320     .name = "OffAutoPCIBAR",
1321     .description = "off/auto/bar0/bar1/bar2/bar3/bar4/bar5",
1322     .enum_table = &OffAutoPCIBAR_lookup,
1323     .get = get_enum,
1324     .set = set_enum,
1325     .set_default_value = set_default_value_enum,
1326 };
1327 
1328 /* --- PCIELinkSpeed 2_5/5/8/16 -- */
1329 
1330 static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1331                                    void *opaque, Error **errp)
1332 {
1333     DeviceState *dev = DEVICE(obj);
1334     Property *prop = opaque;
1335     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1336     int speed;
1337 
1338     switch (*p) {
1339     case QEMU_PCI_EXP_LNK_2_5GT:
1340         speed = PCIE_LINK_SPEED_2_5;
1341         break;
1342     case QEMU_PCI_EXP_LNK_5GT:
1343         speed = PCIE_LINK_SPEED_5;
1344         break;
1345     case QEMU_PCI_EXP_LNK_8GT:
1346         speed = PCIE_LINK_SPEED_8;
1347         break;
1348     case QEMU_PCI_EXP_LNK_16GT:
1349         speed = PCIE_LINK_SPEED_16;
1350         break;
1351     default:
1352         /* Unreachable */
1353         abort();
1354     }
1355 
1356     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp);
1357 }
1358 
1359 static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
1360                                    void *opaque, Error **errp)
1361 {
1362     DeviceState *dev = DEVICE(obj);
1363     Property *prop = opaque;
1364     PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
1365     int speed;
1366     Error *local_err = NULL;
1367 
1368     if (dev->realized) {
1369         qdev_prop_set_after_realize(dev, name, errp);
1370         return;
1371     }
1372 
1373     visit_type_enum(v, prop->name, &speed, prop->info->enum_table, &local_err);
1374     if (local_err) {
1375         error_propagate(errp, local_err);
1376         return;
1377     }
1378 
1379     switch (speed) {
1380     case PCIE_LINK_SPEED_2_5:
1381         *p = QEMU_PCI_EXP_LNK_2_5GT;
1382         break;
1383     case PCIE_LINK_SPEED_5:
1384         *p = QEMU_PCI_EXP_LNK_5GT;
1385         break;
1386     case PCIE_LINK_SPEED_8:
1387         *p = QEMU_PCI_EXP_LNK_8GT;
1388         break;
1389     case PCIE_LINK_SPEED_16:
1390         *p = QEMU_PCI_EXP_LNK_16GT;
1391         break;
1392     default:
1393         /* Unreachable */
1394         abort();
1395     }
1396 }
1397 
1398 const PropertyInfo qdev_prop_pcie_link_speed = {
1399     .name = "PCIELinkSpeed",
1400     .description = "2_5/5/8/16",
1401     .enum_table = &PCIELinkSpeed_lookup,
1402     .get = get_prop_pcielinkspeed,
1403     .set = set_prop_pcielinkspeed,
1404     .set_default_value = set_default_value_enum,
1405 };
1406 
1407 /* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
1408 
1409 static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1410                                    void *opaque, Error **errp)
1411 {
1412     DeviceState *dev = DEVICE(obj);
1413     Property *prop = opaque;
1414     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1415     int width;
1416 
1417     switch (*p) {
1418     case QEMU_PCI_EXP_LNK_X1:
1419         width = PCIE_LINK_WIDTH_1;
1420         break;
1421     case QEMU_PCI_EXP_LNK_X2:
1422         width = PCIE_LINK_WIDTH_2;
1423         break;
1424     case QEMU_PCI_EXP_LNK_X4:
1425         width = PCIE_LINK_WIDTH_4;
1426         break;
1427     case QEMU_PCI_EXP_LNK_X8:
1428         width = PCIE_LINK_WIDTH_8;
1429         break;
1430     case QEMU_PCI_EXP_LNK_X12:
1431         width = PCIE_LINK_WIDTH_12;
1432         break;
1433     case QEMU_PCI_EXP_LNK_X16:
1434         width = PCIE_LINK_WIDTH_16;
1435         break;
1436     case QEMU_PCI_EXP_LNK_X32:
1437         width = PCIE_LINK_WIDTH_32;
1438         break;
1439     default:
1440         /* Unreachable */
1441         abort();
1442     }
1443 
1444     visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp);
1445 }
1446 
1447 static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
1448                                    void *opaque, Error **errp)
1449 {
1450     DeviceState *dev = DEVICE(obj);
1451     Property *prop = opaque;
1452     PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
1453     int width;
1454     Error *local_err = NULL;
1455 
1456     if (dev->realized) {
1457         qdev_prop_set_after_realize(dev, name, errp);
1458         return;
1459     }
1460 
1461     visit_type_enum(v, prop->name, &width, prop->info->enum_table, &local_err);
1462     if (local_err) {
1463         error_propagate(errp, local_err);
1464         return;
1465     }
1466 
1467     switch (width) {
1468     case PCIE_LINK_WIDTH_1:
1469         *p = QEMU_PCI_EXP_LNK_X1;
1470         break;
1471     case PCIE_LINK_WIDTH_2:
1472         *p = QEMU_PCI_EXP_LNK_X2;
1473         break;
1474     case PCIE_LINK_WIDTH_4:
1475         *p = QEMU_PCI_EXP_LNK_X4;
1476         break;
1477     case PCIE_LINK_WIDTH_8:
1478         *p = QEMU_PCI_EXP_LNK_X8;
1479         break;
1480     case PCIE_LINK_WIDTH_12:
1481         *p = QEMU_PCI_EXP_LNK_X12;
1482         break;
1483     case PCIE_LINK_WIDTH_16:
1484         *p = QEMU_PCI_EXP_LNK_X16;
1485         break;
1486     case PCIE_LINK_WIDTH_32:
1487         *p = QEMU_PCI_EXP_LNK_X32;
1488         break;
1489     default:
1490         /* Unreachable */
1491         abort();
1492     }
1493 }
1494 
1495 const PropertyInfo qdev_prop_pcie_link_width = {
1496     .name = "PCIELinkWidth",
1497     .description = "1/2/4/8/12/16/32",
1498     .enum_table = &PCIELinkWidth_lookup,
1499     .get = get_prop_pcielinkwidth,
1500     .set = set_prop_pcielinkwidth,
1501     .set_default_value = set_default_value_enum,
1502 };
1503