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