On Wed, Nov 04, 2020 at 05:36:20PM +0100, Paolo Bonzini wrote: > On 04/11/20 17:00, Eduardo Habkost wrote: > > Move all property types from qdev-properties.c to > > qom/property-types.c. > > > > Signed-off-by: Eduardo Habkost <ehabk...@redhat.com> > > --- > > Changes v1 -> v2: > > * Rebased after changes in previous patches in the series > > --- > > Cc: Paolo Bonzini <pbonz...@redhat.com> > > Cc: "Daniel P. Berrangé" <berra...@redhat.com> > > Cc: Eduardo Habkost <ehabk...@redhat.com> > > Cc: qemu-devel@nongnu.org > > --- > > include/hw/qdev-properties.h | 179 +----------- > > include/qom/property-types.h | 185 ++++++++++++ > > hw/core/qdev-properties.c | 537 ---------------------------------- > > qom/property-types.c | 545 +++++++++++++++++++++++++++++++++++ > > qom/meson.build | 1 + > > 5 files changed, 732 insertions(+), 715 deletions(-) > > create mode 100644 include/qom/property-types.h > > create mode 100644 qom/property-types.c > > I would merge property-types.h and field-property.h in a single file.
I like keeping them separate, to force us to define the API used to create new property types clearly. What if I create a qom/qom.h header that includes object.h + field-properties.h + property-types.h to make this easier to use? > > Actually I wouldn't even bother having separate headers, however it's > certainly valuable to have headers like you have in patch 42: > > Core QOM API Reference > ---------------------- > > .... > > > Field Property API Reference > ---------------------------- > > .... > > > > I'm not sure if it's possible to include rST headers in .h files. It is possible to include rST headers in doc comments, but the way the DOC: blocks work in kernel-doc is weird and has subtle rules and side effects. > > Paolo > > > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h > > index bee26d0319..939b6dbf4e 100644 > > --- a/include/hw/qdev-properties.h > > +++ b/include/hw/qdev-properties.h > > @@ -3,184 +3,7 @@ > > #include "hw/qdev-core.h" > > #include "qom/field-property.h" > > - > > -/*** qdev-properties.c ***/ > > - > > -extern const PropertyInfo prop_info_bit; > > -extern const PropertyInfo prop_info_bit64; > > -extern const PropertyInfo prop_info_bool; > > -extern const PropertyInfo prop_info_enum; > > -extern const PropertyInfo prop_info_uint8; > > -extern const PropertyInfo prop_info_uint16; > > -extern const PropertyInfo prop_info_uint32; > > -extern const PropertyInfo prop_info_int32; > > -extern const PropertyInfo prop_info_uint64; > > -extern const PropertyInfo prop_info_int64; > > -extern const PropertyInfo prop_info_size; > > -extern const PropertyInfo prop_info_string; > > -extern const PropertyInfo prop_info_on_off_auto; > > -extern const PropertyInfo prop_info_size32; > > -extern const PropertyInfo prop_info_arraylen; > > -extern const PropertyInfo prop_info_link; > > - > > -#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) { \ > > - .qdev_prop_name = (_name), \ > > - .info = &(_prop), \ > > - .offset = offsetof(_state, _field) \ > > - + type_check(_type, typeof_field(_state, _field)), \ > > - __VA_ARGS__ \ > > - } > > - > > -#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \ > > - DEFINE_PROP(_name, _state, _field, _prop, _type, \ > > - .set_default = true, \ > > - .defval.i = (_type)_defval) > > - > > -#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \ > > - DEFINE_PROP(_name, _state, _field, _prop, _type) > > - > > -#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) \ > > - DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \ > > - .bitnr = (_bit), \ > > - .set_default = true, \ > > - .defval.u = (bool)_defval) > > - > > -#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) > > \ > > - DEFINE_PROP(_name, _state, _field, _prop, _type, > > \ > > - .set_default = true, > > \ > > - .defval.u = (_type)_defval) > > - > > -#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, > > _type) \ > > - DEFINE_PROP(_name, _state, _field, _prop, _type) > > - > > -#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) \ > > - DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \ > > - .bitnr = (_bit), \ > > - .set_default = true, \ > > - .defval.u = (bool)_defval) > > - > > -#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \ > > - DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \ > > - .set_default = true, \ > > - .defval.u = (bool)_defval) > > - > > -#define PROP_ARRAY_LEN_PREFIX "len-" > > - > > -/** > > - * DEFINE_PROP_ARRAY: > > - * @_name: name of the array > > - * @_state: name of the device state structure type > > - * @_field: uint32_t field in @_state to hold the array length > > - * @_arrayfield: field in @_state (of type '@_arraytype *') which > > - * will point to the array > > - * @_arrayprop: PropertyInfo defining what property the array elements have > > - * @_arraytype: C type of the array elements > > - * > > - * Define device properties for a variable-length array _name. A > > - * static property "len-arrayname" is defined. When the device creator > > - * sets this property to the desired length of array, further dynamic > > - * properties "arrayname[0]", "arrayname[1]", ... are defined so the > > - * device creator can set the array element values. Setting the > > - * "len-arrayname" property more than once is an error. > > - * > > - * When the array length is set, the @_field member of the device > > - * struct is set to the array length, and @_arrayfield is set to point > > - * to (zero-initialised) memory allocated for the array. For a zero > > - * length array, @_field will be set to 0 and @_arrayfield to NULL. > > - * It is the responsibility of the device deinit code to free the > > - * @_arrayfield memory. > > - */ > > -#define DEFINE_PROP_ARRAY(_name, _state, _field, \ > > - _arrayfield, _arrayprop, _arraytype) \ > > - DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name), \ > > - _state, _field, prop_info_arraylen, uint32_t, \ > > - .set_default = true, \ > > - .defval.u = 0, \ > > - .arrayinfo = &(_arrayprop), \ > > - .arrayfieldsize = sizeof(_arraytype), \ > > - .arrayoffset = offsetof(_state, _arrayfield)) > > - > > -#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type) \ > > - DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type, \ > > - .link_type = _type) > > - > > -#define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ > > - DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t) > > -#define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ > > - DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t) > > -#define DEFINE_PROP_UINT32(_n, _s, _f, _d) \ > > - DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t) > > -#define DEFINE_PROP_INT32(_n, _s, _f, _d) \ > > - DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t) > > -#define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ > > - DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t) > > -#define DEFINE_PROP_INT64(_n, _s, _f, _d) \ > > - DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t) > > -#define DEFINE_PROP_SIZE(_n, _s, _f, _d) \ > > - DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t) > > -#define DEFINE_PROP_STRING(_n, _s, _f) \ > > - DEFINE_PROP(_n, _s, _f, prop_info_string, char*) > > -#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \ > > - DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto) > > -#define DEFINE_PROP_SIZE32(_n, _s, _f, _d) \ > > - DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t) > > - > > -#define DEFINE_PROP_END_OF_LIST() \ > > - {} > > - > > -/* > > - * The PROP_* macros can be used as arguments for > > - * object_class_property_add_field(). They will evaluate to a > > - * pointer to a static variable. > > - */ > > - > > -#define FIELD_PROP(def) \ > > - ({ static Property _p = def; &p; }) > > - > > -#define PROP_SIGNED(...) \ > > - FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__)) > > -#define PROP_SIGNED_NODEFAULT(...) \ > > - FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__)) > > -#define PROP_BIT(...) \ > > - FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__)) > > -#define PROP_UNSIGNED(...) \ > > - FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__)) > > -#define PROP_UNSIGNED_NODEFAULT(...) \ > > - FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__)) > > -#define PROP_BIT64(...) \ > > - FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__)) > > -#define PROP_BOOL(...) \ > > - FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__)) > > -#define PROP_ARRAY(...) \ > > - FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__)) > > -#define PROP_LINK(...) \ > > - FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__)) > > -#define PROP_UINT8(...) \ > > - FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__)) > > -#define PROP_UINT16(...) \ > > - FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__)) > > -#define PROP_UINT32(...) \ > > - FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__)) > > -#define PROP_INT32(...) \ > > - FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__)) > > -#define PROP_UINT64(...) \ > > - FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__)) > > -#define PROP_INT64(...) \ > > - FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__)) > > -#define PROP_SIZE(...) \ > > - FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__)) > > -#define PROP_STRING(...) \ > > - FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__)) > > -#define PROP_ON_OFF_AUTO(...) \ > > - FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__)) > > -#define PROP_SIZE32(...) \ > > - FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__)) > > -#define PROP_UUID(...) \ > > - FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__)) > > -#define PROP_UUID_NODEFAULT(...) \ > > - FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__)) > > -#define PROP_END_OF_LIST(...) \ > > - FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__)) > > +#include "qom/property-types.h" > > /* > > * Set properties between creation and realization. > > diff --git a/include/qom/property-types.h b/include/qom/property-types.h > > new file mode 100644 > > index 0000000000..75f758e835 > > --- /dev/null > > +++ b/include/qom/property-types.h > > @@ -0,0 +1,185 @@ > > +/* > > + * QOM field property types > > + */ > > +#ifndef QOM_PROPERTY_TYPES_H > > +#define QOM_PROPERTY_TYPES_H > > + > > +#include "qom/field-property.h" > > + > > +extern const PropertyInfo prop_info_bit; > > +extern const PropertyInfo prop_info_bit64; > > +extern const PropertyInfo prop_info_bool; > > +extern const PropertyInfo prop_info_enum; > > +extern const PropertyInfo prop_info_uint8; > > +extern const PropertyInfo prop_info_uint16; > > +extern const PropertyInfo prop_info_uint32; > > +extern const PropertyInfo prop_info_int32; > > +extern const PropertyInfo prop_info_uint64; > > +extern const PropertyInfo prop_info_int64; > > +extern const PropertyInfo prop_info_size; > > +extern const PropertyInfo prop_info_string; > > +extern const PropertyInfo prop_info_on_off_auto; > > +extern const PropertyInfo prop_info_size32; > > +extern const PropertyInfo prop_info_arraylen; > > +extern const PropertyInfo prop_info_link; > > + > > +#define DEFINE_PROP(_name, _state, _field, _prop, _type, ...) { \ > > + .qdev_prop_name = (_name), \ > > + .info = &(_prop), \ > > + .offset = offsetof(_state, _field) \ > > + + type_check(_type, typeof_field(_state, _field)), \ > > + __VA_ARGS__ \ > > + } > > + > > +#define DEFINE_PROP_SIGNED(_name, _state, _field, _defval, _prop, _type) \ > > + DEFINE_PROP(_name, _state, _field, _prop, _type, \ > > + .set_default = true, \ > > + .defval.i = (_type)_defval) > > + > > +#define DEFINE_PROP_SIGNED_NODEFAULT(_name, _state, _field, _prop, _type) \ > > + DEFINE_PROP(_name, _state, _field, _prop, _type) > > + > > +#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) \ > > + DEFINE_PROP(_name, _state, _field, prop_info_bit, uint32_t, \ > > + .bitnr = (_bit), \ > > + .set_default = true, \ > > + .defval.u = (bool)_defval) > > + > > +#define DEFINE_PROP_UNSIGNED(_name, _state, _field, _defval, _prop, _type) > > \ > > + DEFINE_PROP(_name, _state, _field, _prop, _type, > > \ > > + .set_default = true, > > \ > > + .defval.u = (_type)_defval) > > + > > +#define DEFINE_PROP_UNSIGNED_NODEFAULT(_name, _state, _field, _prop, > > _type) \ > > + DEFINE_PROP(_name, _state, _field, _prop, _type) > > + > > +#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) \ > > + DEFINE_PROP(_name, _state, _field, prop_info_bit64, uint64_t, \ > > + .bitnr = (_bit), \ > > + .set_default = true, \ > > + .defval.u = (bool)_defval) > > + > > +#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) \ > > + DEFINE_PROP(_name, _state, _field, prop_info_bool, bool, \ > > + .set_default = true, \ > > + .defval.u = (bool)_defval) > > + > > +#define PROP_ARRAY_LEN_PREFIX "len-" > > + > > +/** > > + * DEFINE_PROP_ARRAY: > > + * @_name: name of the array > > + * @_state: name of the device state structure type > > + * @_field: uint32_t field in @_state to hold the array length > > + * @_arrayfield: field in @_state (of type '@_arraytype *') which > > + * will point to the array > > + * @_arrayprop: PropertyInfo defining what property the array elements have > > + * @_arraytype: C type of the array elements > > + * > > + * Define device properties for a variable-length array _name. A > > + * static property "len-arrayname" is defined. When the device creator > > + * sets this property to the desired length of array, further dynamic > > + * properties "arrayname[0]", "arrayname[1]", ... are defined so the > > + * device creator can set the array element values. Setting the > > + * "len-arrayname" property more than once is an error. > > + * > > + * When the array length is set, the @_field member of the device > > + * struct is set to the array length, and @_arrayfield is set to point > > + * to (zero-initialised) memory allocated for the array. For a zero > > + * length array, @_field will be set to 0 and @_arrayfield to NULL. > > + * It is the responsibility of the device deinit code to free the > > + * @_arrayfield memory. > > + */ > > +#define DEFINE_PROP_ARRAY(_name, _state, _field, \ > > + _arrayfield, _arrayprop, _arraytype) \ > > + DEFINE_PROP((PROP_ARRAY_LEN_PREFIX _name), \ > > + _state, _field, prop_info_arraylen, uint32_t, \ > > + .set_default = true, \ > > + .defval.u = 0, \ > > + .arrayinfo = &(_arrayprop), \ > > + .arrayfieldsize = sizeof(_arraytype), \ > > + .arrayoffset = offsetof(_state, _arrayfield)) > > + > > +#define DEFINE_PROP_LINK(_name, _state, _field, _type, _ptr_type) \ > > + DEFINE_PROP(_name, _state, _field, prop_info_link, _ptr_type, \ > > + .link_type = _type) > > + > > +#define DEFINE_PROP_UINT8(_n, _s, _f, _d) \ > > + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint8, uint8_t) > > +#define DEFINE_PROP_UINT16(_n, _s, _f, _d) \ > > + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint16, uint16_t) > > +#define DEFINE_PROP_UINT32(_n, _s, _f, _d) \ > > + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint32, uint32_t) > > +#define DEFINE_PROP_INT32(_n, _s, _f, _d) \ > > + DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int32, int32_t) > > +#define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ > > + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_uint64, uint64_t) > > +#define DEFINE_PROP_INT64(_n, _s, _f, _d) \ > > + DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_int64, int64_t) > > +#define DEFINE_PROP_SIZE(_n, _s, _f, _d) \ > > + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size, uint64_t) > > +#define DEFINE_PROP_STRING(_n, _s, _f) \ > > + DEFINE_PROP(_n, _s, _f, prop_info_string, char*) > > +#define DEFINE_PROP_ON_OFF_AUTO(_n, _s, _f, _d) \ > > + DEFINE_PROP_SIGNED(_n, _s, _f, _d, prop_info_on_off_auto, OnOffAuto) > > +#define DEFINE_PROP_SIZE32(_n, _s, _f, _d) \ > > + DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, prop_info_size32, uint32_t) > > + > > +#define DEFINE_PROP_END_OF_LIST() \ > > + {} > > + > > +/* > > + * The PROP_* macros can be used as arguments for > > + * object_class_property_add_field(). They will evaluate to a > > + * pointer to a static variable. > > + */ > > + > > +#define FIELD_PROP(def) \ > > + ({ static Property _p = def; &p; }) > > + > > +#define PROP_SIGNED(...) \ > > + FIELD_PROP(DEFINE_PROP_SIGNED(NULL, __VA_ARGS__)) > > +#define PROP_SIGNED_NODEFAULT(...) \ > > + FIELD_PROP(DEFINE_PROP_SIGNED_NODEFAULT(NULL, __VA_ARGS__)) > > +#define PROP_BIT(...) \ > > + FIELD_PROP(DEFINE_PROP_BIT(NULL, __VA_ARGS__)) > > +#define PROP_UNSIGNED(...) \ > > + FIELD_PROP(DEFINE_PROP_UNSIGNED(NULL, __VA_ARGS__)) > > +#define PROP_UNSIGNED_NODEFAULT(...) \ > > + FIELD_PROP(DEFINE_PROP_UNSIGNED_NODEFAULT(NULL, __VA_ARGS__)) > > +#define PROP_BIT64(...) \ > > + FIELD_PROP(DEFINE_PROP_BIT64(NULL, __VA_ARGS__)) > > +#define PROP_BOOL(...) \ > > + FIELD_PROP(DEFINE_PROP_BOOL(NULL, __VA_ARGS__)) > > +#define PROP_ARRAY(...) \ > > + FIELD_PROP(DEFINE_PROP_ARRAY(NULL, __VA_ARGS__)) > > +#define PROP_LINK(...) \ > > + FIELD_PROP(DEFINE_PROP_LINK(NULL, __VA_ARGS__)) > > +#define PROP_UINT8(...) \ > > + FIELD_PROP(DEFINE_PROP_UINT8(NULL, __VA_ARGS__)) > > +#define PROP_UINT16(...) \ > > + FIELD_PROP(DEFINE_PROP_UINT16(NULL, __VA_ARGS__)) > > +#define PROP_UINT32(...) \ > > + FIELD_PROP(DEFINE_PROP_UINT32(NULL, __VA_ARGS__)) > > +#define PROP_INT32(...) \ > > + FIELD_PROP(DEFINE_PROP_INT32(NULL, __VA_ARGS__)) > > +#define PROP_UINT64(...) \ > > + FIELD_PROP(DEFINE_PROP_UINT64(NULL, __VA_ARGS__)) > > +#define PROP_INT64(...) \ > > + FIELD_PROP(DEFINE_PROP_INT64(NULL, __VA_ARGS__)) > > +#define PROP_SIZE(...) \ > > + FIELD_PROP(DEFINE_PROP_SIZE(NULL, __VA_ARGS__)) > > +#define PROP_STRING(...) \ > > + FIELD_PROP(DEFINE_PROP_STRING(NULL, __VA_ARGS__)) > > +#define PROP_ON_OFF_AUTO(...) \ > > + FIELD_PROP(DEFINE_PROP_ON_OFF_AUTO(NULL, __VA_ARGS__)) > > +#define PROP_SIZE32(...) \ > > + FIELD_PROP(DEFINE_PROP_SIZE32(NULL, __VA_ARGS__)) > > +#define PROP_UUID(...) \ > > + FIELD_PROP(DEFINE_PROP_UUID(NULL, __VA_ARGS__)) > > +#define PROP_UUID_NODEFAULT(...) \ > > + FIELD_PROP(DEFINE_PROP_UUID_NODEFAULT(NULL, __VA_ARGS__)) > > +#define PROP_END_OF_LIST(...) \ > > + FIELD_PROP(DEFINE_PROP_END_OF_LIST(NULL, __VA_ARGS__)) > > + > > +#endif > > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c > > index b75730f15c..5bb4ff5f46 100644 > > --- a/hw/core/qdev-properties.c > > +++ b/hw/core/qdev-properties.c > > @@ -50,496 +50,6 @@ void qdev_prop_allow_set_link_before_realize(const > > Object *obj, > > } > > } > > -void field_prop_get_enum(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - int *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_enum(v, name, ptr, prop->info->enum_table, errp); > > -} > > - > > -void field_prop_set_enum(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - int *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_enum(v, name, ptr, prop->info->enum_table, errp); > > -} > > - > > -void field_prop_set_default_value_enum(ObjectProperty *op, > > - const Property *prop) > > -{ > > - object_property_set_default_str(op, > > - qapi_enum_lookup(prop->info->enum_table, prop->defval.i)); > > -} > > - > > -const PropertyInfo prop_info_enum = { > > - .name = "enum", > > - .get = field_prop_get_enum, > > - .set = field_prop_set_enum, > > - .set_default_value = field_prop_set_default_value_enum, > > -}; > > - > > -/* Bit */ > > - > > -static uint32_t qdev_get_prop_mask(Property *prop) > > -{ > > - assert(prop->info == &prop_info_bit); > > - return 0x1 << prop->bitnr; > > -} > > - > > -static void bit_prop_set(Object *obj, Property *props, bool val) > > -{ > > - uint32_t *p = object_field_prop_ptr(obj, props); > > - uint32_t mask = qdev_get_prop_mask(props); > > - if (val) { > > - *p |= mask; > > - } else { > > - *p &= ~mask; > > - } > > -} > > - > > -static void prop_get_bit(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint32_t *p = object_field_prop_ptr(obj, prop); > > - bool value = (*p & qdev_get_prop_mask(prop)) != 0; > > - > > - visit_type_bool(v, name, &value, errp); > > -} > > - > > -static void prop_set_bit(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - bool value; > > - > > - if (!visit_type_bool(v, name, &value, errp)) { > > - return; > > - } > > - bit_prop_set(obj, prop, value); > > -} > > - > > -static void set_default_value_bool(ObjectProperty *op, const Property > > *prop) > > -{ > > - object_property_set_default_bool(op, prop->defval.u); > > -} > > - > > -const PropertyInfo prop_info_bit = { > > - .name = "bool", > > - .description = "on/off", > > - .get = prop_get_bit, > > - .set = prop_set_bit, > > - .set_default_value = set_default_value_bool, > > -}; > > - > > -/* Bit64 */ > > - > > -static uint64_t qdev_get_prop_mask64(Property *prop) > > -{ > > - assert(prop->info == &prop_info_bit64); > > - return 0x1ull << prop->bitnr; > > -} > > - > > -static void bit64_prop_set(Object *obj, Property *props, bool val) > > -{ > > - uint64_t *p = object_field_prop_ptr(obj, props); > > - uint64_t mask = qdev_get_prop_mask64(props); > > - if (val) { > > - *p |= mask; > > - } else { > > - *p &= ~mask; > > - } > > -} > > - > > -static void prop_get_bit64(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint64_t *p = object_field_prop_ptr(obj, prop); > > - bool value = (*p & qdev_get_prop_mask64(prop)) != 0; > > - > > - visit_type_bool(v, name, &value, errp); > > -} > > - > > -static void prop_set_bit64(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - bool value; > > - > > - if (!visit_type_bool(v, name, &value, errp)) { > > - return; > > - } > > - bit64_prop_set(obj, prop, value); > > -} > > - > > -const PropertyInfo prop_info_bit64 = { > > - .name = "bool", > > - .description = "on/off", > > - .get = prop_get_bit64, > > - .set = prop_set_bit64, > > - .set_default_value = set_default_value_bool, > > -}; > > - > > -/* --- bool --- */ > > - > > -static void get_bool(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - bool *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_bool(v, name, ptr, errp); > > -} > > - > > -static void set_bool(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - bool *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_bool(v, name, ptr, errp); > > -} > > - > > -const PropertyInfo prop_info_bool = { > > - .name = "bool", > > - .get = get_bool, > > - .set = set_bool, > > - .set_default_value = set_default_value_bool, > > -}; > > - > > -/* --- 8bit integer --- */ > > - > > -static void get_uint8(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - uint8_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint8(v, name, ptr, errp); > > -} > > - > > -static void set_uint8(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - uint8_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint8(v, name, ptr, errp); > > -} > > - > > -void field_prop_set_default_value_int(ObjectProperty *op, > > - const Property *prop) > > -{ > > - object_property_set_default_int(op, prop->defval.i); > > -} > > - > > -void field_prop_set_default_value_uint(ObjectProperty *op, > > - const Property *prop) > > -{ > > - object_property_set_default_uint(op, prop->defval.u); > > -} > > - > > -const PropertyInfo prop_info_uint8 = { > > - .name = "uint8", > > - .get = get_uint8, > > - .set = set_uint8, > > - .set_default_value = field_prop_set_default_value_uint, > > -}; > > - > > -/* --- 16bit integer --- */ > > - > > -static void get_uint16(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint16_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint16(v, name, ptr, errp); > > -} > > - > > -static void set_uint16(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint16_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint16(v, name, ptr, errp); > > -} > > - > > -const PropertyInfo prop_info_uint16 = { > > - .name = "uint16", > > - .get = get_uint16, > > - .set = set_uint16, > > - .set_default_value = field_prop_set_default_value_uint, > > -}; > > - > > -/* --- 32bit integer --- */ > > - > > -static void get_uint32(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint32_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint32(v, name, ptr, errp); > > -} > > - > > -static void set_uint32(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint32_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint32(v, name, ptr, errp); > > -} > > - > > -void field_prop_get_int32(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - int32_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_int32(v, name, ptr, errp); > > -} > > - > > -static void set_int32(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - int32_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_int32(v, name, ptr, errp); > > -} > > - > > -const PropertyInfo prop_info_uint32 = { > > - .name = "uint32", > > - .get = get_uint32, > > - .set = set_uint32, > > - .set_default_value = field_prop_set_default_value_uint, > > -}; > > - > > -const PropertyInfo prop_info_int32 = { > > - .name = "int32", > > - .get = field_prop_get_int32, > > - .set = set_int32, > > - .set_default_value = field_prop_set_default_value_int, > > -}; > > - > > -/* --- 64bit integer --- */ > > - > > -static void get_uint64(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint64_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint64(v, name, ptr, errp); > > -} > > - > > -static void set_uint64(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint64_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_uint64(v, name, ptr, errp); > > -} > > - > > -static void get_int64(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - int64_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_int64(v, name, ptr, errp); > > -} > > - > > -static void set_int64(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - int64_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_int64(v, name, ptr, errp); > > -} > > - > > -const PropertyInfo prop_info_uint64 = { > > - .name = "uint64", > > - .get = get_uint64, > > - .set = set_uint64, > > - .set_default_value = field_prop_set_default_value_uint, > > -}; > > - > > -const PropertyInfo prop_info_int64 = { > > - .name = "int64", > > - .get = get_int64, > > - .set = set_int64, > > - .set_default_value = field_prop_set_default_value_int, > > -}; > > - > > -/* --- string --- */ > > - > > -static void release_string(Object *obj, const char *name, void *opaque) > > -{ > > - Property *prop = opaque; > > - g_free(*(char **)object_field_prop_ptr(obj, prop)); > > -} > > - > > -static void get_string(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - char **ptr = object_field_prop_ptr(obj, prop); > > - > > - if (!*ptr) { > > - char *str = (char *)""; > > - visit_type_str(v, name, &str, errp); > > - } else { > > - visit_type_str(v, name, ptr, errp); > > - } > > -} > > - > > -static void set_string(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - char **ptr = object_field_prop_ptr(obj, prop); > > - char *str; > > - > > - if (!visit_type_str(v, name, &str, errp)) { > > - return; > > - } > > - g_free(*ptr); > > - *ptr = str; > > -} > > - > > -const PropertyInfo prop_info_string = { > > - .name = "str", > > - .release = release_string, > > - .get = get_string, > > - .set = set_string, > > -}; > > - > > -/* --- on/off/auto --- */ > > - > > -const PropertyInfo prop_info_on_off_auto = { > > - .name = "OnOffAuto", > > - .description = "on/off/auto", > > - .enum_table = &OnOffAuto_lookup, > > - .get = field_prop_get_enum, > > - .set = field_prop_set_enum, > > - .set_default_value = field_prop_set_default_value_enum, > > -}; > > - > > -/* --- 32bit unsigned int 'size' type --- */ > > - > > -void field_prop_get_size32(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - Property *prop = opaque; > > - uint32_t *ptr = object_field_prop_ptr(obj, prop); > > - uint64_t value = *ptr; > > - > > - visit_type_size(v, name, &value, errp); > > -} > > - > > -static void set_size32(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - uint32_t *ptr = object_field_prop_ptr(obj, prop); > > - uint64_t value; > > - > > - if (!visit_type_size(v, name, &value, errp)) { > > - return; > > - } > > - > > - if (value > UINT32_MAX) { > > - error_setg(errp, > > - "Property %s.%s doesn't take value %" PRIu64 > > - " (maximum: %u)", > > - object_get_typename(obj), name, value, UINT32_MAX); > > - return; > > - } > > - > > - *ptr = value; > > -} > > - > > -const PropertyInfo prop_info_size32 = { > > - .name = "size", > > - .get = field_prop_get_size32, > > - .set = set_size32, > > - .set_default_value = field_prop_set_default_value_uint, > > -}; > > - > > -/* --- support for array properties --- */ > > - > > -static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, > > - void *opaque, Error **errp) > > -{ > > - /* Setter for the property which defines the length of a > > - * variable-sized property array. As well as actually setting the > > - * array-length field in the device struct, we have to create the > > - * array itself and dynamically add the corresponding properties. > > - */ > > - Property *prop = opaque; > > - ObjectProperty *op = object_property_find_err(obj, name, &error_abort); > > - uint32_t *alenptr = object_field_prop_ptr(obj, prop); > > - void **arrayptr = (void *)obj + prop->arrayoffset; > > - void *eltptr; > > - const char *arrayname; > > - int i; > > - > > - if (*alenptr) { > > - error_setg(errp, "array size property %s may not be set more than > > once", > > - name); > > - return; > > - } > > - if (!visit_type_uint32(v, name, alenptr, errp)) { > > - return; > > - } > > - if (!*alenptr) { > > - return; > > - } > > - > > - /* DEFINE_PROP_ARRAY guarantees that name should start with this > > prefix; > > - * strip it off so we can get the name of the array itself. > > - */ > > - assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, > > - strlen(PROP_ARRAY_LEN_PREFIX)) == 0); > > - arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); > > - > > - /* Note that it is the responsibility of the individual device's deinit > > - * to free the array proper. > > - */ > > - *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); > > - for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { > > - g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, > > i); > > - Property *arrayprop = g_new0(Property, 1); > > - arrayprop->info = prop->arrayinfo; > > - /* This ugly piece of pointer arithmetic sets up the offset so > > - * that when the underlying get/set hooks call qdev_get_prop_ptr > > - * they get the right answer despite the array element not actually > > - * being inside the device struct. > > - */ > > - arrayprop->offset = eltptr - (void *)obj; > > - assert(object_field_prop_ptr(obj, arrayprop) == eltptr); > > - object_property_add_field(obj, propname, arrayprop, op->allow_set); > > - } > > -} > > - > > -const PropertyInfo prop_info_arraylen = { > > - .name = "uint32", > > - .get = get_uint32, > > - .set = set_prop_arraylen, > > - .set_default_value = field_prop_set_default_value_uint, > > -}; > > - > > /* --- public helpers --- */ > > static Property *qdev_prop_walk(Property *props, const char *name) > > @@ -712,53 +222,6 @@ void qdev_prop_set_globals(DeviceState *dev) > > dev->hotplugged ? NULL : &error_fatal); > > } > > -/* --- 64bit unsigned int 'size' type --- */ > > - > > -static void get_size(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - uint64_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_size(v, name, ptr, errp); > > -} > > - > > -static void set_size(Object *obj, Visitor *v, const char *name, void > > *opaque, > > - Error **errp) > > -{ > > - Property *prop = opaque; > > - uint64_t *ptr = object_field_prop_ptr(obj, prop); > > - > > - visit_type_size(v, name, ptr, errp); > > -} > > - > > -const PropertyInfo prop_info_size = { > > - .name = "size", > > - .get = get_size, > > - .set = set_size, > > - .set_default_value = field_prop_set_default_value_uint, > > -}; > > - > > -/* --- object link property --- */ > > - > > -static ObjectProperty *create_link_property(ObjectClass *oc, const char > > *name, > > - Property *prop) > > -{ > > - /* > > - * NOTE: object_property_allow_set_link is unconditional, but > > - * ObjectProperty.allow_set may be set for the property too. > > - */ > > - return object_class_property_add_link(oc, name, prop->link_type, > > - prop->offset, > > - object_property_allow_set_link, > > - OBJ_PROP_LINK_STRONG); > > -} > > - > > -const PropertyInfo prop_info_link = { > > - .name = "link", > > - .create = create_link_property, > > -}; > > - > > void qdev_property_add_static(DeviceState *dev, Property *prop) > > { > > object_property_add_field(OBJECT(dev), prop->qdev_prop_name, prop, > > diff --git a/qom/property-types.c b/qom/property-types.c > > new file mode 100644 > > index 0000000000..f566c05ec2 > > --- /dev/null > > +++ b/qom/property-types.c > > @@ -0,0 +1,545 @@ > > +#include "qemu/osdep.h" > > +#include "qom/field-property.h" > > +#include "qom/property-types.h" > > +#include "qom/field-property-internal.h" > > +#include "qapi/qapi-types-common.h" > > +#include "qapi/visitor.h" > > +#include "qapi/error.h" > > +#include "qemu/uuid.h" > > + > > +void field_prop_get_enum(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + int *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_enum(v, name, ptr, prop->info->enum_table, errp); > > +} > > + > > +void field_prop_set_enum(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + int *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_enum(v, name, ptr, prop->info->enum_table, errp); > > +} > > + > > +void field_prop_set_default_value_enum(ObjectProperty *op, > > + const Property *prop) > > +{ > > + object_property_set_default_str(op, > > + qapi_enum_lookup(prop->info->enum_table, prop->defval.i)); > > +} > > + > > +const PropertyInfo prop_info_enum = { > > + .name = "enum", > > + .get = field_prop_get_enum, > > + .set = field_prop_set_enum, > > + .set_default_value = field_prop_set_default_value_enum, > > +}; > > + > > +/* Bit */ > > + > > +static uint32_t qdev_get_prop_mask(Property *prop) > > +{ > > + assert(prop->info == &prop_info_bit); > > + return 0x1 << prop->bitnr; > > +} > > + > > +static void bit_prop_set(Object *obj, Property *props, bool val) > > +{ > > + uint32_t *p = object_field_prop_ptr(obj, props); > > + uint32_t mask = qdev_get_prop_mask(props); > > + if (val) { > > + *p |= mask; > > + } else { > > + *p &= ~mask; > > + } > > +} > > + > > +static void prop_get_bit(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint32_t *p = object_field_prop_ptr(obj, prop); > > + bool value = (*p & qdev_get_prop_mask(prop)) != 0; > > + > > + visit_type_bool(v, name, &value, errp); > > +} > > + > > +static void prop_set_bit(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + bool value; > > + > > + if (!visit_type_bool(v, name, &value, errp)) { > > + return; > > + } > > + bit_prop_set(obj, prop, value); > > +} > > + > > +static void set_default_value_bool(ObjectProperty *op, const Property > > *prop) > > +{ > > + object_property_set_default_bool(op, prop->defval.u); > > +} > > + > > +const PropertyInfo prop_info_bit = { > > + .name = "bool", > > + .description = "on/off", > > + .get = prop_get_bit, > > + .set = prop_set_bit, > > + .set_default_value = set_default_value_bool, > > +}; > > + > > +/* Bit64 */ > > + > > +static uint64_t qdev_get_prop_mask64(Property *prop) > > +{ > > + assert(prop->info == &prop_info_bit64); > > + return 0x1ull << prop->bitnr; > > +} > > + > > +static void bit64_prop_set(Object *obj, Property *props, bool val) > > +{ > > + uint64_t *p = object_field_prop_ptr(obj, props); > > + uint64_t mask = qdev_get_prop_mask64(props); > > + if (val) { > > + *p |= mask; > > + } else { > > + *p &= ~mask; > > + } > > +} > > + > > +static void prop_get_bit64(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint64_t *p = object_field_prop_ptr(obj, prop); > > + bool value = (*p & qdev_get_prop_mask64(prop)) != 0; > > + > > + visit_type_bool(v, name, &value, errp); > > +} > > + > > +static void prop_set_bit64(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + bool value; > > + > > + if (!visit_type_bool(v, name, &value, errp)) { > > + return; > > + } > > + bit64_prop_set(obj, prop, value); > > +} > > + > > +const PropertyInfo prop_info_bit64 = { > > + .name = "bool", > > + .description = "on/off", > > + .get = prop_get_bit64, > > + .set = prop_set_bit64, > > + .set_default_value = set_default_value_bool, > > +}; > > + > > +/* --- bool --- */ > > + > > +static void get_bool(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + bool *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_bool(v, name, ptr, errp); > > +} > > + > > +static void set_bool(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + bool *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_bool(v, name, ptr, errp); > > +} > > + > > +const PropertyInfo prop_info_bool = { > > + .name = "bool", > > + .get = get_bool, > > + .set = set_bool, > > + .set_default_value = set_default_value_bool, > > +}; > > + > > +/* --- 8bit integer --- */ > > + > > +static void get_uint8(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + uint8_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint8(v, name, ptr, errp); > > +} > > + > > +static void set_uint8(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + uint8_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint8(v, name, ptr, errp); > > +} > > + > > +void field_prop_set_default_value_int(ObjectProperty *op, > > + const Property *prop) > > +{ > > + object_property_set_default_int(op, prop->defval.i); > > +} > > + > > +void field_prop_set_default_value_uint(ObjectProperty *op, > > + const Property *prop) > > +{ > > + object_property_set_default_uint(op, prop->defval.u); > > +} > > + > > +const PropertyInfo prop_info_uint8 = { > > + .name = "uint8", > > + .get = get_uint8, > > + .set = set_uint8, > > + .set_default_value = field_prop_set_default_value_uint, > > +}; > > + > > +/* --- 16bit integer --- */ > > + > > +static void get_uint16(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint16_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint16(v, name, ptr, errp); > > +} > > + > > +static void set_uint16(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint16_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint16(v, name, ptr, errp); > > +} > > + > > +const PropertyInfo prop_info_uint16 = { > > + .name = "uint16", > > + .get = get_uint16, > > + .set = set_uint16, > > + .set_default_value = field_prop_set_default_value_uint, > > +}; > > + > > +/* --- 32bit integer --- */ > > + > > +static void get_uint32(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint32_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint32(v, name, ptr, errp); > > +} > > + > > +static void set_uint32(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint32_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint32(v, name, ptr, errp); > > +} > > + > > +void field_prop_get_int32(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + int32_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_int32(v, name, ptr, errp); > > +} > > + > > +static void set_int32(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + int32_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_int32(v, name, ptr, errp); > > +} > > + > > +const PropertyInfo prop_info_uint32 = { > > + .name = "uint32", > > + .get = get_uint32, > > + .set = set_uint32, > > + .set_default_value = field_prop_set_default_value_uint, > > +}; > > + > > +const PropertyInfo prop_info_int32 = { > > + .name = "int32", > > + .get = field_prop_get_int32, > > + .set = set_int32, > > + .set_default_value = field_prop_set_default_value_int, > > +}; > > + > > +/* --- 64bit integer --- */ > > + > > +static void get_uint64(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint64_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint64(v, name, ptr, errp); > > +} > > + > > +static void set_uint64(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint64_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_uint64(v, name, ptr, errp); > > +} > > + > > +static void get_int64(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + int64_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_int64(v, name, ptr, errp); > > +} > > + > > +static void set_int64(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + int64_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_int64(v, name, ptr, errp); > > +} > > + > > +const PropertyInfo prop_info_uint64 = { > > + .name = "uint64", > > + .get = get_uint64, > > + .set = set_uint64, > > + .set_default_value = field_prop_set_default_value_uint, > > +}; > > + > > +const PropertyInfo prop_info_int64 = { > > + .name = "int64", > > + .get = get_int64, > > + .set = set_int64, > > + .set_default_value = field_prop_set_default_value_int, > > +}; > > + > > +/* --- string --- */ > > + > > +static void release_string(Object *obj, const char *name, void *opaque) > > +{ > > + Property *prop = opaque; > > + g_free(*(char **)object_field_prop_ptr(obj, prop)); > > +} > > + > > +static void get_string(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + char **ptr = object_field_prop_ptr(obj, prop); > > + > > + if (!*ptr) { > > + char *str = (char *)""; > > + visit_type_str(v, name, &str, errp); > > + } else { > > + visit_type_str(v, name, ptr, errp); > > + } > > +} > > + > > +static void set_string(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + char **ptr = object_field_prop_ptr(obj, prop); > > + char *str; > > + > > + if (!visit_type_str(v, name, &str, errp)) { > > + return; > > + } > > + g_free(*ptr); > > + *ptr = str; > > +} > > + > > +const PropertyInfo prop_info_string = { > > + .name = "str", > > + .release = release_string, > > + .get = get_string, > > + .set = set_string, > > +}; > > + > > +/* --- on/off/auto --- */ > > + > > +const PropertyInfo prop_info_on_off_auto = { > > + .name = "OnOffAuto", > > + .description = "on/off/auto", > > + .enum_table = &OnOffAuto_lookup, > > + .get = field_prop_get_enum, > > + .set = field_prop_set_enum, > > + .set_default_value = field_prop_set_default_value_enum, > > +}; > > + > > +/* --- 32bit unsigned int 'size' type --- */ > > + > > +void field_prop_get_size32(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + Property *prop = opaque; > > + uint32_t *ptr = object_field_prop_ptr(obj, prop); > > + uint64_t value = *ptr; > > + > > + visit_type_size(v, name, &value, errp); > > +} > > + > > +static void set_size32(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + uint32_t *ptr = object_field_prop_ptr(obj, prop); > > + uint64_t value; > > + > > + if (!visit_type_size(v, name, &value, errp)) { > > + return; > > + } > > + > > + if (value > UINT32_MAX) { > > + error_setg(errp, > > + "Property %s.%s doesn't take value %" PRIu64 > > + " (maximum: %u)", > > + object_get_typename(obj), name, value, UINT32_MAX); > > + return; > > + } > > + > > + *ptr = value; > > +} > > + > > +const PropertyInfo prop_info_size32 = { > > + .name = "size", > > + .get = field_prop_get_size32, > > + .set = set_size32, > > + .set_default_value = field_prop_set_default_value_uint, > > +}; > > + > > +/* --- support for array properties --- */ > > + > > +static void set_prop_arraylen(Object *obj, Visitor *v, const char *name, > > + void *opaque, Error **errp) > > +{ > > + /* Setter for the property which defines the length of a > > + * variable-sized property array. As well as actually setting the > > + * array-length field in the device struct, we have to create the > > + * array itself and dynamically add the corresponding properties. > > + */ > > + Property *prop = opaque; > > + ObjectProperty *op = object_property_find_err(obj, name, &error_abort); > > + uint32_t *alenptr = object_field_prop_ptr(obj, prop); > > + void **arrayptr = (void *)obj + prop->arrayoffset; > > + void *eltptr; > > + const char *arrayname; > > + int i; > > + > > + if (*alenptr) { > > + error_setg(errp, "array size property %s may not be set more than > > once", > > + name); > > + return; > > + } > > + if (!visit_type_uint32(v, name, alenptr, errp)) { > > + return; > > + } > > + if (!*alenptr) { > > + return; > > + } > > + > > + /* DEFINE_PROP_ARRAY guarantees that name should start with this > > prefix; > > + * strip it off so we can get the name of the array itself. > > + */ > > + assert(strncmp(name, PROP_ARRAY_LEN_PREFIX, > > + strlen(PROP_ARRAY_LEN_PREFIX)) == 0); > > + arrayname = name + strlen(PROP_ARRAY_LEN_PREFIX); > > + > > + /* Note that it is the responsibility of the individual device's deinit > > + * to free the array proper. > > + */ > > + *arrayptr = eltptr = g_malloc0(*alenptr * prop->arrayfieldsize); > > + for (i = 0; i < *alenptr; i++, eltptr += prop->arrayfieldsize) { > > + g_autofree char *propname = g_strdup_printf("%s[%d]", arrayname, > > i); > > + Property *arrayprop = g_new0(Property, 1); > > + arrayprop->info = prop->arrayinfo; > > + /* This ugly piece of pointer arithmetic sets up the offset so > > + * that when the underlying get/set hooks call qdev_get_prop_ptr > > + * they get the right answer despite the array element not actually > > + * being inside the device struct. > > + */ > > + arrayprop->offset = eltptr - (void *)obj; > > + assert(object_field_prop_ptr(obj, arrayprop) == eltptr); > > + object_property_add_field(obj, propname, arrayprop, op->allow_set); > > + } > > +} > > + > > +const PropertyInfo prop_info_arraylen = { > > + .name = "uint32", > > + .get = get_uint32, > > + .set = set_prop_arraylen, > > + .set_default_value = field_prop_set_default_value_uint, > > +}; > > + > > +/* --- 64bit unsigned int 'size' type --- */ > > + > > +static void get_size(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + uint64_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_size(v, name, ptr, errp); > > +} > > + > > +static void set_size(Object *obj, Visitor *v, const char *name, void > > *opaque, > > + Error **errp) > > +{ > > + Property *prop = opaque; > > + uint64_t *ptr = object_field_prop_ptr(obj, prop); > > + > > + visit_type_size(v, name, ptr, errp); > > +} > > + > > +const PropertyInfo prop_info_size = { > > + .name = "size", > > + .get = get_size, > > + .set = set_size, > > + .set_default_value = field_prop_set_default_value_uint, > > +}; > > + > > +/* --- object link property --- */ > > + > > +static ObjectProperty *create_link_property(ObjectClass *oc, const char > > *name, > > + Property *prop) > > +{ > > + /* > > + * NOTE: object_property_allow_set_link is unconditional, but > > + * ObjectProperty.allow_set may be set for the property too. > > + */ > > + return object_class_property_add_link(oc, name, prop->link_type, > > + prop->offset, > > + object_property_allow_set_link, > > + OBJ_PROP_LINK_STRONG); > > +} > > + > > +const PropertyInfo prop_info_link = { > > + .name = "link", > > + .create = create_link_property, > > +}; > > diff --git a/qom/meson.build b/qom/meson.build > > index e83794454d..7fdfd6fe7b 100644 > > --- a/qom/meson.build > > +++ b/qom/meson.build > > @@ -5,6 +5,7 @@ qom_ss.add(files( > > 'object_interfaces.c', > > 'qom-qobject.c', > > 'field-property.c', > > + 'property-types.c', > > )) > > qmp_ss.add(files('qom-qmp-cmds.c')) > > > -- Eduardo