From: Paolo Bonzini <pbonzini@redhat.com>
To: Eduardo Habkost <ehabkost@redhat.com>, qemu-devel@nongnu.org
Cc: "Daniel P. Berrange" <berrange@redhat.com>,
"John Snow" <jsnow@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Igor Mammedov" <imammedo@redhat.com>,
"Stefan Berger" <stefanb@linux.ibm.com>
Subject: Re: [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c
Date: Wed, 4 Nov 2020 17:36:20 +0100 [thread overview]
Message-ID: <cf1eade5-3e3e-ffce-ac0f-b680f6462c47@redhat.com> (raw)
In-Reply-To: <20201104160021.2342108-42-ehabkost@redhat.com>
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 <ehabkost@redhat.com>
> ---
> Changes v1 -> v2:
> * Rebased after changes in previous patches in the series
> ---
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: "Daniel P. Berrangé" <berrange@redhat.com>
> Cc: Eduardo Habkost <ehabkost@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.
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.
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'))
>
next prev parent reply other threads:[~2020-11-04 16:39 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-04 15:59 [PATCH v2 00/44] Make qdev static property API usable by any QOM type Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 01/44] cs4231: Get rid of empty property array Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 02/44] cpu: Move cpu_common_props to hw/core/cpu.c Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 03/44] qdev: Move property code to qdev-properties.[ch] Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 04/44] qdev: Check dev->realized at set_size() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 05/44] sparc: Check dev->realized at sparc_set_nwindows() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 06/44] qdev: Don't use dev->id on set_size32() error message Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 07/44] qdev: Make PropertyInfo.print method get Object* argument Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 08/44] qdev: Make bit_prop_set() " Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 09/44] qdev: Make qdev_get_prop_ptr() get Object* arg Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 10/44] qdev: Make qdev_find_global_prop() get Object* argument Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 11/44] qdev: Make check_prop_still_unset() " Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 12/44] qdev: Make error_set_from_qdev_prop_error() " Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 13/44] qdev: Move UUID property to qdev-properties-system.c Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 14/44] qdev: Move softmmu properties to qdev-properties-system.h Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 15/44] qdev: Reuse DEFINE_PROP in all DEFINE_PROP_* macros Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 16/44] sparc: Use DEFINE_PROP for nwindows property Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 17/44] qdev: Get just property name at error_set_from_qdev_prop_error() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 18/44] qdev: Avoid using prop->name unnecessarily Eduardo Habkost
2020-11-04 17:25 ` Stefan Berger
2020-11-04 15:59 ` [PATCH v2 19/44] qdev: Add name parameter to qdev_class_add_property() Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 20/44] qdev: Add name argument to PropertyInfo.create method Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 21/44] qdev: Wrap getters and setters in separate helpers Eduardo Habkost
2020-11-04 15:59 ` [PATCH v2 22/44] qdev: Move dev->realized check to qdev_property_set() Eduardo Habkost
2020-11-04 17:28 ` Stefan Berger
2020-11-04 16:00 ` [PATCH v2 23/44] qdev: Make PropertyInfo.create return ObjectProperty* Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 24/44] qdev: Make qdev_class_add_property() more flexible Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 25/44] qdev: Separate generic and device-specific property registration Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 26/44] qdev: Rename Property.name to Property.qdev_prop_name Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 27/44] qdev: Don't set qdev_prop_name for array elements Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 28/44] qdev: Avoid unnecessary DeviceState* variable at set_prop_arraylen() Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 29/44] qdev: Remove ArrayElementProperty.propname field Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 30/44] qdev: Get rid of ArrayElementProperty struct Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 31/44] qdev: Reuse object_property_add_field() when adding array elements Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 32/44] qom: Add allow_set callback to ObjectProperty Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 33/44] qdev: Make qdev_prop_allow_set() a ObjectProperty.allow_set callback Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 34/44] qdev: Make qdev_propinfo_get_uint16() static Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 35/44] qdev: Rename qdev_propinfo_* to field_prop_* Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 36/44] qdev: Rename qdev_get_prop_ptr() to object_field_prop_ptr() Eduardo Habkost
2020-11-05 18:49 ` Stefan Berger
2020-11-04 16:00 ` [PATCH v2 37/44] qdev: Move qdev_prop_tpm declaration to tpm_prop.h Eduardo Habkost
2020-11-05 18:50 ` Stefan Berger
2020-11-04 16:00 ` [PATCH v2 38/44] qdev: Rename qdev_prop_* to prop_info_* Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 39/44] qdev: PROP_* macros Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 40/44] qdev: Move core field property code to QOM Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 41/44] qdev: Move base property types to qom/property-types.c Eduardo Habkost
2020-11-04 16:36 ` Paolo Bonzini [this message]
2020-11-04 20:50 ` Eduardo Habkost
2020-11-05 9:36 ` Paolo Bonzini
2020-11-04 16:00 ` [PATCH v2 42/44] qom: Include static property API reference in documentation Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 43/44] tests: Use field properties at check-qom-proplist test case Eduardo Habkost
2020-11-04 16:00 ` [PATCH v2 44/44] machine: Register most properties as field properties Eduardo Habkost
2020-11-04 16:36 ` [PATCH v2 00/44] Make qdev static property API usable by any QOM type no-reply
2020-11-06 9:45 ` Kevin Wolf
2020-11-06 15:50 ` Eduardo Habkost
2020-11-06 21:10 ` Eduardo Habkost
2020-11-08 14:05 ` Paolo Bonzini
2020-11-09 11:34 ` Kevin Wolf
2020-11-09 14:15 ` Paolo Bonzini
2020-11-09 15:21 ` Eduardo Habkost
2020-11-09 16:34 ` Paolo Bonzini
2020-11-09 17:16 ` Eduardo Habkost
2020-11-09 17:33 ` Paolo Bonzini
2020-11-09 18:55 ` Eduardo Habkost
2020-11-09 19:27 ` Paolo Bonzini
2020-11-09 20:28 ` Eduardo Habkost
2020-11-10 10:38 ` Kevin Wolf
2020-11-11 18:39 ` Eduardo Habkost
2020-11-12 8:11 ` Paolo Bonzini
2020-11-12 14:53 ` Eduardo Habkost
2020-11-10 10:58 ` Paolo Bonzini
2020-11-10 17:03 ` Eduardo Habkost
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cf1eade5-3e3e-ffce-ac0f-b680f6462c47@redhat.com \
--to=pbonzini@redhat.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=ehabkost@redhat.com \
--cc=imammedo@redhat.com \
--cc=jsnow@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=philmd@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanb@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).