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