qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

qdev-properties.c (27557B)


      1 #include "qemu/osdep.h"
      2 #include "hw/qdev-properties.h"
      3 #include "qapi/error.h"
      4 #include "qapi/qapi-types-misc.h"
      5 #include "qapi/qmp/qerror.h"
      6 #include "qemu/ctype.h"
      7 #include "qemu/error-report.h"
      8 #include "qapi/visitor.h"
      9 #include "qemu/units.h"
     10 #include "qemu/cutils.h"
     11 #include "qdev-prop-internal.h"
     12 
     13 void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
     14                                   Error **errp)
     15 {
     16     if (dev->id) {
     17         error_setg(errp, "Attempt to set property '%s' on device '%s' "
     18                    "(type '%s') after it was realized", name, dev->id,
     19                    object_get_typename(OBJECT(dev)));
     20     } else {
     21         error_setg(errp, "Attempt to set property '%s' on anonymous device "
     22                    "(type '%s') after it was realized", name,
     23                    object_get_typename(OBJECT(dev)));
     24     }
     25 }
     26 
     27 /* returns: true if property is allowed to be set, false otherwise */
     28 static bool qdev_prop_allow_set(Object *obj, const char *name,
     29                                 const PropertyInfo *info, Error **errp)
     30 {
     31     DeviceState *dev = DEVICE(obj);
     32 
     33     if (dev->realized && !info->realized_set_allowed) {
     34         qdev_prop_set_after_realize(dev, name, errp);
     35         return false;
     36     }
     37     return true;
     38 }
     39 
     40 void qdev_prop_allow_set_link_before_realize(const Object *obj,
     41                                              const char *name,
     42                                              Object *val, Error **errp)
     43 {
     44     DeviceState *dev = DEVICE(obj);
     45 
     46     if (dev->realized) {
     47         error_setg(errp, "Attempt to set link property '%s' on device '%s' "
     48                    "(type '%s') after it was realized",
     49                    name, dev->id, object_get_typename(obj));
     50     }
     51 }
     52 
     53 void *object_field_prop_ptr(Object *obj, Property *prop)
     54 {
     55     void *ptr = obj;
     56     ptr += prop->offset;
     57     return ptr;
     58 }
     59 
     60 static void field_prop_get(Object *obj, Visitor *v, const char *name,
     61                            void *opaque, Error **errp)
     62 {
     63     Property *prop = opaque;
     64     return prop->info->get(obj, v, name, opaque, errp);
     65 }
     66 
     67 /**
     68  * field_prop_getter: Return getter function to be used for property
     69  *
     70  * Return value can be NULL if @info has no getter function.
     71  */
     72 static ObjectPropertyAccessor *field_prop_getter(const PropertyInfo *info)
     73 {
     74     return info->get ? field_prop_get : NULL;
     75 }
     76 
     77 static void field_prop_set(Object *obj, Visitor *v, const char *name,
     78                            void *opaque, Error **errp)
     79 {
     80     Property *prop = opaque;
     81 
     82     if (!qdev_prop_allow_set(obj, name, prop->info, errp)) {
     83         return;
     84     }
     85 
     86     return prop->info->set(obj, v, name, opaque, errp);
     87 }
     88 
     89 /**
     90  * field_prop_setter: Return setter function to be used for property
     91  *
     92  * Return value can be NULL if @info has not setter function.
     93  */
     94 static ObjectPropertyAccessor *field_prop_setter(const PropertyInfo *info)
     95 {
     96     return info->set ? field_prop_set : NULL;
     97 }
     98 
     99 void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
    100                             void *opaque, Error **errp)
    101 {
    102     Property *prop = opaque;
    103     int *ptr = object_field_prop_ptr(obj, prop);
    104 
    105     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
    106 }
    107 
    108 void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
    109                             void *opaque, Error **errp)
    110 {
    111     Property *prop = opaque;
    112     int *ptr = object_field_prop_ptr(obj, prop);
    113 
    114     visit_type_enum(v, name, ptr, prop->info->enum_table, errp);
    115 }
    116 
    117 void qdev_propinfo_set_default_value_enum(ObjectProperty *op,
    118                                           const Property *prop)
    119 {
    120     object_property_set_default_str(op,
    121         qapi_enum_lookup(prop->info->enum_table, prop->defval.i));
    122 }
    123 
    124 const PropertyInfo qdev_prop_enum = {
    125     .name  = "enum",
    126     .get   = qdev_propinfo_get_enum,
    127     .set   = qdev_propinfo_set_enum,
    128     .set_default_value = qdev_propinfo_set_default_value_enum,
    129 };
    130 
    131 /* Bit */
    132 
    133 static uint32_t qdev_get_prop_mask(Property *prop)
    134 {
    135     assert(prop->info == &qdev_prop_bit);
    136     return 0x1 << prop->bitnr;
    137 }
    138 
    139 static void bit_prop_set(Object *obj, Property *props, bool val)
    140 {
    141     uint32_t *p = object_field_prop_ptr(obj, props);
    142     uint32_t mask = qdev_get_prop_mask(props);
    143     if (val) {
    144         *p |= mask;
    145     } else {
    146         *p &= ~mask;
    147     }
    148 }
    149 
    150 static void prop_get_bit(Object *obj, Visitor *v, const char *name,
    151                          void *opaque, Error **errp)
    152 {
    153     Property *prop = opaque;
    154     uint32_t *p = object_field_prop_ptr(obj, prop);
    155     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
    156 
    157     visit_type_bool(v, name, &value, errp);
    158 }
    159 
    160 static void prop_set_bit(Object *obj, Visitor *v, const char *name,
    161                          void *opaque, Error **errp)
    162 {
    163     Property *prop = opaque;
    164     bool value;
    165 
    166     if (!visit_type_bool(v, name, &value, errp)) {
    167         return;
    168     }
    169     bit_prop_set(obj, prop, value);
    170 }
    171 
    172 static void set_default_value_bool(ObjectProperty *op, const Property *prop)
    173 {
    174     object_property_set_default_bool(op, prop->defval.u);
    175 }
    176 
    177 const PropertyInfo qdev_prop_bit = {
    178     .name  = "bool",
    179     .description = "on/off",
    180     .get   = prop_get_bit,
    181     .set   = prop_set_bit,
    182     .set_default_value = set_default_value_bool,
    183 };
    184 
    185 /* Bit64 */
    186 
    187 static uint64_t qdev_get_prop_mask64(Property *prop)
    188 {
    189     assert(prop->info == &qdev_prop_bit64);
    190     return 0x1ull << prop->bitnr;
    191 }
    192 
    193 static void bit64_prop_set(Object *obj, Property *props, bool val)
    194 {
    195     uint64_t *p = object_field_prop_ptr(obj, props);
    196     uint64_t mask = qdev_get_prop_mask64(props);
    197     if (val) {
    198         *p |= mask;
    199     } else {
    200         *p &= ~mask;
    201     }
    202 }
    203 
    204 static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
    205                            void *opaque, Error **errp)
    206 {
    207     Property *prop = opaque;
    208     uint64_t *p = object_field_prop_ptr(obj, prop);
    209     bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
    210 
    211     visit_type_bool(v, name, &value, errp);
    212 }
    213 
    214 static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
    215                            void *opaque, Error **errp)
    216 {
    217     Property *prop = opaque;
    218     bool value;
    219 
    220     if (!visit_type_bool(v, name, &value, errp)) {
    221         return;
    222     }
    223     bit64_prop_set(obj, prop, value);
    224 }
    225 
    226 const PropertyInfo qdev_prop_bit64 = {
    227     .name  = "bool",
    228     .description = "on/off",
    229     .get   = prop_get_bit64,
    230     .set   = prop_set_bit64,
    231     .set_default_value = set_default_value_bool,
    232 };
    233 
    234 /* --- bool --- */
    235 
    236 static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
    237                      Error **errp)
    238 {
    239     Property *prop = opaque;
    240     bool *ptr = object_field_prop_ptr(obj, prop);
    241 
    242     visit_type_bool(v, name, ptr, errp);
    243 }
    244 
    245 static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
    246                      Error **errp)
    247 {
    248     Property *prop = opaque;
    249     bool *ptr = object_field_prop_ptr(obj, prop);
    250 
    251     visit_type_bool(v, name, ptr, errp);
    252 }
    253 
    254 const PropertyInfo qdev_prop_bool = {
    255     .name  = "bool",
    256     .get   = get_bool,
    257     .set   = set_bool,
    258     .set_default_value = set_default_value_bool,
    259 };
    260 
    261 /* --- 8bit integer --- */
    262 
    263 static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
    264                       Error **errp)
    265 {
    266     Property *prop = opaque;
    267     uint8_t *ptr = object_field_prop_ptr(obj, prop);
    268 
    269     visit_type_uint8(v, name, ptr, errp);
    270 }
    271 
    272 static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
    273                       Error **errp)
    274 {
    275     Property *prop = opaque;
    276     uint8_t *ptr = object_field_prop_ptr(obj, prop);
    277 
    278     visit_type_uint8(v, name, ptr, errp);
    279 }
    280 
    281 void qdev_propinfo_set_default_value_int(ObjectProperty *op,
    282                                          const Property *prop)
    283 {
    284     object_property_set_default_int(op, prop->defval.i);
    285 }
    286 
    287 void qdev_propinfo_set_default_value_uint(ObjectProperty *op,
    288                                           const Property *prop)
    289 {
    290     object_property_set_default_uint(op, prop->defval.u);
    291 }
    292 
    293 const PropertyInfo qdev_prop_uint8 = {
    294     .name  = "uint8",
    295     .get   = get_uint8,
    296     .set   = set_uint8,
    297     .set_default_value = qdev_propinfo_set_default_value_uint,
    298 };
    299 
    300 /* --- 16bit integer --- */
    301 
    302 static void get_uint16(Object *obj, Visitor *v, const char *name,
    303                        void *opaque, Error **errp)
    304 {
    305     Property *prop = opaque;
    306     uint16_t *ptr = object_field_prop_ptr(obj, prop);
    307 
    308     visit_type_uint16(v, name, ptr, errp);
    309 }
    310 
    311 static void set_uint16(Object *obj, Visitor *v, const char *name,
    312                        void *opaque, Error **errp)
    313 {
    314     Property *prop = opaque;
    315     uint16_t *ptr = object_field_prop_ptr(obj, prop);
    316 
    317     visit_type_uint16(v, name, ptr, errp);
    318 }
    319 
    320 const PropertyInfo qdev_prop_uint16 = {
    321     .name  = "uint16",
    322     .get   = get_uint16,
    323     .set   = set_uint16,
    324     .set_default_value = qdev_propinfo_set_default_value_uint,
    325 };
    326 
    327 /* --- 32bit integer --- */
    328 
    329 static void get_uint32(Object *obj, Visitor *v, const char *name,
    330                        void *opaque, Error **errp)
    331 {
    332     Property *prop = opaque;
    333     uint32_t *ptr = object_field_prop_ptr(obj, prop);
    334 
    335     visit_type_uint32(v, name, ptr, errp);
    336 }
    337 
    338 static void set_uint32(Object *obj, Visitor *v, const char *name,
    339                        void *opaque, Error **errp)
    340 {
    341     Property *prop = opaque;
    342     uint32_t *ptr = object_field_prop_ptr(obj, prop);
    343 
    344     visit_type_uint32(v, name, ptr, errp);
    345 }
    346 
    347 void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
    348                              void *opaque, Error **errp)
    349 {
    350     Property *prop = opaque;
    351     int32_t *ptr = object_field_prop_ptr(obj, prop);
    352 
    353     visit_type_int32(v, name, ptr, errp);
    354 }
    355 
    356 static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
    357                       Error **errp)
    358 {
    359     Property *prop = opaque;
    360     int32_t *ptr = object_field_prop_ptr(obj, prop);
    361 
    362     visit_type_int32(v, name, ptr, errp);
    363 }
    364 
    365 const PropertyInfo qdev_prop_uint32 = {
    366     .name  = "uint32",
    367     .get   = get_uint32,
    368     .set   = set_uint32,
    369     .set_default_value = qdev_propinfo_set_default_value_uint,
    370 };
    371 
    372 const PropertyInfo qdev_prop_int32 = {
    373     .name  = "int32",
    374     .get   = qdev_propinfo_get_int32,
    375     .set   = set_int32,
    376     .set_default_value = qdev_propinfo_set_default_value_int,
    377 };
    378 
    379 /* --- 64bit integer --- */
    380 
    381 static void get_uint64(Object *obj, Visitor *v, const char *name,
    382                        void *opaque, Error **errp)
    383 {
    384     Property *prop = opaque;
    385     uint64_t *ptr = object_field_prop_ptr(obj, prop);
    386 
    387     visit_type_uint64(v, name, ptr, errp);
    388 }
    389 
    390 static void set_uint64(Object *obj, Visitor *v, const char *name,
    391                        void *opaque, Error **errp)
    392 {
    393     Property *prop = opaque;
    394     uint64_t *ptr = object_field_prop_ptr(obj, prop);
    395 
    396     visit_type_uint64(v, name, ptr, errp);
    397 }
    398 
    399 static void get_int64(Object *obj, Visitor *v, const char *name,
    400                       void *opaque, Error **errp)
    401 {
    402     Property *prop = opaque;
    403     int64_t *ptr = object_field_prop_ptr(obj, prop);
    404 
    405     visit_type_int64(v, name, ptr, errp);
    406 }
    407 
    408 static void set_int64(Object *obj, Visitor *v, const char *name,
    409                       void *opaque, Error **errp)
    410 {
    411     Property *prop = opaque;
    412     int64_t *ptr = object_field_prop_ptr(obj, prop);
    413 
    414     visit_type_int64(v, name, ptr, errp);
    415 }
    416 
    417 const PropertyInfo qdev_prop_uint64 = {
    418     .name  = "uint64",
    419     .get   = get_uint64,
    420     .set   = set_uint64,
    421     .set_default_value = qdev_propinfo_set_default_value_uint,
    422 };
    423 
    424 const PropertyInfo qdev_prop_int64 = {
    425     .name  = "int64",
    426     .get   = get_int64,
    427     .set   = set_int64,
    428     .set_default_value = qdev_propinfo_set_default_value_int,
    429 };
    430 
    431 static void set_uint64_checkmask(Object *obj, Visitor *v, const char *name,
    432                       void *opaque, Error **errp)
    433 {
    434     Property *prop = opaque;
    435     uint64_t *ptr = object_field_prop_ptr(obj, prop);
    436 
    437     visit_type_uint64(v, name, ptr, errp);
    438     if (*ptr & ~prop->bitmask) {
    439         error_setg(errp, "Property value for '%s' has bits outside mask '0x%" PRIx64 "'",
    440                    name, prop->bitmask);
    441     }
    442 }
    443 
    444 const PropertyInfo qdev_prop_uint64_checkmask = {
    445     .name  = "uint64",
    446     .get   = get_uint64,
    447     .set   = set_uint64_checkmask,
    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 **)object_field_prop_ptr(obj, prop));
    456 }
    457 
    458 static void get_string(Object *obj, Visitor *v, const char *name,
    459                        void *opaque, Error **errp)
    460 {
    461     Property *prop = opaque;
    462     char **ptr = object_field_prop_ptr(obj, prop);
    463 
    464     if (!*ptr) {
    465         char *str = (char *)"";
    466         visit_type_str(v, name, &str, errp);
    467     } else {
    468         visit_type_str(v, name, ptr, errp);
    469     }
    470 }
    471 
    472 static void set_string(Object *obj, Visitor *v, const char *name,
    473                        void *opaque, Error **errp)
    474 {
    475     Property *prop = opaque;
    476     char **ptr = object_field_prop_ptr(obj, prop);
    477     char *str;
    478 
    479     if (!visit_type_str(v, name, &str, errp)) {
    480         return;
    481     }
    482     g_free(*ptr);
    483     *ptr = str;
    484 }
    485 
    486 const PropertyInfo qdev_prop_string = {
    487     .name  = "str",
    488     .release = release_string,
    489     .get   = get_string,
    490     .set   = set_string,
    491 };
    492 
    493 /* --- on/off/auto --- */
    494 
    495 const PropertyInfo qdev_prop_on_off_auto = {
    496     .name = "OnOffAuto",
    497     .description = "on/off/auto",
    498     .enum_table = &OnOffAuto_lookup,
    499     .get = qdev_propinfo_get_enum,
    500     .set = qdev_propinfo_set_enum,
    501     .set_default_value = qdev_propinfo_set_default_value_enum,
    502 };
    503 
    504 /* --- 32bit unsigned int 'size' type --- */
    505 
    506 void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
    507                               void *opaque, Error **errp)
    508 {
    509     Property *prop = opaque;
    510     uint32_t *ptr = object_field_prop_ptr(obj, prop);
    511     uint64_t value = *ptr;
    512 
    513     visit_type_size(v, name, &value, errp);
    514 }
    515 
    516 static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
    517                        Error **errp)
    518 {
    519     Property *prop = opaque;
    520     uint32_t *ptr = object_field_prop_ptr(obj, prop);
    521     uint64_t value;
    522 
    523     if (!visit_type_size(v, name, &value, errp)) {
    524         return;
    525     }
    526 
    527     if (value > UINT32_MAX) {
    528         error_setg(errp,
    529                    "Property %s.%s doesn't take value %" PRIu64
    530                    " (maximum: %u)",
    531                    object_get_typename(obj), name, value, UINT32_MAX);
    532         return;
    533     }
    534 
    535     *ptr = value;
    536 }
    537 
    538 const PropertyInfo qdev_prop_size32 = {
    539     .name  = "size",
    540     .get = qdev_propinfo_get_size32,
    541     .set = set_size32,
    542     .set_default_value = qdev_propinfo_set_default_value_uint,
    543 };
    544 
    545 /* --- support for array properties --- */
    546 
    547 /* Used as an opaque for the object properties we add for each
    548  * array element. Note that the struct Property must be first
    549  * in the struct so that a pointer to this works as the opaque
    550  * for the underlying element's property hooks as well as for
    551  * our own release callback.
    552  */
    553 typedef struct {
    554     struct Property prop;
    555     char *propname;
    556     ObjectPropertyRelease *release;
    557 } ArrayElementProperty;
    558 
    559 /* object property release callback for array element properties:
    560  * we call the underlying element's property release hook, and
    561  * then free the memory we allocated when we added the property.
    562  */
    563 static void array_element_release(Object *obj, const char *name, void *opaque)
    564 {
    565     ArrayElementProperty *p = opaque;
    566     if (p->release) {
    567         p->release(obj, name, opaque);
    568     }
    569     g_free(p->propname);
    570     g_free(p);
    571 }
    572 
    573 static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
    574                               void *opaque, Error **errp)
    575 {
    576     /* Setter for the property which defines the length of a
    577      * variable-sized property array. As well as actually setting the
    578      * array-length field in the device struct, we have to create the
    579      * array itself and dynamically add the corresponding properties.
    580      */
    581     Property *prop = opaque;
    582     uint32_t *alenptr = object_field_prop_ptr(obj, prop);
    583     void **arrayptr = (void *)obj + prop->arrayoffset;
    584     void *eltptr;
    585     const char *arrayname;
    586     int i;
    587 
    588     if (*alenptr) {
    589         error_setg(errp, "array size property %s may not be set more than once",
    590                    name);
    591         return;
    592     }
    593     if (!visit_type_uint32(v, name, alenptr, errp)) {
    594         return;
    595     }
    596     if (!*alenptr) {
    597         return;
    598     }
    599 
    600     /* DEFINE_PROP_ARRAY guarantees that name should start with this prefix;
    601      * strip it off so we can get the name of the array itself.
    602      */
    603     assert(strncmp(name, PROP_ARRAY_LEN_PREFIX,
    604                    strlen(PROP_ARRAY_LEN_PREFIX)) == 0);
    605     arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX);
    606 
    607     /* Note that it is the responsibility of the individual device's deinit
    608      * to free the array proper.
    609      */
    610     *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize);
    611     for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) {
    612         char *propname = g_strdup_printf("%s[%d]", arrayname, i);
    613         ArrayElementProperty *arrayprop = g_new0(ArrayElementProperty, 1);
    614         arrayprop->release = prop->arrayinfo->release;
    615         arrayprop->propname = propname;
    616         arrayprop->prop.info = prop->arrayinfo;
    617         arrayprop->prop.name = propname;
    618         /* This ugly piece of pointer arithmetic sets up the offset so
    619          * that when the underlying get/set hooks call qdev_get_prop_ptr
    620          * they get the right answer despite the array element not actually
    621          * being inside the device struct.
    622          */
    623         arrayprop->prop.offset = eltptr - (void *)obj;
    624         assert(object_field_prop_ptr(obj, &arrayprop->prop) == eltptr);
    625         object_property_add(obj, propname,
    626                             arrayprop->prop.info->name,
    627                             field_prop_getter(arrayprop->prop.info),
    628                             field_prop_setter(arrayprop->prop.info),
    629                             array_element_release,
    630                             arrayprop);
    631     }
    632 }
    633 
    634 const PropertyInfo qdev_prop_arraylen = {
    635     .name = "uint32",
    636     .get = get_uint32,
    637     .set = set_prop_arraylen,
    638     .set_default_value = qdev_propinfo_set_default_value_uint,
    639 };
    640 
    641 /* --- public helpers --- */
    642 
    643 static Property *qdev_prop_walk(Property *props, const char *name)
    644 {
    645     if (!props) {
    646         return NULL;
    647     }
    648     while (props->name) {
    649         if (strcmp(props->name, name) == 0) {
    650             return props;
    651         }
    652         props++;
    653     }
    654     return NULL;
    655 }
    656 
    657 static Property *qdev_prop_find(DeviceState *dev, const char *name)
    658 {
    659     ObjectClass *class;
    660     Property *prop;
    661 
    662     /* device properties */
    663     class = object_get_class(OBJECT(dev));
    664     do {
    665         prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name);
    666         if (prop) {
    667             return prop;
    668         }
    669         class = object_class_get_parent(class);
    670     } while (class != object_class_by_name(TYPE_DEVICE));
    671 
    672     return NULL;
    673 }
    674 
    675 void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
    676                                     const char *name, const char *value)
    677 {
    678     switch (ret) {
    679     case -EEXIST:
    680         error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
    681                   object_get_typename(obj), name, value);
    682         break;
    683     default:
    684     case -EINVAL:
    685         error_setg(errp, QERR_PROPERTY_VALUE_BAD,
    686                    object_get_typename(obj), name, value);
    687         break;
    688     case -ENOENT:
    689         error_setg(errp, "Property '%s.%s' can't find value '%s'",
    690                   object_get_typename(obj), name, value);
    691         break;
    692     case 0:
    693         break;
    694     }
    695 }
    696 
    697 void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
    698 {
    699     object_property_set_bool(OBJECT(dev), name, value, &error_abort);
    700 }
    701 
    702 void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
    703 {
    704     object_property_set_int(OBJECT(dev), name, value, &error_abort);
    705 }
    706 
    707 void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
    708 {
    709     object_property_set_int(OBJECT(dev), name, value, &error_abort);
    710 }
    711 
    712 void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
    713 {
    714     object_property_set_int(OBJECT(dev), name, value, &error_abort);
    715 }
    716 
    717 void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
    718 {
    719     object_property_set_int(OBJECT(dev), name, value, &error_abort);
    720 }
    721 
    722 void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
    723 {
    724     object_property_set_int(OBJECT(dev), name, value, &error_abort);
    725 }
    726 
    727 void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value)
    728 {
    729     object_property_set_str(OBJECT(dev), name, value, &error_abort);
    730 }
    731 
    732 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
    733 {
    734     Property *prop;
    735 
    736     prop = qdev_prop_find(dev, name);
    737     object_property_set_str(OBJECT(dev), name,
    738                             qapi_enum_lookup(prop->info->enum_table, value),
    739                             &error_abort);
    740 }
    741 
    742 static GPtrArray *global_props(void)
    743 {
    744     static GPtrArray *gp;
    745 
    746     if (!gp) {
    747         gp = g_ptr_array_new();
    748     }
    749 
    750     return gp;
    751 }
    752 
    753 void qdev_prop_register_global(GlobalProperty *prop)
    754 {
    755     g_ptr_array_add(global_props(), prop);
    756 }
    757 
    758 const GlobalProperty *qdev_find_global_prop(Object *obj,
    759                                             const char *name)
    760 {
    761     GPtrArray *props = global_props();
    762     const GlobalProperty *p;
    763     int i;
    764 
    765     for (i = 0; i < props->len; i++) {
    766         p = g_ptr_array_index(props, i);
    767         if (object_dynamic_cast(obj, p->driver)
    768             && !strcmp(p->property, name)) {
    769             return p;
    770         }
    771     }
    772     return NULL;
    773 }
    774 
    775 int qdev_prop_check_globals(void)
    776 {
    777     int i, ret = 0;
    778 
    779     for (i = 0; i < global_props()->len; i++) {
    780         GlobalProperty *prop;
    781         ObjectClass *oc;
    782         DeviceClass *dc;
    783 
    784         prop = g_ptr_array_index(global_props(), i);
    785         if (prop->used) {
    786             continue;
    787         }
    788         oc = object_class_by_name(prop->driver);
    789         oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
    790         if (!oc) {
    791             warn_report("global %s.%s has invalid class name",
    792                         prop->driver, prop->property);
    793             ret = 1;
    794             continue;
    795         }
    796         dc = DEVICE_CLASS(oc);
    797         if (!dc->hotpluggable && !prop->used) {
    798             warn_report("global %s.%s=%s not used",
    799                         prop->driver, prop->property, prop->value);
    800             ret = 1;
    801             continue;
    802         }
    803     }
    804     return ret;
    805 }
    806 
    807 void qdev_prop_set_globals(DeviceState *dev)
    808 {
    809     object_apply_global_props(OBJECT(dev), global_props(),
    810                               dev->hotplugged ? NULL : &error_fatal);
    811 }
    812 
    813 /* --- 64bit unsigned int 'size' type --- */
    814 
    815 static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
    816                      Error **errp)
    817 {
    818     Property *prop = opaque;
    819     uint64_t *ptr = object_field_prop_ptr(obj, prop);
    820 
    821     visit_type_size(v, name, ptr, errp);
    822 }
    823 
    824 static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
    825                      Error **errp)
    826 {
    827     Property *prop = opaque;
    828     uint64_t *ptr = object_field_prop_ptr(obj, prop);
    829 
    830     visit_type_size(v, name, ptr, errp);
    831 }
    832 
    833 const PropertyInfo qdev_prop_size = {
    834     .name  = "size",
    835     .get = get_size,
    836     .set = set_size,
    837     .set_default_value = qdev_propinfo_set_default_value_uint,
    838 };
    839 
    840 /* --- object link property --- */
    841 
    842 static ObjectProperty *create_link_property(ObjectClass *oc, const char *name,
    843                                             Property *prop)
    844 {
    845     return object_class_property_add_link(oc, name, prop->link_type,
    846                                           prop->offset,
    847                                           qdev_prop_allow_set_link_before_realize,
    848                                           OBJ_PROP_LINK_STRONG);
    849 }
    850 
    851 const PropertyInfo qdev_prop_link = {
    852     .name = "link",
    853     .create = create_link_property,
    854 };
    855 
    856 void qdev_property_add_static(DeviceState *dev, Property *prop)
    857 {
    858     Object *obj = OBJECT(dev);
    859     ObjectProperty *op;
    860 
    861     assert(!prop->info->create);
    862 
    863     op = object_property_add(obj, prop->name, prop->info->name,
    864                              field_prop_getter(prop->info),
    865                              field_prop_setter(prop->info),
    866                              prop->info->release,
    867                              prop);
    868 
    869     object_property_set_description(obj, prop->name,
    870                                     prop->info->description);
    871 
    872     if (prop->set_default) {
    873         prop->info->set_default_value(op, prop);
    874         if (op->init) {
    875             op->init(obj, op);
    876         }
    877     }
    878 }
    879 
    880 static void qdev_class_add_property(DeviceClass *klass, const char *name,
    881                                     Property *prop)
    882 {
    883     ObjectClass *oc = OBJECT_CLASS(klass);
    884     ObjectProperty *op;
    885 
    886     if (prop->info->create) {
    887         op = prop->info->create(oc, name, prop);
    888     } else {
    889         op = object_class_property_add(oc,
    890                                        name, prop->info->name,
    891                                        field_prop_getter(prop->info),
    892                                        field_prop_setter(prop->info),
    893                                        prop->info->release,
    894                                        prop);
    895     }
    896     if (prop->set_default) {
    897         prop->info->set_default_value(op, prop);
    898     }
    899     object_class_property_set_description(oc, name, prop->info->description);
    900 }
    901 
    902 /**
    903  * Legacy property handling
    904  */
    905 
    906 static void qdev_get_legacy_property(Object *obj, Visitor *v,
    907                                      const char *name, void *opaque,
    908                                      Error **errp)
    909 {
    910     Property *prop = opaque;
    911 
    912     char buffer[1024];
    913     char *ptr = buffer;
    914 
    915     prop->info->print(obj, prop, buffer, sizeof(buffer));
    916     visit_type_str(v, name, &ptr, errp);
    917 }
    918 
    919 /**
    920  * qdev_class_add_legacy_property:
    921  * @dev: Device to add the property to.
    922  * @prop: The qdev property definition.
    923  *
    924  * Add a legacy QOM property to @dev for qdev property @prop.
    925  *
    926  * Legacy properties are string versions of QOM properties.  The format of
    927  * the string depends on the property type.  Legacy properties are only
    928  * needed for "info qtree".
    929  *
    930  * Do not use this in new code!  QOM Properties added through this interface
    931  * will be given names in the "legacy" namespace.
    932  */
    933 static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
    934 {
    935     g_autofree char *name = NULL;
    936 
    937     /* Register pointer properties as legacy properties */
    938     if (!prop->info->print && prop->info->get) {
    939         return;
    940     }
    941 
    942     name = g_strdup_printf("legacy-%s", prop->name);
    943     object_class_property_add(OBJECT_CLASS(dc), name, "str",
    944         prop->info->print ? qdev_get_legacy_property : prop->info->get,
    945         NULL, NULL, prop);
    946 }
    947 
    948 void device_class_set_props(DeviceClass *dc, Property *props)
    949 {
    950     Property *prop;
    951 
    952     dc->props_ = props;
    953     for (prop = props; prop && prop->name; prop++) {
    954         qdev_class_add_legacy_property(dc, prop);
    955         qdev_class_add_property(dc, prop->name, prop);
    956     }
    957 }
    958 
    959 void qdev_alias_all_properties(DeviceState *target, Object *source)
    960 {
    961     ObjectClass *class;
    962     Property *prop;
    963 
    964     class = object_get_class(OBJECT(target));
    965     do {
    966         DeviceClass *dc = DEVICE_CLASS(class);
    967 
    968         for (prop = dc->props_; prop && prop->name; prop++) {
    969             object_property_add_alias(source, prop->name,
    970                                       OBJECT(target), prop->name);
    971         }
    972         class = object_class_get_parent(class);
    973     } while (class != object_class_by_name(TYPE_DEVICE));
    974 }