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'))