aboutsummaryrefslogtreecommitdiff
path: root/hw/core/qdev-properties.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core/qdev-properties.c')
-rw-r--r--hw/core/qdev-properties.c285
1 files changed, 169 insertions, 116 deletions
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 509cbf155d..a2eaa43831 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -6,7 +6,6 @@
#include "qemu/ctype.h"
#include "qemu/error-report.h"
#include "qapi/visitor.h"
-#include "qemu/uuid.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qdev-prop-internal.h"
@@ -38,9 +37,9 @@ void qdev_prop_allow_set_link_before_realize(const Object *obj,
}
}
-void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
+void *qdev_get_prop_ptr(Object *obj, Property *prop)
{
- void *ptr = dev;
+ void *ptr = obj;
ptr += prop->offset;
return ptr;
}
@@ -48,9 +47,8 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
void qdev_propinfo_get_enum(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- int *ptr = qdev_get_prop_ptr(dev, prop);
+ int *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_enum(v, prop->name, ptr, prop->info->enum_table, errp);
}
@@ -60,7 +58,7 @@ void qdev_propinfo_set_enum(Object *obj, Visitor *v, const char *name,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- int *ptr = qdev_get_prop_ptr(dev, prop);
+ int *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -92,9 +90,9 @@ static uint32_t qdev_get_prop_mask(Property *prop)
return 0x1 << prop->bitnr;
}
-static void bit_prop_set(DeviceState *dev, Property *props, bool val)
+static void bit_prop_set(Object *obj, Property *props, bool val)
{
- uint32_t *p = qdev_get_prop_ptr(dev, props);
+ uint32_t *p = qdev_get_prop_ptr(obj, props);
uint32_t mask = qdev_get_prop_mask(props);
if (val) {
*p |= mask;
@@ -106,9 +104,8 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val)
static void prop_get_bit(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint32_t *p = qdev_get_prop_ptr(dev, prop);
+ uint32_t *p = qdev_get_prop_ptr(obj, prop);
bool value = (*p & qdev_get_prop_mask(prop)) != 0;
visit_type_bool(v, name, &value, errp);
@@ -129,7 +126,7 @@ static void prop_set_bit(Object *obj, Visitor *v, const char *name,
if (!visit_type_bool(v, name, &value, errp)) {
return;
}
- bit_prop_set(dev, prop, value);
+ bit_prop_set(obj, prop, value);
}
static void set_default_value_bool(ObjectProperty *op, const Property *prop)
@@ -153,9 +150,9 @@ static uint64_t qdev_get_prop_mask64(Property *prop)
return 0x1ull << prop->bitnr;
}
-static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
+static void bit64_prop_set(Object *obj, Property *props, bool val)
{
- uint64_t *p = qdev_get_prop_ptr(dev, props);
+ uint64_t *p = qdev_get_prop_ptr(obj, props);
uint64_t mask = qdev_get_prop_mask64(props);
if (val) {
*p |= mask;
@@ -167,9 +164,8 @@ static void bit64_prop_set(DeviceState *dev, Property *props, bool val)
static void prop_get_bit64(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint64_t *p = qdev_get_prop_ptr(dev, prop);
+ uint64_t *p = qdev_get_prop_ptr(obj, prop);
bool value = (*p & qdev_get_prop_mask64(prop)) != 0;
visit_type_bool(v, name, &value, errp);
@@ -190,7 +186,7 @@ static void prop_set_bit64(Object *obj, Visitor *v, const char *name,
if (!visit_type_bool(v, name, &value, errp)) {
return;
}
- bit64_prop_set(dev, prop, value);
+ bit64_prop_set(obj, prop, value);
}
const PropertyInfo qdev_prop_bit64 = {
@@ -206,9 +202,8 @@ const PropertyInfo qdev_prop_bit64 = {
static void get_bool(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- bool *ptr = qdev_get_prop_ptr(dev, prop);
+ bool *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_bool(v, name, ptr, errp);
}
@@ -218,7 +213,7 @@ static void set_bool(Object *obj, Visitor *v, const char *name, void *opaque,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- bool *ptr = qdev_get_prop_ptr(dev, prop);
+ bool *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -240,9 +235,8 @@ const PropertyInfo qdev_prop_bool = {
static void get_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_uint8(v, name, ptr, errp);
}
@@ -252,7 +246,7 @@ static void set_uint8(Object *obj, Visitor *v, const char *name, void *opaque,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint8_t *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -283,12 +277,11 @@ const PropertyInfo qdev_prop_uint8 = {
/* --- 16bit integer --- */
-void qdev_propinfo_get_uint16(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
+static void get_uint16(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_uint16(v, name, ptr, errp);
}
@@ -298,7 +291,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint16_t *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -310,7 +303,7 @@ static void set_uint16(Object *obj, Visitor *v, const char *name,
const PropertyInfo qdev_prop_uint16 = {
.name = "uint16",
- .get = qdev_propinfo_get_uint16,
+ .get = get_uint16,
.set = set_uint16,
.set_default_value = qdev_propinfo_set_default_value_uint,
};
@@ -320,9 +313,8 @@ const PropertyInfo qdev_prop_uint16 = {
static void get_uint32(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_uint32(v, name, ptr, errp);
}
@@ -332,7 +324,7 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -345,9 +337,8 @@ static void set_uint32(Object *obj, Visitor *v, const char *name,
void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int32_t *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_int32(v, name, ptr, errp);
}
@@ -357,7 +348,7 @@ static void set_int32(Object *obj, Visitor *v, const char *name, void *opaque,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int32_t *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -386,9 +377,8 @@ const PropertyInfo qdev_prop_int32 = {
static void get_uint64(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_uint64(v, name, ptr, errp);
}
@@ -398,7 +388,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -411,9 +401,8 @@ static void set_uint64(Object *obj, Visitor *v, const char *name,
static void get_int64(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_int64(v, name, ptr, errp);
}
@@ -423,7 +412,7 @@ static void set_int64(Object *obj, Visitor *v, const char *name,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t *ptr = qdev_get_prop_ptr(obj, prop);
if (dev->realized) {
qdev_prop_set_after_realize(dev, name, errp);
@@ -452,15 +441,14 @@ const PropertyInfo qdev_prop_int64 = {
static void release_string(Object *obj, const char *name, void *opaque)
{
Property *prop = opaque;
- g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
+ g_free(*(char **)qdev_get_prop_ptr(obj, prop));
}
static void get_string(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- char **ptr = qdev_get_prop_ptr(dev, prop);
+ char **ptr = qdev_get_prop_ptr(obj, prop);
if (!*ptr) {
char *str = (char *)"";
@@ -475,7 +463,7 @@ static void set_string(Object *obj, Visitor *v, const char *name,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- char **ptr = qdev_get_prop_ptr(dev, prop);
+ char **ptr = qdev_get_prop_ptr(obj, prop);
char *str;
if (dev->realized) {
@@ -513,9 +501,8 @@ const PropertyInfo qdev_prop_on_off_auto = {
void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
uint64_t value = *ptr;
visit_type_size(v, name, &value, errp);
@@ -526,7 +513,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint32_t *ptr = qdev_get_prop_ptr(obj, prop);
uint64_t value;
if (dev->realized) {
@@ -542,7 +529,7 @@ static void set_size32(Object *obj, Visitor *v, const char *name, void *opaque,
error_setg(errp,
"Property %s.%s doesn't take value %" PRIu64
" (maximum: %u)",
- dev->id ? : "", name, value, UINT32_MAX);
+ object_get_typename(obj), name, value, UINT32_MAX);
return;
}
@@ -556,63 +543,6 @@ const PropertyInfo qdev_prop_size32 = {
.set_default_value = qdev_propinfo_set_default_value_uint,
};
-/* --- UUID --- */
-
-static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
-{
- DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
- QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
- char buffer[UUID_FMT_LEN + 1];
- char *p = buffer;
-
- qemu_uuid_unparse(uuid, buffer);
-
- visit_type_str(v, name, &p, errp);
-}
-
-#define UUID_VALUE_AUTO "auto"
-
-static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
- Error **errp)
-{
- DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
- QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
- char *str;
-
- if (dev->realized) {
- qdev_prop_set_after_realize(dev, name, errp);
- return;
- }
-
- if (!visit_type_str(v, name, &str, errp)) {
- return;
- }
-
- if (!strcmp(str, UUID_VALUE_AUTO)) {
- qemu_uuid_generate(uuid);
- } else if (qemu_uuid_parse(str, uuid) < 0) {
- error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
- }
- g_free(str);
-}
-
-static void set_default_uuid_auto(ObjectProperty *op, const Property *prop)
-{
- object_property_set_default_str(op, UUID_VALUE_AUTO);
-}
-
-const PropertyInfo qdev_prop_uuid = {
- .name = "str",
- .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
- "\" for random value (default)",
- .get = get_uuid,
- .set = set_uuid,
- .set_default_value = set_default_uuid_auto,
-};
-
/* --- support for array properties --- */
/* Used as an opaque for the object properties we add for each
@@ -651,7 +581,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
*/
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
+ uint32_t *alenptr = qdev_get_prop_ptr(obj, prop);
void **arrayptr = (void *)dev + prop->arrayoffset;
void *eltptr;
const char *arrayname;
@@ -697,7 +627,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, const char *name,
* being inside the device struct.
*/
arrayprop->prop.offset = eltptr - (void *)dev;
- assert(qdev_get_prop_ptr(dev, &arrayprop->prop) == eltptr);
+ assert(qdev_get_prop_ptr(obj, &arrayprop->prop) == eltptr);
object_property_add(obj, propname,
arrayprop->prop.info->name,
arrayprop->prop.info->get,
@@ -748,22 +678,22 @@ static Property *qdev_prop_find(DeviceState *dev, const char *name)
return NULL;
}
-void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj,
Property *prop, const char *value)
{
switch (ret) {
case -EEXIST:
error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use",
- object_get_typename(OBJECT(dev)), prop->name, value);
+ object_get_typename(obj), prop->name, value);
break;
default:
case -EINVAL:
error_setg(errp, QERR_PROPERTY_VALUE_BAD,
- object_get_typename(OBJECT(dev)), prop->name, value);
+ object_get_typename(obj), prop->name, value);
break;
case -ENOENT:
error_setg(errp, "Property '%s.%s' can't find value '%s'",
- object_get_typename(OBJECT(dev)), prop->name, value);
+ object_get_typename(obj), prop->name, value);
break;
case 0:
break;
@@ -831,7 +761,7 @@ void qdev_prop_register_global(GlobalProperty *prop)
g_ptr_array_add(global_props(), prop);
}
-const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
+const GlobalProperty *qdev_find_global_prop(Object *obj,
const char *name)
{
GPtrArray *props = global_props();
@@ -840,7 +770,7 @@ const GlobalProperty *qdev_find_global_prop(DeviceState *dev,
for (i = 0; i < props->len; i++) {
p = g_ptr_array_index(props, i);
- if (object_dynamic_cast(OBJECT(dev), p->driver)
+ if (object_dynamic_cast(obj, p->driver)
&& !strcmp(p->property, name)) {
return p;
}
@@ -891,9 +821,8 @@ void qdev_prop_set_globals(DeviceState *dev)
static void get_size(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
- DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
visit_type_size(v, name, ptr, errp);
}
@@ -903,7 +832,12 @@ static void set_size(Object *obj, Visitor *v, const char *name, void *opaque,
{
DeviceState *dev = DEVICE(obj);
Property *prop = opaque;
- uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
+ uint64_t *ptr = qdev_get_prop_ptr(obj, prop);
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
visit_type_size(v, name, ptr, errp);
}
@@ -929,3 +863,122 @@ const PropertyInfo qdev_prop_link = {
.name = "link",
.create = create_link_property,
};
+
+void qdev_property_add_static(DeviceState *dev, Property *prop)
+{
+ Object *obj = OBJECT(dev);
+ ObjectProperty *op;
+
+ assert(!prop->info->create);
+
+ op = object_property_add(obj, prop->name, prop->info->name,
+ prop->info->get, prop->info->set,
+ prop->info->release,
+ prop);
+
+ object_property_set_description(obj, prop->name,
+ prop->info->description);
+
+ if (prop->set_default) {
+ prop->info->set_default_value(op, prop);
+ if (op->init) {
+ op->init(obj, op);
+ }
+ }
+}
+
+static void qdev_class_add_property(DeviceClass *klass, Property *prop)
+{
+ ObjectClass *oc = OBJECT_CLASS(klass);
+
+ if (prop->info->create) {
+ prop->info->create(oc, prop);
+ } else {
+ ObjectProperty *op;
+
+ op = object_class_property_add(oc,
+ prop->name, prop->info->name,
+ prop->info->get, prop->info->set,
+ prop->info->release,
+ prop);
+ if (prop->set_default) {
+ prop->info->set_default_value(op, prop);
+ }
+ }
+ object_class_property_set_description(oc, prop->name,
+ prop->info->description);
+}
+
+/**
+ * Legacy property handling
+ */
+
+static void qdev_get_legacy_property(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ Property *prop = opaque;
+
+ char buffer[1024];
+ char *ptr = buffer;
+
+ prop->info->print(obj, prop, buffer, sizeof(buffer));
+ visit_type_str(v, name, &ptr, errp);
+}
+
+/**
+ * qdev_class_add_legacy_property:
+ * @dev: Device to add the property to.
+ * @prop: The qdev property definition.
+ *
+ * Add a legacy QOM property to @dev for qdev property @prop.
+ *
+ * Legacy properties are string versions of QOM properties. The format of
+ * the string depends on the property type. Legacy properties are only
+ * needed for "info qtree".
+ *
+ * Do not use this in new code! QOM Properties added through this interface
+ * will be given names in the "legacy" namespace.
+ */
+static void qdev_class_add_legacy_property(DeviceClass *dc, Property *prop)
+{
+ g_autofree char *name = NULL;
+
+ /* Register pointer properties as legacy properties */
+ if (!prop->info->print && prop->info->get) {
+ return;
+ }
+
+ name = g_strdup_printf("legacy-%s", prop->name);
+ object_class_property_add(OBJECT_CLASS(dc), name, "str",
+ prop->info->print ? qdev_get_legacy_property : prop->info->get,
+ NULL, NULL, prop);
+}
+
+void device_class_set_props(DeviceClass *dc, Property *props)
+{
+ Property *prop;
+
+ dc->props_ = props;
+ for (prop = props; prop && prop->name; prop++) {
+ qdev_class_add_legacy_property(dc, prop);
+ qdev_class_add_property(dc, prop);
+ }
+}
+
+void qdev_alias_all_properties(DeviceState *target, Object *source)
+{
+ ObjectClass *class;
+ Property *prop;
+
+ class = object_get_class(OBJECT(target));
+ do {
+ DeviceClass *dc = DEVICE_CLASS(class);
+
+ for (prop = dc->props_; prop && prop->name; prop++) {
+ object_property_add_alias(source, prop->name,
+ OBJECT(target), prop->name);
+ }
+ class = object_class_get_parent(class);
+ } while (class != object_class_by_name(TYPE_DEVICE));
+}