xref: /openbmc/qemu/hw/core/qdev-properties.c (revision 864a2178)
1 #include "qemu/osdep.h"
2 #include "net/net.h"
3 #include "hw/qdev.h"
4 #include "qapi/error.h"
5 #include "hw/pci/pci.h"
6 #include "qapi/qmp/qerror.h"
7 #include "qemu/error-report.h"
8 #include "sysemu/block-backend.h"
9 #include "hw/block/block.h"
10 #include "net/hub.h"
11 #include "qapi/visitor.h"
12 #include "chardev/char.h"
13 
14 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
15                                   Error **errp)
16 {
17     if (dev->id) {
18         error_setg(errp, "Attempt to set property '%s' on device '%s' "
19                    "(type '%s') after it was realized", name, dev->id,
20                    object_get_typename(OBJECT(dev)));
21     } else {
22         error_setg(errp, "Attempt to set property '%s' on anonymous device "
23                    "(type '%s') after it was realized", name,
24                    object_get_typename(OBJECT(dev)));
25     }
26 }
27 
28 void qdev_prop_allow_set_link_before_realize(const Object *obj,
29                                              const char *name,
30                                              Object *val, Error **errp)
31 {
32     DeviceState *dev = DEVICE(obj);
33 
34     if (dev->realized) {
35         error_setg(errp, "Attempt to set link property '%s' on device '%s' "
36                    "(type '%s') after it was realized",
37                    name, dev->id, object_get_typename(obj));
38     }
39 }
40 
41 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
42 {
43     void *ptr = dev;
44     ptr += prop->offset;
45     return ptr;
46 }
47 
48 static void get_enum(Object *obj, Visitor *v, const char *name, void *opaque,
49                      Error **errp)
50 {
51     DeviceState *dev = DEVICE(obj);
52     Property *prop = opaque;
53     int *ptr = qdev_get_prop_ptr(dev, prop);
54 
55     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
56 }
57 
58 static void set_enum(Object *obj, Visitor *v, const char *name, void *opaque,
59                      Error **errp)
60 {
61     DeviceState *dev = DEVICE(obj);
62     Property *prop = opaque;
63     int *ptr = qdev_get_prop_ptr(dev, prop);
64 
65     if (dev->realized) {
66         qdev_prop_set_after_realize(dev, name, errp);
67         return;
68     }
69 
70     visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
71 }
72 
73 static void set_default_value_enum(Object *obj, const Property *prop)
74 {
75     object_property_set_str(obj, prop->info->enum_table[prop->defval.i],
76                             prop->name, &error_abort);
77 }
78 
79 /* Bit */
80 
81 static uint32_t qdev_get_prop_mask(Property *prop)
82 {
83     assert(prop->info == &qdev_prop_bit);
84     return 0x1 << prop->bitnr;
85 }
86 
87 static void bit_prop_set(DeviceState *dev, Property *props, bool val)
88 {
89     uint32_t *p = qdev_get_prop_ptr(dev, props);
90     uint32_t mask = qdev_get_prop_mask(props);
91     if (val) {
92         *p |= mask;
93     } else {
94         *p &= ~mask;
95     }
96 }
97 
98 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
99                          void *opaque, Error **errp)
100 {
101     DeviceState *dev = DEVICE(obj);
102     Property *prop = opaque;
103     uint32_t *p = qdev_get_prop_ptr(dev, prop);
104     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
105 
106     visit_type_bool(v, name, &value, errp);
107 }
108 
109 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
110                          void *opaque, Error **errp)
111 {
112     DeviceState *dev = DEVICE(obj);
113     Property *prop = opaque;
114     Error *local_err = NULL;
115     bool value;
116 
117     if (dev->realized) {
118         qdev_prop_set_after_realize(dev, name, errp);
119         return;
120     }
121 
122     visit_type_bool(v, name, &value, &local_err);
123     if (local_err) {
124         error_propagate(errp, local_err);
125         return;
126     }
127     bit_prop_set(dev, prop, value);
128 }
129 
130 static void set_default_value_bool(Object *obj, const Property *prop)
131 {
132     object_property_set_bool(obj, prop->defval.u, prop->name, &error_abort);
133 }
134 
135 const PropertyInfo qdev_prop_bit = {
136     .name  = "bool",
137     .description = "on/off",
138     .get   = prop_get_bit,
139     .set   = prop_set_bit,
140     .set_default_value = set_default_value_bool,
141 };
142 
143 /* Bit64 */
144 
145 static uint64_t qdev_get_prop_mask64(Property *prop)
146 {
147     assert(prop->info == &qdev_prop_bit64);
148     return 0x1ull << prop->bitnr;
149 }
150 
151 static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
152 {
153     uint64_t *p = qdev_get_prop_ptr(dev, props);
154     uint64_t mask = qdev_get_prop_mask64(props);
155     if (val) {
156         *p |= mask;
157     } else {
158         *p &= ~mask;
159     }
160 }
161 
162 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
163                            void *opaque, Error **errp)
164 {
165     DeviceState *dev = DEVICE(obj);
166     Property *prop = opaque;
167     uint64_t *p = qdev_get_prop_ptr(dev, prop);
168     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
169 
170     visit_type_bool(v, name, &value, errp);
171 }
172 
173 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
174                            void *opaque, Error **errp)
175 {
176     DeviceState *dev = DEVICE(obj);
177     Property *prop = opaque;
178     Error *local_err = NULL;
179     bool value;
180 
181     if (dev->realized) {
182         qdev_prop_set_after_realize(dev, name, errp);
183         return;
184     }
185 
186     visit_type_bool(v, name, &value, &local_err);
187     if (local_err) {
188         error_propagate(errp, local_err);
189         return;
190     }
191     bit64_prop_set(dev, prop, value);
192 }
193 
194 const PropertyInfo qdev_prop_bit64 = {
195     .name  = "bool",
196     .description = "on/off",
197     .get   = prop_get_bit64,
198     .set   = prop_set_bit64,
199     .set_default_value = set_default_value_bool,
200 };
201 
202 /* --- bool --- */
203 
204 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
205                      Error **errp)
206 {
207     DeviceState *dev = DEVICE(obj);
208     Property *prop = opaque;
209     bool *ptr = qdev_get_prop_ptr(dev, prop);
210 
211     visit_type_bool(v, name, ptr, errp);
212 }
213 
214 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
215                      Error **errp)
216 {
217     DeviceState *dev = DEVICE(obj);
218     Property *prop = opaque;
219     bool *ptr = qdev_get_prop_ptr(dev, prop);
220 
221     if (dev->realized) {
222         qdev_prop_set_after_realize(dev, name, errp);
223         return;
224     }
225 
226     visit_type_bool(v, name, ptr, errp);
227 }
228 
229 const PropertyInfo qdev_prop_bool = {
230     .name  = "bool",
231     .get   = get_bool,
232     .set   = set_bool,
233     .set_default_value = set_default_value_bool,
234 };
235 
236 /* --- 8bit integer --- */
237 
238 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
239                       Error **errp)
240 {
241     DeviceState *dev = DEVICE(obj);
242     Property *prop = opaque;
243     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
244 
245     visit_type_uint8(v, name, ptr, errp);
246 }
247 
248 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
249                       Error **errp)
250 {
251     DeviceState *dev = DEVICE(obj);
252     Property *prop = opaque;
253     uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
254 
255     if (dev->realized) {
256         qdev_prop_set_after_realize(dev, name, errp);
257         return;
258     }
259 
260     visit_type_uint8(v, name, ptr, errp);
261 }
262 
263 static void set_default_value_int(Object *obj, const Property *prop)
264 {
265     object_property_set_int(obj, prop->defval.i, prop->name, &error_abort);
266 }
267 
268 static void set_default_value_uint(Object *obj, const Property *prop)
269 {
270     object_property_set_uint(obj, prop->defval.u, prop->name, &error_abort);
271 }
272 
273 const PropertyInfo qdev_prop_uint8 = {
274     .name  = "uint8",
275     .get   = get_uint8,
276     .set   = set_uint8,
277     .set_default_value = set_default_value_uint,
278 };
279 
280 /* --- 16bit integer --- */
281 
282 static void get_uint16(Object *obj, Visitor *v, const char *name,
283                        void *opaque, Error **errp)
284 {
285     DeviceState *dev = DEVICE(obj);
286     Property *prop = opaque;
287     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
288 
289     visit_type_uint16(v, name, ptr, errp);
290 }
291 
292 static void set_uint16(Object *obj, Visitor *v, const char *name,
293                        void *opaque, Error **errp)
294 {
295     DeviceState *dev = DEVICE(obj);
296     Property *prop = opaque;
297     uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
298 
299     if (dev->realized) {
300         qdev_prop_set_after_realize(dev, name, errp);
301         return;
302     }
303 
304     visit_type_uint16(v, name, ptr, errp);
305 }
306 
307 const PropertyInfo qdev_prop_uint16 = {
308     .name  = "uint16",
309     .get   = get_uint16,
310     .set   = set_uint16,
311     .set_default_value = set_default_value_uint,
312 };
313 
314 /* --- 32bit integer --- */
315 
316 static void get_uint32(Object *obj, Visitor *v, const char *name,
317                        void *opaque, Error **errp)
318 {
319     DeviceState *dev = DEVICE(obj);
320     Property *prop = opaque;
321     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
322 
323     visit_type_uint32(v, name, ptr, errp);
324 }
325 
326 static void set_uint32(Object *obj, Visitor *v, const char *name,
327                        void *opaque, Error **errp)
328 {
329     DeviceState *dev = DEVICE(obj);
330     Property *prop = opaque;
331     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
332 
333     if (dev->realized) {
334         qdev_prop_set_after_realize(dev, name, errp);
335         return;
336     }
337 
338     visit_type_uint32(v, name, ptr, errp);
339 }
340 
341 static void get_int32(Object *obj, Visitor *v, const char *name, void *opaque,
342                       Error **errp)
343 {
344     DeviceState *dev = DEVICE(obj);
345     Property *prop = opaque;
346     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
347 
348     visit_type_int32(v, name, ptr, errp);
349 }
350 
351 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
352                       Error **errp)
353 {
354     DeviceState *dev = DEVICE(obj);
355     Property *prop = opaque;
356     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
357 
358     if (dev->realized) {
359         qdev_prop_set_after_realize(dev, name, errp);
360         return;
361     }
362 
363     visit_type_int32(v, name, ptr, errp);
364 }
365 
366 const PropertyInfo qdev_prop_uint32 = {
367     .name  = "uint32",
368     .get   = get_uint32,
369     .set   = set_uint32,
370     .set_default_value = set_default_value_uint,
371 };
372 
373 const PropertyInfo qdev_prop_int32 = {
374     .name  = "int32",
375     .get   = get_int32,
376     .set   = set_int32,
377     .set_default_value = set_default_value_int,
378 };
379 
380 /* --- 64bit integer --- */
381 
382 static void get_uint64(Object *obj, Visitor *v, const char *name,
383                        void *opaque, Error **errp)
384 {
385     DeviceState *dev = DEVICE(obj);
386     Property *prop = opaque;
387     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
388 
389     visit_type_uint64(v, name, ptr, errp);
390 }
391 
392 static void set_uint64(Object *obj, Visitor *v, const char *name,
393                        void *opaque, Error **errp)
394 {
395     DeviceState *dev = DEVICE(obj);
396     Property *prop = opaque;
397     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
398 
399     if (dev->realized) {
400         qdev_prop_set_after_realize(dev, name, errp);
401         return;
402     }
403 
404     visit_type_uint64(v, name, ptr, errp);
405 }
406 
407 const PropertyInfo qdev_prop_uint64 = {
408     .name  = "uint64",
409     .get   = get_uint64,
410     .set   = set_uint64,
411     .set_default_value = set_default_value_uint,
412 };
413 
414 /* --- string --- */
415 
416 static void release_string(Object *obj, const char *name, void *opaque)
417 {
418     Property *prop = opaque;
419     g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
420 }
421 
422 static void get_string(Object *obj, Visitor *v, const char *name,
423                        void *opaque, Error **errp)
424 {
425     DeviceState *dev = DEVICE(obj);
426     Property *prop = opaque;
427     char **ptr = qdev_get_prop_ptr(dev, prop);
428 
429     if (!*ptr) {
430         char *str = (char *)"";
431         visit_type_str(v, name, &str, errp);
432     } else {
433         visit_type_str(v, name, ptr, errp);
434     }
435 }
436 
437 static void set_string(Object *obj, Visitor *v, const char *name,
438                        void *opaque, Error **errp)
439 {
440     DeviceState *dev = DEVICE(obj);
441     Property *prop = opaque;
442     char **ptr = qdev_get_prop_ptr(dev, prop);
443     Error *local_err = NULL;
444     char *str;
445 
446     if (dev->realized) {
447         qdev_prop_set_after_realize(dev, name, errp);
448         return;
449     }
450 
451     visit_type_str(v, name, &str, &local_err);
452     if (local_err) {
453         error_propagate(errp, local_err);
454         return;
455     }
456     g_free(*ptr);
457     *ptr = str;
458 }
459 
460 const PropertyInfo qdev_prop_string = {
461     .name  = "str",
462     .release = release_string,
463     .get   = get_string,
464     .set   = set_string,
465 };
466 
467 /* --- pointer --- */
468 
469 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
470 const PropertyInfo qdev_prop_ptr = {
471     .name  = "ptr",
472 };
473 
474 /* --- mac address --- */
475 
476 /*
477  * accepted syntax versions:
478  *   01:02:03:04:05:06
479  *   01-02-03-04-05-06
480  */
481 static void get_mac(Object *obj, Visitor *v, const char *name, void *opaque,
482                     Error **errp)
483 {
484     DeviceState *dev = DEVICE(obj);
485     Property *prop = opaque;
486     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
487     char buffer[2 * 6 + 5 + 1];
488     char *p = buffer;
489 
490     snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
491              mac->a[0], mac->a[1], mac->a[2],
492              mac->a[3], mac->a[4], mac->a[5]);
493 
494     visit_type_str(v, name, &p, errp);
495 }
496 
497 static void set_mac(Object *obj, Visitor *v, const char *name, void *opaque,
498                     Error **errp)
499 {
500     DeviceState *dev = DEVICE(obj);
501     Property *prop = opaque;
502     MACAddr *mac = qdev_get_prop_ptr(dev, prop);
503     Error *local_err = NULL;
504     int i, pos;
505     char *str, *p;
506 
507     if (dev->realized) {
508         qdev_prop_set_after_realize(dev, name, errp);
509         return;
510     }
511 
512     visit_type_str(v, name, &str, &local_err);
513     if (local_err) {
514         error_propagate(errp, local_err);
515         return;
516     }
517 
518     for (i = 0, pos = 0; i < 6; i++, pos += 3) {
519         if (!qemu_isxdigit(str[pos])) {
520             goto inval;
521         }
522         if (!qemu_isxdigit(str[pos+1])) {
523             goto inval;
524         }
525         if (i == 5) {
526             if (str[pos+2] != '\0') {
527                 goto inval;
528             }
529         } else {
530             if (str[pos+2] != ':' && str[pos+2] != '-') {
531                 goto inval;
532             }
533         }
534         mac->a[i] = strtol(str+pos, &p, 16);
535     }
536     g_free(str);
537     return;
538 
539 inval:
540     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
541     g_free(str);
542 }
543 
544 const PropertyInfo qdev_prop_macaddr = {
545     .name  = "str",
546     .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
547     .get   = get_mac,
548     .set   = set_mac,
549 };
550 
551 /* --- on/off/auto --- */
552 
553 const PropertyInfo qdev_prop_on_off_auto = {
554     .name = "OnOffAuto",
555     .description = "on/off/auto",
556     .enum_table = OnOffAuto_lookup,
557     .get = get_enum,
558     .set = set_enum,
559     .set_default_value = set_default_value_enum,
560 };
561 
562 /* --- lost tick policy --- */
563 
564 QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
565 
566 const PropertyInfo qdev_prop_losttickpolicy = {
567     .name  = "LostTickPolicy",
568     .enum_table  = LostTickPolicy_lookup,
569     .get   = get_enum,
570     .set   = set_enum,
571     .set_default_value = set_default_value_enum,
572 };
573 
574 /* --- Block device error handling policy --- */
575 
576 QEMU_BUILD_BUG_ON(sizeof(BlockdevOnError) != sizeof(int));
577 
578 const PropertyInfo qdev_prop_blockdev_on_error = {
579     .name = "BlockdevOnError",
580     .description = "Error handling policy, "
581                    "report/ignore/enospc/stop/auto",
582     .enum_table = BlockdevOnError_lookup,
583     .get = get_enum,
584     .set = set_enum,
585     .set_default_value = set_default_value_enum,
586 };
587 
588 /* --- BIOS CHS translation */
589 
590 QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
591 
592 const PropertyInfo qdev_prop_bios_chs_trans = {
593     .name = "BiosAtaTranslation",
594     .description = "Logical CHS translation algorithm, "
595                    "auto/none/lba/large/rechs",
596     .enum_table = BiosAtaTranslation_lookup,
597     .get = get_enum,
598     .set = set_enum,
599     .set_default_value = set_default_value_enum,
600 };
601 
602 /* --- FDC default drive types */
603 
604 const PropertyInfo qdev_prop_fdc_drive_type = {
605     .name = "FdcDriveType",
606     .description = "FDC drive type, "
607                    "144/288/120/none/auto",
608     .enum_table = FloppyDriveType_lookup,
609     .get = get_enum,
610     .set = set_enum,
611     .set_default_value = set_default_value_enum,
612 };
613 
614 /* --- pci address --- */
615 
616 /*
617  * bus-local address, i.e. "$slot" or "$slot.$fn"
618  */
619 static void set_pci_devfn(Object *obj, Visitor *v, const char *name,
620                           void *opaque, Error **errp)
621 {
622     DeviceState *dev = DEVICE(obj);
623     Property *prop = opaque;
624     int32_t value, *ptr = qdev_get_prop_ptr(dev, prop);
625     unsigned int slot, fn, n;
626     Error *local_err = NULL;
627     char *str;
628 
629     if (dev->realized) {
630         qdev_prop_set_after_realize(dev, name, errp);
631         return;
632     }
633 
634     visit_type_str(v, name, &str, &local_err);
635     if (local_err) {
636         error_free(local_err);
637         local_err = NULL;
638         visit_type_int32(v, name, &value, &local_err);
639         if (local_err) {
640             error_propagate(errp, local_err);
641         } else if (value < -1 || value > 255) {
642             error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
643                        name ? name : "null", "pci_devfn");
644         } else {
645             *ptr = value;
646         }
647         return;
648     }
649 
650     if (sscanf(str, "%x.%x%n", &slot, &fn, &n) != 2) {
651         fn = 0;
652         if (sscanf(str, "%x%n", &slot, &n) != 1) {
653             goto invalid;
654         }
655     }
656     if (str[n] != '\0' || fn > 7 || slot > 31) {
657         goto invalid;
658     }
659     *ptr = slot << 3 | fn;
660     g_free(str);
661     return;
662 
663 invalid:
664     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
665     g_free(str);
666 }
667 
668 static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
669                            size_t len)
670 {
671     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
672 
673     if (*ptr == -1) {
674         return snprintf(dest, len, "<unset>");
675     } else {
676         return snprintf(dest, len, "%02x.%x", *ptr >> 3, *ptr & 7);
677     }
678 }
679 
680 const PropertyInfo qdev_prop_pci_devfn = {
681     .name  = "int32",
682     .description = "Slot and optional function number, example: 06.0 or 06",
683     .print = print_pci_devfn,
684     .get   = get_int32,
685     .set   = set_pci_devfn,
686     .set_default_value = set_default_value_int,
687 };
688 
689 /* --- blocksize --- */
690 
691 static void set_blocksize(Object *obj, Visitor *v, const char *name,
692                           void *opaque, Error **errp)
693 {
694     DeviceState *dev = DEVICE(obj);
695     Property *prop = opaque;
696     uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop);
697     Error *local_err = NULL;
698     const int64_t min = 512;
699     const int64_t max = 32768;
700 
701     if (dev->realized) {
702         qdev_prop_set_after_realize(dev, name, errp);
703         return;
704     }
705 
706     visit_type_uint16(v, name, &value, &local_err);
707     if (local_err) {
708         error_propagate(errp, local_err);
709         return;
710     }
711     /* value of 0 means "unset" */
712     if (value && (value < min || value > max)) {
713         error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
714                    dev->id ? : "", name, (int64_t)value, min, max);
715         return;
716     }
717 
718     /* We rely on power-of-2 blocksizes for bitmasks */
719     if ((value & (value - 1)) != 0) {
720         error_setg(errp,
721                   "Property %s.%s doesn't take value '%" PRId64 "', it's not a power of 2",
722                   dev->id ?: "", name, (int64_t)value);
723         return;
724     }
725 
726     *ptr = value;
727 }
728 
729 const PropertyInfo qdev_prop_blocksize = {
730     .name  = "uint16",
731     .description = "A power of two between 512 and 32768",
732     .get   = get_uint16,
733     .set   = set_blocksize,
734     .set_default_value = set_default_value_uint,
735 };
736 
737 /* --- pci host address --- */
738 
739 static void get_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
740                                  void *opaque, Error **errp)
741 {
742     DeviceState *dev = DEVICE(obj);
743     Property *prop = opaque;
744     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
745     char buffer[] = "ffff:ff:ff.f";
746     char *p = buffer;
747     int rc = 0;
748 
749     /*
750      * Catch "invalid" device reference from vfio-pci and allow the
751      * default buffer representing the non-existent device to be used.
752      */
753     if (~addr->domain || ~addr->bus || ~addr->slot || ~addr->function) {
754         rc = snprintf(buffer, sizeof(buffer), "%04x:%02x:%02x.%0d",
755                       addr->domain, addr->bus, addr->slot, addr->function);
756         assert(rc == sizeof(buffer) - 1);
757     }
758 
759     visit_type_str(v, name, &p, errp);
760 }
761 
762 /*
763  * Parse [<domain>:]<bus>:<slot>.<func>
764  *   if <domain> is not supplied, it's assumed to be 0.
765  */
766 static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
767                                  void *opaque, Error **errp)
768 {
769     DeviceState *dev = DEVICE(obj);
770     Property *prop = opaque;
771     PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
772     Error *local_err = NULL;
773     char *str, *p;
774     char *e;
775     unsigned long val;
776     unsigned long dom = 0, bus = 0;
777     unsigned int slot = 0, func = 0;
778 
779     if (dev->realized) {
780         qdev_prop_set_after_realize(dev, name, errp);
781         return;
782     }
783 
784     visit_type_str(v, name, &str, &local_err);
785     if (local_err) {
786         error_propagate(errp, local_err);
787         return;
788     }
789 
790     p = str;
791     val = strtoul(p, &e, 16);
792     if (e == p || *e != ':') {
793         goto inval;
794     }
795     bus = val;
796 
797     p = e + 1;
798     val = strtoul(p, &e, 16);
799     if (e == p) {
800         goto inval;
801     }
802     if (*e == ':') {
803         dom = bus;
804         bus = val;
805         p = e + 1;
806         val = strtoul(p, &e, 16);
807         if (e == p) {
808             goto inval;
809         }
810     }
811     slot = val;
812 
813     if (*e != '.') {
814         goto inval;
815     }
816     p = e + 1;
817     val = strtoul(p, &e, 10);
818     if (e == p) {
819         goto inval;
820     }
821     func = val;
822 
823     if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
824         goto inval;
825     }
826 
827     if (*e) {
828         goto inval;
829     }
830 
831     addr->domain = dom;
832     addr->bus = bus;
833     addr->slot = slot;
834     addr->function = func;
835 
836     g_free(str);
837     return;
838 
839 inval:
840     error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
841     g_free(str);
842 }
843 
844 const PropertyInfo qdev_prop_pci_host_devaddr = {
845     .name = "str",
846     .description = "Address (bus/device/function) of "
847                    "the host device, example: 04:10.0",
848     .get = get_pci_host_devaddr,
849     .set = set_pci_host_devaddr,
850 };
851 
852 /* --- support for array properties --- */
853 
854 /* Used as an opaque for the object properties we add for each
855  * array element. Note that the struct Property must be first
856  * in the struct so that a pointer to this works as the opaque
857  * for the underlying element's property hooks as well as for
858  * our own release callback.
859  */
860 typedef struct {
861     struct Property prop;
862     char *propname;
863     ObjectPropertyRelease *release;
864 } ArrayElementProperty;
865 
866 /* object property release callback for array element properties:
867  * we call the underlying element's property release hook, and
868  * then free the memory we allocated when we added the property.
869  */
870 static void array_element_release(Object *obj, const char *name, void *opaque)
871 {
872     ArrayElementProperty *p = opaque;
873     if (p->release) {
874         p->release(obj, name, opaque);
875     }
876     g_free(p->propname);
877     g_free(p);
878 }
879 
880 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
881                               void *opaque, Error **errp)
882 {
883     /* Setter for the property which defines the length of a
884      * variable-sized property array. As well as actually setting the
885      * array-length field in the device struct, we have to create the
886      * array itself and dynamically add the corresponding properties.
887      */
888     DeviceState *dev = DEVICE(obj);
889     Property *prop = opaque;
890     uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
891     void **arrayptr = (void *)dev + prop->arrayoffset;
892     Error *local_err = NULL;
893     void *eltptr;
894     const char *arrayname;
895     int i;
896 
897     if (dev->realized) {
898         qdev_prop_set_after_realize(dev, name, errp);
899         return;
900     }
901     if (*alenptr) {
902         error_setg(errp, "array size property %s may not be set more than once",
903                    name);
904         return;
905     }
906     visit_type_uint32(v, name, alenptr, &local_err);
907     if (local_err) {
908         error_propagate(errp, local_err);
909         return;
910     }
911     if (!*alenptr) {
912         return;
913     }
914 
915     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
916      * strip it off so we can get the name of the array itself.
917      */
918     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
919                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
920     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
921 
922     /* Note that it is the responsibility of the individual device's deinit
923      * to free the array proper.
924      */
925     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
926     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
927         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
928         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
929         arrayprop->release = prop->arrayinfo->release;
930         arrayprop->propname = propname;
931         arrayprop->prop.info = prop->arrayinfo;
932         arrayprop->prop.name = propname;
933         /* This ugly piece of pointer arithmetic sets up the offset so
934          * that when the underlying get/set hooks call qdev_get_prop_ptr
935          * they get the right answer despite the array element not actually
936          * being inside the device struct.
937          */
938         arrayprop->prop.offset = eltptr - (void *)dev;
939         assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
940         object_property_add(obj, propname,
941                             arrayprop->prop.info->name,
942                             arrayprop->prop.info->get,
943                             arrayprop->prop.info->set,
944                             array_element_release,
945                             arrayprop, &local_err);
946         if (local_err) {
947             error_propagate(errp, local_err);
948             return;
949         }
950     }
951 }
952 
953 const PropertyInfo qdev_prop_arraylen = {
954     .name = "uint32",
955     .get = get_uint32,
956     .set = set_prop_arraylen,
957     .set_default_value = set_default_value_uint,
958 };
959 
960 /* --- public helpers --- */
961 
962 static Property *qdev_prop_walk(Property *props, const char *name)
963 {
964     if (!props) {
965         return NULL;
966     }
967     while (props->name) {
968         if (strcmp(props->name, name) == 0) {
969             return props;
970         }
971         props++;
972     }
973     return NULL;
974 }
975 
976 static Property *qdev_prop_find(DeviceState *dev, const char *name)
977 {
978     ObjectClass *class;
979     Property *prop;
980 
981     /* device properties */
982     class = object_get_class(OBJECT(dev));
983     do {
984         prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
985         if (prop) {
986             return prop;
987         }
988         class = object_class_get_parent(class);
989     } while (class != object_class_by_name(TYPE_DEVICE));
990 
991     return NULL;
992 }
993 
994 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
995                                     Property *prop, const char *value)
996 {
997     switch (ret) {
998     case -EEXIST:
999         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
1000                   object_get_typename(OBJECT(dev)), prop->name, value);
1001         break;
1002     default:
1003     case -EINVAL:
1004         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
1005                    object_get_typename(OBJECT(dev)), prop->name, value);
1006         break;
1007     case -ENOENT:
1008         error_setg(errp, "Property '%s.%s' can't find value '%s'",
1009                   object_get_typename(OBJECT(dev)), prop->name, value);
1010         break;
1011     case 0:
1012         break;
1013     }
1014 }
1015 
1016 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
1017 {
1018     object_property_set_bool(OBJECT(dev), value, name, &error_abort);
1019 }
1020 
1021 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
1022 {
1023     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1024 }
1025 
1026 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
1027 {
1028     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1029 }
1030 
1031 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
1032 {
1033     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1034 }
1035 
1036 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
1037 {
1038     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1039 }
1040 
1041 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
1042 {
1043     object_property_set_int(OBJECT(dev), value, name, &error_abort);
1044 }
1045 
1046 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
1047 {
1048     object_property_set_str(OBJECT(dev), value, name, &error_abort);
1049 }
1050 
1051 void qdev_prop_set_macaddr(DeviceState *dev, const char *name,
1052                            const uint8_t *value)
1053 {
1054     char str[2 * 6 + 5 + 1];
1055     snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
1056              value[0], value[1], value[2], value[3], value[4], value[5]);
1057 
1058     object_property_set_str(OBJECT(dev), str, name, &error_abort);
1059 }
1060 
1061 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
1062 {
1063     Property *prop;
1064 
1065     prop = qdev_prop_find(dev, name);
1066     object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
1067                             name, &error_abort);
1068 }
1069 
1070 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
1071 {
1072     Property *prop;
1073     void **ptr;
1074 
1075     prop = qdev_prop_find(dev, name);
1076     assert(prop && prop->info == &qdev_prop_ptr);
1077     ptr = qdev_get_prop_ptr(dev, prop);
1078     *ptr = value;
1079 }
1080 
1081 static GList *global_props;
1082 
1083 void qdev_prop_register_global(GlobalProperty *prop)
1084 {
1085     global_props = g_list_append(global_props, prop);
1086 }
1087 
1088 void register_compat_prop(const char *driver,
1089                           const char *property,
1090                           const char *value)
1091 {
1092     GlobalProperty *p = g_new0(GlobalProperty, 1);
1093 
1094     /* Any compat_props must never cause error */
1095     p->errp = &error_abort;
1096     p->driver = driver;
1097     p->property = property;
1098     p->value = value;
1099     qdev_prop_register_global(p);
1100 }
1101 
1102 void register_compat_props_array(GlobalProperty *prop)
1103 {
1104     for (; prop && prop->driver; prop++) {
1105         register_compat_prop(prop->driver, prop->property, prop->value);
1106     }
1107 }
1108 
1109 void qdev_prop_register_global_list(GlobalProperty *props)
1110 {
1111     int i;
1112 
1113     for (i = 0; props[i].driver != NULL; i++) {
1114         qdev_prop_register_global(props+i);
1115     }
1116 }
1117 
1118 int qdev_prop_check_globals(void)
1119 {
1120     GList *l;
1121     int ret = 0;
1122 
1123     for (l = global_props; l; l = l->next) {
1124         GlobalProperty *prop = l->data;
1125         ObjectClass *oc;
1126         DeviceClass *dc;
1127         if (prop->used) {
1128             continue;
1129         }
1130         if (!prop->user_provided) {
1131             continue;
1132         }
1133         oc = object_class_by_name(prop->driver);
1134         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
1135         if (!oc) {
1136             warn_report("global %s.%s has invalid class name",
1137                         prop->driver, prop->property);
1138             ret = 1;
1139             continue;
1140         }
1141         dc = DEVICE_CLASS(oc);
1142         if (!dc->hotpluggable && !prop->used) {
1143             warn_report("global %s.%s=%s not used",
1144                         prop->driver, prop->property, prop->value);
1145             ret = 1;
1146             continue;
1147         }
1148     }
1149     return ret;
1150 }
1151 
1152 static void qdev_prop_set_globals_for_type(DeviceState *dev,
1153                                            const char *typename)
1154 {
1155     GList *l;
1156 
1157     for (l = global_props; l; l = l->next) {
1158         GlobalProperty *prop = l->data;
1159         Error *err = NULL;
1160 
1161         if (strcmp(typename, prop->driver) != 0) {
1162             continue;
1163         }
1164         prop->used = true;
1165         object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
1166         if (err != NULL) {
1167             error_prepend(&err, "can't apply global %s.%s=%s: ",
1168                           prop->driver, prop->property, prop->value);
1169             if (!dev->hotplugged && prop->errp) {
1170                 error_propagate(prop->errp, err);
1171             } else {
1172                 assert(prop->user_provided);
1173                 warn_report_err(err);
1174             }
1175         }
1176     }
1177 }
1178 
1179 void qdev_prop_set_globals(DeviceState *dev)
1180 {
1181     ObjectClass *class = object_get_class(OBJECT(dev));
1182 
1183     do {
1184         qdev_prop_set_globals_for_type(dev, object_class_get_name(class));
1185         class = object_class_get_parent(class);
1186     } while (class);
1187 }
1188 
1189 /* --- 64bit unsigned int 'size' type --- */
1190 
1191 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
1192                      Error **errp)
1193 {
1194     DeviceState *dev = DEVICE(obj);
1195     Property *prop = opaque;
1196     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1197 
1198     visit_type_size(v, name, ptr, errp);
1199 }
1200 
1201 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
1202                      Error **errp)
1203 {
1204     DeviceState *dev = DEVICE(obj);
1205     Property *prop = opaque;
1206     uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
1207 
1208     visit_type_size(v, name, ptr, errp);
1209 }
1210 
1211 const PropertyInfo qdev_prop_size = {
1212     .name  = "size",
1213     .get = get_size,
1214     .set = set_size,
1215     .set_default_value = set_default_value_uint,
1216 };
1217 
1218 /* --- object link property --- */
1219 
1220 static void create_link_property(Object *obj, Property *prop, Error **errp)
1221 {
1222     Object **child = qdev_get_prop_ptr(DEVICE(obj), prop);
1223 
1224     object_property_add_link(obj, prop->name, prop->link_type,
1225                              child,
1226                              qdev_prop_allow_set_link_before_realize,
1227                              OBJ_PROP_LINK_UNREF_ON_RELEASE,
1228                              errp);
1229 }
1230 
1231 const PropertyInfo qdev_prop_link = {
1232     .name = "link",
1233     .create = create_link_property,
1234 };
1235