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