* [Qemu-devel] [PATCH v2 01/27] qom: clean up cast macros
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:03 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 02/27] qom: more documentation on subclassing Paolo Bonzini
` (26 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/object.h | 22 +++++++++++++++-------
1 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index 9d0251d..ab1c48c 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -259,6 +259,16 @@ struct TypeInfo
((Object *)(obj))
/**
+ * OBJECT_CLASS:
+ * @class: A derivative of #ObjectClas.
+ *
+ * Converts a class to an #ObjectClass. Since all objects are #Objects,
+ * this function will always succeed.
+ */
+#define OBJECT_CLASS(class) \
+ ((ObjectClass *)(class))
+
+/**
* OBJECT_CHECK:
* @type: The C type to use for the return value.
* @obj: A derivative of @type to cast.
@@ -272,7 +282,7 @@ struct TypeInfo
* generated.
*/
#define OBJECT_CHECK(type, obj, name) \
- ((type *)object_dynamic_cast_assert((Object *)(obj), (name)))
+ ((type *)object_dynamic_cast_assert(OBJECT(obj), (name)))
/**
* OBJECT_CLASS_CHECK:
@@ -280,11 +290,12 @@ struct TypeInfo
* @obj: A derivative of @type to cast.
* @name: the QOM typename of @class.
*
- * A type safe version of @object_check_class. This macro is typically wrapped
- * by each type to perform type safe casts of a class to a specific class type.
+ * A type safe version of @object_class_dynamic_cast_assert. This macro is
+ * typically wrapped by each type to perform type safe casts of a class to a
+ * specific class type.
*/
#define OBJECT_CLASS_CHECK(class, obj, name) \
- ((class *)object_class_dynamic_cast_assert((ObjectClass *)(obj), (name)))
+ ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name)))
/**
* OBJECT_GET_CLASS:
@@ -299,9 +310,6 @@ struct TypeInfo
#define OBJECT_GET_CLASS(class, obj, name) \
OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name)
-#define OBJECT_CLASS(class) \
- ((ObjectClass *)(class))
-
/**
* InterfaceClass:
* @parent_class: the base class
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 01/27] qom: clean up cast macros
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 01/27] qom: clean up cast macros Paolo Bonzini
@ 2012-02-06 14:03 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:03 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> include/qemu/object.h | 22 +++++++++++++++-------
> 1 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index 9d0251d..ab1c48c 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -259,6 +259,16 @@ struct TypeInfo
> ((Object *)(obj))
>
> /**
> + * OBJECT_CLASS:
> + * @class: A derivative of #ObjectClas.
> + *
> + * Converts a class to an #ObjectClass. Since all objects are #Objects,
> + * this function will always succeed.
> + */
> +#define OBJECT_CLASS(class) \
> + ((ObjectClass *)(class))
> +
> +/**
> * OBJECT_CHECK:
> * @type: The C type to use for the return value.
> * @obj: A derivative of @type to cast.
> @@ -272,7 +282,7 @@ struct TypeInfo
> * generated.
> */
> #define OBJECT_CHECK(type, obj, name) \
> - ((type *)object_dynamic_cast_assert((Object *)(obj), (name)))
> + ((type *)object_dynamic_cast_assert(OBJECT(obj), (name)))
>
> /**
> * OBJECT_CLASS_CHECK:
> @@ -280,11 +290,12 @@ struct TypeInfo
> * @obj: A derivative of @type to cast.
> * @name: the QOM typename of @class.
> *
> - * A type safe version of @object_check_class. This macro is typically wrapped
> - * by each type to perform type safe casts of a class to a specific class type.
> + * A type safe version of @object_class_dynamic_cast_assert. This macro is
> + * typically wrapped by each type to perform type safe casts of a class to a
> + * specific class type.
> */
> #define OBJECT_CLASS_CHECK(class, obj, name) \
> - ((class *)object_class_dynamic_cast_assert((ObjectClass *)(obj), (name)))
> + ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name)))
>
> /**
> * OBJECT_GET_CLASS:
> @@ -299,9 +310,6 @@ struct TypeInfo
> #define OBJECT_GET_CLASS(class, obj, name) \
> OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name)
>
> -#define OBJECT_CLASS(class) \
> - ((ObjectClass *)(class))
> -
> /**
> * InterfaceClass:
> * @parent_class: the base class
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 02/27] qom: more documentation on subclassing
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 01/27] qom: clean up cast macros Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:04 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 03/27] qom: clean up/optimize object_dynamic_cast Paolo Bonzini
` (25 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/object.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index ab1c48c..ad7d32d 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -55,6 +55,9 @@ typedef struct InterfaceInfo InterfaceInfo;
*
* #define TYPE_MY_DEVICE "my-device"
*
+ * // No new virtual functions: we can reuse the typedef for the
+ * // superclass.
+ * typedef DeviceClass MyDeviceClass;
* typedef struct MyDevice
* {
* DeviceState parent;
@@ -88,8 +91,21 @@ typedef struct InterfaceInfo InterfaceInfo;
*
* Using object_new(), a new #Object derivative will be instantiated. You can
* cast an #Object to a subclass (or base-class) type using
- * object_dynamic_cast(). You typically want to define a macro wrapper around
- * object_dynamic_cast_assert() to make it easier to convert to a specific type.
+ * object_dynamic_cast(). You typically want to define macro wrappers around
+ * OBJECT_CHECK() and OBJECT_CLASS_CHECK() to make it easier to convert to a
+ * specific type:
+ *
+ * <example>
+ * <title>Typecasting macros</title>
+ * <programlisting>
+ * #define MY_DEVICE_GET_CLASS(obj) \
+ * OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
+ * #define MY_DEVICE_CLASS(klass) \
+ * OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
+ * #define MY_DEVICE(obj) \
+ * OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
+ * </programlisting>
+ * </example>
*
* # Class Initialization #
*
@@ -108,7 +124,61 @@ typedef struct InterfaceInfo InterfaceInfo;
*
* Once all of the parent classes have been initialized, #TypeInfo::class_init
* is called to let the class being instantiated provide default initialize for
- * it's virtual functions.
+ * it's virtual functions. Here is how the above example might be modified
+ * to introduce an overridden virtual function:
+ *
+ * <example>
+ * <title>Overriding a virtual function</title>
+ * <programlisting>
+ * #include "qdev.h"
+ *
+ * void my_device_class_init(ObjectClass *klass, void *class_data)
+ * {
+ * DeviceClass *dc = DEVICE_CLASS(klass);
+ * dc->reset = my_device_reset;
+ * }
+ *
+ * static TypeInfo my_device_info = {
+ * .name = TYPE_MY_DEVICE,
+ * .parent = TYPE_DEVICE,
+ * .instance_size = sizeof(MyDevice),
+ * .class_init = my_device_class_init,
+ * };
+ * </programlisting>
+ * </example>
+ *
+ * Introducing new virtual functions requires a class to define its own
+ * struct and to add a .class_size member to the TypeInfo. Each function
+ * will also have a wrapper to call it easily:
+ *
+ * <example>
+ * <title>Defining an abstract class</title>
+ * <programlisting>
+ * #include "qdev.h"
+ *
+ * typedef struct MyDeviceClass
+ * {
+ * DeviceClass parent;
+ *
+ * void (*frobnicate) (MyDevice *obj);
+ * } MyDeviceClass;
+ *
+ * static TypeInfo my_device_info = {
+ * .name = TYPE_MY_DEVICE,
+ * .parent = TYPE_DEVICE,
+ * .instance_size = sizeof(MyDevice),
+ * .abstract = true, // or set a default in my_device_class_init
+ * .class_size = sizeof(MyDeviceClass),
+ * };
+ *
+ * void my_device_frobnicate(MyDevice *obj)
+ * {
+ * MyDeviceClass *klass = MY_DEVICE_GET_CLASS(obj);
+ *
+ * klass->frobnicate(obj);
+ * }
+ * </programlisting>
+ * </example>
*
* # Interfaces #
*
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 02/27] qom: more documentation on subclassing
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 02/27] qom: more documentation on subclassing Paolo Bonzini
@ 2012-02-06 14:04 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:04 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
And thank you very much for adding to the docs!
Regards,
Anthony Liguori
> ---
> include/qemu/object.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++--
> 1 files changed, 73 insertions(+), 3 deletions(-)
>
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index ab1c48c..ad7d32d 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -55,6 +55,9 @@ typedef struct InterfaceInfo InterfaceInfo;
> *
> * #define TYPE_MY_DEVICE "my-device"
> *
> + * // No new virtual functions: we can reuse the typedef for the
> + * // superclass.
> + * typedef DeviceClass MyDeviceClass;
> * typedef struct MyDevice
> * {
> * DeviceState parent;
> @@ -88,8 +91,21 @@ typedef struct InterfaceInfo InterfaceInfo;
> *
> * Using object_new(), a new #Object derivative will be instantiated. You can
> * cast an #Object to a subclass (or base-class) type using
> - * object_dynamic_cast(). You typically want to define a macro wrapper around
> - * object_dynamic_cast_assert() to make it easier to convert to a specific type.
> + * object_dynamic_cast(). You typically want to define macro wrappers around
> + * OBJECT_CHECK() and OBJECT_CLASS_CHECK() to make it easier to convert to a
> + * specific type:
> + *
> + *<example>
> + *<title>Typecasting macros</title>
> + *<programlisting>
> + * #define MY_DEVICE_GET_CLASS(obj) \
> + * OBJECT_GET_CLASS(MyDeviceClass, obj, TYPE_MY_DEVICE)
> + * #define MY_DEVICE_CLASS(klass) \
> + * OBJECT_CLASS_CHECK(MyDeviceClass, klass, TYPE_MY_DEVICE)
> + * #define MY_DEVICE(obj) \
> + * OBJECT_CHECK(MyDevice, obj, TYPE_MY_DEVICE)
> + *</programlisting>
> + *</example>
> *
> * # Class Initialization #
> *
> @@ -108,7 +124,61 @@ typedef struct InterfaceInfo InterfaceInfo;
> *
> * Once all of the parent classes have been initialized, #TypeInfo::class_init
> * is called to let the class being instantiated provide default initialize for
> - * it's virtual functions.
> + * it's virtual functions. Here is how the above example might be modified
> + * to introduce an overridden virtual function:
> + *
> + *<example>
> + *<title>Overriding a virtual function</title>
> + *<programlisting>
> + * #include "qdev.h"
> + *
> + * void my_device_class_init(ObjectClass *klass, void *class_data)
> + * {
> + * DeviceClass *dc = DEVICE_CLASS(klass);
> + * dc->reset = my_device_reset;
> + * }
> + *
> + * static TypeInfo my_device_info = {
> + * .name = TYPE_MY_DEVICE,
> + * .parent = TYPE_DEVICE,
> + * .instance_size = sizeof(MyDevice),
> + * .class_init = my_device_class_init,
> + * };
> + *</programlisting>
> + *</example>
> + *
> + * Introducing new virtual functions requires a class to define its own
> + * struct and to add a .class_size member to the TypeInfo. Each function
> + * will also have a wrapper to call it easily:
> + *
> + *<example>
> + *<title>Defining an abstract class</title>
> + *<programlisting>
> + * #include "qdev.h"
> + *
> + * typedef struct MyDeviceClass
> + * {
> + * DeviceClass parent;
> + *
> + * void (*frobnicate) (MyDevice *obj);
> + * } MyDeviceClass;
> + *
> + * static TypeInfo my_device_info = {
> + * .name = TYPE_MY_DEVICE,
> + * .parent = TYPE_DEVICE,
> + * .instance_size = sizeof(MyDevice),
> + * .abstract = true, // or set a default in my_device_class_init
> + * .class_size = sizeof(MyDeviceClass),
> + * };
> + *
> + * void my_device_frobnicate(MyDevice *obj)
> + * {
> + * MyDeviceClass *klass = MY_DEVICE_GET_CLASS(obj);
> + *
> + * klass->frobnicate(obj);
> + * }
> + *</programlisting>
> + *</example>
> *
> * # Interfaces #
> *
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 03/27] qom: clean up/optimize object_dynamic_cast
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 01/27] qom: clean up cast macros Paolo Bonzini
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 02/27] qom: more documentation on subclassing Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:10 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 04/27] qom: avoid useless conversions from string to type Paolo Bonzini
` (24 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
The interface loop can be performed only on the parent object. It
does not need to be done on each interface. Similarly, we can
simplify the code by switching early from the implementation
object to the parent object.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qom/object.c | 38 ++++++++++++++++++--------------------
1 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index 4261944..4d21f0a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -372,7 +372,6 @@ static bool object_is_type(Object *obj, const char *typename)
{
TypeImpl *target_type = type_get_by_name(typename);
TypeImpl *type = obj->class->type;
- GSList *i;
/* Check if typename is a direct ancestor of type */
while (type) {
@@ -383,15 +382,6 @@ static bool object_is_type(Object *obj, const char *typename)
type = type_get_parent(type);
}
- /* Check if obj has an interface of typename */
- for (i = obj->interfaces; i; i = i->next) {
- Interface *iface = i->data;
-
- if (object_is_type(OBJECT(iface), typename)) {
- return true;
- }
- }
-
return false;
}
@@ -404,6 +394,24 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
return obj;
}
+ /* Check if obj is an interface and its containing object is a direct
+ * ancestor of typename. In principle we could do this test at the very
+ * beginning of object_dynamic_cast, avoiding a second call to
+ * object_is_type. However, casting between interfaces is relatively
+ * rare, and object_is_type(obj, TYPE_INTERFACE) would fail almost always.
+ *
+ * Perhaps we could add a magic value to the object header for increased
+ * (run-time) type safety and to speed up tests like this one. If we ever
+ * do that we can revisit the order here.
+ */
+ if (object_is_type(obj, TYPE_INTERFACE)) {
+ assert(!obj->interfaces);
+ obj = INTERFACE(obj)->obj;
+ if (object_is_type(obj, typename)) {
+ return obj;
+ }
+ }
+
/* Check if obj has an interface of typename */
for (i = obj->interfaces; i; i = i->next) {
Interface *iface = i->data;
@@ -413,16 +421,6 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
}
}
- /* Check if obj is an interface and its containing object is a direct
- * ancestor of typename */
- if (object_is_type(obj, TYPE_INTERFACE)) {
- Interface *iface = INTERFACE(obj);
-
- if (object_is_type(iface->obj, typename)) {
- return iface->obj;
- }
- }
-
return NULL;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 03/27] qom: clean up/optimize object_dynamic_cast
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 03/27] qom: clean up/optimize object_dynamic_cast Paolo Bonzini
@ 2012-02-06 14:10 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:10 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> The interface loop can be performed only on the parent object. It
> does not need to be done on each interface. Similarly, we can
> simplify the code by switching early from the implementation
> object to the parent object.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> qom/object.c | 38 ++++++++++++++++++--------------------
> 1 files changed, 18 insertions(+), 20 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index 4261944..4d21f0a 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -372,7 +372,6 @@ static bool object_is_type(Object *obj, const char *typename)
> {
> TypeImpl *target_type = type_get_by_name(typename);
> TypeImpl *type = obj->class->type;
> - GSList *i;
>
> /* Check if typename is a direct ancestor of type */
> while (type) {
> @@ -383,15 +382,6 @@ static bool object_is_type(Object *obj, const char *typename)
> type = type_get_parent(type);
> }
>
> - /* Check if obj has an interface of typename */
> - for (i = obj->interfaces; i; i = i->next) {
> - Interface *iface = i->data;
> -
> - if (object_is_type(OBJECT(iface), typename)) {
> - return true;
> - }
> - }
> -
> return false;
> }
So this changes object_is_type() to only determine if the the object is a direct
ancestor. I think it's worth changing the name to something like
object_is_ancestor_of() or something like that.
>
> @@ -404,6 +394,24 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
> return obj;
> }
>
> + /* Check if obj is an interface and its containing object is a direct
> + * ancestor of typename. In principle we could do this test at the very
> + * beginning of object_dynamic_cast, avoiding a second call to
> + * object_is_type. However, casting between interfaces is relatively
> + * rare, and object_is_type(obj, TYPE_INTERFACE) would fail almost always.
> + *
> + * Perhaps we could add a magic value to the object header for increased
> + * (run-time) type safety and to speed up tests like this one. If we ever
> + * do that we can revisit the order here.
> + */
> + if (object_is_type(obj, TYPE_INTERFACE)) {
> + assert(!obj->interfaces);
> + obj = INTERFACE(obj)->obj;
> + if (object_is_type(obj, typename)) {
> + return obj;
> + }
> + }
> +
> /* Check if obj has an interface of typename */
> for (i = obj->interfaces; i; i = i->next) {
> Interface *iface = i->data;
> @@ -413,16 +421,6 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
> }
> }
>
> - /* Check if obj is an interface and its containing object is a direct
> - * ancestor of typename */
> - if (object_is_type(obj, TYPE_INTERFACE)) {
> - Interface *iface = INTERFACE(obj);
> -
> - if (object_is_type(iface->obj, typename)) {
> - return iface->obj;
> - }
> - }
> -
> return NULL;
> }
This looks pretty right to me. We really need a unit test for this stuff. I've
got one in my tree, I'll dig it out so we can start more rigorously validating
these different casting cases.
Regards,
Anthony Liguori
>
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 04/27] qom: avoid useless conversions from string to type
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (2 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 03/27] qom: clean up/optimize object_dynamic_cast Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:14 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 05/27] qom: do not include qdev header file Paolo Bonzini
` (23 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qom/object.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index 4d21f0a..a89e9e3 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -368,9 +368,10 @@ void object_delete(Object *obj)
g_free(obj);
}
-static bool object_is_type(Object *obj, const char *typename)
+static Type type_interface;
+
+static bool object_is_type(Object *obj, TypeImpl *target_type)
{
- TypeImpl *target_type = type_get_by_name(typename);
TypeImpl *type = obj->class->type;
/* Check if typename is a direct ancestor of type */
@@ -387,10 +388,11 @@ static bool object_is_type(Object *obj, const char *typename)
Object *object_dynamic_cast(Object *obj, const char *typename)
{
+ TypeImpl *target_type = type_get_by_name(typename);
GSList *i;
/* Check if typename is a direct ancestor */
- if (object_is_type(obj, typename)) {
+ if (object_is_type(obj, target_type)) {
return obj;
}
@@ -404,10 +406,10 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
* (run-time) type safety and to speed up tests like this one. If we ever
* do that we can revisit the order here.
*/
- if (object_is_type(obj, TYPE_INTERFACE)) {
+ if (object_is_type(obj, type_interface)) {
assert(!obj->interfaces);
obj = INTERFACE(obj)->obj;
- if (object_is_type(obj, typename)) {
+ if (object_is_type(obj, target_type)) {
return obj;
}
}
@@ -416,7 +418,7 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
for (i = obj->interfaces; i; i = i->next) {
Interface *iface = i->data;
- if (object_is_type(OBJECT(iface), typename)) {
+ if (object_is_type(OBJECT(iface), target_type)) {
return OBJECT(iface);
}
}
@@ -433,7 +435,7 @@ static void register_interface(void)
.abstract = true,
};
- type_register_static(&interface_info);
+ type_interface = type_register_static(&interface_info);
}
device_init(register_interface);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 04/27] qom: avoid useless conversions from string to type
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 04/27] qom: avoid useless conversions from string to type Paolo Bonzini
@ 2012-02-06 14:14 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:14 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> qom/object.c | 16 +++++++++-------
> 1 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index 4d21f0a..a89e9e3 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -368,9 +368,10 @@ void object_delete(Object *obj)
> g_free(obj);
> }
>
> -static bool object_is_type(Object *obj, const char *typename)
> +static Type type_interface;
> +
Statics belong at the top of the file. But I'd rather not introduce a global
unless we have some sort of compelling data that shows that it's a performance
problem.
The type lookup is done through a hash table, at most it's going to be 2-3
integer comparisons followed by a strcmp() of a small word. It shouldn't be
that slow.
Regards,
Anthony Liguori
> +static bool object_is_type(Object *obj, TypeImpl *target_type)
> {
> - TypeImpl *target_type = type_get_by_name(typename);
> TypeImpl *type = obj->class->type;
>
> /* Check if typename is a direct ancestor of type */
> @@ -387,10 +388,11 @@ static bool object_is_type(Object *obj, const char *typename)
>
> Object *object_dynamic_cast(Object *obj, const char *typename)
> {
> + TypeImpl *target_type = type_get_by_name(typename);
> GSList *i;
>
> /* Check if typename is a direct ancestor */
> - if (object_is_type(obj, typename)) {
> + if (object_is_type(obj, target_type)) {
> return obj;
> }
>
> @@ -404,10 +406,10 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
> * (run-time) type safety and to speed up tests like this one. If we ever
> * do that we can revisit the order here.
> */
> - if (object_is_type(obj, TYPE_INTERFACE)) {
> + if (object_is_type(obj, type_interface)) {
> assert(!obj->interfaces);
> obj = INTERFACE(obj)->obj;
> - if (object_is_type(obj, typename)) {
> + if (object_is_type(obj, target_type)) {
> return obj;
> }
> }
> @@ -416,7 +418,7 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
> for (i = obj->interfaces; i; i = i->next) {
> Interface *iface = i->data;
>
> - if (object_is_type(OBJECT(iface), typename)) {
> + if (object_is_type(OBJECT(iface), target_type)) {
> return OBJECT(iface);
> }
> }
> @@ -433,7 +435,7 @@ static void register_interface(void)
> .abstract = true,
> };
>
> - type_register_static(&interface_info);
> + type_interface = type_register_static(&interface_info);
> }
>
> device_init(register_interface);
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 05/27] qom: do not include qdev header file
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (3 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 04/27] qom: avoid useless conversions from string to type Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:15 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers Paolo Bonzini
` (22 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qom/object.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index a89e9e3..c0f6d54 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -13,8 +13,6 @@
#include "qemu/object.h"
#include "qemu-common.h"
#include "qapi/qapi-visit-core.h"
-#include "hw/qdev.h"
-// FIXME remove above
#define MAX_INTERFACES 32
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 05/27] qom: do not include qdev header file
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 05/27] qom: do not include qdev header file Paolo Bonzini
@ 2012-02-06 14:15 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:15 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> qom/object.c | 2 --
> 1 files changed, 0 insertions(+), 2 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index a89e9e3..c0f6d54 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -13,8 +13,6 @@
> #include "qemu/object.h"
> #include "qemu-common.h"
> #include "qapi/qapi-visit-core.h"
> -#include "hw/qdev.h"
> -// FIXME remove above
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
>
> #define MAX_INTERFACES 32
>
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (4 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 05/27] qom: do not include qdev header file Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:16 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 07/27] qom: add property get/set wrappers for C types Paolo Bonzini
` (21 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Move the creation of QmpInputVisitor and QmpOutputVisitor from
qmp.c to qom/object.c, since it's the only practical way to access
object properties.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/qom-qobject.h | 43 +++++++++++++++++++++++++++++++++++++++++++
qmp.c | 18 +++---------------
qom/Makefile | 2 +-
qom/qom-qobject.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 91 insertions(+), 16 deletions(-)
create mode 100644 include/qemu/qom-qobject.h
create mode 100644 qom/qom-qobject.c
diff --git a/include/qemu/qom-qobject.h b/include/qemu/qom-qobject.h
new file mode 100644
index 0000000..9094eef
--- /dev/null
+++ b/include/qemu/qom-qobject.h
@@ -0,0 +1,42 @@
+/*
+ * QEMU Object Model - QObject wrappers
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_QOM_QOBJECT_H
+#define QEMU_QOM_QOBJECT_H
+
+#include "qemu/object.h"
+
+/*
+ * object_property_get_qobject:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to QObject, or NULL if
+ * an error occurs.
+ */
+struct QObject *object_property_get_qobject(Object *obj, const char *name,
+ struct Error **errp);
+
+/**
+ * object_property_set_qobject:
+ * @obj: the object
+ * @ret: The value that will be written to the property.
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a property to a object.
+ */
+void object_property_set_qobject(Object *obj, struct QObject *qobj,
+ const char *name, struct Error **errp);
+
+#endif
diff --git a/qmp.c b/qmp.c
index 45052cc..1f64844 100644
--- a/qmp.c
+++ b/qmp.c
@@ -21,9 +21,8 @@
#include "kvm.h"
#include "arch_init.h"
#include "hw/qdev.h"
-#include "qapi/qmp-input-visitor.h"
-#include "qapi/qmp-output-visitor.h"
#include "blockdev.h"
+#include "qemu/qom-qobject.h"
NameInfo *qmp_query_name(Error **errp)
{
@@ -198,7 +197,6 @@ int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret)
const char *property = qdict_get_str(qdict, "property");
QObject *value = qdict_get(qdict, "value");
Error *local_err = NULL;
- QmpInputVisitor *mi;
Object *obj;
obj = object_resolve_path(path, NULL);
@@ -207,10 +205,7 @@ int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret)
goto out;
}
- mi = qmp_input_visitor_new(value);
- object_property_set(obj, qmp_input_get_visitor(mi), property, &local_err);
-
- qmp_input_visitor_cleanup(mi);
+ object_property_set_qobject(obj, value, property, &local_err);
out:
if (local_err) {
@@ -227,7 +222,6 @@ int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret)
const char *path = qdict_get_str(qdict, "path");
const char *property = qdict_get_str(qdict, "property");
Error *local_err = NULL;
- QmpOutputVisitor *mo;
Object *obj;
obj = object_resolve_path(path, NULL);
@@ -236,13 +230,7 @@ int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret)
goto out;
}
- mo = qmp_output_visitor_new();
- object_property_get(obj, qmp_output_get_visitor(mo), property, &local_err);
- if (!local_err) {
- *ret = qmp_output_get_qobject(mo);
- }
-
- qmp_output_visitor_cleanup(mo);
+ *ret = object_property_get_qobject(obj, property, &local_err);
out:
if (local_err) {
diff --git a/qom/Makefile b/qom/Makefile
index f33f0be..885a263 100644
--- a/qom/Makefile
+++ b/qom/Makefile
@@ -1 +1 @@
-qom-y = object.o container.o
+qom-y = object.o container.o qom-qobject.o
diff --git a/qom/qom-qobject.c b/qom/qom-qobject.c
new file mode 100644
index 0000000..90375b0
--- /dev/null
+++ b/qom/qom-qobject.c
@@ -0,0 +1,44 @@
+/*
+ * QEMU Object Model - QObject wrappers
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * Author: Paolo Bonzini <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qemu/object.h"
+#include "qemu/qom-qobject.h"
+#include "qapi/qapi-visit-core.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+
+void object_property_set_qobject(Object *obj, QObject *value,
+ const char *name, Error **errp)
+{
+ QmpInputVisitor *mi;
+ mi = qmp_input_visitor_new(value);
+ object_property_set(obj, qmp_input_get_visitor(mi), name, errp);
+
+ qmp_input_visitor_cleanup(mi);
+}
+
+QObject *object_property_get_qobject(Object *obj, const char *name,
+ Error **errp)
+{
+ QObject *ret = NULL;
+ Error *local_err = NULL;
+ QmpOutputVisitor *mo;
+
+ mo = qmp_output_visitor_new();
+ object_property_get(obj, qmp_output_get_visitor(mo), name, &local_err);
+ if (!local_err) {
+ ret = qmp_output_get_qobject(mo);
+ }
+ error_propagate(errp, local_err);
+ qmp_output_visitor_cleanup(mo);
+ return ret;
+}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers Paolo Bonzini
@ 2012-02-06 14:16 ` Anthony Liguori
2012-02-07 9:12 ` Paolo Bonzini
0 siblings, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:16 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Move the creation of QmpInputVisitor and QmpOutputVisitor from
> qmp.c to qom/object.c, since it's the only practical way to access
> object properties.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reluctantly-Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
As long as we keep this isolated such that it's easy to remove. At some point,
we need to remove all usage of QObject in the tree and replace it with GVariant.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers
2012-02-06 14:16 ` Anthony Liguori
@ 2012-02-07 9:12 ` Paolo Bonzini
2012-02-08 12:29 ` Luiz Capitulino
0 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-07 9:12 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On 02/06/2012 03:16 PM, Anthony Liguori wrote:
>
>> Move the creation of QmpInputVisitor and QmpOutputVisitor from
>> qmp.c to qom/object.c, since it's the only practical way to access
>> object properties.
>>
>> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
>
> Reluctantly-Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Fair enough, thanks very much. :)
> As long as we keep this isolated such that it's easy to remove. At some
> point, we need to remove all usage of QObject in the tree and replace it
> with GVariant.
Agreed, we'll revisit after Luiz completes QAPI.
Paolo
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers
2012-02-07 9:12 ` Paolo Bonzini
@ 2012-02-08 12:29 ` Luiz Capitulino
0 siblings, 0 replies; 62+ messages in thread
From: Luiz Capitulino @ 2012-02-08 12:29 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On Tue, 07 Feb 2012 10:12:34 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:
> On 02/06/2012 03:16 PM, Anthony Liguori wrote:
> >
> >> Move the creation of QmpInputVisitor and QmpOutputVisitor from
> >> qmp.c to qom/object.c, since it's the only practical way to access
> >> object properties.
> >>
> >> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> >
> > Reluctantly-Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
>
> Fair enough, thanks very much. :)
>
> > As long as we keep this isolated such that it's easy to remove. At some
> > point, we need to remove all usage of QObject in the tree and replace it
> > with GVariant.
>
> Agreed, we'll revisit after Luiz completes QAPI.
Commands are not far away. Events are still missing, although they could be
converted along with the introduction of GVariant.
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 07/27] qom: add property get/set wrappers for C types
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (5 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 06/27] qom: add QObject-based property get/set wrappers Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:17 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 08/27] qom: fix off-by-one Paolo Bonzini
` (20 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Add wrappers that let you get/set properties using normal C data types.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/object.h | 70 +++++++++++++++++++++++++++++
qom/object.c | 119 +++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 180 insertions(+), 9 deletions(-)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index ad7d32d..b27f80e 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -622,6 +622,76 @@ void object_property_get(Object *obj, struct Visitor *v, const char *name,
struct Error **errp);
/**
+ * object_property_set_str:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a string value to a property.
+ */
+void object_property_set_str(Object *obj, const char *value,
+ const char *name, struct Error **errp);
+
+/**
+ * object_property_get_str:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to a C string, or NULL if
+ * an error occurs (including when the property value is not a string).
+ * The caller should free the string.
+ */
+char *object_property_get_str(Object *obj, const char *name,
+ struct Error **errp);
+
+/**
+ * object_property_set_bool:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a bool value to a property.
+ */
+void object_property_set_bool(Object *obj, bool value,
+ const char *name, struct Error **errp);
+
+/**
+ * object_property_get_bool:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to a boolean, or NULL if
+ * an error occurs (including when the property value is not a bool).
+ */
+bool object_property_get_bool(Object *obj, const char *name,
+ struct Error **errp);
+
+/**
+ * object_property_set_int:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an integer value to a property.
+ */
+void object_property_set_int(Object *obj, int64_t value,
+ const char *name, struct Error **errp);
+
+/**
+ * object_property_get_int:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an integer, or NULL if
+ * an error occurs (including when the property value is not an integer).
+ */
+int64_t object_property_get_int(Object *obj, const char *name,
+ struct Error **errp);
+
+/**
* object_property_set:
* @obj: the object
* @v: the visitor that will be used to write the property value. This should
diff --git a/qom/object.c b/qom/object.c
index c0f6d54..d3a443f 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -14,6 +14,14 @@
#include "qemu-common.h"
#include "qapi/qapi-visit-core.h"
+/* TODO: replace QObject with a simpler visitor to avoid a dependency
+ * of the QOM core on QObject? */
+#include "qemu/qom-qobject.h"
+#include "qobject.h"
+#include "qbool.h"
+#include "qint.h"
+#include "qstring.h"
+
#define MAX_INTERFACES 32
typedef struct InterfaceImpl InterfaceImpl;
@@ -646,6 +654,99 @@ void object_property_set(Object *obj, Visitor *v, const char *name,
}
}
+void object_property_set_str(Object *obj, const char *value,
+ const char *name, Error **errp)
+{
+ QString *qstr = qstring_from_str(value);
+ object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
+
+ QDECREF(qstr);
+}
+
+char *object_property_get_str(Object *obj, const char *name,
+ Error **errp)
+{
+ QObject *ret = object_property_get_qobject(obj, name, errp);
+ QString *qstring;
+ char *retval;
+
+ if (!ret) {
+ return NULL;
+ }
+ qstring = qobject_to_qstring(ret);
+ if (!qstring) {
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
+ retval = NULL;
+ } else {
+ retval = g_strdup(qstring_get_str(qstring));
+ }
+
+ QDECREF(qstring);
+ return retval;
+}
+
+void object_property_set_bool(Object *obj, bool value,
+ const char *name, Error **errp)
+{
+ QBool *qbool = qbool_from_int(value);
+ object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
+
+ QDECREF(qbool);
+}
+
+bool object_property_get_bool(Object *obj, const char *name,
+ Error **errp)
+{
+ QObject *ret = object_property_get_qobject(obj, name, errp);
+ QBool *qbool;
+ bool retval;
+
+ if (!ret) {
+ return false;
+ }
+ qbool = qobject_to_qbool(ret);
+ if (!qbool) {
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
+ retval = false;
+ } else {
+ retval = qbool_get_int(qbool);
+ }
+
+ QDECREF(qbool);
+ return retval;
+}
+
+void object_property_set_int(Object *obj, int64_t value,
+ const char *name, Error **errp)
+{
+ QInt *qint = qint_from_int(value);
+ object_property_set_qobject(obj, QOBJECT(qint), name, errp);
+
+ QDECREF(qint);
+}
+
+int64_t object_property_get_int(Object *obj, const char *name,
+ Error **errp)
+{
+ QObject *ret = object_property_get_qobject(obj, name, errp);
+ QInt *qint;
+ int64_t retval;
+
+ if (!ret) {
+ return -1;
+ }
+ qint = qobject_to_qint(ret);
+ if (!qint) {
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
+ retval = -1;
+ } else {
+ retval = qint_get_int(qint);
+ }
+
+ QDECREF(qint);
+ return retval;
+}
+
const char *object_property_get_type(Object *obj, const char *name, Error **errp)
{
ObjectProperty *prop = object_property_find(obj, name);
@@ -927,8 +1028,8 @@ typedef struct StringProperty
void (*set)(Object *, const char *, Error **);
} StringProperty;
-static void object_property_get_str(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+static void property_get_str(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
StringProperty *prop = opaque;
char *value;
@@ -940,8 +1041,8 @@ static void object_property_get_str(Object *obj, Visitor *v, void *opaque,
}
}
-static void object_property_set_str(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+static void property_set_str(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
StringProperty *prop = opaque;
char *value;
@@ -957,8 +1058,8 @@ static void object_property_set_str(Object *obj, Visitor *v, void *opaque,
g_free(value);
}
-static void object_property_release_str(Object *obj, const char *name,
- void *opaque)
+static void property_release_str(Object *obj, const char *name,
+ void *opaque)
{
StringProperty *prop = opaque;
g_free(prop);
@@ -975,8 +1076,8 @@ void object_property_add_str(Object *obj, const char *name,
prop->set = set;
object_property_add(obj, name, "string",
- get ? object_property_get_str : NULL,
- set ? object_property_set_str : NULL,
- object_property_release_str,
+ get ? property_get_str : NULL,
+ set ? property_set_str : NULL,
+ property_release_str,
prop, errp);
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 07/27] qom: add property get/set wrappers for C types
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 07/27] qom: add property get/set wrappers for C types Paolo Bonzini
@ 2012-02-06 14:17 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:17 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Add wrappers that let you get/set properties using normal C data types.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> include/qemu/object.h | 70 +++++++++++++++++++++++++++++
> qom/object.c | 119 +++++++++++++++++++++++++++++++++++++++++++++----
> 2 files changed, 180 insertions(+), 9 deletions(-)
>
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index ad7d32d..b27f80e 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -622,6 +622,76 @@ void object_property_get(Object *obj, struct Visitor *v, const char *name,
> struct Error **errp);
>
> /**
> + * object_property_set_str:
> + * @value: the value to be written to the property
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Writes a string value to a property.
> + */
> +void object_property_set_str(Object *obj, const char *value,
> + const char *name, struct Error **errp);
> +
> +/**
> + * object_property_get_str:
> + * @obj: the object
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Returns: the value of the property, converted to a C string, or NULL if
> + * an error occurs (including when the property value is not a string).
> + * The caller should free the string.
> + */
> +char *object_property_get_str(Object *obj, const char *name,
> + struct Error **errp);
> +
> +/**
> + * object_property_set_bool:
> + * @value: the value to be written to the property
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Writes a bool value to a property.
> + */
> +void object_property_set_bool(Object *obj, bool value,
> + const char *name, struct Error **errp);
> +
> +/**
> + * object_property_get_bool:
> + * @obj: the object
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Returns: the value of the property, converted to a boolean, or NULL if
> + * an error occurs (including when the property value is not a bool).
> + */
> +bool object_property_get_bool(Object *obj, const char *name,
> + struct Error **errp);
> +
> +/**
> + * object_property_set_int:
> + * @value: the value to be written to the property
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Writes an integer value to a property.
> + */
> +void object_property_set_int(Object *obj, int64_t value,
> + const char *name, struct Error **errp);
> +
> +/**
> + * object_property_get_int:
> + * @obj: the object
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Returns: the value of the property, converted to an integer, or NULL if
> + * an error occurs (including when the property value is not an integer).
> + */
> +int64_t object_property_get_int(Object *obj, const char *name,
> + struct Error **errp);
> +
> +/**
> * object_property_set:
> * @obj: the object
> * @v: the visitor that will be used to write the property value. This should
> diff --git a/qom/object.c b/qom/object.c
> index c0f6d54..d3a443f 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -14,6 +14,14 @@
> #include "qemu-common.h"
> #include "qapi/qapi-visit-core.h"
>
> +/* TODO: replace QObject with a simpler visitor to avoid a dependency
> + * of the QOM core on QObject? */
> +#include "qemu/qom-qobject.h"
> +#include "qobject.h"
> +#include "qbool.h"
> +#include "qint.h"
> +#include "qstring.h"
> +
> #define MAX_INTERFACES 32
>
> typedef struct InterfaceImpl InterfaceImpl;
> @@ -646,6 +654,99 @@ void object_property_set(Object *obj, Visitor *v, const char *name,
> }
> }
>
> +void object_property_set_str(Object *obj, const char *value,
> + const char *name, Error **errp)
> +{
> + QString *qstr = qstring_from_str(value);
> + object_property_set_qobject(obj, QOBJECT(qstr), name, errp);
> +
> + QDECREF(qstr);
> +}
> +
> +char *object_property_get_str(Object *obj, const char *name,
> + Error **errp)
> +{
> + QObject *ret = object_property_get_qobject(obj, name, errp);
> + QString *qstring;
> + char *retval;
> +
> + if (!ret) {
> + return NULL;
> + }
> + qstring = qobject_to_qstring(ret);
> + if (!qstring) {
> + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "string");
> + retval = NULL;
> + } else {
> + retval = g_strdup(qstring_get_str(qstring));
> + }
> +
> + QDECREF(qstring);
> + return retval;
> +}
> +
> +void object_property_set_bool(Object *obj, bool value,
> + const char *name, Error **errp)
> +{
> + QBool *qbool = qbool_from_int(value);
> + object_property_set_qobject(obj, QOBJECT(qbool), name, errp);
> +
> + QDECREF(qbool);
> +}
> +
> +bool object_property_get_bool(Object *obj, const char *name,
> + Error **errp)
> +{
> + QObject *ret = object_property_get_qobject(obj, name, errp);
> + QBool *qbool;
> + bool retval;
> +
> + if (!ret) {
> + return false;
> + }
> + qbool = qobject_to_qbool(ret);
> + if (!qbool) {
> + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean");
> + retval = false;
> + } else {
> + retval = qbool_get_int(qbool);
> + }
> +
> + QDECREF(qbool);
> + return retval;
> +}
> +
> +void object_property_set_int(Object *obj, int64_t value,
> + const char *name, Error **errp)
> +{
> + QInt *qint = qint_from_int(value);
> + object_property_set_qobject(obj, QOBJECT(qint), name, errp);
> +
> + QDECREF(qint);
> +}
> +
> +int64_t object_property_get_int(Object *obj, const char *name,
> + Error **errp)
> +{
> + QObject *ret = object_property_get_qobject(obj, name, errp);
> + QInt *qint;
> + int64_t retval;
> +
> + if (!ret) {
> + return -1;
> + }
> + qint = qobject_to_qint(ret);
> + if (!qint) {
> + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "int");
> + retval = -1;
> + } else {
> + retval = qint_get_int(qint);
> + }
> +
> + QDECREF(qint);
> + return retval;
> +}
> +
> const char *object_property_get_type(Object *obj, const char *name, Error **errp)
> {
> ObjectProperty *prop = object_property_find(obj, name);
> @@ -927,8 +1028,8 @@ typedef struct StringProperty
> void (*set)(Object *, const char *, Error **);
> } StringProperty;
>
> -static void object_property_get_str(Object *obj, Visitor *v, void *opaque,
> - const char *name, Error **errp)
> +static void property_get_str(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> {
> StringProperty *prop = opaque;
> char *value;
> @@ -940,8 +1041,8 @@ static void object_property_get_str(Object *obj, Visitor *v, void *opaque,
> }
> }
>
> -static void object_property_set_str(Object *obj, Visitor *v, void *opaque,
> - const char *name, Error **errp)
> +static void property_set_str(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> {
> StringProperty *prop = opaque;
> char *value;
> @@ -957,8 +1058,8 @@ static void object_property_set_str(Object *obj, Visitor *v, void *opaque,
> g_free(value);
> }
>
> -static void object_property_release_str(Object *obj, const char *name,
> - void *opaque)
> +static void property_release_str(Object *obj, const char *name,
> + void *opaque)
> {
> StringProperty *prop = opaque;
> g_free(prop);
> @@ -975,8 +1076,8 @@ void object_property_add_str(Object *obj, const char *name,
> prop->set = set;
>
> object_property_add(obj, name, "string",
> - get ? object_property_get_str : NULL,
> - set ? object_property_set_str : NULL,
> - object_property_release_str,
> + get ? property_get_str : NULL,
> + set ? property_set_str : NULL,
> + property_release_str,
> prop, errp);
> }
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 08/27] qom: fix off-by-one
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (6 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 07/27] qom: add property get/set wrappers for C types Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:19 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 09/27] qom: add object_resolve_path_type Paolo Bonzini
` (19 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qom/object.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index b26272f..314fc7a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -871,7 +871,7 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
gchar *target_type;
target_type = g_strdup(&type[5]);
- target_type[strlen(target_type) - 2] = 0;
+ *strchr(target_type, '>') = 0;
if (object_dynamic_cast(target, target_type)) {
object_ref(target);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 08/27] qom: fix off-by-one
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 08/27] qom: fix off-by-one Paolo Bonzini
@ 2012-02-06 14:19 ` Anthony Liguori
2012-02-07 9:13 ` Paolo Bonzini
0 siblings, 1 reply; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:19 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> qom/object.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index b26272f..314fc7a 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -871,7 +871,7 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
> gchar *target_type;
>
> target_type = g_strdup(&type[5]);
> - target_type[strlen(target_type) - 2] = 0;
> + *strchr(target_type, '>') = 0;
Should use an intermediate variable here and do a NULL check.
My eyes can't handle dereferencing strchr() directly even if I understand why
it's safe to do :-)
Regards,
Anthony Liguori
>
> if (object_dynamic_cast(target, target_type)) {
> object_ref(target);
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 08/27] qom: fix off-by-one
2012-02-06 14:19 ` Anthony Liguori
@ 2012-02-07 9:13 ` Paolo Bonzini
0 siblings, 0 replies; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-07 9:13 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
On 02/06/2012 03:19 PM, Anthony Liguori wrote:
>>
>> target_type = g_strdup(&type[5]);
>> - target_type[strlen(target_type) - 2] = 0;
>> + *strchr(target_type, '>') = 0;
>
> Should use an intermediate variable here and do a NULL check.
>
> My eyes can't handle dereferencing strchr() directly even if I
> understand why it's safe to do :-)
Ok, I'll change to strrchr too since I have to respin.
Paolo
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 09/27] qom: add object_resolve_path_type
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (7 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 08/27] qom: fix off-by-one Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:21 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 10/27] qom: use object_resolve_path_type for links Paolo Bonzini
` (18 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/object.h | 25 +++++++++++++++++++++++--
qom/object.c | 26 ++++++++++++++++++--------
2 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index f36aff6..4ec7942 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -773,14 +773,35 @@ gchar *object_get_canonical_path(Object *obj);
* specifying objects easy. At each level of the composition tree, the partial
* path is matched as an absolute path. The first match is not returned. At
* least two matches are searched for. A successful result is only returned if
- * only one match is founded. If more than one match is found, a flag is
- * return to indicate that the match was ambiguous.
+ * only one match is found. If more than one match is found, a flag is
+ * returned to indicate that the match was ambiguous.
*
* Returns: The matched object or NULL on path lookup failure.
*/
Object *object_resolve_path(const char *path, bool *ambiguous);
/**
+ * object_resolve_path_type:
+ * @path: the path to resolve
+ * @typename: the type to look for.
+ * @ambiguous: returns true if the path resolution failed because of an
+ * ambiguous match
+ *
+ * This is similar to object_resolve_path. However, when looking for a
+ * partial path only matches that implement the given type are considered.
+ * This restricts the search and avoids spuriously flagging matches as
+ * ambiguous.
+ *
+ * For both partial and absolute paths, the return value goes through
+ * a dynamic cast to @typename. This is important if either the link,
+ * or the typename itself are of interface types.
+ *
+ * Returns: The matched object or NULL on path lookup failure.
+ */
+Object *object_resolve_path_type(const char *path, const char *typename,
+ bool *ambiguous);
+
+/**
* object_property_add_child:
* @obj: the object to add a property to
* @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index 314fc7a..ea4a1f5 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -947,17 +947,18 @@ gchar *object_get_canonical_path(Object *obj)
static Object *object_resolve_abs_path(Object *parent,
gchar **parts,
+ const char *typename,
int index)
{
ObjectProperty *prop;
Object *child;
if (parts[index] == NULL) {
- return parent;
+ return object_dynamic_cast(parent, typename);
}
if (strcmp(parts[index], "") == 0) {
- return object_resolve_abs_path(parent, parts, index + 1);
+ return object_resolve_abs_path(parent, parts, typename, index + 1);
}
prop = object_property_find(parent, parts[index]);
@@ -979,17 +980,18 @@ static Object *object_resolve_abs_path(Object *parent,
return NULL;
}
- return object_resolve_abs_path(child, parts, index + 1);
+ return object_resolve_abs_path(child, parts, typename, index + 1);
}
static Object *object_resolve_partial_path(Object *parent,
gchar **parts,
+ const char *typename,
bool *ambiguous)
{
Object *obj;
ObjectProperty *prop;
- obj = object_resolve_abs_path(parent, parts, 0);
+ obj = object_resolve_abs_path(parent, parts, typename, 0);
QTAILQ_FOREACH(prop, &parent->properties, node) {
Object *found;
@@ -998,7 +1000,8 @@ static Object *object_resolve_partial_path(Object *parent,
continue;
}
- found = object_resolve_partial_path(prop->opaque, parts, ambiguous);
+ found = object_resolve_partial_path(prop->opaque, parts,
+ typename, ambiguous);
if (found) {
if (obj) {
if (ambiguous) {
@@ -1017,7 +1020,8 @@ static Object *object_resolve_partial_path(Object *parent,
return obj;
}
-Object *object_resolve_path(const char *path, bool *ambiguous)
+Object *object_resolve_path_type(const char *path, const char *typename,
+ bool *ambiguous)
{
bool partial_path = true;
Object *obj;
@@ -1037,9 +1041,10 @@ Object *object_resolve_path(const char *path, bool *ambiguous)
if (ambiguous) {
*ambiguous = false;
}
- obj = object_resolve_partial_path(object_get_root(), parts, ambiguous);
+ obj = object_resolve_partial_path(object_get_root(), parts,
+ typename, ambiguous);
} else {
- obj = object_resolve_abs_path(object_get_root(), parts, 1);
+ obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
}
g_strfreev(parts);
@@ -1047,6 +1052,11 @@ Object *object_resolve_path(const char *path, bool *ambiguous)
return obj;
}
+Object *object_resolve_path(const char *path, bool *ambiguous)
+{
+ return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
+}
+
typedef struct StringProperty
{
char *(*get)(Object *, Error **);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 09/27] qom: add object_resolve_path_type
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 09/27] qom: add object_resolve_path_type Paolo Bonzini
@ 2012-02-06 14:21 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:21 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> include/qemu/object.h | 25 +++++++++++++++++++++++--
> qom/object.c | 26 ++++++++++++++++++--------
> 2 files changed, 41 insertions(+), 10 deletions(-)
>
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index f36aff6..4ec7942 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -773,14 +773,35 @@ gchar *object_get_canonical_path(Object *obj);
> * specifying objects easy. At each level of the composition tree, the partial
> * path is matched as an absolute path. The first match is not returned. At
> * least two matches are searched for. A successful result is only returned if
> - * only one match is founded. If more than one match is found, a flag is
> - * return to indicate that the match was ambiguous.
> + * only one match is found. If more than one match is found, a flag is
> + * returned to indicate that the match was ambiguous.
> *
> * Returns: The matched object or NULL on path lookup failure.
> */
> Object *object_resolve_path(const char *path, bool *ambiguous);
>
> /**
> + * object_resolve_path_type:
> + * @path: the path to resolve
> + * @typename: the type to look for.
> + * @ambiguous: returns true if the path resolution failed because of an
> + * ambiguous match
> + *
> + * This is similar to object_resolve_path. However, when looking for a
> + * partial path only matches that implement the given type are considered.
> + * This restricts the search and avoids spuriously flagging matches as
> + * ambiguous.
> + *
> + * For both partial and absolute paths, the return value goes through
> + * a dynamic cast to @typename. This is important if either the link,
> + * or the typename itself are of interface types.
> + *
> + * Returns: The matched object or NULL on path lookup failure.
> + */
> +Object *object_resolve_path_type(const char *path, const char *typename,
> + bool *ambiguous);
> +
> +/**
> * object_property_add_child:
> * @obj: the object to add a property to
> * @name: the name of the property
> diff --git a/qom/object.c b/qom/object.c
> index 314fc7a..ea4a1f5 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -947,17 +947,18 @@ gchar *object_get_canonical_path(Object *obj)
>
> static Object *object_resolve_abs_path(Object *parent,
> gchar **parts,
> + const char *typename,
> int index)
> {
> ObjectProperty *prop;
> Object *child;
>
> if (parts[index] == NULL) {
> - return parent;
> + return object_dynamic_cast(parent, typename);
> }
>
> if (strcmp(parts[index], "") == 0) {
> - return object_resolve_abs_path(parent, parts, index + 1);
> + return object_resolve_abs_path(parent, parts, typename, index + 1);
> }
>
> prop = object_property_find(parent, parts[index]);
> @@ -979,17 +980,18 @@ static Object *object_resolve_abs_path(Object *parent,
> return NULL;
> }
>
> - return object_resolve_abs_path(child, parts, index + 1);
> + return object_resolve_abs_path(child, parts, typename, index + 1);
> }
>
> static Object *object_resolve_partial_path(Object *parent,
> gchar **parts,
> + const char *typename,
> bool *ambiguous)
> {
> Object *obj;
> ObjectProperty *prop;
>
> - obj = object_resolve_abs_path(parent, parts, 0);
> + obj = object_resolve_abs_path(parent, parts, typename, 0);
>
> QTAILQ_FOREACH(prop,&parent->properties, node) {
> Object *found;
> @@ -998,7 +1000,8 @@ static Object *object_resolve_partial_path(Object *parent,
> continue;
> }
>
> - found = object_resolve_partial_path(prop->opaque, parts, ambiguous);
> + found = object_resolve_partial_path(prop->opaque, parts,
> + typename, ambiguous);
> if (found) {
> if (obj) {
> if (ambiguous) {
> @@ -1017,7 +1020,8 @@ static Object *object_resolve_partial_path(Object *parent,
> return obj;
> }
>
> -Object *object_resolve_path(const char *path, bool *ambiguous)
> +Object *object_resolve_path_type(const char *path, const char *typename,
> + bool *ambiguous)
> {
> bool partial_path = true;
> Object *obj;
> @@ -1037,9 +1041,10 @@ Object *object_resolve_path(const char *path, bool *ambiguous)
> if (ambiguous) {
> *ambiguous = false;
> }
> - obj = object_resolve_partial_path(object_get_root(), parts, ambiguous);
> + obj = object_resolve_partial_path(object_get_root(), parts,
> + typename, ambiguous);
> } else {
> - obj = object_resolve_abs_path(object_get_root(), parts, 1);
> + obj = object_resolve_abs_path(object_get_root(), parts, typename, 1);
> }
>
> g_strfreev(parts);
> @@ -1047,6 +1052,11 @@ Object *object_resolve_path(const char *path, bool *ambiguous)
> return obj;
> }
>
> +Object *object_resolve_path(const char *path, bool *ambiguous)
> +{
> + return object_resolve_path_type(path, TYPE_OBJECT, ambiguous);
> +}
> +
> typedef struct StringProperty
> {
> char *(*get)(Object *, Error **);
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 10/27] qom: use object_resolve_path_type for links
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (8 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 09/27] qom: add object_resolve_path_type Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:24 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 11/27] qom: fix canonical paths vs. interfaces Paolo Bonzini
` (17 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
This allows to restrict partial matches to objects of the expected
type. It will let people use bare names to reference drives
even though their name might be the same as a device's (e.g.
-drive id=hd0,if=none,... -device ...,drive=hd0,id=hd0).
As a useful byproduct, this fixes a problem with links of interface
type. When a link property's type is an interface, the code expects
the implementation object (not the parent object) to be stored in the
variable. The parent object does not contain the right vtable.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qerror.c | 4 ++++
qerror.h | 3 +++
qom/object.c | 32 ++++++++++++++++----------------
3 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/qerror.c b/qerror.c
index 3d179c8..8e6efaf 100644
--- a/qerror.c
+++ b/qerror.c
@@ -48,6 +48,10 @@ static const QErrorStringTable qerror_table[] = {
.desc = "Could not add client",
},
{
+ .error_fmt = QERR_AMBIGUOUS_PATH,
+ .desc = "Path '%(path)' does not uniquely identify a %(object)"
+ },
+ {
.error_fmt = QERR_BAD_BUS_FOR_DEVICE,
.desc = "Device '%(device)' can't go on a %(bad_bus_type) bus",
},
diff --git a/qerror.h b/qerror.h
index 8c36ddb..e8718bf 100644
--- a/qerror.h
+++ b/qerror.h
@@ -54,6 +54,9 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_ADD_CLIENT_FAILED \
"{ 'class': 'AddClientFailed', 'data': {} }"
+#define QERR_AMBIGUOUS_PATH \
+ "{ 'class': 'AmbiguousPath', 'data': { 'path': %s } }"
+
#define QERR_BAD_BUS_FOR_DEVICE \
"{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }"
diff --git a/qom/object.c b/qom/object.c
index ea4a1f5..75be582 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -854,6 +854,7 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
bool ambiguous = false;
const char *type;
char *path;
+ gchar *target_type;
type = object_property_get_type(obj, name, NULL);
@@ -861,31 +862,30 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
if (*child) {
object_unref(*child);
+ *child = NULL;
}
if (strcmp(path, "") != 0) {
Object *target;
- target = object_resolve_path(path, &ambiguous);
- if (target) {
- gchar *target_type;
-
- target_type = g_strdup(&type[5]);
- *strchr(target_type, '>') = 0;
+ target_type = g_strdup(&type[5]);
+ *strchr(target_type, '>') = 0;
+ target = object_resolve_path_type(path, target_type, &ambiguous);
- if (object_dynamic_cast(target, target_type)) {
- object_ref(target);
- *child = target;
+ if (ambiguous) {
+ error_set(errp, QERR_AMBIGUOUS_PATH, path);
+ } else if (target) {
+ object_ref(target);
+ *child = target;
+ } else {
+ target = object_resolve_path(path, &ambiguous);
+ if (target || ambiguous) {
+ error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
} else {
- error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
+ error_set(errp, QERR_DEVICE_NOT_FOUND, path);
}
-
- g_free(target_type);
- } else {
- error_set(errp, QERR_DEVICE_NOT_FOUND, path);
}
- } else {
- *child = NULL;
+ g_free(target_type);
}
g_free(path);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 10/27] qom: use object_resolve_path_type for links
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 10/27] qom: use object_resolve_path_type for links Paolo Bonzini
@ 2012-02-06 14:24 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:24 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> This allows to restrict partial matches to objects of the expected
> type. It will let people use bare names to reference drives
> even though their name might be the same as a device's (e.g.
> -drive id=hd0,if=none,... -device ...,drive=hd0,id=hd0).
>
> As a useful byproduct, this fixes a problem with links of interface
> type. When a link property's type is an interface, the code expects
> the implementation object (not the parent object) to be stored in the
> variable. The parent object does not contain the right vtable.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
I'm really happy with how this turned out.
Regards,
Anthony Liguori
> ---
> qerror.c | 4 ++++
> qerror.h | 3 +++
> qom/object.c | 32 ++++++++++++++++----------------
> 3 files changed, 23 insertions(+), 16 deletions(-)
>
> diff --git a/qerror.c b/qerror.c
> index 3d179c8..8e6efaf 100644
> --- a/qerror.c
> +++ b/qerror.c
> @@ -48,6 +48,10 @@ static const QErrorStringTable qerror_table[] = {
> .desc = "Could not add client",
> },
> {
> + .error_fmt = QERR_AMBIGUOUS_PATH,
> + .desc = "Path '%(path)' does not uniquely identify a %(object)"
> + },
> + {
> .error_fmt = QERR_BAD_BUS_FOR_DEVICE,
> .desc = "Device '%(device)' can't go on a %(bad_bus_type) bus",
> },
> diff --git a/qerror.h b/qerror.h
> index 8c36ddb..e8718bf 100644
> --- a/qerror.h
> +++ b/qerror.h
> @@ -54,6 +54,9 @@ QError *qobject_to_qerror(const QObject *obj);
> #define QERR_ADD_CLIENT_FAILED \
> "{ 'class': 'AddClientFailed', 'data': {} }"
>
> +#define QERR_AMBIGUOUS_PATH \
> + "{ 'class': 'AmbiguousPath', 'data': { 'path': %s } }"
> +
> #define QERR_BAD_BUS_FOR_DEVICE \
> "{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }"
>
> diff --git a/qom/object.c b/qom/object.c
> index ea4a1f5..75be582 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -854,6 +854,7 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
> bool ambiguous = false;
> const char *type;
> char *path;
> + gchar *target_type;
>
> type = object_property_get_type(obj, name, NULL);
>
> @@ -861,31 +862,30 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
>
> if (*child) {
> object_unref(*child);
> + *child = NULL;
> }
>
> if (strcmp(path, "") != 0) {
> Object *target;
>
> - target = object_resolve_path(path,&ambiguous);
> - if (target) {
> - gchar *target_type;
> -
> - target_type = g_strdup(&type[5]);
> - *strchr(target_type, '>') = 0;
> + target_type = g_strdup(&type[5]);
> + *strchr(target_type, '>') = 0;
> + target = object_resolve_path_type(path, target_type,&ambiguous);
>
> - if (object_dynamic_cast(target, target_type)) {
> - object_ref(target);
> - *child = target;
> + if (ambiguous) {
> + error_set(errp, QERR_AMBIGUOUS_PATH, path);
> + } else if (target) {
> + object_ref(target);
> + *child = target;
> + } else {
> + target = object_resolve_path(path,&ambiguous);
> + if (target || ambiguous) {
> + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
> } else {
> - error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
> + error_set(errp, QERR_DEVICE_NOT_FOUND, path);
> }
> -
> - g_free(target_type);
> - } else {
> - error_set(errp, QERR_DEVICE_NOT_FOUND, path);
> }
> - } else {
> - *child = NULL;
> + g_free(target_type);
> }
>
> g_free(path);
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 11/27] qom: fix canonical paths vs. interfaces
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (9 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 10/27] qom: use object_resolve_path_type for links Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:24 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 12/27] qom: add property get/set wrappers for links Paolo Bonzini
` (16 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qom/object.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index 75be582..e8418bc 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -819,6 +819,12 @@ void object_property_add_child(Object *obj, const char *name,
{
gchar *type;
+ /* Registering an interface object in the composition tree will mightily
+ * confuse object_get_canonical_path (which, on the other hand, knows how
+ * to get the canonical path of an interface object).
+ */
+ assert(!object_is_type(obj, type_interface));
+
type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
object_property_add(obj, name, type, object_get_child_property,
@@ -912,6 +918,10 @@ gchar *object_get_canonical_path(Object *obj)
Object *root = object_get_root();
char *newpath = NULL, *path = NULL;
+ if (object_is_type(obj, type_interface)) {
+ obj = INTERFACE(obj)->obj;
+ }
+
while (obj != root) {
ObjectProperty *prop = NULL;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 11/27] qom: fix canonical paths vs. interfaces
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 11/27] qom: fix canonical paths vs. interfaces Paolo Bonzini
@ 2012-02-06 14:24 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:24 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> qom/object.c | 10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/qom/object.c b/qom/object.c
> index 75be582..e8418bc 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -819,6 +819,12 @@ void object_property_add_child(Object *obj, const char *name,
> {
> gchar *type;
>
> + /* Registering an interface object in the composition tree will mightily
> + * confuse object_get_canonical_path (which, on the other hand, knows how
> + * to get the canonical path of an interface object).
> + */
> + assert(!object_is_type(obj, type_interface));
> +
> type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
>
> object_property_add(obj, name, type, object_get_child_property,
> @@ -912,6 +918,10 @@ gchar *object_get_canonical_path(Object *obj)
> Object *root = object_get_root();
> char *newpath = NULL, *path = NULL;
>
> + if (object_is_type(obj, type_interface)) {
> + obj = INTERFACE(obj)->obj;
> + }
> +
> while (obj != root) {
> ObjectProperty *prop = NULL;
>
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 12/27] qom: add property get/set wrappers for links
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (10 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 11/27] qom: fix canonical paths vs. interfaces Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:27 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 13/27] qdev: remove direct calls to print/parse Paolo Bonzini
` (15 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
These can set a link to any object, as long as it is included in
the composition tree.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/object.h | 24 ++++++++++++++++++++++++
qom/object.c | 25 +++++++++++++++++++++++++
2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index 4ec7942..910b767 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -658,6 +658,30 @@ char *object_property_get_str(Object *obj, const char *name,
struct Error **errp);
/**
+ * object_property_set_link:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an object's canonical path to a property.
+ */
+void object_property_set_link(Object *obj, Object *value,
+ const char *name, struct Error **errp);
+
+/**
+ * object_property_get_link:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, resolved from a path to an Object,
+ * or NULL if an error occurs (including when the property value is not a
+ * string or not a valid object path).
+ */
+Object *object_property_get_link(Object *obj, const char *name,
+ struct Error **errp);
+
+/**
* object_property_set_bool:
* @value: the value to be written to the property
* @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index e8418bc..b3cff50 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -710,6 +710,30 @@ char *object_property_get_str(Object *obj, const char *name,
return retval;
}
+void object_property_set_link(Object *obj, Object *value,
+ const char *name, Error **errp)
+{
+ object_property_set_str(obj, object_get_canonical_path(value),
+ name, errp);
+}
+
+Object *object_property_get_link(Object *obj, const char *name,
+ Error **errp)
+{
+ char *str = object_property_get_str(obj, name, errp);
+ Object *target = NULL;
+
+ if (str && *str) {
+ target = object_resolve_path(str, NULL);
+ if (!target) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, str);
+ }
+ }
+
+ g_free(str);
+ return target;
+}
+
void object_property_set_bool(Object *obj, bool value,
const char *name, Error **errp)
{
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 12/27] qom: add property get/set wrappers for links
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 12/27] qom: add property get/set wrappers for links Paolo Bonzini
@ 2012-02-06 14:27 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:27 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> These can set a link to any object, as long as it is included in
> the composition tree.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> include/qemu/object.h | 24 ++++++++++++++++++++++++
> qom/object.c | 25 +++++++++++++++++++++++++
> 2 files changed, 49 insertions(+), 0 deletions(-)
>
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index 4ec7942..910b767 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -658,6 +658,30 @@ char *object_property_get_str(Object *obj, const char *name,
> struct Error **errp);
>
> /**
> + * object_property_set_link:
> + * @value: the value to be written to the property
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Writes an object's canonical path to a property.
> + */
> +void object_property_set_link(Object *obj, Object *value,
> + const char *name, struct Error **errp);
> +
> +/**
> + * object_property_get_link:
> + * @obj: the object
> + * @name: the name of the property
> + * @errp: returns an error if this function fails
> + *
> + * Returns: the value of the property, resolved from a path to an Object,
> + * or NULL if an error occurs (including when the property value is not a
> + * string or not a valid object path).
> + */
> +Object *object_property_get_link(Object *obj, const char *name,
> + struct Error **errp);
> +
> +/**
> * object_property_set_bool:
> * @value: the value to be written to the property
> * @name: the name of the property
> diff --git a/qom/object.c b/qom/object.c
> index e8418bc..b3cff50 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -710,6 +710,30 @@ char *object_property_get_str(Object *obj, const char *name,
> return retval;
> }
>
> +void object_property_set_link(Object *obj, Object *value,
> + const char *name, Error **errp)
> +{
> + object_property_set_str(obj, object_get_canonical_path(value),
> + name, errp);
> +}
We could fall back to setting the link directly via the property opaque, but I
guess that might let us get lazy about filling in the composition tree.
Regards,
Anthony Liguori
> +
> +Object *object_property_get_link(Object *obj, const char *name,
> + Error **errp)
> +{
> + char *str = object_property_get_str(obj, name, errp);
> + Object *target = NULL;
> +
> + if (str&& *str) {
> + target = object_resolve_path(str, NULL);
> + if (!target) {
> + error_set(errp, QERR_DEVICE_NOT_FOUND, str);
> + }
> + }
> +
> + g_free(str);
> + return target;
> +}
> +
> void object_property_set_bool(Object *obj, bool value,
> const char *name, Error **errp)
> {
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 13/27] qdev: remove direct calls to print/parse
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (11 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 12/27] qom: add property get/set wrappers for links Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:30 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 14/27] qdev: allow reusing get/set for legacy property Paolo Bonzini
` (14 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
There's no need to call into ->parse and ->print manually. The
QOM legacy properties do that for us.
Furthermore, in some cases legacy and static properties have exactly
the same behavior, and we could drop the legacy properties right away.
Add an appropriate fallback to prepare for this.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-monitor.c | 30 +++++++++++++++++-------------
hw/qdev-properties.c | 26 ++++++++++----------------
hw/qdev.c | 9 +++++++++
3 files changed, 36 insertions(+), 29 deletions(-)
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 135c2bf..49f13ca 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -485,22 +485,26 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent);
static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
const char *prefix, int indent)
{
- char buf[64];
-
if (!props)
return;
- while (props->name) {
- /*
- * TODO Properties without a print method are just for dirty
- * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
- * marked for removal. The test props->info->print should be
- * removed along with it.
- */
- if (props->info->print) {
- props->info->print(dev, props, buf, sizeof(buf));
- qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
+ for (; props->name; props++) {
+ Error *err = NULL;
+ char *value;
+ char *legacy_name = g_strdup_printf("legacy-%s", props->name);
+ if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
+ value = object_property_get_str(OBJECT(dev), legacy_name, &err);
+ } else {
+ value = object_property_get_str(OBJECT(dev), props->name, &err);
+ }
+ g_free(legacy_name);
+
+ if (err) {
+ error_free(err);
+ continue;
}
- props++;
+ qdev_printf("%s-prop: %s = %s\n", prefix, props->name,
+ value && *value ? value : "<null>");
+ g_free(value);
}
}
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index c4583a1..5e19ec8 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1073,24 +1073,18 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
{
- Property *prop;
- int ret;
+ char *legacy_name;
+ Error *err = NULL;
- prop = qdev_prop_find(dev, name);
- /*
- * TODO Properties without a parse method are just for dirty
- * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
- * marked for removal. The test !prop->info->parse should be
- * removed along with it.
- */
- if (!prop || !prop->info->parse) {
- qerror_report(QERR_PROPERTY_NOT_FOUND, object_get_typename(OBJECT(dev)), name);
- return -1;
+ legacy_name = g_strdup_printf("legacy-%s", name);
+ if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
+ object_property_set_str(OBJECT(dev), value, legacy_name, &err);
+ } else {
+ object_property_set_str(OBJECT(dev), value, name, &err);
}
- ret = prop->info->parse(dev, prop, value);
- if (ret < 0) {
- Error *err;
- error_set_from_qdev_prop_error(&err, ret, dev, prop, value);
+ g_free(legacy_name);
+
+ if (err) {
qerror_report_err(err);
error_free(err);
return -1;
diff --git a/hw/qdev.c b/hw/qdev.c
index e3b53b7..a731e41 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -581,6 +581,15 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
void qdev_property_add_static(DeviceState *dev, Property *prop,
Error **errp)
{
+ /*
+ * TODO qdev_prop_ptr does not have getters or setters. It must
+ * go now that it can be replaced with links. The test should be
+ * removed along with it: all static properties are read/write.
+ */
+ if (!prop->info->get && !prop->info->set) {
+ return;
+ }
+
object_property_add(OBJECT(dev), prop->name, prop->info->name,
prop->info->get, prop->info->set,
NULL,
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 13/27] qdev: remove direct calls to print/parse
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 13/27] qdev: remove direct calls to print/parse Paolo Bonzini
@ 2012-02-06 14:30 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:30 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> There's no need to call into ->parse and ->print manually. The
> QOM legacy properties do that for us.
>
> Furthermore, in some cases legacy and static properties have exactly
> the same behavior, and we could drop the legacy properties right away.
> Add an appropriate fallback to prepare for this.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Nice cleanup. Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
I wonder how far we are from moving most of qdev-monitor.c to hmp.c and qmp.c
respectively. I think that given this patch, we can actually implement info
qtree/qdm via qom QMP operations.
That would be a fairly nice win.
Regards,
Anthony Liguori
> ---
> hw/qdev-monitor.c | 30 +++++++++++++++++-------------
> hw/qdev-properties.c | 26 ++++++++++----------------
> hw/qdev.c | 9 +++++++++
> 3 files changed, 36 insertions(+), 29 deletions(-)
>
> diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
> index 135c2bf..49f13ca 100644
> --- a/hw/qdev-monitor.c
> +++ b/hw/qdev-monitor.c
> @@ -485,22 +485,26 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent);
> static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
> const char *prefix, int indent)
> {
> - char buf[64];
> -
> if (!props)
> return;
> - while (props->name) {
> - /*
> - * TODO Properties without a print method are just for dirty
> - * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
> - * marked for removal. The test props->info->print should be
> - * removed along with it.
> - */
> - if (props->info->print) {
> - props->info->print(dev, props, buf, sizeof(buf));
> - qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
> + for (; props->name; props++) {
> + Error *err = NULL;
> + char *value;
> + char *legacy_name = g_strdup_printf("legacy-%s", props->name);
> + if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
> + value = object_property_get_str(OBJECT(dev), legacy_name,&err);
> + } else {
> + value = object_property_get_str(OBJECT(dev), props->name,&err);
> + }
> + g_free(legacy_name);
> +
> + if (err) {
> + error_free(err);
> + continue;
> }
> - props++;
> + qdev_printf("%s-prop: %s = %s\n", prefix, props->name,
> + value&& *value ? value : "<null>");
> + g_free(value);
> }
> }
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index c4583a1..5e19ec8 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -1073,24 +1073,18 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
>
> int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> {
> - Property *prop;
> - int ret;
> + char *legacy_name;
> + Error *err = NULL;
>
> - prop = qdev_prop_find(dev, name);
> - /*
> - * TODO Properties without a parse method are just for dirty
> - * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
> - * marked for removal. The test !prop->info->parse should be
> - * removed along with it.
> - */
> - if (!prop || !prop->info->parse) {
> - qerror_report(QERR_PROPERTY_NOT_FOUND, object_get_typename(OBJECT(dev)), name);
> - return -1;
> + legacy_name = g_strdup_printf("legacy-%s", name);
> + if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
> + object_property_set_str(OBJECT(dev), value, legacy_name,&err);
> + } else {
> + object_property_set_str(OBJECT(dev), value, name,&err);
> }
> - ret = prop->info->parse(dev, prop, value);
> - if (ret< 0) {
> - Error *err;
> - error_set_from_qdev_prop_error(&err, ret, dev, prop, value);
> + g_free(legacy_name);
> +
> + if (err) {
> qerror_report_err(err);
> error_free(err);
> return -1;
> diff --git a/hw/qdev.c b/hw/qdev.c
> index e3b53b7..a731e41 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -581,6 +581,15 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> void qdev_property_add_static(DeviceState *dev, Property *prop,
> Error **errp)
> {
> + /*
> + * TODO qdev_prop_ptr does not have getters or setters. It must
> + * go now that it can be replaced with links. The test should be
> + * removed along with it: all static properties are read/write.
> + */
> + if (!prop->info->get&& !prop->info->set) {
> + return;
> + }
> +
> object_property_add(OBJECT(dev), prop->name, prop->info->name,
> prop->info->get, prop->info->set,
> NULL,
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 14/27] qdev: allow reusing get/set for legacy property
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (12 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 13/27] qdev: remove direct calls to print/parse Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:31 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 15/27] qdev: remove parse method for string properties Paolo Bonzini
` (13 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
In some cases, a legacy property does need a special print method
but not a special parse method. In this case, we can reuse the get/set
from the static (non-legacy) property.
If neither parse nor print is needed, though, do not register the
legacy property at all. The previous patch ensures that the right
fallback will be used.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index a731e41..660ee38 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -550,21 +550,24 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
* Do not use this is new code! Properties added through this interface will
* be given names and types in the "legacy" namespace.
*
- * Legacy properties are always processed as strings. The format of the string
- * depends on the property type.
+ * Legacy properties are string versions of other OOM properties. The format
+ * of the string depends on the property type.
*/
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp)
{
gchar *name, *type;
+ if (!prop->info->print && !prop->info->parse) {
+ return;
+ }
name = g_strdup_printf("legacy-%s", prop->name);
type = g_strdup_printf("legacy<%s>",
prop->info->legacy_name ?: prop->info->name);
object_property_add(OBJECT(dev), name, type,
- prop->info->print ? qdev_get_legacy_property : NULL,
- prop->info->parse ? qdev_set_legacy_property : NULL,
+ prop->info->print ? qdev_get_legacy_property : prop->info->get,
+ prop->info->parse ? qdev_set_legacy_property : prop->info->set,
NULL,
prop, errp);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 14/27] qdev: allow reusing get/set for legacy property
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 14/27] qdev: allow reusing get/set for legacy property Paolo Bonzini
@ 2012-02-06 14:31 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:31 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> In some cases, a legacy property does need a special print method
> but not a special parse method. In this case, we can reuse the get/set
> from the static (non-legacy) property.
>
> If neither parse nor print is needed, though, do not register the
> legacy property at all. The previous patch ensures that the right
> fallback will be used.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev.c | 11 +++++++----
> 1 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/hw/qdev.c b/hw/qdev.c
> index a731e41..660ee38 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -550,21 +550,24 @@ static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
> * Do not use this is new code! Properties added through this interface will
> * be given names and types in the "legacy" namespace.
> *
> - * Legacy properties are always processed as strings. The format of the string
> - * depends on the property type.
> + * Legacy properties are string versions of other OOM properties. The format
> + * of the string depends on the property type.
> */
> void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> Error **errp)
> {
> gchar *name, *type;
>
> + if (!prop->info->print&& !prop->info->parse) {
> + return;
> + }
> name = g_strdup_printf("legacy-%s", prop->name);
> type = g_strdup_printf("legacy<%s>",
> prop->info->legacy_name ?: prop->info->name);
>
> object_property_add(OBJECT(dev), name, type,
> - prop->info->print ? qdev_get_legacy_property : NULL,
> - prop->info->parse ? qdev_set_legacy_property : NULL,
> + prop->info->print ? qdev_get_legacy_property : prop->info->get,
> + prop->info->parse ? qdev_set_legacy_property : prop->info->set,
> NULL,
> prop, errp);
>
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 15/27] qdev: remove parse method for string properties
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (13 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 14/27] qdev: allow reusing get/set for legacy property Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:31 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 16/27] qdev: remove print/parse methods from LostTickPolicy properties Paolo Bonzini
` (12 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
We need the print method to put double quotes, but parsing is not special.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 11 -----------
1 files changed, 0 insertions(+), 11 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 5e19ec8..1fc77b5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -510,16 +510,6 @@ PropertyInfo qdev_prop_hex64 = {
/* --- string --- */
-static int parse_string(DeviceState *dev, Property *prop, const char *str)
-{
- char **ptr = qdev_get_prop_ptr(dev, prop);
-
- if (*ptr)
- g_free(*ptr);
- *ptr = g_strdup(str);
- return 0;
-}
-
static void free_string(DeviceState *dev, Property *prop)
{
g_free(*(char **)qdev_get_prop_ptr(dev, prop));
@@ -581,7 +571,6 @@ PropertyInfo qdev_prop_string = {
.name = "string",
.type = PROP_TYPE_STRING,
.size = sizeof(char*),
- .parse = parse_string,
.print = print_string,
.free = free_string,
.get = get_string,
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 15/27] qdev: remove parse method for string properties
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 15/27] qdev: remove parse method for string properties Paolo Bonzini
@ 2012-02-06 14:31 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:31 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> We need the print method to put double quotes, but parsing is not special.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 11 -----------
> 1 files changed, 0 insertions(+), 11 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 5e19ec8..1fc77b5 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -510,16 +510,6 @@ PropertyInfo qdev_prop_hex64 = {
>
> /* --- string --- */
>
> -static int parse_string(DeviceState *dev, Property *prop, const char *str)
> -{
> - char **ptr = qdev_get_prop_ptr(dev, prop);
> -
> - if (*ptr)
> - g_free(*ptr);
> - *ptr = g_strdup(str);
> - return 0;
> -}
> -
> static void free_string(DeviceState *dev, Property *prop)
> {
> g_free(*(char **)qdev_get_prop_ptr(dev, prop));
> @@ -581,7 +571,6 @@ PropertyInfo qdev_prop_string = {
> .name = "string",
> .type = PROP_TYPE_STRING,
> .size = sizeof(char*),
> - .parse = parse_string,
> .print = print_string,
> .free = free_string,
> .get = get_string,
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 16/27] qdev: remove print/parse methods from LostTickPolicy properties
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (14 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 15/27] qdev: remove parse method for string properties Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:32 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 17/27] qdev: remove parse/print methods for mac properties Paolo Bonzini
` (11 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Also generalize the code so that we can have more enum properties
in the future.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 62 +++++++++++++++++++++++++-------------------------
hw/qdev.h | 1 +
qemu-common.h | 1 +
3 files changed, 33 insertions(+), 31 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 1fc77b5..dea287a 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -893,50 +893,50 @@ PropertyInfo qdev_prop_macaddr = {
/* --- lost tick policy --- */
-static const struct {
- const char *name;
- LostTickPolicy code;
-} lost_tick_policy_table[] = {
- { .name = "discard", .code = LOST_TICK_DISCARD },
- { .name = "delay", .code = LOST_TICK_DELAY },
- { .name = "merge", .code = LOST_TICK_MERGE },
- { .name = "slew", .code = LOST_TICK_SLEW },
+static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
+ [LOST_TICK_DISCARD] = "discard",
+ [LOST_TICK_DELAY] = "delay",
+ [LOST_TICK_MERGE] = "merge",
+ [LOST_TICK_SLEW] = "slew",
+ [LOST_TICK_MAX] = NULL,
};
-static int parse_lost_tick_policy(DeviceState *dev, Property *prop,
- const char *str)
+QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
+
+static void get_enum(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
- LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
- int i;
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ int *ptr = qdev_get_prop_ptr(dev, prop);
- for (i = 0; i < ARRAY_SIZE(lost_tick_policy_table); i++) {
- if (!strcasecmp(str, lost_tick_policy_table[i].name)) {
- *ptr = lost_tick_policy_table[i].code;
- break;
- }
- }
- if (i == ARRAY_SIZE(lost_tick_policy_table)) {
- return -EINVAL;
- }
- return 0;
+ visit_type_enum(v, ptr, prop->info->enum_table,
+ prop->info->name, prop->name, errp);
}
-static int print_lost_tick_policy(DeviceState *dev, Property *prop, char *dest,
- size_t len)
+static void set_enum(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
- LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ int *ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
- return snprintf(dest, len, "%s", lost_tick_policy_table[*ptr].name);
+ visit_type_enum(v, ptr, prop->info->enum_table,
+ prop->info->name, prop->name, errp);
}
PropertyInfo qdev_prop_losttickpolicy = {
- .name = "lost_tick_policy",
+ .name = "LostTickPolicy",
.type = PROP_TYPE_LOSTTICKPOLICY,
.size = sizeof(LostTickPolicy),
- .parse = parse_lost_tick_policy,
- .print = print_lost_tick_policy,
- .get = get_generic,
- .set = set_generic,
+ .enum_table = lost_tick_policy_table,
+ .get = get_enum,
+ .set = set_enum,
};
/* --- pci address --- */
diff --git a/hw/qdev.h b/hw/qdev.h
index ab53273..c31dc4e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -140,6 +140,7 @@ struct PropertyInfo {
const char *legacy_name;
size_t size;
enum PropertyType type;
+ const char **enum_table;
int64_t min;
int64_t max;
int (*parse)(DeviceState *dev, Property *prop, const char *str);
diff --git a/qemu-common.h b/qemu-common.h
index 8b69a9e..9b997f8 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -255,6 +255,7 @@ typedef enum LostTickPolicy {
LOST_TICK_DELAY,
LOST_TICK_MERGE,
LOST_TICK_SLEW,
+ LOST_TICK_MAX
} LostTickPolicy;
void tcg_exec_init(unsigned long tb_size);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 16/27] qdev: remove print/parse methods from LostTickPolicy properties
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 16/27] qdev: remove print/parse methods from LostTickPolicy properties Paolo Bonzini
@ 2012-02-06 14:32 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:32 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Also generalize the code so that we can have more enum properties
> in the future.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 62 +++++++++++++++++++++++++-------------------------
> hw/qdev.h | 1 +
> qemu-common.h | 1 +
> 3 files changed, 33 insertions(+), 31 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 1fc77b5..dea287a 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -893,50 +893,50 @@ PropertyInfo qdev_prop_macaddr = {
>
> /* --- lost tick policy --- */
>
> -static const struct {
> - const char *name;
> - LostTickPolicy code;
> -} lost_tick_policy_table[] = {
> - { .name = "discard", .code = LOST_TICK_DISCARD },
> - { .name = "delay", .code = LOST_TICK_DELAY },
> - { .name = "merge", .code = LOST_TICK_MERGE },
> - { .name = "slew", .code = LOST_TICK_SLEW },
> +static const char *lost_tick_policy_table[LOST_TICK_MAX+1] = {
> + [LOST_TICK_DISCARD] = "discard",
> + [LOST_TICK_DELAY] = "delay",
> + [LOST_TICK_MERGE] = "merge",
> + [LOST_TICK_SLEW] = "slew",
> + [LOST_TICK_MAX] = NULL,
> };
>
> -static int parse_lost_tick_policy(DeviceState *dev, Property *prop,
> - const char *str)
> +QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int));
> +
> +static void get_enum(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> {
> - LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
> - int i;
> + DeviceState *dev = DEVICE(obj);
> + Property *prop = opaque;
> + int *ptr = qdev_get_prop_ptr(dev, prop);
>
> - for (i = 0; i< ARRAY_SIZE(lost_tick_policy_table); i++) {
> - if (!strcasecmp(str, lost_tick_policy_table[i].name)) {
> - *ptr = lost_tick_policy_table[i].code;
> - break;
> - }
> - }
> - if (i == ARRAY_SIZE(lost_tick_policy_table)) {
> - return -EINVAL;
> - }
> - return 0;
> + visit_type_enum(v, ptr, prop->info->enum_table,
> + prop->info->name, prop->name, errp);
> }
>
> -static int print_lost_tick_policy(DeviceState *dev, Property *prop, char *dest,
> - size_t len)
> +static void set_enum(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> {
> - LostTickPolicy *ptr = qdev_get_prop_ptr(dev, prop);
> + DeviceState *dev = DEVICE(obj);
> + Property *prop = opaque;
> + int *ptr = qdev_get_prop_ptr(dev, prop);
> +
> + if (dev->state != DEV_STATE_CREATED) {
> + error_set(errp, QERR_PERMISSION_DENIED);
> + return;
> + }
>
> - return snprintf(dest, len, "%s", lost_tick_policy_table[*ptr].name);
> + visit_type_enum(v, ptr, prop->info->enum_table,
> + prop->info->name, prop->name, errp);
> }
>
> PropertyInfo qdev_prop_losttickpolicy = {
> - .name = "lost_tick_policy",
> + .name = "LostTickPolicy",
> .type = PROP_TYPE_LOSTTICKPOLICY,
> .size = sizeof(LostTickPolicy),
> - .parse = parse_lost_tick_policy,
> - .print = print_lost_tick_policy,
> - .get = get_generic,
> - .set = set_generic,
> + .enum_table = lost_tick_policy_table,
> + .get = get_enum,
> + .set = set_enum,
> };
>
> /* --- pci address --- */
> diff --git a/hw/qdev.h b/hw/qdev.h
> index ab53273..c31dc4e 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -140,6 +140,7 @@ struct PropertyInfo {
> const char *legacy_name;
> size_t size;
> enum PropertyType type;
> + const char **enum_table;
> int64_t min;
> int64_t max;
> int (*parse)(DeviceState *dev, Property *prop, const char *str);
> diff --git a/qemu-common.h b/qemu-common.h
> index 8b69a9e..9b997f8 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -255,6 +255,7 @@ typedef enum LostTickPolicy {
> LOST_TICK_DELAY,
> LOST_TICK_MERGE,
> LOST_TICK_SLEW,
> + LOST_TICK_MAX
> } LostTickPolicy;
>
> void tcg_exec_init(unsigned long tb_size);
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 17/27] qdev: remove parse/print methods for mac properties
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (15 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 16/27] qdev: remove print/parse methods from LostTickPolicy properties Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:32 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 18/27] qdev: make the non-legacy pci address property accept an integer Paolo Bonzini
` (10 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 61 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index dea287a..42b9b24 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -848,46 +848,69 @@ PropertyInfo qdev_prop_ptr = {
* 01:02:03:04:05:06
* 01-02-03-04-05-06
*/
-static int parse_mac(DeviceState *dev, Property *prop, const char *str)
+static void get_mac(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+ char buffer[2 * 6 + 5 + 1];
+ char *p = buffer;
+
+ snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac->a[0], mac->a[1], mac->a[2],
+ mac->a[3], mac->a[4], mac->a[5]);
+
+ visit_type_str(v, &p, name, errp);
+}
+
+static void set_mac(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
int i, pos;
- char *p;
+ char *str, *p;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_str(v, &str, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
for (i = 0, pos = 0; i < 6; i++, pos += 3) {
if (!qemu_isxdigit(str[pos]))
- return -EINVAL;
+ goto inval;
if (!qemu_isxdigit(str[pos+1]))
- return -EINVAL;
+ goto inval;
if (i == 5) {
if (str[pos+2] != '\0')
- return -EINVAL;
+ goto inval;
} else {
if (str[pos+2] != ':' && str[pos+2] != '-')
- return -EINVAL;
+ goto inval;
}
mac->a[i] = strtol(str+pos, &p, 16);
}
- return 0;
-}
-
-static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
-{
- MACAddr *mac = qdev_get_prop_ptr(dev, prop);
+ return;
- return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
- mac->a[0], mac->a[1], mac->a[2],
- mac->a[3], mac->a[4], mac->a[5]);
+inval:
+ error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
}
PropertyInfo qdev_prop_macaddr = {
.name = "macaddr",
.type = PROP_TYPE_MACADDR,
.size = sizeof(MACAddr),
- .parse = parse_mac,
- .print = print_mac,
- .get = get_generic,
- .set = set_generic,
+ .get = get_mac,
+ .set = set_mac,
};
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 17/27] qdev: remove parse/print methods for mac properties
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 17/27] qdev: remove parse/print methods for mac properties Paolo Bonzini
@ 2012-02-06 14:32 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:32 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
> hw/qdev-properties.c | 61 ++++++++++++++++++++++++++++++++++---------------
> 1 files changed, 42 insertions(+), 19 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index dea287a..42b9b24 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -848,46 +848,69 @@ PropertyInfo qdev_prop_ptr = {
> * 01:02:03:04:05:06
> * 01-02-03-04-05-06
> */
> -static int parse_mac(DeviceState *dev, Property *prop, const char *str)
> +static void get_mac(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + DeviceState *dev = DEVICE(obj);
> + Property *prop = opaque;
> + MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> + char buffer[2 * 6 + 5 + 1];
> + char *p = buffer;
> +
> + snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
> + mac->a[0], mac->a[1], mac->a[2],
> + mac->a[3], mac->a[4], mac->a[5]);
> +
> + visit_type_str(v,&p, name, errp);
> +}
> +
> +static void set_mac(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> {
> + DeviceState *dev = DEVICE(obj);
> + Property *prop = opaque;
> MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> + Error *local_err = NULL;
> int i, pos;
> - char *p;
> + char *str, *p;
> +
> + if (dev->state != DEV_STATE_CREATED) {
> + error_set(errp, QERR_PERMISSION_DENIED);
> + return;
> + }
> +
> + visit_type_str(v,&str, name,&local_err);
> + if (local_err) {
> + error_propagate(errp, local_err);
> + return;
> + }
>
> for (i = 0, pos = 0; i< 6; i++, pos += 3) {
> if (!qemu_isxdigit(str[pos]))
> - return -EINVAL;
> + goto inval;
> if (!qemu_isxdigit(str[pos+1]))
> - return -EINVAL;
> + goto inval;
> if (i == 5) {
> if (str[pos+2] != '\0')
> - return -EINVAL;
> + goto inval;
> } else {
> if (str[pos+2] != ':'&& str[pos+2] != '-')
> - return -EINVAL;
> + goto inval;
> }
> mac->a[i] = strtol(str+pos,&p, 16);
> }
> - return 0;
> -}
> -
> -static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
> -{
> - MACAddr *mac = qdev_get_prop_ptr(dev, prop);
> + return;
>
> - return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
> - mac->a[0], mac->a[1], mac->a[2],
> - mac->a[3], mac->a[4], mac->a[5]);
> +inval:
> + error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> }
>
> PropertyInfo qdev_prop_macaddr = {
> .name = "macaddr",
> .type = PROP_TYPE_MACADDR,
> .size = sizeof(MACAddr),
> - .parse = parse_mac,
> - .print = print_mac,
> - .get = get_generic,
> - .set = set_generic,
> + .get = get_mac,
> + .set = set_mac,
> };
>
>
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 18/27] qdev: make the non-legacy pci address property accept an integer
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (16 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 17/27] qdev: remove parse/print methods for mac properties Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:33 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 19/27] qdev: remove parse/print methods for pointer properties Paolo Bonzini
` (9 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
PCI addresses are set with qdev_prop_uint32. Thus we make the QOM
property accept a device and function encoded in an 8-bit integer,
instead of the magic dd.f hex string.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 28 +++++++++-------------------
1 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 42b9b24..9a67cc5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -999,30 +999,20 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
}
}
-static void get_pci_devfn(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
- DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
- uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
- char buffer[32];
- char *p = buffer;
-
- buffer[0] = 0;
- if (*ptr != -1) {
- snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr >> 3, *ptr & 7);
- }
- visit_type_str(v, &p, name, errp);
-}
-
PropertyInfo qdev_prop_pci_devfn = {
- .name = "pci-devfn",
+ .name = "int32",
+ .legacy_name = "pci-devfn",
.type = PROP_TYPE_UINT32,
.size = sizeof(uint32_t),
.parse = parse_pci_devfn,
.print = print_pci_devfn,
- .get = get_pci_devfn,
- .set = set_generic,
+ .get = get_int32,
+ .set = set_int32,
+ /* FIXME: this should be -1...255, but the address is stored
+ * into an uint32_t rather than int32_t.
+ */
+ .min = 0,
+ .max = 0xFFFFFFFFULL,
};
/* --- public helpers --- */
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 18/27] qdev: make the non-legacy pci address property accept an integer
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 18/27] qdev: make the non-legacy pci address property accept an integer Paolo Bonzini
@ 2012-02-06 14:33 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:33 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> PCI addresses are set with qdev_prop_uint32. Thus we make the QOM
> property accept a device and function encoded in an 8-bit integer,
> instead of the magic dd.f hex string.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 28 +++++++++-------------------
> 1 files changed, 9 insertions(+), 19 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 42b9b24..9a67cc5 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -999,30 +999,20 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
> }
> }
>
> -static void get_pci_devfn(Object *obj, Visitor *v, void *opaque,
> - const char *name, Error **errp)
> -{
> - DeviceState *dev = DEVICE(obj);
> - Property *prop = opaque;
> - uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
> - char buffer[32];
> - char *p = buffer;
> -
> - buffer[0] = 0;
> - if (*ptr != -1) {
> - snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr>> 3, *ptr& 7);
> - }
> - visit_type_str(v,&p, name, errp);
> -}
> -
> PropertyInfo qdev_prop_pci_devfn = {
> - .name = "pci-devfn",
> + .name = "int32",
> + .legacy_name = "pci-devfn",
> .type = PROP_TYPE_UINT32,
> .size = sizeof(uint32_t),
> .parse = parse_pci_devfn,
> .print = print_pci_devfn,
> - .get = get_pci_devfn,
> - .set = set_generic,
> + .get = get_int32,
> + .set = set_int32,
> + /* FIXME: this should be -1...255, but the address is stored
> + * into an uint32_t rather than int32_t.
> + */
> + .min = 0,
> + .max = 0xFFFFFFFFULL,
> };
>
> /* --- public helpers --- */
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 19/27] qdev: remove parse/print methods for pointer properties
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (17 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 18/27] qdev: make the non-legacy pci address property accept an integer Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:34 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 20/27] qdev: let QOM free properties Paolo Bonzini
` (8 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Pointer properties (except for PROP_PTR of course) should not need a
legacy counterpart. In the future, relative paths will ensure that
QEMU will support the same syntax as now for drives etc..
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 128 ++++++++++++++++++++++++++++----------------------
1 files changed, 72 insertions(+), 56 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 9a67cc5..67995a3 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -579,9 +579,8 @@ PropertyInfo qdev_prop_string = {
/* --- drive --- */
-static int parse_drive(DeviceState *dev, Property *prop, const char *str)
+static int parse_drive(DeviceState *dev, const char *str, void **ptr)
{
- BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
BlockDriverState *bs;
bs = bdrv_find(str);
@@ -603,35 +602,30 @@ static void free_drive(DeviceState *dev, Property *prop)
}
}
-static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
+static const char *print_drive(void *ptr)
{
- BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "%s",
- *ptr ? bdrv_get_device_name(*ptr) : "<null>");
+ return bdrv_get_device_name(ptr);
}
-static void get_generic(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+static void get_pointer(Object *obj, Visitor *v, Property *prop,
+ const char *(*print)(void *ptr),
+ const char *name, Error **errp)
{
DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
void **ptr = qdev_get_prop_ptr(dev, prop);
- char buffer[1024];
- char *p = buffer;
+ char *p;
- buffer[0] = 0;
- if (*ptr) {
- prop->info->print(dev, prop, buffer, sizeof(buffer));
- }
+ p = (char *) (*ptr ? print(*ptr) : "");
visit_type_str(v, &p, name, errp);
}
-static void set_generic(Object *obj, Visitor *v, void *opaque,
+static void set_pointer(Object *obj, Visitor *v, Property *prop,
+ int (*parse)(DeviceState *dev, const char *str, void **ptr),
const char *name, Error **errp)
{
DeviceState *dev = DEVICE(obj);
- Property *prop = opaque;
Error *local_err = NULL;
+ void **ptr = qdev_get_prop_ptr(dev, prop);
char *str;
int ret;
@@ -650,36 +644,45 @@ static void set_generic(Object *obj, Visitor *v, void *opaque,
error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
return;
}
- ret = prop->info->parse(dev, prop, str);
+ ret = parse(dev, str, ptr);
error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
g_free(str);
}
+static void get_drive(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ get_pointer(obj, v, opaque, print_drive, name, errp);
+}
+
+static void set_drive(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ set_pointer(obj, v, opaque, parse_drive, name, errp);
+}
+
PropertyInfo qdev_prop_drive = {
.name = "drive",
.type = PROP_TYPE_DRIVE,
.size = sizeof(BlockDriverState *),
- .parse = parse_drive,
- .print = print_drive,
- .get = get_generic,
- .set = set_generic,
+ .get = get_drive,
+ .set = set_drive,
.free = free_drive,
};
/* --- character device --- */
-static int parse_chr(DeviceState *dev, Property *prop, const char *str)
+static int parse_chr(DeviceState *dev, const char *str, void **ptr)
{
- CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
-
- *ptr = qemu_chr_find(str);
- if (*ptr == NULL) {
+ CharDriverState *chr = qemu_chr_find(str);
+ if (chr == NULL) {
return -ENOENT;
}
- if ((*ptr)->avail_connections < 1) {
+ if (chr->avail_connections < 1) {
return -EEXIST;
}
- --(*ptr)->avail_connections;
+ *ptr = chr;
+ --chr->avail_connections;
return 0;
}
@@ -693,62 +696,75 @@ static void free_chr(DeviceState *dev, Property *prop)
}
-static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
+static const char *print_chr(void *ptr)
{
- CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+ CharDriverState *chr = ptr;
- if (*ptr && (*ptr)->label) {
- return snprintf(dest, len, "%s", (*ptr)->label);
- } else {
- return snprintf(dest, len, "<null>");
- }
+ return chr->label ? chr->label : "";
+}
+
+static void get_chr(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ get_pointer(obj, v, opaque, print_chr, name, errp);
+}
+
+static void set_chr(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ set_pointer(obj, v, opaque, parse_chr, name, errp);
}
PropertyInfo qdev_prop_chr = {
.name = "chr",
.type = PROP_TYPE_CHR,
.size = sizeof(CharDriverState*),
- .parse = parse_chr,
- .print = print_chr,
- .get = get_generic,
- .set = set_generic,
+ .get = get_chr,
+ .set = set_chr,
.free = free_chr,
};
/* --- netdev device --- */
-static int parse_netdev(DeviceState *dev, Property *prop, const char *str)
+static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
{
- VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
+ VLANClientState *netdev = qemu_find_netdev(str);
- *ptr = qemu_find_netdev(str);
- if (*ptr == NULL)
+ if (netdev == NULL) {
return -ENOENT;
- if ((*ptr)->peer) {
+ }
+ if (netdev->peer) {
return -EEXIST;
}
+ *ptr = netdev;
return 0;
}
-static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t len)
+static const char *print_netdev(void *ptr)
{
- VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
+ VLANClientState *netdev = ptr;
- if (*ptr && (*ptr)->name) {
- return snprintf(dest, len, "%s", (*ptr)->name);
- } else {
- return snprintf(dest, len, "<null>");
- }
+ return netdev->name ? netdev->name : "";
+}
+
+static void get_netdev(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ get_pointer(obj, v, opaque, print_netdev, name, errp);
+}
+
+static void set_netdev(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ set_pointer(obj, v, opaque, parse_netdev, name, errp);
}
PropertyInfo qdev_prop_netdev = {
.name = "netdev",
.type = PROP_TYPE_NETDEV,
.size = sizeof(VLANClientState*),
- .parse = parse_netdev,
- .print = print_netdev,
- .get = get_generic,
- .set = set_generic,
+ .get = get_netdev,
+ .set = set_netdev,
};
/* --- vlan --- */
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 19/27] qdev: remove parse/print methods for pointer properties
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 19/27] qdev: remove parse/print methods for pointer properties Paolo Bonzini
@ 2012-02-06 14:34 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:34 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Pointer properties (except for PROP_PTR of course) should not need a
> legacy counterpart. In the future, relative paths will ensure that
> QEMU will support the same syntax as now for drives etc..
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 128 ++++++++++++++++++++++++++++----------------------
> 1 files changed, 72 insertions(+), 56 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 9a67cc5..67995a3 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -579,9 +579,8 @@ PropertyInfo qdev_prop_string = {
>
> /* --- drive --- */
>
> -static int parse_drive(DeviceState *dev, Property *prop, const char *str)
> +static int parse_drive(DeviceState *dev, const char *str, void **ptr)
> {
> - BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
> BlockDriverState *bs;
>
> bs = bdrv_find(str);
> @@ -603,35 +602,30 @@ static void free_drive(DeviceState *dev, Property *prop)
> }
> }
>
> -static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
> +static const char *print_drive(void *ptr)
> {
> - BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
> - return snprintf(dest, len, "%s",
> - *ptr ? bdrv_get_device_name(*ptr) : "<null>");
> + return bdrv_get_device_name(ptr);
> }
>
> -static void get_generic(Object *obj, Visitor *v, void *opaque,
> - const char *name, Error **errp)
> +static void get_pointer(Object *obj, Visitor *v, Property *prop,
> + const char *(*print)(void *ptr),
> + const char *name, Error **errp)
> {
> DeviceState *dev = DEVICE(obj);
> - Property *prop = opaque;
> void **ptr = qdev_get_prop_ptr(dev, prop);
> - char buffer[1024];
> - char *p = buffer;
> + char *p;
>
> - buffer[0] = 0;
> - if (*ptr) {
> - prop->info->print(dev, prop, buffer, sizeof(buffer));
> - }
> + p = (char *) (*ptr ? print(*ptr) : "");
> visit_type_str(v,&p, name, errp);
> }
>
> -static void set_generic(Object *obj, Visitor *v, void *opaque,
> +static void set_pointer(Object *obj, Visitor *v, Property *prop,
> + int (*parse)(DeviceState *dev, const char *str, void **ptr),
> const char *name, Error **errp)
> {
> DeviceState *dev = DEVICE(obj);
> - Property *prop = opaque;
> Error *local_err = NULL;
> + void **ptr = qdev_get_prop_ptr(dev, prop);
> char *str;
> int ret;
>
> @@ -650,36 +644,45 @@ static void set_generic(Object *obj, Visitor *v, void *opaque,
> error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> return;
> }
> - ret = prop->info->parse(dev, prop, str);
> + ret = parse(dev, str, ptr);
> error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
> g_free(str);
> }
>
> +static void get_drive(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + get_pointer(obj, v, opaque, print_drive, name, errp);
> +}
> +
> +static void set_drive(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + set_pointer(obj, v, opaque, parse_drive, name, errp);
> +}
> +
> PropertyInfo qdev_prop_drive = {
> .name = "drive",
> .type = PROP_TYPE_DRIVE,
> .size = sizeof(BlockDriverState *),
> - .parse = parse_drive,
> - .print = print_drive,
> - .get = get_generic,
> - .set = set_generic,
> + .get = get_drive,
> + .set = set_drive,
> .free = free_drive,
> };
>
> /* --- character device --- */
>
> -static int parse_chr(DeviceState *dev, Property *prop, const char *str)
> +static int parse_chr(DeviceState *dev, const char *str, void **ptr)
> {
> - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
> -
> - *ptr = qemu_chr_find(str);
> - if (*ptr == NULL) {
> + CharDriverState *chr = qemu_chr_find(str);
> + if (chr == NULL) {
> return -ENOENT;
> }
> - if ((*ptr)->avail_connections< 1) {
> + if (chr->avail_connections< 1) {
> return -EEXIST;
> }
> - --(*ptr)->avail_connections;
> + *ptr = chr;
> + --chr->avail_connections;
> return 0;
> }
>
> @@ -693,62 +696,75 @@ static void free_chr(DeviceState *dev, Property *prop)
> }
>
>
> -static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
> +static const char *print_chr(void *ptr)
> {
> - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
> + CharDriverState *chr = ptr;
>
> - if (*ptr&& (*ptr)->label) {
> - return snprintf(dest, len, "%s", (*ptr)->label);
> - } else {
> - return snprintf(dest, len, "<null>");
> - }
> + return chr->label ? chr->label : "";
> +}
> +
> +static void get_chr(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + get_pointer(obj, v, opaque, print_chr, name, errp);
> +}
> +
> +static void set_chr(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + set_pointer(obj, v, opaque, parse_chr, name, errp);
> }
>
> PropertyInfo qdev_prop_chr = {
> .name = "chr",
> .type = PROP_TYPE_CHR,
> .size = sizeof(CharDriverState*),
> - .parse = parse_chr,
> - .print = print_chr,
> - .get = get_generic,
> - .set = set_generic,
> + .get = get_chr,
> + .set = set_chr,
> .free = free_chr,
> };
>
> /* --- netdev device --- */
>
> -static int parse_netdev(DeviceState *dev, Property *prop, const char *str)
> +static int parse_netdev(DeviceState *dev, const char *str, void **ptr)
> {
> - VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
> + VLANClientState *netdev = qemu_find_netdev(str);
>
> - *ptr = qemu_find_netdev(str);
> - if (*ptr == NULL)
> + if (netdev == NULL) {
> return -ENOENT;
> - if ((*ptr)->peer) {
> + }
> + if (netdev->peer) {
> return -EEXIST;
> }
> + *ptr = netdev;
> return 0;
> }
>
> -static int print_netdev(DeviceState *dev, Property *prop, char *dest, size_t len)
> +static const char *print_netdev(void *ptr)
> {
> - VLANClientState **ptr = qdev_get_prop_ptr(dev, prop);
> + VLANClientState *netdev = ptr;
>
> - if (*ptr&& (*ptr)->name) {
> - return snprintf(dest, len, "%s", (*ptr)->name);
> - } else {
> - return snprintf(dest, len, "<null>");
> - }
> + return netdev->name ? netdev->name : "";
> +}
> +
> +static void get_netdev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + get_pointer(obj, v, opaque, print_netdev, name, errp);
> +}
> +
> +static void set_netdev(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + set_pointer(obj, v, opaque, parse_netdev, name, errp);
> }
>
> PropertyInfo qdev_prop_netdev = {
> .name = "netdev",
> .type = PROP_TYPE_NETDEV,
> .size = sizeof(VLANClientState*),
> - .parse = parse_netdev,
> - .print = print_netdev,
> - .get = get_generic,
> - .set = set_generic,
> + .get = get_netdev,
> + .set = set_netdev,
> };
>
> /* --- vlan --- */
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 20/27] qdev: let QOM free properties
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (18 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 19/27] qdev: remove parse/print methods for pointer properties Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:35 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 21/27] qdev: fix off-by-one Paolo Bonzini
` (7 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Drop the special free callback. Instead, register a "regular"
release method in the non-legacy property.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 19 ++++++++++++-------
hw/qdev.c | 8 +-------
hw/qdev.h | 2 +-
3 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 67995a3..d69a987 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -510,9 +510,10 @@ PropertyInfo qdev_prop_hex64 = {
/* --- string --- */
-static void free_string(DeviceState *dev, Property *prop)
+static void release_string(Object *obj, const char *name, void *opaque)
{
- g_free(*(char **)qdev_get_prop_ptr(dev, prop));
+ Property *prop = opaque;
+ g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
}
static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
@@ -572,7 +573,7 @@ PropertyInfo qdev_prop_string = {
.type = PROP_TYPE_STRING,
.size = sizeof(char*),
.print = print_string,
- .free = free_string,
+ .release = release_string,
.get = get_string,
.set = set_string,
};
@@ -592,8 +593,10 @@ static int parse_drive(DeviceState *dev, const char *str, void **ptr)
return 0;
}
-static void free_drive(DeviceState *dev, Property *prop)
+static void release_drive(Object *obj, const char *name, void *opaque)
{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
if (*ptr) {
@@ -667,7 +670,7 @@ PropertyInfo qdev_prop_drive = {
.size = sizeof(BlockDriverState *),
.get = get_drive,
.set = set_drive,
- .free = free_drive,
+ .release = release_drive,
};
/* --- character device --- */
@@ -686,8 +689,10 @@ static int parse_chr(DeviceState *dev, const char *str, void **ptr)
return 0;
}
-static void free_chr(DeviceState *dev, Property *prop)
+static void release_chr(Object *obj, const char *name, void *opaque)
{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
if (*ptr) {
@@ -721,7 +726,7 @@ PropertyInfo qdev_prop_chr = {
.size = sizeof(CharDriverState*),
.get = get_chr,
.set = set_chr,
- .free = free_chr,
+ .release = release_chr,
};
/* --- netdev device --- */
diff --git a/hw/qdev.c b/hw/qdev.c
index 660ee38..f719f14 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -595,7 +595,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
object_property_add(OBJECT(dev), prop->name, prop->info->name,
prop->info->get, prop->info->set,
- NULL,
+ prop->info->release,
prop, errp);
}
@@ -626,7 +626,6 @@ static void device_finalize(Object *obj)
{
DeviceState *dev = DEVICE(obj);
BusState *bus;
- Property *prop;
DeviceClass *dc = DEVICE_GET_CLASS(dev);
if (dev->state == DEV_STATE_INITIALIZED) {
@@ -645,11 +644,6 @@ static void device_finalize(Object *obj)
}
}
QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
- for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
- if (prop->info->free) {
- prop->info->free(dev, prop);
- }
- }
}
void device_reset(DeviceState *dev)
diff --git a/hw/qdev.h b/hw/qdev.h
index c31dc4e..acccf26 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -145,9 +145,9 @@ struct PropertyInfo {
int64_t max;
int (*parse)(DeviceState *dev, Property *prop, const char *str);
int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
- void (*free)(DeviceState *dev, Property *prop);
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
+ ObjectPropertyRelease *release;
};
typedef struct GlobalProperty {
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 20/27] qdev: let QOM free properties
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 20/27] qdev: let QOM free properties Paolo Bonzini
@ 2012-02-06 14:35 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:35 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Drop the special free callback. Instead, register a "regular"
> release method in the non-legacy property.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 19 ++++++++++++-------
> hw/qdev.c | 8 +-------
> hw/qdev.h | 2 +-
> 3 files changed, 14 insertions(+), 15 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 67995a3..d69a987 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -510,9 +510,10 @@ PropertyInfo qdev_prop_hex64 = {
>
> /* --- string --- */
>
> -static void free_string(DeviceState *dev, Property *prop)
> +static void release_string(Object *obj, const char *name, void *opaque)
> {
> - g_free(*(char **)qdev_get_prop_ptr(dev, prop));
> + Property *prop = opaque;
> + g_free(*(char **)qdev_get_prop_ptr(DEVICE(obj), prop));
> }
>
> static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
> @@ -572,7 +573,7 @@ PropertyInfo qdev_prop_string = {
> .type = PROP_TYPE_STRING,
> .size = sizeof(char*),
> .print = print_string,
> - .free = free_string,
> + .release = release_string,
> .get = get_string,
> .set = set_string,
> };
> @@ -592,8 +593,10 @@ static int parse_drive(DeviceState *dev, const char *str, void **ptr)
> return 0;
> }
>
> -static void free_drive(DeviceState *dev, Property *prop)
> +static void release_drive(Object *obj, const char *name, void *opaque)
> {
> + DeviceState *dev = DEVICE(obj);
> + Property *prop = opaque;
> BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
>
> if (*ptr) {
> @@ -667,7 +670,7 @@ PropertyInfo qdev_prop_drive = {
> .size = sizeof(BlockDriverState *),
> .get = get_drive,
> .set = set_drive,
> - .free = free_drive,
> + .release = release_drive,
> };
>
> /* --- character device --- */
> @@ -686,8 +689,10 @@ static int parse_chr(DeviceState *dev, const char *str, void **ptr)
> return 0;
> }
>
> -static void free_chr(DeviceState *dev, Property *prop)
> +static void release_chr(Object *obj, const char *name, void *opaque)
> {
> + DeviceState *dev = DEVICE(obj);
> + Property *prop = opaque;
> CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
>
> if (*ptr) {
> @@ -721,7 +726,7 @@ PropertyInfo qdev_prop_chr = {
> .size = sizeof(CharDriverState*),
> .get = get_chr,
> .set = set_chr,
> - .free = free_chr,
> + .release = release_chr,
> };
>
> /* --- netdev device --- */
> diff --git a/hw/qdev.c b/hw/qdev.c
> index 660ee38..f719f14 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -595,7 +595,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
>
> object_property_add(OBJECT(dev), prop->name, prop->info->name,
> prop->info->get, prop->info->set,
> - NULL,
> + prop->info->release,
> prop, errp);
> }
>
> @@ -626,7 +626,6 @@ static void device_finalize(Object *obj)
> {
> DeviceState *dev = DEVICE(obj);
> BusState *bus;
> - Property *prop;
> DeviceClass *dc = DEVICE_GET_CLASS(dev);
>
> if (dev->state == DEV_STATE_INITIALIZED) {
> @@ -645,11 +644,6 @@ static void device_finalize(Object *obj)
> }
> }
> QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
> - for (prop = qdev_get_props(dev); prop&& prop->name; prop++) {
> - if (prop->info->free) {
> - prop->info->free(dev, prop);
> - }
> - }
> }
>
> void device_reset(DeviceState *dev)
> diff --git a/hw/qdev.h b/hw/qdev.h
> index c31dc4e..acccf26 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -145,9 +145,9 @@ struct PropertyInfo {
> int64_t max;
> int (*parse)(DeviceState *dev, Property *prop, const char *str);
> int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
> - void (*free)(DeviceState *dev, Property *prop);
> ObjectPropertyAccessor *get;
> ObjectPropertyAccessor *set;
> + ObjectPropertyRelease *release;
> };
>
> typedef struct GlobalProperty {
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 21/27] qdev: fix off-by-one
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (19 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 20/27] qdev: let QOM free properties Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:35 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM Paolo Bonzini
` (6 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Integer properties did not work.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index d69a987..debb37f 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -151,7 +151,7 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,
error_propagate(errp, local_err);
return;
}
- if (value > prop->info->min && value <= prop->info->max) {
+ if (value >= prop->info->min && value <= prop->info->max) {
*ptr = value;
} else {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
@@ -259,7 +259,7 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,
error_propagate(errp, local_err);
return;
}
- if (value > prop->info->min && value <= prop->info->max) {
+ if (value >= prop->info->min && value <= prop->info->max) {
*ptr = value;
} else {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
@@ -333,7 +333,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
error_propagate(errp, local_err);
return;
}
- if (value > prop->info->min && value <= prop->info->max) {
+ if (value >= prop->info->min && value <= prop->info->max) {
*ptr = value;
} else {
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 21/27] qdev: fix off-by-one
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 21/27] qdev: fix off-by-one Paolo Bonzini
@ 2012-02-06 14:35 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:35 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Integer properties did not work.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index d69a987..debb37f 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -151,7 +151,7 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,
> error_propagate(errp, local_err);
> return;
> }
> - if (value> prop->info->min&& value<= prop->info->max) {
> + if (value>= prop->info->min&& value<= prop->info->max) {
> *ptr = value;
> } else {
> error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> @@ -259,7 +259,7 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,
> error_propagate(errp, local_err);
> return;
> }
> - if (value> prop->info->min&& value<= prop->info->max) {
> + if (value>= prop->info->min&& value<= prop->info->max) {
> *ptr = value;
> } else {
> error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
> @@ -333,7 +333,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
> error_propagate(errp, local_err);
> return;
> }
> - if (value> prop->info->min&& value<= prop->info->max) {
> + if (value>= prop->info->min&& value<= prop->info->max) {
> *ptr = value;
> } else {
> error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (20 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 21/27] qdev: fix off-by-one Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:36 ` Anthony Liguori
2012-02-11 15:46 ` Blue Swirl
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 23/27] qdev: inline qdev_prop_set into qdev_prop_set_ptr Paolo Bonzini
` (5 subsequent siblings)
27 siblings, 2 replies; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Do not poke anymore in the struct when accessing qdev properties.
Instead, ask the object to set the right value.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-addr.c | 5 ++-
hw/qdev-properties.c | 78 ++++++++++++++++++++++++++++++++++---------------
hw/qdev.h | 4 +--
3 files changed, 59 insertions(+), 28 deletions(-)
diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 5976dcd..8daa733 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -71,5 +71,8 @@ PropertyInfo qdev_prop_taddr = {
void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_TADDR);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
+
}
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index debb37f..5a11676 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1115,7 +1115,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
return 0;
}
-void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
+static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
{
Property *prop;
@@ -1135,52 +1135,63 @@ void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyT
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_BIT);
+ Error *errp = NULL;
+ object_property_set_bool(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_INT32);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
+ Error *errp = NULL;
+ object_property_set_str(OBJECT(dev), value, name, &errp);
+ assert(!errp);
}
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
{
- int res;
-
- res = bdrv_attach_dev(value, dev);
- if (res < 0) {
- error_report("Can't attach drive %s to %s.%s: %s",
- bdrv_get_device_name(value),
- dev->id ? dev->id : object_get_typename(OBJECT(dev)),
- name, strerror(-res));
+ Error *errp = NULL;
+ object_property_set_str(OBJECT(dev), bdrv_get_device_name(value),
+ name, &errp);
+ if (errp) {
+ qerror_report_err(errp);
+ error_free(errp);
return -1;
}
- qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
return 0;
}
@@ -1192,28 +1203,47 @@ void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverS
}
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
+ Error *errp = NULL;
+ assert(value->label);
+ object_property_set_str(OBJECT(dev), value->label, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
+ Error *errp = NULL;
+ assert(value->name);
+ object_property_set_str(OBJECT(dev), value->name, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
+ Error *errp = NULL;
+ object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
+ assert(!errp);
}
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
{
- qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
+ Error *errp = NULL;
+ char str[2 * 6 + 5 + 1];
+ snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
+ value[0], value[1], value[2], value[3], value[4], value[5]);
+
+ object_property_set_str(OBJECT(dev), str, name, &errp);
+ assert(!errp);
}
-void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
- LostTickPolicy *value)
+void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
{
- qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY);
+ Property *prop;
+ Error *errp = NULL;
+
+ prop = qdev_prop_find(dev, name);
+ object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
+ name, &errp);
+ assert(!errp);
}
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
diff --git a/hw/qdev.h b/hw/qdev.h
index acccf26..9ccd5c3 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -310,7 +310,6 @@ extern PropertyInfo qdev_prop_pci_devfn;
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
int qdev_prop_exists(DeviceState *dev, const char *name);
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
-void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type);
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
@@ -324,8 +323,7 @@ void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
-void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
- LostTickPolicy *value);
+void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
/* FIXME: Remove opaque pointer properties. */
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
void qdev_prop_set_defaults(DeviceState *dev, Property *props);
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM Paolo Bonzini
@ 2012-02-06 14:36 ` Anthony Liguori
2012-02-11 15:46 ` Blue Swirl
1 sibling, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:36 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Do not poke anymore in the struct when accessing qdev properties.
> Instead, ask the object to set the right value.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-addr.c | 5 ++-
> hw/qdev-properties.c | 78 ++++++++++++++++++++++++++++++++++---------------
> hw/qdev.h | 4 +--
> 3 files changed, 59 insertions(+), 28 deletions(-)
>
> diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
> index 5976dcd..8daa733 100644
> --- a/hw/qdev-addr.c
> +++ b/hw/qdev-addr.c
> @@ -71,5 +71,8 @@ PropertyInfo qdev_prop_taddr = {
>
> void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_TADDR);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> +
> }
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index debb37f..5a11676 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -1115,7 +1115,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> return 0;
> }
>
> -void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
> +static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
> {
> Property *prop;
>
> @@ -1135,52 +1135,63 @@ void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyT
>
> void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_BIT);
> + Error *errp = NULL;
> + object_property_set_bool(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_UINT8);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_UINT16);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_UINT32);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_INT32);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_UINT64);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_STRING);
> + Error *errp = NULL;
> + object_property_set_str(OBJECT(dev), value, name,&errp);
> + assert(!errp);
> }
>
> int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
> {
> - int res;
> -
> - res = bdrv_attach_dev(value, dev);
> - if (res< 0) {
> - error_report("Can't attach drive %s to %s.%s: %s",
> - bdrv_get_device_name(value),
> - dev->id ? dev->id : object_get_typename(OBJECT(dev)),
> - name, strerror(-res));
> + Error *errp = NULL;
> + object_property_set_str(OBJECT(dev), bdrv_get_device_name(value),
> + name,&errp);
> + if (errp) {
> + qerror_report_err(errp);
> + error_free(errp);
> return -1;
> }
> - qdev_prop_set(dev, name,&value, PROP_TYPE_DRIVE);
> return 0;
> }
>
> @@ -1192,28 +1203,47 @@ void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverS
> }
> void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_CHR);
> + Error *errp = NULL;
> + assert(value->label);
> + object_property_set_str(OBJECT(dev), value->label, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_NETDEV);
> + Error *errp = NULL;
> + assert(value->name);
> + object_property_set_str(OBJECT(dev), value->name, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_VLAN);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value ? value->id : -1, name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
> {
> - qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
> + Error *errp = NULL;
> + char str[2 * 6 + 5 + 1];
> + snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
> + value[0], value[1], value[2], value[3], value[4], value[5]);
> +
> + object_property_set_str(OBJECT(dev), str, name,&errp);
> + assert(!errp);
> }
>
> -void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
> - LostTickPolicy *value)
> +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
> {
> - qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY);
> + Property *prop;
> + Error *errp = NULL;
> +
> + prop = qdev_prop_find(dev, name);
> + object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
> + name,&errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
> diff --git a/hw/qdev.h b/hw/qdev.h
> index acccf26..9ccd5c3 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -310,7 +310,6 @@ extern PropertyInfo qdev_prop_pci_devfn;
> void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
> int qdev_prop_exists(DeviceState *dev, const char *name);
> int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
> -void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type);
> void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
> void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
> void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
> @@ -324,8 +323,7 @@ void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
> int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
> void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
> void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
> -void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
> - LostTickPolicy *value);
> +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
> /* FIXME: Remove opaque pointer properties. */
> void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
> void qdev_prop_set_defaults(DeviceState *dev, Property *props);
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM Paolo Bonzini
2012-02-06 14:36 ` Anthony Liguori
@ 2012-02-11 15:46 ` Blue Swirl
2012-02-13 7:53 ` Paolo Bonzini
1 sibling, 1 reply; 62+ messages in thread
From: Blue Swirl @ 2012-02-11 15:46 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On Sat, Feb 4, 2012 at 08:02, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Do not poke anymore in the struct when accessing qdev properties.
> Instead, ask the object to set the right value.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> hw/qdev-addr.c | 5 ++-
> hw/qdev-properties.c | 78 ++++++++++++++++++++++++++++++++++---------------
> hw/qdev.h | 4 +--
> 3 files changed, 59 insertions(+), 28 deletions(-)
>
> diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
> index 5976dcd..8daa733 100644
> --- a/hw/qdev-addr.c
> +++ b/hw/qdev-addr.c
> @@ -71,5 +71,8 @@ PropertyInfo qdev_prop_taddr = {
>
> void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_TADDR);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> +
> }
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index debb37f..5a11676 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -1115,7 +1115,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> return 0;
> }
>
> -void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
> +static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
> {
> Property *prop;
>
> @@ -1135,52 +1135,63 @@ void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyT
>
> void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_BIT);
> + Error *errp = NULL;
> + object_property_set_bool(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT8);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_INT32);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_UINT64);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
> + Error *errp = NULL;
> + object_property_set_str(OBJECT(dev), value, name, &errp);
> + assert(!errp);
> }
>
> int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
> {
> - int res;
> -
> - res = bdrv_attach_dev(value, dev);
> - if (res < 0) {
> - error_report("Can't attach drive %s to %s.%s: %s",
> - bdrv_get_device_name(value),
> - dev->id ? dev->id : object_get_typename(OBJECT(dev)),
> - name, strerror(-res));
> + Error *errp = NULL;
> + object_property_set_str(OBJECT(dev), bdrv_get_device_name(value),
> + name, &errp);
> + if (errp) {
> + qerror_report_err(errp);
> + error_free(errp);
> return -1;
> }
> - qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
> return 0;
> }
>
> @@ -1192,28 +1203,47 @@ void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverS
> }
> void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_CHR);
> + Error *errp = NULL;
> + assert(value->label);
This breaks Sparc32 and PPC:
Program received signal SIGSEGV, Segmentation fault.
qdev_prop_set_chr (dev=0x157e170, name=0x5bda5f "chrB", value=0x0)
at /src/qemu/hw/qdev-properties.c:1142
1142 assert(value->label);
(gdb) bt
#0 qdev_prop_set_chr (dev=0x157e170, name=0x5bda5f "chrB", value=0x0)
at /src/qemu/hw/qdev-properties.c:1142
#1 0x000000000046e1af in slavio_serial_ms_kbd_init (base=1895825408,
irq=0x11cdab0, disabled=0, clock=4915200, it_shift=1)
at /src/qemu/hw/escc.c:859
#2 0x000000000054117d in sun4m_hw_init (hwdef=0x5ef660, RAM_size=134217728,
boot_device=<value optimized out>, kernel_filename=<value optimized out>,
kernel_cmdline=0x57ade2 "", initrd_filename=<value optimized out>,
cpu_model=0x0) at /src/qemu/hw/sun4m.c:961
#3 0x00000000005419d1 in ss5_init (RAM_size=<value optimized out>,
boot_device=<value optimized out>, kernel_filename=<value optimized out>,
kernel_cmdline=<value optimized out>,
initrd_filename=<value optimized out>, cpu_model=<value optimized out>)
at /src/qemu/hw/sun4m.c:1317
#4 0x0000000000481a3e in main (argc=<value optimized out>,
argv=<value optimized out>, envp=<value optimized out>)
at /src/qemu/vl.c:3391
Program received signal SIGSEGV, Segmentation fault.
qdev_prop_set_chr (dev=0x1365580, name=0x6ed811 "chrB", value=0x0)
at /src/qemu/hw/qdev-properties.c:1142
1142 assert(value->label);
(gdb) bt
#0 qdev_prop_set_chr (dev=0x1365580, name=0x6ed811 "chrB", value=0x0)
at /src/qemu/hw/qdev-properties.c:1142
#1 0x000000000048b484 in escc_init (base=0, irqA=0x12deb48, irqB=0x12deb60,
chrA=0x128ff60, chrB=0x0, clock=<value optimized out>, it_shift=4)
at /src/qemu/hw/escc.c:698
#2 0x00000000005ab173 in ppc_heathrow_init (ram_size=134217728,
boot_device=<value optimized out>, kernel_filename=0x0,
kernel_cmdline=<value optimized out>,
initrd_filename=<value optimized out>, cpu_model=<value optimized out>)
at /src/qemu/hw/ppc_oldworld.c:246
#3 0x00000000004d9a8e in main (argc=<value optimized out>,
argv=<value optimized out>, envp=<value optimized out>)
at /src/qemu/vl.c:3391
This is running qemu-system-sparc and qemu-system-ppc with no arguments.
> + object_property_set_str(OBJECT(dev), value->label, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_NETDEV);
> + Error *errp = NULL;
> + assert(value->name);
> + object_property_set_str(OBJECT(dev), value->name, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value)
> {
> - qdev_prop_set(dev, name, &value, PROP_TYPE_VLAN);
> + Error *errp = NULL;
> + object_property_set_int(OBJECT(dev), value ? value->id : -1, name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value)
> {
> - qdev_prop_set(dev, name, value, PROP_TYPE_MACADDR);
> + Error *errp = NULL;
> + char str[2 * 6 + 5 + 1];
> + snprintf(str, sizeof(str), "%02x:%02x:%02x:%02x:%02x:%02x",
> + value[0], value[1], value[2], value[3], value[4], value[5]);
> +
> + object_property_set_str(OBJECT(dev), str, name, &errp);
> + assert(!errp);
> }
>
> -void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
> - LostTickPolicy *value)
> +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
> {
> - qdev_prop_set(dev, name, value, PROP_TYPE_LOSTTICKPOLICY);
> + Property *prop;
> + Error *errp = NULL;
> +
> + prop = qdev_prop_find(dev, name);
> + object_property_set_str(OBJECT(dev), prop->info->enum_table[value],
> + name, &errp);
> + assert(!errp);
> }
>
> void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
> diff --git a/hw/qdev.h b/hw/qdev.h
> index acccf26..9ccd5c3 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -310,7 +310,6 @@ extern PropertyInfo qdev_prop_pci_devfn;
> void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
> int qdev_prop_exists(DeviceState *dev, const char *name);
> int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
> -void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type);
> void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
> void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
> void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
> @@ -324,8 +323,7 @@ void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
> int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
> void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
> void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
> -void qdev_prop_set_losttickpolicy(DeviceState *dev, const char *name,
> - LostTickPolicy *value);
> +void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
> /* FIXME: Remove opaque pointer properties. */
> void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
> void qdev_prop_set_defaults(DeviceState *dev, Property *props);
> --
> 1.7.7.6
>
>
>
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM
2012-02-11 15:46 ` Blue Swirl
@ 2012-02-13 7:53 ` Paolo Bonzini
0 siblings, 0 replies; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-13 7:53 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
On 02/11/2012 04:46 PM, Blue Swirl wrote:
> Program received signal SIGSEGV, Segmentation fault.
> qdev_prop_set_chr (dev=0x1365580, name=0x6ed811 "chrB", value=0x0)
> at /src/qemu/hw/qdev-properties.c:1142
> 1142 assert(value->label);
> (gdb) bt
> #0 qdev_prop_set_chr (dev=0x1365580, name=0x6ed811 "chrB", value=0x0)
> at /src/qemu/hw/qdev-properties.c:1142
> #1 0x000000000048b484 in escc_init (base=0, irqA=0x12deb48, irqB=0x12deb60,
> chrA=0x128ff60, chrB=0x0, clock=<value optimized out>, it_shift=4)
> at /src/qemu/hw/escc.c:698
> #2 0x00000000005ab173 in ppc_heathrow_init (ram_size=134217728,
> boot_device=<value optimized out>, kernel_filename=0x0,
> kernel_cmdline=<value optimized out>,
> initrd_filename=<value optimized out>, cpu_model=<value optimized out>)
> at /src/qemu/hw/ppc_oldworld.c:246
> #3 0x00000000004d9a8e in main (argc=<value optimized out>,
> argv=<value optimized out>, envp=<value optimized out>)
> at /src/qemu/vl.c:3391
>
> This is running qemu-system-sparc and qemu-system-ppc with no arguments.
Will fix, thanks for reporting.
Paolo
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 23/27] qdev: inline qdev_prop_set into qdev_prop_set_ptr
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (21 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 22/27] qdev: access properties via QOM Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:37 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 24/27] qdev: initialize properties via QOM Paolo Bonzini
` (4 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
qdev_prop_set is not needed anymore except for hacks, simplify it and
inline it.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 26 +++++++-------------------
1 files changed, 7 insertions(+), 19 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 5a11676..b3cd2a8 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1115,24 +1115,6 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
return 0;
}
-static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
-{
- Property *prop;
-
- prop = qdev_prop_find(dev, name);
- if (!prop) {
- fprintf(stderr, "%s: property \"%s.%s\" not found\n",
- __FUNCTION__, object_get_typename(OBJECT(dev)), name);
- abort();
- }
- if (prop->info->type != type) {
- fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
- __FUNCTION__, object_get_typename(OBJECT(dev)), name);
- abort();
- }
- qdev_prop_cpy(dev, prop, src);
-}
-
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
{
Error *errp = NULL;
@@ -1248,7 +1230,13 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
{
- qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
+ Property *prop;
+ void **ptr;
+
+ prop = qdev_prop_find(dev, name);
+ assert(prop && prop->info == &qdev_prop_ptr);
+ ptr = qdev_get_prop_ptr(dev, prop);
+ *ptr = value;
}
void qdev_prop_set_defaults(DeviceState *dev, Property *props)
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 23/27] qdev: inline qdev_prop_set into qdev_prop_set_ptr
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 23/27] qdev: inline qdev_prop_set into qdev_prop_set_ptr Paolo Bonzini
@ 2012-02-06 14:37 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:37 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> qdev_prop_set is not needed anymore except for hacks, simplify it and
> inline it.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 26 +++++++-------------------
> 1 files changed, 7 insertions(+), 19 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 5a11676..b3cd2a8 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -1115,24 +1115,6 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
> return 0;
> }
>
> -static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
> -{
> - Property *prop;
> -
> - prop = qdev_prop_find(dev, name);
> - if (!prop) {
> - fprintf(stderr, "%s: property \"%s.%s\" not found\n",
> - __FUNCTION__, object_get_typename(OBJECT(dev)), name);
> - abort();
> - }
> - if (prop->info->type != type) {
> - fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
> - __FUNCTION__, object_get_typename(OBJECT(dev)), name);
> - abort();
> - }
> - qdev_prop_cpy(dev, prop, src);
> -}
> -
> void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value)
> {
> Error *errp = NULL;
> @@ -1248,7 +1230,13 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value)
>
> void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
> {
> - qdev_prop_set(dev, name,&value, PROP_TYPE_PTR);
> + Property *prop;
> + void **ptr;
> +
> + prop = qdev_prop_find(dev, name);
> + assert(prop&& prop->info ==&qdev_prop_ptr);
> + ptr = qdev_get_prop_ptr(dev, prop);
> + *ptr = value;
> }
>
> void qdev_prop_set_defaults(DeviceState *dev, Property *props)
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 24/27] qdev: initialize properties via QOM
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (22 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 23/27] qdev: inline qdev_prop_set into qdev_prop_set_ptr Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:38 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 25/27] qdev: remove unused fields from PropertyInfo Paolo Bonzini
` (3 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Similarly, use the object properties also to set the default
values of the qdev properties. This requires reordering
registration and initialization.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 29 ++++++++++++++---------------
hw/qdev.c | 4 ++--
hw/qdev.h | 11 +++++++----
3 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index b3cd2a8..49bed30 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -26,17 +26,6 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val)
*p &= ~mask;
}
-static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)
-{
- if (props->info->type == PROP_TYPE_BIT) {
- bool *defval = src;
- bit_prop_set(dev, props, *defval);
- } else {
- char *dst = qdev_get_prop_ptr(dev, props);
- memcpy(dst, src, props->info->size);
- }
-}
-
/* Bit */
static int parse_bit(DeviceState *dev, Property *prop, const char *str)
{
@@ -1241,13 +1230,23 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
void qdev_prop_set_defaults(DeviceState *dev, Property *props)
{
+ Object *obj = OBJECT(dev);
if (!props)
return;
- while (props->name) {
- if (props->defval) {
- qdev_prop_cpy(dev, props, props->defval);
+ for (; props->name; props++) {
+ Error *errp = NULL;
+ if (props->qtype == QTYPE_NONE) {
+ continue;
}
- props++;
+ if (props->qtype == QTYPE_QBOOL) {
+ object_property_set_bool(obj, props->defval, props->name, &errp);
+ } else if (props->info->enum_table) {
+ object_property_set_str(obj, props->info->enum_table[props->defval],
+ props->name, &errp);
+ } else if (props->qtype == QTYPE_QINT) {
+ object_property_set_int(obj, props->defval, props->name, &errp);
+ }
+ assert(!errp);
}
}
diff --git a/hw/qdev.c b/hw/qdev.c
index f719f14..dc1d1a1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -86,11 +86,11 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
dev->parent_bus = bus;
QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
- qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
qdev_property_add_static(dev, prop, NULL);
}
+ qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
}
/* Create a new device. This only initializes the device state structure
@@ -612,13 +612,13 @@ static void device_initfn(Object *obj)
dev->instance_id_alias = -1;
dev->state = DEV_STATE_CREATED;
- qdev_prop_set_defaults(dev, qdev_get_props(dev));
for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
qdev_property_add_static(dev, prop, NULL);
}
object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
+ qdev_prop_set_defaults(dev, qdev_get_props(dev));
}
/* Unlink device from bus and free the structure. */
diff --git a/hw/qdev.h b/hw/qdev.h
index 9ccd5c3..a3bcf0b 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -112,8 +112,9 @@ struct Property {
const char *name;
PropertyInfo *info;
int offset;
- int bitnr;
- void *defval;
+ uint8_t bitnr;
+ uint8_t qtype;
+ int64_t defval;
};
enum PropertyType {
@@ -255,7 +256,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
.info = &(_prop), \
.offset = offsetof(_state, _field) \
+ type_check(_type,typeof_field(_state, _field)), \
- .defval = (_type[]) { _defval }, \
+ .qtype = QTYPE_QINT, \
+ .defval = (_type)_defval, \
}
#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
.name = (_name), \
@@ -263,7 +265,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
.bitnr = (_bit), \
.offset = offsetof(_state, _field) \
+ type_check(uint32_t,typeof_field(_state, _field)), \
- .defval = (bool[]) { (_defval) }, \
+ .qtype = QTYPE_QBOOL, \
+ .defval = (bool)_defval, \
}
#define DEFINE_PROP_UINT8(_n, _s, _f, _d) \
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 24/27] qdev: initialize properties via QOM
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 24/27] qdev: initialize properties via QOM Paolo Bonzini
@ 2012-02-06 14:38 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:38 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Similarly, use the object properties also to set the default
> values of the qdev properties. This requires reordering
> registration and initialization.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
> ---
> hw/qdev-properties.c | 29 ++++++++++++++---------------
> hw/qdev.c | 4 ++--
> hw/qdev.h | 11 +++++++----
> 3 files changed, 23 insertions(+), 21 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index b3cd2a8..49bed30 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -26,17 +26,6 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val)
> *p&= ~mask;
> }
>
> -static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)
> -{
> - if (props->info->type == PROP_TYPE_BIT) {
> - bool *defval = src;
> - bit_prop_set(dev, props, *defval);
> - } else {
> - char *dst = qdev_get_prop_ptr(dev, props);
> - memcpy(dst, src, props->info->size);
> - }
> -}
> -
> /* Bit */
> static int parse_bit(DeviceState *dev, Property *prop, const char *str)
> {
> @@ -1241,13 +1230,23 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
>
> void qdev_prop_set_defaults(DeviceState *dev, Property *props)
> {
> + Object *obj = OBJECT(dev);
> if (!props)
> return;
> - while (props->name) {
> - if (props->defval) {
> - qdev_prop_cpy(dev, props, props->defval);
> + for (; props->name; props++) {
> + Error *errp = NULL;
> + if (props->qtype == QTYPE_NONE) {
> + continue;
> }
> - props++;
> + if (props->qtype == QTYPE_QBOOL) {
> + object_property_set_bool(obj, props->defval, props->name,&errp);
> + } else if (props->info->enum_table) {
> + object_property_set_str(obj, props->info->enum_table[props->defval],
> + props->name,&errp);
> + } else if (props->qtype == QTYPE_QINT) {
> + object_property_set_int(obj, props->defval, props->name,&errp);
> + }
> + assert(!errp);
> }
> }
>
> diff --git a/hw/qdev.c b/hw/qdev.c
> index f719f14..dc1d1a1 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -86,11 +86,11 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
> dev->parent_bus = bus;
> QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
>
> - qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
> for (prop = qdev_get_bus_info(dev)->props; prop&& prop->name; prop++) {
> qdev_property_add_legacy(dev, prop, NULL);
> qdev_property_add_static(dev, prop, NULL);
> }
> + qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
> }
>
> /* Create a new device. This only initializes the device state structure
> @@ -612,13 +612,13 @@ static void device_initfn(Object *obj)
> dev->instance_id_alias = -1;
> dev->state = DEV_STATE_CREATED;
>
> - qdev_prop_set_defaults(dev, qdev_get_props(dev));
> for (prop = qdev_get_props(dev); prop&& prop->name; prop++) {
> qdev_property_add_legacy(dev, prop, NULL);
> qdev_property_add_static(dev, prop, NULL);
> }
>
> object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
> + qdev_prop_set_defaults(dev, qdev_get_props(dev));
> }
>
> /* Unlink device from bus and free the structure. */
> diff --git a/hw/qdev.h b/hw/qdev.h
> index 9ccd5c3..a3bcf0b 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -112,8 +112,9 @@ struct Property {
> const char *name;
> PropertyInfo *info;
> int offset;
> - int bitnr;
> - void *defval;
> + uint8_t bitnr;
> + uint8_t qtype;
> + int64_t defval;
> };
>
> enum PropertyType {
> @@ -255,7 +256,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
> .info =&(_prop), \
> .offset = offsetof(_state, _field) \
> + type_check(_type,typeof_field(_state, _field)), \
> - .defval = (_type[]) { _defval }, \
> + .qtype = QTYPE_QINT, \
> + .defval = (_type)_defval, \
> }
> #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
> .name = (_name), \
> @@ -263,7 +265,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
> .bitnr = (_bit), \
> .offset = offsetof(_state, _field) \
> + type_check(uint32_t,typeof_field(_state, _field)), \
> - .defval = (bool[]) { (_defval) }, \
> + .qtype = QTYPE_QBOOL, \
> + .defval = (bool)_defval, \
> }
>
> #define DEFINE_PROP_UINT8(_n, _s, _f, _d) \
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 25/27] qdev: remove unused fields from PropertyInfo
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (23 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 24/27] qdev: initialize properties via QOM Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:39 ` Anthony Liguori
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM Paolo Bonzini
` (2 subsequent siblings)
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-addr.c | 2 --
hw/qdev-properties.c | 38 +-------------------------------------
hw/qdev.h | 21 ---------------------
3 files changed, 1 insertions(+), 60 deletions(-)
diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 8daa733..0bb16c7 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -61,8 +61,6 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_taddr = {
.name = "taddr",
- .type = PROP_TYPE_TADDR,
- .size = sizeof(target_phys_addr_t),
.parse = parse_taddr,
.print = print_taddr,
.get = get_taddr,
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 49bed30..b6d6fcf 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -12,7 +12,7 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
static uint32_t qdev_get_prop_mask(Property *prop)
{
- assert(prop->info->type == PROP_TYPE_BIT);
+ assert(prop->info == &qdev_prop_bit);
return 0x1 << prop->bitnr;
}
@@ -79,8 +79,6 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_bit = {
.name = "boolean",
.legacy_name = "on/off",
- .type = PROP_TYPE_BIT,
- .size = sizeof(uint32_t),
.parse = parse_bit,
.print = print_bit,
.get = get_bit,
@@ -151,8 +149,6 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint8 = {
.name = "uint8",
- .type = PROP_TYPE_UINT8,
- .size = sizeof(uint8_t),
.parse = parse_uint8,
.print = print_uint8,
.get = get_int8,
@@ -185,8 +181,6 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_hex8 = {
.name = "uint8",
.legacy_name = "hex8",
- .type = PROP_TYPE_UINT8,
- .size = sizeof(uint8_t),
.parse = parse_hex8,
.print = print_hex8,
.get = get_int8,
@@ -259,8 +253,6 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint16 = {
.name = "uint16",
- .type = PROP_TYPE_UINT16,
- .size = sizeof(uint16_t),
.parse = parse_uint16,
.print = print_uint16,
.get = get_int16,
@@ -333,8 +325,6 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint32 = {
.name = "uint32",
- .type = PROP_TYPE_UINT32,
- .size = sizeof(uint32_t),
.parse = parse_uint32,
.print = print_uint32,
.get = get_int32,
@@ -364,8 +354,6 @@ static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_int32 = {
.name = "int32",
- .type = PROP_TYPE_INT32,
- .size = sizeof(int32_t),
.parse = parse_int32,
.print = print_int32,
.get = get_int32,
@@ -398,8 +386,6 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_hex32 = {
.name = "uint32",
.legacy_name = "hex32",
- .type = PROP_TYPE_UINT32,
- .size = sizeof(uint32_t),
.parse = parse_hex32,
.print = print_hex32,
.get = get_int32,
@@ -457,8 +443,6 @@ static void set_int64(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_uint64 = {
.name = "uint64",
- .type = PROP_TYPE_UINT64,
- .size = sizeof(uint64_t),
.parse = parse_uint64,
.print = print_uint64,
.get = get_int64,
@@ -489,8 +473,6 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
PropertyInfo qdev_prop_hex64 = {
.name = "uint64",
.legacy_name = "hex64",
- .type = PROP_TYPE_UINT64,
- .size = sizeof(uint64_t),
.parse = parse_hex64,
.print = print_hex64,
.get = get_int64,
@@ -559,8 +541,6 @@ static void set_string(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_string = {
.name = "string",
- .type = PROP_TYPE_STRING,
- .size = sizeof(char*),
.print = print_string,
.release = release_string,
.get = get_string,
@@ -655,8 +635,6 @@ static void set_drive(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_drive = {
.name = "drive",
- .type = PROP_TYPE_DRIVE,
- .size = sizeof(BlockDriverState *),
.get = get_drive,
.set = set_drive,
.release = release_drive,
@@ -711,8 +689,6 @@ static void set_chr(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_chr = {
.name = "chr",
- .type = PROP_TYPE_CHR,
- .size = sizeof(CharDriverState*),
.get = get_chr,
.set = set_chr,
.release = release_chr,
@@ -755,8 +731,6 @@ static void set_netdev(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_netdev = {
.name = "netdev",
- .type = PROP_TYPE_NETDEV,
- .size = sizeof(VLANClientState*),
.get = get_netdev,
.set = set_netdev,
};
@@ -834,8 +808,6 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_vlan = {
.name = "vlan",
- .type = PROP_TYPE_VLAN,
- .size = sizeof(VLANClientState*),
.parse = parse_vlan,
.print = print_vlan,
.get = get_vlan,
@@ -847,8 +819,6 @@ PropertyInfo qdev_prop_vlan = {
/* Not a proper property, just for dirty hacks. TODO Remove it! */
PropertyInfo qdev_prop_ptr = {
.name = "ptr",
- .type = PROP_TYPE_PTR,
- .size = sizeof(void*),
};
/* --- mac address --- */
@@ -917,8 +887,6 @@ inval:
PropertyInfo qdev_prop_macaddr = {
.name = "macaddr",
- .type = PROP_TYPE_MACADDR,
- .size = sizeof(MACAddr),
.get = get_mac,
.set = set_mac,
};
@@ -965,8 +933,6 @@ static void set_enum(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_losttickpolicy = {
.name = "LostTickPolicy",
- .type = PROP_TYPE_LOSTTICKPOLICY,
- .size = sizeof(LostTickPolicy),
.enum_table = lost_tick_policy_table,
.get = get_enum,
.set = set_enum,
@@ -1012,8 +978,6 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
PropertyInfo qdev_prop_pci_devfn = {
.name = "int32",
.legacy_name = "pci-devfn",
- .type = PROP_TYPE_UINT32,
- .size = sizeof(uint32_t),
.parse = parse_pci_devfn,
.print = print_pci_devfn,
.get = get_int32,
diff --git a/hw/qdev.h b/hw/qdev.h
index a3bcf0b..9cc3f98 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -117,30 +117,9 @@ struct Property {
int64_t defval;
};
-enum PropertyType {
- PROP_TYPE_UNSPEC = 0,
- PROP_TYPE_UINT8,
- PROP_TYPE_UINT16,
- PROP_TYPE_UINT32,
- PROP_TYPE_INT32,
- PROP_TYPE_UINT64,
- PROP_TYPE_TADDR,
- PROP_TYPE_MACADDR,
- PROP_TYPE_LOSTTICKPOLICY,
- PROP_TYPE_DRIVE,
- PROP_TYPE_CHR,
- PROP_TYPE_STRING,
- PROP_TYPE_NETDEV,
- PROP_TYPE_VLAN,
- PROP_TYPE_PTR,
- PROP_TYPE_BIT,
-};
-
struct PropertyInfo {
const char *name;
const char *legacy_name;
- size_t size;
- enum PropertyType type;
const char **enum_table;
int64_t min;
int64_t max;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 25/27] qdev: remove unused fields from PropertyInfo
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 25/27] qdev: remove unused fields from PropertyInfo Paolo Bonzini
@ 2012-02-06 14:39 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:39 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori <aliguori@us.ibm.com>
> ---
> hw/qdev-addr.c | 2 --
> hw/qdev-properties.c | 38 +-------------------------------------
> hw/qdev.h | 21 ---------------------
> 3 files changed, 1 insertions(+), 60 deletions(-)
>
> diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
> index 8daa733..0bb16c7 100644
> --- a/hw/qdev-addr.c
> +++ b/hw/qdev-addr.c
> @@ -61,8 +61,6 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_taddr = {
> .name = "taddr",
> - .type = PROP_TYPE_TADDR,
> - .size = sizeof(target_phys_addr_t),
> .parse = parse_taddr,
> .print = print_taddr,
> .get = get_taddr,
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 49bed30..b6d6fcf 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -12,7 +12,7 @@ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
>
> static uint32_t qdev_get_prop_mask(Property *prop)
> {
> - assert(prop->info->type == PROP_TYPE_BIT);
> + assert(prop->info ==&qdev_prop_bit);
> return 0x1<< prop->bitnr;
> }
>
> @@ -79,8 +79,6 @@ static void set_bit(Object *obj, Visitor *v, void *opaque,
> PropertyInfo qdev_prop_bit = {
> .name = "boolean",
> .legacy_name = "on/off",
> - .type = PROP_TYPE_BIT,
> - .size = sizeof(uint32_t),
> .parse = parse_bit,
> .print = print_bit,
> .get = get_bit,
> @@ -151,8 +149,6 @@ static void set_int8(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_uint8 = {
> .name = "uint8",
> - .type = PROP_TYPE_UINT8,
> - .size = sizeof(uint8_t),
> .parse = parse_uint8,
> .print = print_uint8,
> .get = get_int8,
> @@ -185,8 +181,6 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
> PropertyInfo qdev_prop_hex8 = {
> .name = "uint8",
> .legacy_name = "hex8",
> - .type = PROP_TYPE_UINT8,
> - .size = sizeof(uint8_t),
> .parse = parse_hex8,
> .print = print_hex8,
> .get = get_int8,
> @@ -259,8 +253,6 @@ static void set_int16(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_uint16 = {
> .name = "uint16",
> - .type = PROP_TYPE_UINT16,
> - .size = sizeof(uint16_t),
> .parse = parse_uint16,
> .print = print_uint16,
> .get = get_int16,
> @@ -333,8 +325,6 @@ static void set_int32(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_uint32 = {
> .name = "uint32",
> - .type = PROP_TYPE_UINT32,
> - .size = sizeof(uint32_t),
> .parse = parse_uint32,
> .print = print_uint32,
> .get = get_int32,
> @@ -364,8 +354,6 @@ static int print_int32(DeviceState *dev, Property *prop, char *dest, size_t len)
>
> PropertyInfo qdev_prop_int32 = {
> .name = "int32",
> - .type = PROP_TYPE_INT32,
> - .size = sizeof(int32_t),
> .parse = parse_int32,
> .print = print_int32,
> .get = get_int32,
> @@ -398,8 +386,6 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
> PropertyInfo qdev_prop_hex32 = {
> .name = "uint32",
> .legacy_name = "hex32",
> - .type = PROP_TYPE_UINT32,
> - .size = sizeof(uint32_t),
> .parse = parse_hex32,
> .print = print_hex32,
> .get = get_int32,
> @@ -457,8 +443,6 @@ static void set_int64(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_uint64 = {
> .name = "uint64",
> - .type = PROP_TYPE_UINT64,
> - .size = sizeof(uint64_t),
> .parse = parse_uint64,
> .print = print_uint64,
> .get = get_int64,
> @@ -489,8 +473,6 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
> PropertyInfo qdev_prop_hex64 = {
> .name = "uint64",
> .legacy_name = "hex64",
> - .type = PROP_TYPE_UINT64,
> - .size = sizeof(uint64_t),
> .parse = parse_hex64,
> .print = print_hex64,
> .get = get_int64,
> @@ -559,8 +541,6 @@ static void set_string(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_string = {
> .name = "string",
> - .type = PROP_TYPE_STRING,
> - .size = sizeof(char*),
> .print = print_string,
> .release = release_string,
> .get = get_string,
> @@ -655,8 +635,6 @@ static void set_drive(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_drive = {
> .name = "drive",
> - .type = PROP_TYPE_DRIVE,
> - .size = sizeof(BlockDriverState *),
> .get = get_drive,
> .set = set_drive,
> .release = release_drive,
> @@ -711,8 +689,6 @@ static void set_chr(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_chr = {
> .name = "chr",
> - .type = PROP_TYPE_CHR,
> - .size = sizeof(CharDriverState*),
> .get = get_chr,
> .set = set_chr,
> .release = release_chr,
> @@ -755,8 +731,6 @@ static void set_netdev(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_netdev = {
> .name = "netdev",
> - .type = PROP_TYPE_NETDEV,
> - .size = sizeof(VLANClientState*),
> .get = get_netdev,
> .set = set_netdev,
> };
> @@ -834,8 +808,6 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_vlan = {
> .name = "vlan",
> - .type = PROP_TYPE_VLAN,
> - .size = sizeof(VLANClientState*),
> .parse = parse_vlan,
> .print = print_vlan,
> .get = get_vlan,
> @@ -847,8 +819,6 @@ PropertyInfo qdev_prop_vlan = {
> /* Not a proper property, just for dirty hacks. TODO Remove it! */
> PropertyInfo qdev_prop_ptr = {
> .name = "ptr",
> - .type = PROP_TYPE_PTR,
> - .size = sizeof(void*),
> };
>
> /* --- mac address --- */
> @@ -917,8 +887,6 @@ inval:
>
> PropertyInfo qdev_prop_macaddr = {
> .name = "macaddr",
> - .type = PROP_TYPE_MACADDR,
> - .size = sizeof(MACAddr),
> .get = get_mac,
> .set = set_mac,
> };
> @@ -965,8 +933,6 @@ static void set_enum(Object *obj, Visitor *v, void *opaque,
>
> PropertyInfo qdev_prop_losttickpolicy = {
> .name = "LostTickPolicy",
> - .type = PROP_TYPE_LOSTTICKPOLICY,
> - .size = sizeof(LostTickPolicy),
> .enum_table = lost_tick_policy_table,
> .get = get_enum,
> .set = set_enum,
> @@ -1012,8 +978,6 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
> PropertyInfo qdev_prop_pci_devfn = {
> .name = "int32",
> .legacy_name = "pci-devfn",
> - .type = PROP_TYPE_UINT32,
> - .size = sizeof(uint32_t),
> .parse = parse_pci_devfn,
> .print = print_pci_devfn,
> .get = get_int32,
> diff --git a/hw/qdev.h b/hw/qdev.h
> index a3bcf0b..9cc3f98 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -117,30 +117,9 @@ struct Property {
> int64_t defval;
> };
>
> -enum PropertyType {
> - PROP_TYPE_UNSPEC = 0,
> - PROP_TYPE_UINT8,
> - PROP_TYPE_UINT16,
> - PROP_TYPE_UINT32,
> - PROP_TYPE_INT32,
> - PROP_TYPE_UINT64,
> - PROP_TYPE_TADDR,
> - PROP_TYPE_MACADDR,
> - PROP_TYPE_LOSTTICKPOLICY,
> - PROP_TYPE_DRIVE,
> - PROP_TYPE_CHR,
> - PROP_TYPE_STRING,
> - PROP_TYPE_NETDEV,
> - PROP_TYPE_VLAN,
> - PROP_TYPE_PTR,
> - PROP_TYPE_BIT,
> -};
> -
> struct PropertyInfo {
> const char *name;
> const char *legacy_name;
> - size_t size;
> - enum PropertyType type;
> const char **enum_table;
> int64_t min;
> int64_t max;
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (24 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 25/27] qdev: remove unused fields from PropertyInfo Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:42 ` Anthony Liguori
2012-02-06 16:32 ` Peter Maydell
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 27/27] omap: remove PROP_PTR properties Paolo Bonzini
2012-02-07 13:20 ` [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
27 siblings, 2 replies; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Make the OMAP clocks QOM objects, so that they we can put them in a branch
of the object graph and turn the pointer properties into links.
As in the current code, the clocks are copied into a freshly allocated
memory block when they are initialized. However, the "templates" now
have a separate struct definition because the header must be created
anyway with object_initialize. The linking of children to parents
is moved to a separate loop for simplicity.
Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/omap.h | 4 +
hw/omap1.c | 6 +-
hw/omap2.c | 16 ++--
hw/omap_clk.c | 357 ++++++++++++++++++++++++++++++++------------------------
4 files changed, 219 insertions(+), 164 deletions(-)
diff --git a/hw/omap.h b/hw/omap.h
index 60fa34c..5c0f95a 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -49,6 +49,8 @@
# define OMAP_CS3_SIZE 0x04000000
/* omap_clk.c */
+#define TYPE_OMAP_CLK "omap-clk"
+
struct omap_mpu_state_s;
typedef struct clk *omap_clk;
omap_clk omap_findclk(struct omap_mpu_state_s *mpu, const char *name);
@@ -61,6 +63,8 @@ void omap_clk_canidle(omap_clk clk, int can);
void omap_clk_setrate(omap_clk clk, int divide, int multiply);
int64_t omap_clk_getrate(omap_clk clk);
void omap_clk_reparent(omap_clk clk, omap_clk parent);
+void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
+ const char *name, const char *clk);
/* OMAP2 l4 Interconnect */
struct omap_l4_s;
diff --git a/hw/omap1.c b/hw/omap1.c
index 1aa5f23..12f1197 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -3856,7 +3856,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
cpu_irq = arm_pic_init_cpu(s->env);
s->ih[0] = qdev_create(NULL, "omap-intc");
qdev_prop_set_uint32(s->ih[0], "size", 0x100);
- qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
+ omap_prop_set_clk(s, s->ih[0], "clk", "arminth_ck");
qdev_init_nofail(s->ih[0]);
busdev = sysbus_from_qdev(s->ih[0]);
sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
@@ -3864,7 +3864,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
sysbus_mmio_map(busdev, 0, 0xfffecb00);
s->ih[1] = qdev_create(NULL, "omap-intc");
qdev_prop_set_uint32(s->ih[1], "size", 0x800);
- qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
+ omap_prop_set_clk(s, s->ih[1], "clk", "arminth_ck");
qdev_init_nofail(s->ih[1]);
busdev = sysbus_from_qdev(s->ih[1]);
sysbus_connect_irq(busdev, 0,
@@ -3977,7 +3977,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
s->gpio = qdev_create(NULL, "omap-gpio");
qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
- qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
+ omap_prop_set_clk(s, s->gpio, "clk", "arm_gpio_ck");
qdev_init_nofail(s->gpio);
sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0,
qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
diff --git a/hw/omap2.c b/hw/omap2.c
index a6851b0..b1fe0d3 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -2282,8 +2282,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
cpu_irq = arm_pic_init_cpu(s->env);
s->ih[0] = qdev_create(NULL, "omap2-intc");
qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
- qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
- qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
+ omap_prop_set_clk(s, s->ih[0], "fclk", "mpu_intc_fclk");
+ omap_prop_set_clk(s, s->ih[0], "iclk", "mpu_intc_iclk");
qdev_init_nofail(s->ih[0]);
busdev = sysbus_from_qdev(s->ih[0]);
sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
@@ -2408,13 +2408,13 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
s->gpio = qdev_create(NULL, "omap2-gpio");
qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
- qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk"));
- qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk"));
- qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk"));
- qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk"));
- qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk"));
+ omap_prop_set_clk(s, s->gpio, "iclk", "gpio_iclk");
+ omap_prop_set_clk(s, s->gpio, "fclk0", "gpio1_dbclk");
+ omap_prop_set_clk(s, s->gpio, "fclk1", "gpio2_dbclk");
+ omap_prop_set_clk(s, s->gpio, "fclk2", "gpio3_dbclk");
+ omap_prop_set_clk(s, s->gpio, "fclk3", "gpio4_dbclk");
if (s->mpu_model == omap2430) {
- qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk"));
+ omap_prop_set_clk(s, s->gpio, "fclk4", "gpio5_dbclk");
}
qdev_init_nofail(s->gpio);
busdev = sysbus_from_qdev(s->gpio);
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 8448006..c4c2b80 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -19,14 +19,14 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw.h"
+#include "qdev.h"
#include "omap.h"
+#include "qemu/object.h"
-struct clk {
+struct ClkInfo {
const char *name;
const char *alias;
- struct clk *parent;
- struct clk *child1;
- struct clk *sibling;
+ struct ClkInfo *parent;
#define ALWAYS_ENABLED (1 << 0)
#define CLOCK_IN_OMAP310 (1 << 10)
#define CLOCK_IN_OMAP730 (1 << 11)
@@ -38,6 +38,21 @@ struct clk {
uint32_t flags;
int id;
+ unsigned long rate; /* Current rate (if .running) */
+ unsigned int divisor; /* Rate relative to input (if .enabled) */
+ unsigned int multiplier; /* Rate relative to input (if .enabled) */
+};
+
+struct clk {
+ Object obj;
+ const char *name;
+ const char *alias;
+ struct clk *parent;
+ struct clk *child1;
+ struct clk *sibling;
+ uint32_t flags;
+ int id;
+
int running; /* Is currently ticking */
int enabled; /* Is enabled, regardless of its input clk */
unsigned long rate; /* Current rate (if .running) */
@@ -47,20 +62,26 @@ struct clk {
int usecount; /* Automatically idle when unused */
};
-static struct clk xtal_osc12m = {
+static TypeInfo omap_clk_info = {
+ .name = TYPE_OMAP_CLK,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(struct clk),
+};
+
+static struct ClkInfo xtal_osc12m = {
.name = "xtal_osc_12m",
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk xtal_osc32k = {
+static struct ClkInfo xtal_osc32k = {
.name = "xtal_osc_32k",
.rate = 32768,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
};
-static struct clk ck_ref = {
+static struct ClkInfo ck_ref = {
.name = "ck_ref",
.alias = "clkin",
.parent = &xtal_osc12m,
@@ -69,33 +90,33 @@ static struct clk ck_ref = {
};
/* If a dpll is disabled it becomes a bypass, child clocks don't stop */
-static struct clk dpll1 = {
+static struct ClkInfo dpll1 = {
.name = "dpll1",
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
ALWAYS_ENABLED,
};
-static struct clk dpll2 = {
+static struct ClkInfo dpll2 = {
.name = "dpll2",
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
};
-static struct clk dpll3 = {
+static struct ClkInfo dpll3 = {
.name = "dpll3",
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
};
-static struct clk dpll4 = {
+static struct ClkInfo dpll4 = {
.name = "dpll4",
.parent = &ck_ref,
.multiplier = 4,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk apll = {
+static struct ClkInfo apll = {
.name = "apll",
.parent = &ck_ref,
.multiplier = 48,
@@ -103,25 +124,25 @@ static struct clk apll = {
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk ck_48m = {
+static struct ClkInfo ck_48m = {
.name = "ck_48m",
.parent = &dpll4, /* either dpll4 or apll */
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk ck_dpll1out = {
+static struct ClkInfo ck_dpll1out = {
.name = "ck_dpll1out",
.parent = &dpll1,
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk sossi_ck = {
+static struct ClkInfo sossi_ck = {
.name = "ck_sossi",
.parent = &ck_dpll1out,
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk clkm1 = {
+static struct ClkInfo clkm1 = {
.name = "clkm1",
.alias = "ck_gen1",
.parent = &dpll1,
@@ -129,7 +150,7 @@ static struct clk clkm1 = {
ALWAYS_ENABLED,
};
-static struct clk clkm2 = {
+static struct ClkInfo clkm2 = {
.name = "clkm2",
.alias = "ck_gen2",
.parent = &dpll1,
@@ -137,7 +158,7 @@ static struct clk clkm2 = {
ALWAYS_ENABLED,
};
-static struct clk clkm3 = {
+static struct ClkInfo clkm3 = {
.name = "clkm3",
.alias = "ck_gen3",
.parent = &dpll1, /* either dpll1 or ck_ref */
@@ -145,7 +166,7 @@ static struct clk clkm3 = {
ALWAYS_ENABLED,
};
-static struct clk arm_ck = {
+static struct ClkInfo arm_ck = {
.name = "arm_ck",
.alias = "mpu_ck",
.parent = &clkm1,
@@ -153,14 +174,14 @@ static struct clk arm_ck = {
ALWAYS_ENABLED,
};
-static struct clk armper_ck = {
+static struct ClkInfo armper_ck = {
.name = "armper_ck",
.alias = "mpuper_ck",
.parent = &clkm1,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk arm_gpio_ck = {
+static struct ClkInfo arm_gpio_ck = {
.name = "arm_gpio_ck",
.alias = "mpu_gpio_ck",
.parent = &clkm1,
@@ -168,21 +189,21 @@ static struct clk arm_gpio_ck = {
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
};
-static struct clk armxor_ck = {
+static struct ClkInfo armxor_ck = {
.name = "armxor_ck",
.alias = "mpuxor_ck",
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk armtim_ck = {
+static struct ClkInfo armtim_ck = {
.name = "armtim_ck",
.alias = "mputim_ck",
.parent = &ck_ref, /* either CLKIN or DPLL1 */
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk armwdt_ck = {
+static struct ClkInfo armwdt_ck = {
.name = "armwdt_ck",
.alias = "mpuwd_ck",
.parent = &clkm1,
@@ -191,7 +212,7 @@ static struct clk armwdt_ck = {
ALWAYS_ENABLED,
};
-static struct clk arminth_ck16xx = {
+static struct ClkInfo arminth_ck16xx = {
.name = "arminth_ck",
.parent = &arm_ck,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
@@ -202,38 +223,38 @@ static struct clk arminth_ck16xx = {
*/
};
-static struct clk dsp_ck = {
+static struct ClkInfo dsp_ck = {
.name = "dsp_ck",
.parent = &clkm2,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
};
-static struct clk dspmmu_ck = {
+static struct ClkInfo dspmmu_ck = {
.name = "dspmmu_ck",
.parent = &clkm2,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
ALWAYS_ENABLED,
};
-static struct clk dspper_ck = {
+static struct ClkInfo dspper_ck = {
.name = "dspper_ck",
.parent = &clkm2,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
};
-static struct clk dspxor_ck = {
+static struct ClkInfo dspxor_ck = {
.name = "dspxor_ck",
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
};
-static struct clk dsptim_ck = {
+static struct ClkInfo dsptim_ck = {
.name = "dsptim_ck",
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
};
-static struct clk tc_ck = {
+static struct ClkInfo tc_ck = {
.name = "tc_ck",
.parent = &clkm3,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
@@ -241,7 +262,7 @@ static struct clk tc_ck = {
ALWAYS_ENABLED,
};
-static struct clk arminth_ck15xx = {
+static struct ClkInfo arminth_ck15xx = {
.name = "arminth_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
@@ -251,33 +272,33 @@ static struct clk arminth_ck15xx = {
*/
};
-static struct clk tipb_ck = {
+static struct ClkInfo tipb_ck = {
/* No-idle controlled by "tc_ck" */
.name = "tipb_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
};
-static struct clk l3_ocpi_ck = {
+static struct ClkInfo l3_ocpi_ck = {
/* No-idle controlled by "tc_ck" */
.name = "l3_ocpi_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk tc1_ck = {
+static struct ClkInfo tc1_ck = {
.name = "tc1_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk tc2_ck = {
+static struct ClkInfo tc2_ck = {
.name = "tc2_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk dma_ck = {
+static struct ClkInfo dma_ck = {
/* No-idle controlled by "tc_ck" */
.name = "dma_ck",
.parent = &tc_ck,
@@ -285,62 +306,62 @@ static struct clk dma_ck = {
ALWAYS_ENABLED,
};
-static struct clk dma_lcdfree_ck = {
+static struct ClkInfo dma_lcdfree_ck = {
.name = "dma_lcdfree_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
};
-static struct clk api_ck = {
+static struct ClkInfo api_ck = {
.name = "api_ck",
.alias = "mpui_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk lb_ck = {
+static struct ClkInfo lb_ck = {
.name = "lb_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
};
-static struct clk lbfree_ck = {
+static struct ClkInfo lbfree_ck = {
.name = "lbfree_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
};
-static struct clk hsab_ck = {
+static struct ClkInfo hsab_ck = {
.name = "hsab_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
};
-static struct clk rhea1_ck = {
+static struct ClkInfo rhea1_ck = {
.name = "rhea1_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
};
-static struct clk rhea2_ck = {
+static struct ClkInfo rhea2_ck = {
.name = "rhea2_ck",
.parent = &tc_ck,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
};
-static struct clk lcd_ck_16xx = {
+static struct ClkInfo lcd_ck_16xx = {
.name = "lcd_ck",
.parent = &clkm3,
.flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
};
-static struct clk lcd_ck_1510 = {
+static struct ClkInfo lcd_ck_1510 = {
.name = "lcd_ck",
.parent = &clkm3,
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
};
-static struct clk uart1_1510 = {
+static struct ClkInfo uart1_1510 = {
.name = "uart1_ck",
/* Direct from ULPD, no real parent */
.parent = &armper_ck, /* either armper_ck or dpll4 */
@@ -348,7 +369,7 @@ static struct clk uart1_1510 = {
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
};
-static struct clk uart1_16xx = {
+static struct ClkInfo uart1_16xx = {
.name = "uart1_ck",
/* Direct from ULPD, no real parent */
.parent = &armper_ck,
@@ -356,7 +377,7 @@ static struct clk uart1_16xx = {
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk uart2_ck = {
+static struct ClkInfo uart2_ck = {
.name = "uart2_ck",
/* Direct from ULPD, no real parent */
.parent = &armper_ck, /* either armper_ck or dpll4 */
@@ -365,7 +386,7 @@ static struct clk uart2_ck = {
ALWAYS_ENABLED,
};
-static struct clk uart3_1510 = {
+static struct ClkInfo uart3_1510 = {
.name = "uart3_ck",
/* Direct from ULPD, no real parent */
.parent = &armper_ck, /* either armper_ck or dpll4 */
@@ -373,7 +394,7 @@ static struct clk uart3_1510 = {
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
};
-static struct clk uart3_16xx = {
+static struct ClkInfo uart3_16xx = {
.name = "uart3_ck",
/* Direct from ULPD, no real parent */
.parent = &armper_ck,
@@ -381,7 +402,7 @@ static struct clk uart3_16xx = {
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
+static struct ClkInfo usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
.name = "usb_clk0",
.alias = "usb.clko",
/* Direct from ULPD, no parent */
@@ -389,14 +410,14 @@ static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk usb_hhc_ck1510 = {
+static struct ClkInfo usb_hhc_ck1510 = {
.name = "usb_hhc_ck",
/* Direct from ULPD, no parent */
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
};
-static struct clk usb_hhc_ck16xx = {
+static struct ClkInfo usb_hhc_ck16xx = {
.name = "usb_hhc_ck",
/* Direct from ULPD, no parent */
.rate = 48000000,
@@ -404,7 +425,7 @@ static struct clk usb_hhc_ck16xx = {
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk usb_w2fc_mclk = {
+static struct ClkInfo usb_w2fc_mclk = {
.name = "usb_w2fc_mclk",
.alias = "usb_w2fc_ck",
.parent = &ck_48m,
@@ -412,45 +433,45 @@ static struct clk usb_w2fc_mclk = {
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
};
-static struct clk mclk_1510 = {
+static struct ClkInfo mclk_1510 = {
.name = "mclk",
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510,
};
-static struct clk bclk_310 = {
+static struct ClkInfo bclk_310 = {
.name = "bt_mclk_out", /* Alias midi_mclk_out? */
.parent = &armper_ck,
.flags = CLOCK_IN_OMAP310,
};
-static struct clk mclk_310 = {
+static struct ClkInfo mclk_310 = {
.name = "com_mclk_out",
.parent = &armper_ck,
.flags = CLOCK_IN_OMAP310,
};
-static struct clk mclk_16xx = {
+static struct ClkInfo mclk_16xx = {
.name = "mclk",
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk bclk_1510 = {
+static struct ClkInfo bclk_1510 = {
.name = "bclk",
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
.flags = CLOCK_IN_OMAP1510,
};
-static struct clk bclk_16xx = {
+static struct ClkInfo bclk_16xx = {
.name = "bclk",
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk mmc1_ck = {
+static struct ClkInfo mmc1_ck = {
.name = "mmc_ck",
.id = 1,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
@@ -459,7 +480,7 @@ static struct clk mmc1_ck = {
.flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
};
-static struct clk mmc2_ck = {
+static struct ClkInfo mmc2_ck = {
.name = "mmc_ck",
.id = 2,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
@@ -468,25 +489,25 @@ static struct clk mmc2_ck = {
.flags = CLOCK_IN_OMAP16XX,
};
-static struct clk cam_mclk = {
+static struct ClkInfo cam_mclk = {
.name = "cam.mclk",
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
.rate = 12000000,
};
-static struct clk cam_exclk = {
+static struct ClkInfo cam_exclk = {
.name = "cam.exclk",
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
/* Either 12M from cam.mclk or 48M from dpll4 */
.parent = &cam_mclk,
};
-static struct clk cam_lclk = {
+static struct ClkInfo cam_lclk = {
.name = "cam.lclk",
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
};
-static struct clk i2c_fck = {
+static struct ClkInfo i2c_fck = {
.name = "i2c_fck",
.id = 1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
@@ -494,349 +515,349 @@ static struct clk i2c_fck = {
.parent = &armxor_ck,
};
-static struct clk i2c_ick = {
+static struct ClkInfo i2c_ick = {
.name = "i2c_ick",
.id = 1,
.flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.parent = &armper_ck,
};
-static struct clk clk32k = {
+static struct ClkInfo clk32k = {
.name = "clk32-kHz",
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.parent = &xtal_osc32k,
};
-static struct clk ref_clk = {
+static struct ClkInfo ref_clk = {
.name = "ref_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.rate = 12000000, /* 12 MHz or 13 MHz or 19.2 MHz */
/*.parent = sys.xtalin */
};
-static struct clk apll_96m = {
+static struct ClkInfo apll_96m = {
.name = "apll_96m",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.rate = 96000000,
/*.parent = ref_clk */
};
-static struct clk apll_54m = {
+static struct ClkInfo apll_54m = {
.name = "apll_54m",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.rate = 54000000,
/*.parent = ref_clk */
};
-static struct clk sys_clk = {
+static struct ClkInfo sys_clk = {
.name = "sys_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.rate = 32768,
/*.parent = sys.xtalin */
};
-static struct clk sleep_clk = {
+static struct ClkInfo sleep_clk = {
.name = "sleep_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.rate = 32768,
/*.parent = sys.xtalin */
};
-static struct clk dpll_ck = {
+static struct ClkInfo dpll_ck = {
.name = "dpll",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.parent = &ref_clk,
};
-static struct clk dpll_x2_ck = {
+static struct ClkInfo dpll_x2_ck = {
.name = "dpll_x2",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.parent = &ref_clk,
};
-static struct clk wdt1_sys_clk = {
+static struct ClkInfo wdt1_sys_clk = {
.name = "wdt1_sys_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
.rate = 32768,
/*.parent = sys.xtalin */
};
-static struct clk func_96m_clk = {
+static struct ClkInfo func_96m_clk = {
.name = "func_96m_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.divisor = 1,
.parent = &apll_96m,
};
-static struct clk func_48m_clk = {
+static struct ClkInfo func_48m_clk = {
.name = "func_48m_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.divisor = 2,
.parent = &apll_96m,
};
-static struct clk func_12m_clk = {
+static struct ClkInfo func_12m_clk = {
.name = "func_12m_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.divisor = 8,
.parent = &apll_96m,
};
-static struct clk func_54m_clk = {
+static struct ClkInfo func_54m_clk = {
.name = "func_54m_clk",
.flags = CLOCK_IN_OMAP242X,
.divisor = 1,
.parent = &apll_54m,
};
-static struct clk sys_clkout = {
+static struct ClkInfo sys_clkout = {
.name = "clkout",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk sys_clkout2 = {
+static struct ClkInfo sys_clkout2 = {
.name = "clkout2",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_clk = {
+static struct ClkInfo core_clk = {
.name = "core_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &dpll_x2_ck, /* Switchable between dpll_ck and clk32k */
};
-static struct clk l3_clk = {
+static struct ClkInfo l3_clk = {
.name = "l3_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_clk,
};
-static struct clk core_l4_iclk = {
+static struct ClkInfo core_l4_iclk = {
.name = "core_l4_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &l3_clk,
};
-static struct clk wu_l4_iclk = {
+static struct ClkInfo wu_l4_iclk = {
.name = "wu_l4_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &l3_clk,
};
-static struct clk core_l3_iclk = {
+static struct ClkInfo core_l3_iclk = {
.name = "core_l3_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_clk,
};
-static struct clk core_l4_usb_clk = {
+static struct ClkInfo core_l4_usb_clk = {
.name = "core_l4_usb_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &l3_clk,
};
-static struct clk wu_gpt1_clk = {
+static struct ClkInfo wu_gpt1_clk = {
.name = "wu_gpt1_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk wu_32k_clk = {
+static struct ClkInfo wu_32k_clk = {
.name = "wu_32k_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk uart1_fclk = {
+static struct ClkInfo uart1_fclk = {
.name = "uart1_fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &func_48m_clk,
};
-static struct clk uart1_iclk = {
+static struct ClkInfo uart1_iclk = {
.name = "uart1_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l4_iclk,
};
-static struct clk uart2_fclk = {
+static struct ClkInfo uart2_fclk = {
.name = "uart2_fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &func_48m_clk,
};
-static struct clk uart2_iclk = {
+static struct ClkInfo uart2_iclk = {
.name = "uart2_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l4_iclk,
};
-static struct clk uart3_fclk = {
+static struct ClkInfo uart3_fclk = {
.name = "uart3_fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &func_48m_clk,
};
-static struct clk uart3_iclk = {
+static struct ClkInfo uart3_iclk = {
.name = "uart3_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l4_iclk,
};
-static struct clk mpu_fclk = {
+static struct ClkInfo mpu_fclk = {
.name = "mpu_fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_clk,
};
-static struct clk mpu_iclk = {
+static struct ClkInfo mpu_iclk = {
.name = "mpu_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_clk,
};
-static struct clk int_m_fclk = {
+static struct ClkInfo int_m_fclk = {
.name = "int_m_fclk",
.alias = "mpu_intc_fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_clk,
};
-static struct clk int_m_iclk = {
+static struct ClkInfo int_m_iclk = {
.name = "int_m_iclk",
.alias = "mpu_intc_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_clk,
};
-static struct clk core_gpt2_clk = {
+static struct ClkInfo core_gpt2_clk = {
.name = "core_gpt2_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt3_clk = {
+static struct ClkInfo core_gpt3_clk = {
.name = "core_gpt3_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt4_clk = {
+static struct ClkInfo core_gpt4_clk = {
.name = "core_gpt4_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt5_clk = {
+static struct ClkInfo core_gpt5_clk = {
.name = "core_gpt5_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt6_clk = {
+static struct ClkInfo core_gpt6_clk = {
.name = "core_gpt6_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt7_clk = {
+static struct ClkInfo core_gpt7_clk = {
.name = "core_gpt7_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt8_clk = {
+static struct ClkInfo core_gpt8_clk = {
.name = "core_gpt8_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt9_clk = {
+static struct ClkInfo core_gpt9_clk = {
.name = "core_gpt9_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt10_clk = {
+static struct ClkInfo core_gpt10_clk = {
.name = "core_gpt10_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt11_clk = {
+static struct ClkInfo core_gpt11_clk = {
.name = "core_gpt11_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk core_gpt12_clk = {
+static struct ClkInfo core_gpt12_clk = {
.name = "core_gpt12_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &sys_clk,
};
-static struct clk mcbsp1_clk = {
+static struct ClkInfo mcbsp1_clk = {
.name = "mcbsp1_cg",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.divisor = 2,
.parent = &func_96m_clk,
};
-static struct clk mcbsp2_clk = {
+static struct ClkInfo mcbsp2_clk = {
.name = "mcbsp2_cg",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.divisor = 2,
.parent = &func_96m_clk,
};
-static struct clk emul_clk = {
+static struct ClkInfo emul_clk = {
.name = "emul_ck",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &func_54m_clk,
};
-static struct clk sdma_fclk = {
+static struct ClkInfo sdma_fclk = {
.name = "sdma_fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &l3_clk,
};
-static struct clk sdma_iclk = {
+static struct ClkInfo sdma_iclk = {
.name = "sdma_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l3_iclk, /* core_l4_iclk for the configuration port */
};
-static struct clk i2c1_fclk = {
+static struct ClkInfo i2c1_fclk = {
.name = "i2c1.fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &func_12m_clk,
.divisor = 1,
};
-static struct clk i2c1_iclk = {
+static struct ClkInfo i2c1_iclk = {
.name = "i2c1.iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l4_iclk,
};
-static struct clk i2c2_fclk = {
+static struct ClkInfo i2c2_fclk = {
.name = "i2c2.fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &func_12m_clk,
.divisor = 1,
};
-static struct clk i2c2_iclk = {
+static struct ClkInfo i2c2_iclk = {
.name = "i2c2.iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l4_iclk,
};
-static struct clk gpio_dbclk[5] = {
+static struct ClkInfo gpio_dbclk[5] = {
{
.name = "gpio1_dbclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
@@ -860,25 +881,25 @@ static struct clk gpio_dbclk[5] = {
},
};
-static struct clk gpio_iclk = {
+static struct ClkInfo gpio_iclk = {
.name = "gpio_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &wu_l4_iclk,
};
-static struct clk mmc_fck = {
+static struct ClkInfo mmc_fck = {
.name = "mmc_fclk",
.flags = CLOCK_IN_OMAP242X,
.parent = &func_96m_clk,
};
-static struct clk mmc_ick = {
+static struct ClkInfo mmc_ick = {
.name = "mmc_iclk",
.flags = CLOCK_IN_OMAP242X,
.parent = &core_l4_iclk,
};
-static struct clk spi_fclk[3] = {
+static struct ClkInfo spi_fclk[3] = {
{
.name = "spi1_fclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
@@ -894,7 +915,7 @@ static struct clk spi_fclk[3] = {
},
};
-static struct clk dss_clk[2] = {
+static struct ClkInfo dss_clk[2] = {
{
.name = "dss_clk1",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
@@ -906,25 +927,25 @@ static struct clk dss_clk[2] = {
},
};
-static struct clk dss_54m_clk = {
+static struct ClkInfo dss_54m_clk = {
.name = "dss_54m_clk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &func_54m_clk,
};
-static struct clk dss_l3_iclk = {
+static struct ClkInfo dss_l3_iclk = {
.name = "dss_l3_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l3_iclk,
};
-static struct clk dss_l4_iclk = {
+static struct ClkInfo dss_l4_iclk = {
.name = "dss_l4_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.parent = &core_l4_iclk,
};
-static struct clk spi_iclk[3] = {
+static struct ClkInfo spi_iclk[3] = {
{
.name = "spi1_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
@@ -940,14 +961,14 @@ static struct clk spi_iclk[3] = {
},
};
-static struct clk omapctrl_clk = {
+static struct ClkInfo omapctrl_clk = {
.name = "omapctrl_iclk",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
/* XXX Should be in WKUP domain */
.parent = &core_l4_iclk,
};
-static struct clk *onchip_clks[] = {
+static struct ClkInfo *onchip_clks[] = {
/* OMAP 1 */
/* non-ULPD clocks */
@@ -1219,7 +1240,9 @@ int64_t omap_clk_getrate(omap_clk clk)
void omap_clk_init(struct omap_mpu_state_s *mpu)
{
- struct clk **i, *j, *k;
+ Object *clocks;
+ struct ClkInfo **i;
+ struct clk *j;
int count;
int flag;
@@ -1236,29 +1259,57 @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
else
return;
- for (i = onchip_clks, count = 0; *i; i ++)
- if ((*i)->flags & flag)
- count ++;
+ clocks = object_new("container");
+ object_property_add_child(object_get_root(), "clocks",
+ clocks, NULL);
+
+ for (i = onchip_clks, count = 0; *i; i++) {
+ if ((*i)->flags & flag) {
+ count++;
+ }
+ }
mpu->clks = (struct clk *) g_malloc0(sizeof(struct clk) * (count + 1));
- for (i = onchip_clks, j = mpu->clks; *i; i ++)
+ for (i = onchip_clks, j = mpu->clks; *i; i++) {
+ if ((*i)->flags & flag) {
+ object_initialize(j, TYPE_OMAP_CLK);
+ j->name = (*i)->name;
+ j->alias = (*i)->alias;
+ j->flags = (*i)->flags;
+ j->id = (*i)->id;
+ j->rate = (*i)->rate;
+ j->divisor = (*i)->divisor ?: 1;
+ j->multiplier = (*i)->multiplier ?: 1;
+ object_property_add_child(clocks, j->name, OBJECT(j), NULL);
+ j++;
+ }
+ }
+
+ for (i = onchip_clks, j = mpu->clks; *i; i++) {
if ((*i)->flags & flag) {
- memcpy(j, *i, sizeof(struct clk));
- for (k = mpu->clks; k < j; k ++)
- if (j->parent && !strcmp(j->parent->name, k->name)) {
- j->parent = k;
- j->sibling = k->child1;
- k->child1 = j;
- } else if (k->parent && !strcmp(k->parent->name, j->name)) {
- k->parent = j;
- k->sibling = j->child1;
- j->child1 = k;
- }
- j->divisor = j->divisor ?: 1;
- j->multiplier = j->multiplier ?: 1;
- j ++;
+ if ((*i)->parent) {
+ j->parent = omap_findclk(mpu, (*i)->parent->name);
+ j->sibling = j->parent->child1;
+ j->parent->child1 = j;
+ }
+ j++;
}
- for (j = mpu->clks; count --; j ++) {
+ }
+
+ for (j = mpu->clks; count--; j++) {
omap_clk_update(j);
omap_clk_rate_update(j);
}
}
+
+void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
+ const char *name, const char *clk)
+{
+ struct clk *target = omap_findclk(s, clk);
+ qdev_prop_set_ptr(dev, name, target);
+}
+
+static void omap_clk_register(void)
+{
+ type_register_static(&omap_clk_info);
+}
+device_init(omap_clk_register)
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM Paolo Bonzini
@ 2012-02-06 14:42 ` Anthony Liguori
2012-02-06 16:32 ` Peter Maydell
1 sibling, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:42 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Peter Maydell, qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Make the OMAP clocks QOM objects, so that they we can put them in a branch
> of the object graph and turn the pointer properties into links.
>
> As in the current code, the clocks are copied into a freshly allocated
> memory block when they are initialized. However, the "templates" now
> have a separate struct definition because the header must be created
> anyway with object_initialize. The linking of children to parents
> is moved to a separate loop for simplicity.
>
> Cc: Peter Maydell<peter.maydell@linaro.org>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> hw/omap.h | 4 +
> hw/omap1.c | 6 +-
> hw/omap2.c | 16 ++--
> hw/omap_clk.c | 357 ++++++++++++++++++++++++++++++++------------------------
> 4 files changed, 219 insertions(+), 164 deletions(-)
>
> diff --git a/hw/omap.h b/hw/omap.h
> index 60fa34c..5c0f95a 100644
> --- a/hw/omap.h
> +++ b/hw/omap.h
> @@ -49,6 +49,8 @@
> # define OMAP_CS3_SIZE 0x04000000
>
> /* omap_clk.c */
> +#define TYPE_OMAP_CLK "omap-clk"
> +
> struct omap_mpu_state_s;
> typedef struct clk *omap_clk;
> omap_clk omap_findclk(struct omap_mpu_state_s *mpu, const char *name);
> @@ -61,6 +63,8 @@ void omap_clk_canidle(omap_clk clk, int can);
> void omap_clk_setrate(omap_clk clk, int divide, int multiply);
> int64_t omap_clk_getrate(omap_clk clk);
> void omap_clk_reparent(omap_clk clk, omap_clk parent);
> +void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
> + const char *name, const char *clk);
>
> /* OMAP2 l4 Interconnect */
> struct omap_l4_s;
> diff --git a/hw/omap1.c b/hw/omap1.c
> index 1aa5f23..12f1197 100644
> --- a/hw/omap1.c
> +++ b/hw/omap1.c
> @@ -3856,7 +3856,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
> cpu_irq = arm_pic_init_cpu(s->env);
> s->ih[0] = qdev_create(NULL, "omap-intc");
> qdev_prop_set_uint32(s->ih[0], "size", 0x100);
> - qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
> + omap_prop_set_clk(s, s->ih[0], "clk", "arminth_ck");
> qdev_init_nofail(s->ih[0]);
> busdev = sysbus_from_qdev(s->ih[0]);
> sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
> @@ -3864,7 +3864,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
> sysbus_mmio_map(busdev, 0, 0xfffecb00);
> s->ih[1] = qdev_create(NULL, "omap-intc");
> qdev_prop_set_uint32(s->ih[1], "size", 0x800);
> - qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
> + omap_prop_set_clk(s, s->ih[1], "clk", "arminth_ck");
> qdev_init_nofail(s->ih[1]);
> busdev = sysbus_from_qdev(s->ih[1]);
> sysbus_connect_irq(busdev, 0,
> @@ -3977,7 +3977,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
>
> s->gpio = qdev_create(NULL, "omap-gpio");
> qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
> - qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
> + omap_prop_set_clk(s, s->gpio, "clk", "arm_gpio_ck");
> qdev_init_nofail(s->gpio);
> sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0,
> qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
> diff --git a/hw/omap2.c b/hw/omap2.c
> index a6851b0..b1fe0d3 100644
> --- a/hw/omap2.c
> +++ b/hw/omap2.c
> @@ -2282,8 +2282,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
> cpu_irq = arm_pic_init_cpu(s->env);
> s->ih[0] = qdev_create(NULL, "omap2-intc");
> qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
> - qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
> - qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
> + omap_prop_set_clk(s, s->ih[0], "fclk", "mpu_intc_fclk");
> + omap_prop_set_clk(s, s->ih[0], "iclk", "mpu_intc_iclk");
> qdev_init_nofail(s->ih[0]);
> busdev = sysbus_from_qdev(s->ih[0]);
> sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
> @@ -2408,13 +2408,13 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
>
> s->gpio = qdev_create(NULL, "omap2-gpio");
> qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
> - qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk"));
> + omap_prop_set_clk(s, s->gpio, "iclk", "gpio_iclk");
> + omap_prop_set_clk(s, s->gpio, "fclk0", "gpio1_dbclk");
> + omap_prop_set_clk(s, s->gpio, "fclk1", "gpio2_dbclk");
> + omap_prop_set_clk(s, s->gpio, "fclk2", "gpio3_dbclk");
> + omap_prop_set_clk(s, s->gpio, "fclk3", "gpio4_dbclk");
> if (s->mpu_model == omap2430) {
> - qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk"));
> + omap_prop_set_clk(s, s->gpio, "fclk4", "gpio5_dbclk");
> }
> qdev_init_nofail(s->gpio);
> busdev = sysbus_from_qdev(s->gpio);
> diff --git a/hw/omap_clk.c b/hw/omap_clk.c
> index 8448006..c4c2b80 100644
> --- a/hw/omap_clk.c
> +++ b/hw/omap_clk.c
> @@ -19,14 +19,14 @@
> * with this program; if not, see<http://www.gnu.org/licenses/>.
> */
> #include "hw.h"
> +#include "qdev.h"
> #include "omap.h"
> +#include "qemu/object.h"
>
> -struct clk {
> +struct ClkInfo {
> const char *name;
> const char *alias;
> - struct clk *parent;
> - struct clk *child1;
> - struct clk *sibling;
> + struct ClkInfo *parent;
> #define ALWAYS_ENABLED (1<< 0)
> #define CLOCK_IN_OMAP310 (1<< 10)
> #define CLOCK_IN_OMAP730 (1<< 11)
> @@ -38,6 +38,21 @@ struct clk {
> uint32_t flags;
> int id;
>
> + unsigned long rate; /* Current rate (if .running) */
> + unsigned int divisor; /* Rate relative to input (if .enabled) */
> + unsigned int multiplier; /* Rate relative to input (if .enabled) */
> +};
> +
> +struct clk {
> + Object obj;
> + const char *name;
> + const char *alias;
> + struct clk *parent;
> + struct clk *child1;
> + struct clk *sibling;
> + uint32_t flags;
> + int id;
> +
> int running; /* Is currently ticking */
> int enabled; /* Is enabled, regardless of its input clk */
> unsigned long rate; /* Current rate (if .running) */
> @@ -47,20 +62,26 @@ struct clk {
> int usecount; /* Automatically idle when unused */
> };
>
> -static struct clk xtal_osc12m = {
> +static TypeInfo omap_clk_info = {
> + .name = TYPE_OMAP_CLK,
> + .parent = TYPE_OBJECT,
> + .instance_size = sizeof(struct clk),
> +};
> +
> +static struct ClkInfo xtal_osc12m = {
> .name = "xtal_osc_12m",
> .rate = 12000000,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk xtal_osc32k = {
> +static struct ClkInfo xtal_osc32k = {
> .name = "xtal_osc_32k",
> .rate = 32768,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
> CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> };
>
> -static struct clk ck_ref = {
> +static struct ClkInfo ck_ref = {
> .name = "ck_ref",
> .alias = "clkin",
> .parent =&xtal_osc12m,
> @@ -69,33 +90,33 @@ static struct clk ck_ref = {
> };
>
> /* If a dpll is disabled it becomes a bypass, child clocks don't stop */
> -static struct clk dpll1 = {
> +static struct ClkInfo dpll1 = {
> .name = "dpll1",
> .parent =&ck_ref,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
> ALWAYS_ENABLED,
> };
>
> -static struct clk dpll2 = {
> +static struct ClkInfo dpll2 = {
> .name = "dpll2",
> .parent =&ck_ref,
> .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk dpll3 = {
> +static struct ClkInfo dpll3 = {
> .name = "dpll3",
> .parent =&ck_ref,
> .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk dpll4 = {
> +static struct ClkInfo dpll4 = {
> .name = "dpll4",
> .parent =&ck_ref,
> .multiplier = 4,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk apll = {
> +static struct ClkInfo apll = {
> .name = "apll",
> .parent =&ck_ref,
> .multiplier = 48,
> @@ -103,25 +124,25 @@ static struct clk apll = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk ck_48m = {
> +static struct ClkInfo ck_48m = {
> .name = "ck_48m",
> .parent =&dpll4, /* either dpll4 or apll */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk ck_dpll1out = {
> +static struct ClkInfo ck_dpll1out = {
> .name = "ck_dpll1out",
> .parent =&dpll1,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk sossi_ck = {
> +static struct ClkInfo sossi_ck = {
> .name = "ck_sossi",
> .parent =&ck_dpll1out,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk clkm1 = {
> +static struct ClkInfo clkm1 = {
> .name = "clkm1",
> .alias = "ck_gen1",
> .parent =&dpll1,
> @@ -129,7 +150,7 @@ static struct clk clkm1 = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk clkm2 = {
> +static struct ClkInfo clkm2 = {
> .name = "clkm2",
> .alias = "ck_gen2",
> .parent =&dpll1,
> @@ -137,7 +158,7 @@ static struct clk clkm2 = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk clkm3 = {
> +static struct ClkInfo clkm3 = {
> .name = "clkm3",
> .alias = "ck_gen3",
> .parent =&dpll1, /* either dpll1 or ck_ref */
> @@ -145,7 +166,7 @@ static struct clk clkm3 = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk arm_ck = {
> +static struct ClkInfo arm_ck = {
> .name = "arm_ck",
> .alias = "mpu_ck",
> .parent =&clkm1,
> @@ -153,14 +174,14 @@ static struct clk arm_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk armper_ck = {
> +static struct ClkInfo armper_ck = {
> .name = "armper_ck",
> .alias = "mpuper_ck",
> .parent =&clkm1,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk arm_gpio_ck = {
> +static struct ClkInfo arm_gpio_ck = {
> .name = "arm_gpio_ck",
> .alias = "mpu_gpio_ck",
> .parent =&clkm1,
> @@ -168,21 +189,21 @@ static struct clk arm_gpio_ck = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk armxor_ck = {
> +static struct ClkInfo armxor_ck = {
> .name = "armxor_ck",
> .alias = "mpuxor_ck",
> .parent =&ck_ref,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk armtim_ck = {
> +static struct ClkInfo armtim_ck = {
> .name = "armtim_ck",
> .alias = "mputim_ck",
> .parent =&ck_ref, /* either CLKIN or DPLL1 */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk armwdt_ck = {
> +static struct ClkInfo armwdt_ck = {
> .name = "armwdt_ck",
> .alias = "mpuwd_ck",
> .parent =&clkm1,
> @@ -191,7 +212,7 @@ static struct clk armwdt_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk arminth_ck16xx = {
> +static struct ClkInfo arminth_ck16xx = {
> .name = "arminth_ck",
> .parent =&arm_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> @@ -202,38 +223,38 @@ static struct clk arminth_ck16xx = {
> */
> };
>
> -static struct clk dsp_ck = {
> +static struct ClkInfo dsp_ck = {
> .name = "dsp_ck",
> .parent =&clkm2,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dspmmu_ck = {
> +static struct ClkInfo dspmmu_ck = {
> .name = "dspmmu_ck",
> .parent =&clkm2,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> ALWAYS_ENABLED,
> };
>
> -static struct clk dspper_ck = {
> +static struct ClkInfo dspper_ck = {
> .name = "dspper_ck",
> .parent =&clkm2,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dspxor_ck = {
> +static struct ClkInfo dspxor_ck = {
> .name = "dspxor_ck",
> .parent =&ck_ref,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dsptim_ck = {
> +static struct ClkInfo dsptim_ck = {
> .name = "dsptim_ck",
> .parent =&ck_ref,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk tc_ck = {
> +static struct ClkInfo tc_ck = {
> .name = "tc_ck",
> .parent =&clkm3,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> @@ -241,7 +262,7 @@ static struct clk tc_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk arminth_ck15xx = {
> +static struct ClkInfo arminth_ck15xx = {
> .name = "arminth_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> @@ -251,33 +272,33 @@ static struct clk arminth_ck15xx = {
> */
> };
>
> -static struct clk tipb_ck = {
> +static struct ClkInfo tipb_ck = {
> /* No-idle controlled by "tc_ck" */
> .name = "tipb_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk l3_ocpi_ck = {
> +static struct ClkInfo l3_ocpi_ck = {
> /* No-idle controlled by "tc_ck" */
> .name = "l3_ocpi_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk tc1_ck = {
> +static struct ClkInfo tc1_ck = {
> .name = "tc1_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk tc2_ck = {
> +static struct ClkInfo tc2_ck = {
> .name = "tc2_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dma_ck = {
> +static struct ClkInfo dma_ck = {
> /* No-idle controlled by "tc_ck" */
> .name = "dma_ck",
> .parent =&tc_ck,
> @@ -285,62 +306,62 @@ static struct clk dma_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk dma_lcdfree_ck = {
> +static struct ClkInfo dma_lcdfree_ck = {
> .name = "dma_lcdfree_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> };
>
> -static struct clk api_ck = {
> +static struct ClkInfo api_ck = {
> .name = "api_ck",
> .alias = "mpui_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk lb_ck = {
> +static struct ClkInfo lb_ck = {
> .name = "lb_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk lbfree_ck = {
> +static struct ClkInfo lbfree_ck = {
> .name = "lbfree_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk hsab_ck = {
> +static struct ClkInfo hsab_ck = {
> .name = "hsab_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk rhea1_ck = {
> +static struct ClkInfo rhea1_ck = {
> .name = "rhea1_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> };
>
> -static struct clk rhea2_ck = {
> +static struct ClkInfo rhea2_ck = {
> .name = "rhea2_ck",
> .parent =&tc_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> };
>
> -static struct clk lcd_ck_16xx = {
> +static struct ClkInfo lcd_ck_16xx = {
> .name = "lcd_ck",
> .parent =&clkm3,
> .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
> };
>
> -static struct clk lcd_ck_1510 = {
> +static struct ClkInfo lcd_ck_1510 = {
> .name = "lcd_ck",
> .parent =&clkm3,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk uart1_1510 = {
> +static struct ClkInfo uart1_1510 = {
> .name = "uart1_ck",
> /* Direct from ULPD, no real parent */
> .parent =&armper_ck, /* either armper_ck or dpll4 */
> @@ -348,7 +369,7 @@ static struct clk uart1_1510 = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk uart1_16xx = {
> +static struct ClkInfo uart1_16xx = {
> .name = "uart1_ck",
> /* Direct from ULPD, no real parent */
> .parent =&armper_ck,
> @@ -356,7 +377,7 @@ static struct clk uart1_16xx = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk uart2_ck = {
> +static struct ClkInfo uart2_ck = {
> .name = "uart2_ck",
> /* Direct from ULPD, no real parent */
> .parent =&armper_ck, /* either armper_ck or dpll4 */
> @@ -365,7 +386,7 @@ static struct clk uart2_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk uart3_1510 = {
> +static struct ClkInfo uart3_1510 = {
> .name = "uart3_ck",
> /* Direct from ULPD, no real parent */
> .parent =&armper_ck, /* either armper_ck or dpll4 */
> @@ -373,7 +394,7 @@ static struct clk uart3_1510 = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk uart3_16xx = {
> +static struct ClkInfo uart3_16xx = {
> .name = "uart3_ck",
> /* Direct from ULPD, no real parent */
> .parent =&armper_ck,
> @@ -381,7 +402,7 @@ static struct clk uart3_16xx = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
> +static struct ClkInfo usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
> .name = "usb_clk0",
> .alias = "usb.clko",
> /* Direct from ULPD, no parent */
> @@ -389,14 +410,14 @@ static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk usb_hhc_ck1510 = {
> +static struct ClkInfo usb_hhc_ck1510 = {
> .name = "usb_hhc_ck",
> /* Direct from ULPD, no parent */
> .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk usb_hhc_ck16xx = {
> +static struct ClkInfo usb_hhc_ck16xx = {
> .name = "usb_hhc_ck",
> /* Direct from ULPD, no parent */
> .rate = 48000000,
> @@ -404,7 +425,7 @@ static struct clk usb_hhc_ck16xx = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk usb_w2fc_mclk = {
> +static struct ClkInfo usb_w2fc_mclk = {
> .name = "usb_w2fc_mclk",
> .alias = "usb_w2fc_ck",
> .parent =&ck_48m,
> @@ -412,45 +433,45 @@ static struct clk usb_w2fc_mclk = {
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk mclk_1510 = {
> +static struct ClkInfo mclk_1510 = {
> .name = "mclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .rate = 12000000,
> .flags = CLOCK_IN_OMAP1510,
> };
>
> -static struct clk bclk_310 = {
> +static struct ClkInfo bclk_310 = {
> .name = "bt_mclk_out", /* Alias midi_mclk_out? */
> .parent =&armper_ck,
> .flags = CLOCK_IN_OMAP310,
> };
>
> -static struct clk mclk_310 = {
> +static struct ClkInfo mclk_310 = {
> .name = "com_mclk_out",
> .parent =&armper_ck,
> .flags = CLOCK_IN_OMAP310,
> };
>
> -static struct clk mclk_16xx = {
> +static struct ClkInfo mclk_16xx = {
> .name = "mclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk bclk_1510 = {
> +static struct ClkInfo bclk_1510 = {
> .name = "bclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .rate = 12000000,
> .flags = CLOCK_IN_OMAP1510,
> };
>
> -static struct clk bclk_16xx = {
> +static struct ClkInfo bclk_16xx = {
> .name = "bclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk mmc1_ck = {
> +static struct ClkInfo mmc1_ck = {
> .name = "mmc_ck",
> .id = 1,
> /* Functional clock is direct from ULPD, interface clock is ARMPER */
> @@ -459,7 +480,7 @@ static struct clk mmc1_ck = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk mmc2_ck = {
> +static struct ClkInfo mmc2_ck = {
> .name = "mmc_ck",
> .id = 2,
> /* Functional clock is direct from ULPD, interface clock is ARMPER */
> @@ -468,25 +489,25 @@ static struct clk mmc2_ck = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk cam_mclk = {
> +static struct ClkInfo cam_mclk = {
> .name = "cam.mclk",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> .rate = 12000000,
> };
>
> -static struct clk cam_exclk = {
> +static struct ClkInfo cam_exclk = {
> .name = "cam.exclk",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> /* Either 12M from cam.mclk or 48M from dpll4 */
> .parent =&cam_mclk,
> };
>
> -static struct clk cam_lclk = {
> +static struct ClkInfo cam_lclk = {
> .name = "cam.lclk",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk i2c_fck = {
> +static struct ClkInfo i2c_fck = {
> .name = "i2c_fck",
> .id = 1,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> @@ -494,349 +515,349 @@ static struct clk i2c_fck = {
> .parent =&armxor_ck,
> };
>
> -static struct clk i2c_ick = {
> +static struct ClkInfo i2c_ick = {
> .name = "i2c_ick",
> .id = 1,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> .parent =&armper_ck,
> };
>
> -static struct clk clk32k = {
> +static struct ClkInfo clk32k = {
> .name = "clk32-kHz",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .parent =&xtal_osc32k,
> };
>
> -static struct clk ref_clk = {
> +static struct ClkInfo ref_clk = {
> .name = "ref_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 12000000, /* 12 MHz or 13 MHz or 19.2 MHz */
> /*.parent = sys.xtalin */
> };
>
> -static struct clk apll_96m = {
> +static struct ClkInfo apll_96m = {
> .name = "apll_96m",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 96000000,
> /*.parent = ref_clk */
> };
>
> -static struct clk apll_54m = {
> +static struct ClkInfo apll_54m = {
> .name = "apll_54m",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 54000000,
> /*.parent = ref_clk */
> };
>
> -static struct clk sys_clk = {
> +static struct ClkInfo sys_clk = {
> .name = "sys_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 32768,
> /*.parent = sys.xtalin */
> };
>
> -static struct clk sleep_clk = {
> +static struct ClkInfo sleep_clk = {
> .name = "sleep_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 32768,
> /*.parent = sys.xtalin */
> };
>
> -static struct clk dpll_ck = {
> +static struct ClkInfo dpll_ck = {
> .name = "dpll",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .parent =&ref_clk,
> };
>
> -static struct clk dpll_x2_ck = {
> +static struct ClkInfo dpll_x2_ck = {
> .name = "dpll_x2",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .parent =&ref_clk,
> };
>
> -static struct clk wdt1_sys_clk = {
> +static struct ClkInfo wdt1_sys_clk = {
> .name = "wdt1_sys_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 32768,
> /*.parent = sys.xtalin */
> };
>
> -static struct clk func_96m_clk = {
> +static struct ClkInfo func_96m_clk = {
> .name = "func_96m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 1,
> .parent =&apll_96m,
> };
>
> -static struct clk func_48m_clk = {
> +static struct ClkInfo func_48m_clk = {
> .name = "func_48m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 2,
> .parent =&apll_96m,
> };
>
> -static struct clk func_12m_clk = {
> +static struct ClkInfo func_12m_clk = {
> .name = "func_12m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 8,
> .parent =&apll_96m,
> };
>
> -static struct clk func_54m_clk = {
> +static struct ClkInfo func_54m_clk = {
> .name = "func_54m_clk",
> .flags = CLOCK_IN_OMAP242X,
> .divisor = 1,
> .parent =&apll_54m,
> };
>
> -static struct clk sys_clkout = {
> +static struct ClkInfo sys_clkout = {
> .name = "clkout",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk sys_clkout2 = {
> +static struct ClkInfo sys_clkout2 = {
> .name = "clkout2",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_clk = {
> +static struct ClkInfo core_clk = {
> .name = "core_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&dpll_x2_ck, /* Switchable between dpll_ck and clk32k */
> };
>
> -static struct clk l3_clk = {
> +static struct ClkInfo l3_clk = {
> .name = "l3_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_clk,
> };
>
> -static struct clk core_l4_iclk = {
> +static struct ClkInfo core_l4_iclk = {
> .name = "core_l4_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&l3_clk,
> };
>
> -static struct clk wu_l4_iclk = {
> +static struct ClkInfo wu_l4_iclk = {
> .name = "wu_l4_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&l3_clk,
> };
>
> -static struct clk core_l3_iclk = {
> +static struct ClkInfo core_l3_iclk = {
> .name = "core_l3_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_clk,
> };
>
> -static struct clk core_l4_usb_clk = {
> +static struct ClkInfo core_l4_usb_clk = {
> .name = "core_l4_usb_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&l3_clk,
> };
>
> -static struct clk wu_gpt1_clk = {
> +static struct ClkInfo wu_gpt1_clk = {
> .name = "wu_gpt1_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk wu_32k_clk = {
> +static struct ClkInfo wu_32k_clk = {
> .name = "wu_32k_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk uart1_fclk = {
> +static struct ClkInfo uart1_fclk = {
> .name = "uart1_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&func_48m_clk,
> };
>
> -static struct clk uart1_iclk = {
> +static struct ClkInfo uart1_iclk = {
> .name = "uart1_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l4_iclk,
> };
>
> -static struct clk uart2_fclk = {
> +static struct ClkInfo uart2_fclk = {
> .name = "uart2_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&func_48m_clk,
> };
>
> -static struct clk uart2_iclk = {
> +static struct ClkInfo uart2_iclk = {
> .name = "uart2_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l4_iclk,
> };
>
> -static struct clk uart3_fclk = {
> +static struct ClkInfo uart3_fclk = {
> .name = "uart3_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&func_48m_clk,
> };
>
> -static struct clk uart3_iclk = {
> +static struct ClkInfo uart3_iclk = {
> .name = "uart3_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l4_iclk,
> };
>
> -static struct clk mpu_fclk = {
> +static struct ClkInfo mpu_fclk = {
> .name = "mpu_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_clk,
> };
>
> -static struct clk mpu_iclk = {
> +static struct ClkInfo mpu_iclk = {
> .name = "mpu_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_clk,
> };
>
> -static struct clk int_m_fclk = {
> +static struct ClkInfo int_m_fclk = {
> .name = "int_m_fclk",
> .alias = "mpu_intc_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_clk,
> };
>
> -static struct clk int_m_iclk = {
> +static struct ClkInfo int_m_iclk = {
> .name = "int_m_iclk",
> .alias = "mpu_intc_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_clk,
> };
>
> -static struct clk core_gpt2_clk = {
> +static struct ClkInfo core_gpt2_clk = {
> .name = "core_gpt2_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt3_clk = {
> +static struct ClkInfo core_gpt3_clk = {
> .name = "core_gpt3_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt4_clk = {
> +static struct ClkInfo core_gpt4_clk = {
> .name = "core_gpt4_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt5_clk = {
> +static struct ClkInfo core_gpt5_clk = {
> .name = "core_gpt5_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt6_clk = {
> +static struct ClkInfo core_gpt6_clk = {
> .name = "core_gpt6_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt7_clk = {
> +static struct ClkInfo core_gpt7_clk = {
> .name = "core_gpt7_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt8_clk = {
> +static struct ClkInfo core_gpt8_clk = {
> .name = "core_gpt8_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt9_clk = {
> +static struct ClkInfo core_gpt9_clk = {
> .name = "core_gpt9_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt10_clk = {
> +static struct ClkInfo core_gpt10_clk = {
> .name = "core_gpt10_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt11_clk = {
> +static struct ClkInfo core_gpt11_clk = {
> .name = "core_gpt11_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk core_gpt12_clk = {
> +static struct ClkInfo core_gpt12_clk = {
> .name = "core_gpt12_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&sys_clk,
> };
>
> -static struct clk mcbsp1_clk = {
> +static struct ClkInfo mcbsp1_clk = {
> .name = "mcbsp1_cg",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 2,
> .parent =&func_96m_clk,
> };
>
> -static struct clk mcbsp2_clk = {
> +static struct ClkInfo mcbsp2_clk = {
> .name = "mcbsp2_cg",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 2,
> .parent =&func_96m_clk,
> };
>
> -static struct clk emul_clk = {
> +static struct ClkInfo emul_clk = {
> .name = "emul_ck",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&func_54m_clk,
> };
>
> -static struct clk sdma_fclk = {
> +static struct ClkInfo sdma_fclk = {
> .name = "sdma_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&l3_clk,
> };
>
> -static struct clk sdma_iclk = {
> +static struct ClkInfo sdma_iclk = {
> .name = "sdma_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l3_iclk, /* core_l4_iclk for the configuration port */
> };
>
> -static struct clk i2c1_fclk = {
> +static struct ClkInfo i2c1_fclk = {
> .name = "i2c1.fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&func_12m_clk,
> .divisor = 1,
> };
>
> -static struct clk i2c1_iclk = {
> +static struct ClkInfo i2c1_iclk = {
> .name = "i2c1.iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l4_iclk,
> };
>
> -static struct clk i2c2_fclk = {
> +static struct ClkInfo i2c2_fclk = {
> .name = "i2c2.fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&func_12m_clk,
> .divisor = 1,
> };
>
> -static struct clk i2c2_iclk = {
> +static struct ClkInfo i2c2_iclk = {
> .name = "i2c2.iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l4_iclk,
> };
>
> -static struct clk gpio_dbclk[5] = {
> +static struct ClkInfo gpio_dbclk[5] = {
> {
> .name = "gpio1_dbclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -860,25 +881,25 @@ static struct clk gpio_dbclk[5] = {
> },
> };
>
> -static struct clk gpio_iclk = {
> +static struct ClkInfo gpio_iclk = {
> .name = "gpio_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&wu_l4_iclk,
> };
>
> -static struct clk mmc_fck = {
> +static struct ClkInfo mmc_fck = {
> .name = "mmc_fclk",
> .flags = CLOCK_IN_OMAP242X,
> .parent =&func_96m_clk,
> };
>
> -static struct clk mmc_ick = {
> +static struct ClkInfo mmc_ick = {
> .name = "mmc_iclk",
> .flags = CLOCK_IN_OMAP242X,
> .parent =&core_l4_iclk,
> };
>
> -static struct clk spi_fclk[3] = {
> +static struct ClkInfo spi_fclk[3] = {
> {
> .name = "spi1_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -894,7 +915,7 @@ static struct clk spi_fclk[3] = {
> },
> };
>
> -static struct clk dss_clk[2] = {
> +static struct ClkInfo dss_clk[2] = {
> {
> .name = "dss_clk1",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -906,25 +927,25 @@ static struct clk dss_clk[2] = {
> },
> };
>
> -static struct clk dss_54m_clk = {
> +static struct ClkInfo dss_54m_clk = {
> .name = "dss_54m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&func_54m_clk,
> };
>
> -static struct clk dss_l3_iclk = {
> +static struct ClkInfo dss_l3_iclk = {
> .name = "dss_l3_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l3_iclk,
> };
>
> -static struct clk dss_l4_iclk = {
> +static struct ClkInfo dss_l4_iclk = {
> .name = "dss_l4_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent =&core_l4_iclk,
> };
>
> -static struct clk spi_iclk[3] = {
> +static struct ClkInfo spi_iclk[3] = {
> {
> .name = "spi1_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -940,14 +961,14 @@ static struct clk spi_iclk[3] = {
> },
> };
>
> -static struct clk omapctrl_clk = {
> +static struct ClkInfo omapctrl_clk = {
> .name = "omapctrl_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> /* XXX Should be in WKUP domain */
> .parent =&core_l4_iclk,
> };
>
> -static struct clk *onchip_clks[] = {
> +static struct ClkInfo *onchip_clks[] = {
> /* OMAP 1 */
>
> /* non-ULPD clocks */
> @@ -1219,7 +1240,9 @@ int64_t omap_clk_getrate(omap_clk clk)
>
> void omap_clk_init(struct omap_mpu_state_s *mpu)
> {
> - struct clk **i, *j, *k;
> + Object *clocks;
> + struct ClkInfo **i;
> + struct clk *j;
> int count;
> int flag;
>
> @@ -1236,29 +1259,57 @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
> else
> return;
>
> - for (i = onchip_clks, count = 0; *i; i ++)
> - if ((*i)->flags& flag)
> - count ++;
> + clocks = object_new("container");
> + object_property_add_child(object_get_root(), "clocks",
> + clocks, NULL);
I don't know that hanging this off of /clocks is the right approach. Obviously,
we can change it down the road but the tree is supposed to reflect some sort of
logical hierarchy.
If I understand it correctly, we're creating a clock object for any possible
clock even if the device isn't using it? It's hard to tell as this code is, er,
special :-)
At any rate, it would be nice to reflect a better hierarchy here. Just a FIXME
comment would be appropriate for now IMHO.
Regards,
Anthony Liguori
> +
> + for (i = onchip_clks, count = 0; *i; i++) {
> + if ((*i)->flags& flag) {
> + count++;
> + }
> + }
> mpu->clks = (struct clk *) g_malloc0(sizeof(struct clk) * (count + 1));
> - for (i = onchip_clks, j = mpu->clks; *i; i ++)
> + for (i = onchip_clks, j = mpu->clks; *i; i++) {
> + if ((*i)->flags& flag) {
> + object_initialize(j, TYPE_OMAP_CLK);
> + j->name = (*i)->name;
> + j->alias = (*i)->alias;
> + j->flags = (*i)->flags;
> + j->id = (*i)->id;
> + j->rate = (*i)->rate;
> + j->divisor = (*i)->divisor ?: 1;
> + j->multiplier = (*i)->multiplier ?: 1;
> + object_property_add_child(clocks, j->name, OBJECT(j), NULL);
> + j++;
> + }
> + }
> +
> + for (i = onchip_clks, j = mpu->clks; *i; i++) {
> if ((*i)->flags& flag) {
> - memcpy(j, *i, sizeof(struct clk));
> - for (k = mpu->clks; k< j; k ++)
> - if (j->parent&& !strcmp(j->parent->name, k->name)) {
> - j->parent = k;
> - j->sibling = k->child1;
> - k->child1 = j;
> - } else if (k->parent&& !strcmp(k->parent->name, j->name)) {
> - k->parent = j;
> - k->sibling = j->child1;
> - j->child1 = k;
> - }
> - j->divisor = j->divisor ?: 1;
> - j->multiplier = j->multiplier ?: 1;
> - j ++;
> + if ((*i)->parent) {
> + j->parent = omap_findclk(mpu, (*i)->parent->name);
> + j->sibling = j->parent->child1;
> + j->parent->child1 = j;
> + }
> + j++;
> }
> - for (j = mpu->clks; count --; j ++) {
> + }
> +
> + for (j = mpu->clks; count--; j++) {
> omap_clk_update(j);
> omap_clk_rate_update(j);
> }
> }
> +
> +void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
> + const char *name, const char *clk)
> +{
> + struct clk *target = omap_findclk(s, clk);
> + qdev_prop_set_ptr(dev, name, target);
> +}
> +
> +static void omap_clk_register(void)
> +{
> + type_register_static(&omap_clk_info);
> +}
> +device_init(omap_clk_register)
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM Paolo Bonzini
2012-02-06 14:42 ` Anthony Liguori
@ 2012-02-06 16:32 ` Peter Maydell
1 sibling, 0 replies; 62+ messages in thread
From: Peter Maydell @ 2012-02-06 16:32 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
cc'ing Andrzej who also has some interest in the omap platforms.
-- PMM
On 4 February 2012 08:02, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Make the OMAP clocks QOM objects, so that they we can put them in a branch
> of the object graph and turn the pointer properties into links.
>
> As in the current code, the clocks are copied into a freshly allocated
> memory block when they are initialized. However, the "templates" now
> have a separate struct definition because the header must be created
> anyway with object_initialize. The linking of children to parents
> is moved to a separate loop for simplicity.
>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> hw/omap.h | 4 +
> hw/omap1.c | 6 +-
> hw/omap2.c | 16 ++--
> hw/omap_clk.c | 357 ++++++++++++++++++++++++++++++++------------------------
> 4 files changed, 219 insertions(+), 164 deletions(-)
>
> diff --git a/hw/omap.h b/hw/omap.h
> index 60fa34c..5c0f95a 100644
> --- a/hw/omap.h
> +++ b/hw/omap.h
> @@ -49,6 +49,8 @@
> # define OMAP_CS3_SIZE 0x04000000
>
> /* omap_clk.c */
> +#define TYPE_OMAP_CLK "omap-clk"
> +
> struct omap_mpu_state_s;
> typedef struct clk *omap_clk;
> omap_clk omap_findclk(struct omap_mpu_state_s *mpu, const char *name);
> @@ -61,6 +63,8 @@ void omap_clk_canidle(omap_clk clk, int can);
> void omap_clk_setrate(omap_clk clk, int divide, int multiply);
> int64_t omap_clk_getrate(omap_clk clk);
> void omap_clk_reparent(omap_clk clk, omap_clk parent);
> +void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
> + const char *name, const char *clk);
>
> /* OMAP2 l4 Interconnect */
> struct omap_l4_s;
> diff --git a/hw/omap1.c b/hw/omap1.c
> index 1aa5f23..12f1197 100644
> --- a/hw/omap1.c
> +++ b/hw/omap1.c
> @@ -3856,7 +3856,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
> cpu_irq = arm_pic_init_cpu(s->env);
> s->ih[0] = qdev_create(NULL, "omap-intc");
> qdev_prop_set_uint32(s->ih[0], "size", 0x100);
> - qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
> + omap_prop_set_clk(s, s->ih[0], "clk", "arminth_ck");
> qdev_init_nofail(s->ih[0]);
> busdev = sysbus_from_qdev(s->ih[0]);
> sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
> @@ -3864,7 +3864,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
> sysbus_mmio_map(busdev, 0, 0xfffecb00);
> s->ih[1] = qdev_create(NULL, "omap-intc");
> qdev_prop_set_uint32(s->ih[1], "size", 0x800);
> - qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
> + omap_prop_set_clk(s, s->ih[1], "clk", "arminth_ck");
> qdev_init_nofail(s->ih[1]);
> busdev = sysbus_from_qdev(s->ih[1]);
> sysbus_connect_irq(busdev, 0,
> @@ -3977,7 +3977,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
>
> s->gpio = qdev_create(NULL, "omap-gpio");
> qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
> - qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
> + omap_prop_set_clk(s, s->gpio, "clk", "arm_gpio_ck");
> qdev_init_nofail(s->gpio);
> sysbus_connect_irq(sysbus_from_qdev(s->gpio), 0,
> qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
> diff --git a/hw/omap2.c b/hw/omap2.c
> index a6851b0..b1fe0d3 100644
> --- a/hw/omap2.c
> +++ b/hw/omap2.c
> @@ -2282,8 +2282,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
> cpu_irq = arm_pic_init_cpu(s->env);
> s->ih[0] = qdev_create(NULL, "omap2-intc");
> qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
> - qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
> - qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
> + omap_prop_set_clk(s, s->ih[0], "fclk", "mpu_intc_fclk");
> + omap_prop_set_clk(s, s->ih[0], "iclk", "mpu_intc_iclk");
> qdev_init_nofail(s->ih[0]);
> busdev = sysbus_from_qdev(s->ih[0]);
> sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
> @@ -2408,13 +2408,13 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
>
> s->gpio = qdev_create(NULL, "omap2-gpio");
> qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
> - qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk"));
> - qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk"));
> + omap_prop_set_clk(s, s->gpio, "iclk", "gpio_iclk");
> + omap_prop_set_clk(s, s->gpio, "fclk0", "gpio1_dbclk");
> + omap_prop_set_clk(s, s->gpio, "fclk1", "gpio2_dbclk");
> + omap_prop_set_clk(s, s->gpio, "fclk2", "gpio3_dbclk");
> + omap_prop_set_clk(s, s->gpio, "fclk3", "gpio4_dbclk");
> if (s->mpu_model == omap2430) {
> - qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk"));
> + omap_prop_set_clk(s, s->gpio, "fclk4", "gpio5_dbclk");
> }
> qdev_init_nofail(s->gpio);
> busdev = sysbus_from_qdev(s->gpio);
> diff --git a/hw/omap_clk.c b/hw/omap_clk.c
> index 8448006..c4c2b80 100644
> --- a/hw/omap_clk.c
> +++ b/hw/omap_clk.c
> @@ -19,14 +19,14 @@
> * with this program; if not, see <http://www.gnu.org/licenses/>.
> */
> #include "hw.h"
> +#include "qdev.h"
> #include "omap.h"
> +#include "qemu/object.h"
>
> -struct clk {
> +struct ClkInfo {
> const char *name;
> const char *alias;
> - struct clk *parent;
> - struct clk *child1;
> - struct clk *sibling;
> + struct ClkInfo *parent;
> #define ALWAYS_ENABLED (1 << 0)
> #define CLOCK_IN_OMAP310 (1 << 10)
> #define CLOCK_IN_OMAP730 (1 << 11)
> @@ -38,6 +38,21 @@ struct clk {
> uint32_t flags;
> int id;
>
> + unsigned long rate; /* Current rate (if .running) */
> + unsigned int divisor; /* Rate relative to input (if .enabled) */
> + unsigned int multiplier; /* Rate relative to input (if .enabled) */
> +};
> +
> +struct clk {
> + Object obj;
> + const char *name;
> + const char *alias;
> + struct clk *parent;
> + struct clk *child1;
> + struct clk *sibling;
> + uint32_t flags;
> + int id;
> +
> int running; /* Is currently ticking */
> int enabled; /* Is enabled, regardless of its input clk */
> unsigned long rate; /* Current rate (if .running) */
> @@ -47,20 +62,26 @@ struct clk {
> int usecount; /* Automatically idle when unused */
> };
>
> -static struct clk xtal_osc12m = {
> +static TypeInfo omap_clk_info = {
> + .name = TYPE_OMAP_CLK,
> + .parent = TYPE_OBJECT,
> + .instance_size = sizeof(struct clk),
> +};
> +
> +static struct ClkInfo xtal_osc12m = {
> .name = "xtal_osc_12m",
> .rate = 12000000,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk xtal_osc32k = {
> +static struct ClkInfo xtal_osc32k = {
> .name = "xtal_osc_32k",
> .rate = 32768,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
> CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> };
>
> -static struct clk ck_ref = {
> +static struct ClkInfo ck_ref = {
> .name = "ck_ref",
> .alias = "clkin",
> .parent = &xtal_osc12m,
> @@ -69,33 +90,33 @@ static struct clk ck_ref = {
> };
>
> /* If a dpll is disabled it becomes a bypass, child clocks don't stop */
> -static struct clk dpll1 = {
> +static struct ClkInfo dpll1 = {
> .name = "dpll1",
> .parent = &ck_ref,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
> ALWAYS_ENABLED,
> };
>
> -static struct clk dpll2 = {
> +static struct ClkInfo dpll2 = {
> .name = "dpll2",
> .parent = &ck_ref,
> .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk dpll3 = {
> +static struct ClkInfo dpll3 = {
> .name = "dpll3",
> .parent = &ck_ref,
> .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk dpll4 = {
> +static struct ClkInfo dpll4 = {
> .name = "dpll4",
> .parent = &ck_ref,
> .multiplier = 4,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk apll = {
> +static struct ClkInfo apll = {
> .name = "apll",
> .parent = &ck_ref,
> .multiplier = 48,
> @@ -103,25 +124,25 @@ static struct clk apll = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk ck_48m = {
> +static struct ClkInfo ck_48m = {
> .name = "ck_48m",
> .parent = &dpll4, /* either dpll4 or apll */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk ck_dpll1out = {
> +static struct ClkInfo ck_dpll1out = {
> .name = "ck_dpll1out",
> .parent = &dpll1,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk sossi_ck = {
> +static struct ClkInfo sossi_ck = {
> .name = "ck_sossi",
> .parent = &ck_dpll1out,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk clkm1 = {
> +static struct ClkInfo clkm1 = {
> .name = "clkm1",
> .alias = "ck_gen1",
> .parent = &dpll1,
> @@ -129,7 +150,7 @@ static struct clk clkm1 = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk clkm2 = {
> +static struct ClkInfo clkm2 = {
> .name = "clkm2",
> .alias = "ck_gen2",
> .parent = &dpll1,
> @@ -137,7 +158,7 @@ static struct clk clkm2 = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk clkm3 = {
> +static struct ClkInfo clkm3 = {
> .name = "clkm3",
> .alias = "ck_gen3",
> .parent = &dpll1, /* either dpll1 or ck_ref */
> @@ -145,7 +166,7 @@ static struct clk clkm3 = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk arm_ck = {
> +static struct ClkInfo arm_ck = {
> .name = "arm_ck",
> .alias = "mpu_ck",
> .parent = &clkm1,
> @@ -153,14 +174,14 @@ static struct clk arm_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk armper_ck = {
> +static struct ClkInfo armper_ck = {
> .name = "armper_ck",
> .alias = "mpuper_ck",
> .parent = &clkm1,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk arm_gpio_ck = {
> +static struct ClkInfo arm_gpio_ck = {
> .name = "arm_gpio_ck",
> .alias = "mpu_gpio_ck",
> .parent = &clkm1,
> @@ -168,21 +189,21 @@ static struct clk arm_gpio_ck = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk armxor_ck = {
> +static struct ClkInfo armxor_ck = {
> .name = "armxor_ck",
> .alias = "mpuxor_ck",
> .parent = &ck_ref,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk armtim_ck = {
> +static struct ClkInfo armtim_ck = {
> .name = "armtim_ck",
> .alias = "mputim_ck",
> .parent = &ck_ref, /* either CLKIN or DPLL1 */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk armwdt_ck = {
> +static struct ClkInfo armwdt_ck = {
> .name = "armwdt_ck",
> .alias = "mpuwd_ck",
> .parent = &clkm1,
> @@ -191,7 +212,7 @@ static struct clk armwdt_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk arminth_ck16xx = {
> +static struct ClkInfo arminth_ck16xx = {
> .name = "arminth_ck",
> .parent = &arm_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> @@ -202,38 +223,38 @@ static struct clk arminth_ck16xx = {
> */
> };
>
> -static struct clk dsp_ck = {
> +static struct ClkInfo dsp_ck = {
> .name = "dsp_ck",
> .parent = &clkm2,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dspmmu_ck = {
> +static struct ClkInfo dspmmu_ck = {
> .name = "dspmmu_ck",
> .parent = &clkm2,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> ALWAYS_ENABLED,
> };
>
> -static struct clk dspper_ck = {
> +static struct ClkInfo dspper_ck = {
> .name = "dspper_ck",
> .parent = &clkm2,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dspxor_ck = {
> +static struct ClkInfo dspxor_ck = {
> .name = "dspxor_ck",
> .parent = &ck_ref,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dsptim_ck = {
> +static struct ClkInfo dsptim_ck = {
> .name = "dsptim_ck",
> .parent = &ck_ref,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk tc_ck = {
> +static struct ClkInfo tc_ck = {
> .name = "tc_ck",
> .parent = &clkm3,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> @@ -241,7 +262,7 @@ static struct clk tc_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk arminth_ck15xx = {
> +static struct ClkInfo arminth_ck15xx = {
> .name = "arminth_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> @@ -251,33 +272,33 @@ static struct clk arminth_ck15xx = {
> */
> };
>
> -static struct clk tipb_ck = {
> +static struct ClkInfo tipb_ck = {
> /* No-idle controlled by "tc_ck" */
> .name = "tipb_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk l3_ocpi_ck = {
> +static struct ClkInfo l3_ocpi_ck = {
> /* No-idle controlled by "tc_ck" */
> .name = "l3_ocpi_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk tc1_ck = {
> +static struct ClkInfo tc1_ck = {
> .name = "tc1_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk tc2_ck = {
> +static struct ClkInfo tc2_ck = {
> .name = "tc2_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk dma_ck = {
> +static struct ClkInfo dma_ck = {
> /* No-idle controlled by "tc_ck" */
> .name = "dma_ck",
> .parent = &tc_ck,
> @@ -285,62 +306,62 @@ static struct clk dma_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk dma_lcdfree_ck = {
> +static struct ClkInfo dma_lcdfree_ck = {
> .name = "dma_lcdfree_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> };
>
> -static struct clk api_ck = {
> +static struct ClkInfo api_ck = {
> .name = "api_ck",
> .alias = "mpui_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk lb_ck = {
> +static struct ClkInfo lb_ck = {
> .name = "lb_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk lbfree_ck = {
> +static struct ClkInfo lbfree_ck = {
> .name = "lbfree_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk hsab_ck = {
> +static struct ClkInfo hsab_ck = {
> .name = "hsab_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk rhea1_ck = {
> +static struct ClkInfo rhea1_ck = {
> .name = "rhea1_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> };
>
> -static struct clk rhea2_ck = {
> +static struct ClkInfo rhea2_ck = {
> .name = "rhea2_ck",
> .parent = &tc_ck,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> };
>
> -static struct clk lcd_ck_16xx = {
> +static struct ClkInfo lcd_ck_16xx = {
> .name = "lcd_ck",
> .parent = &clkm3,
> .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
> };
>
> -static struct clk lcd_ck_1510 = {
> +static struct ClkInfo lcd_ck_1510 = {
> .name = "lcd_ck",
> .parent = &clkm3,
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk uart1_1510 = {
> +static struct ClkInfo uart1_1510 = {
> .name = "uart1_ck",
> /* Direct from ULPD, no real parent */
> .parent = &armper_ck, /* either armper_ck or dpll4 */
> @@ -348,7 +369,7 @@ static struct clk uart1_1510 = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk uart1_16xx = {
> +static struct ClkInfo uart1_16xx = {
> .name = "uart1_ck",
> /* Direct from ULPD, no real parent */
> .parent = &armper_ck,
> @@ -356,7 +377,7 @@ static struct clk uart1_16xx = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk uart2_ck = {
> +static struct ClkInfo uart2_ck = {
> .name = "uart2_ck",
> /* Direct from ULPD, no real parent */
> .parent = &armper_ck, /* either armper_ck or dpll4 */
> @@ -365,7 +386,7 @@ static struct clk uart2_ck = {
> ALWAYS_ENABLED,
> };
>
> -static struct clk uart3_1510 = {
> +static struct ClkInfo uart3_1510 = {
> .name = "uart3_ck",
> /* Direct from ULPD, no real parent */
> .parent = &armper_ck, /* either armper_ck or dpll4 */
> @@ -373,7 +394,7 @@ static struct clk uart3_1510 = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
> };
>
> -static struct clk uart3_16xx = {
> +static struct ClkInfo uart3_16xx = {
> .name = "uart3_ck",
> /* Direct from ULPD, no real parent */
> .parent = &armper_ck,
> @@ -381,7 +402,7 @@ static struct clk uart3_16xx = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
> +static struct ClkInfo usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
> .name = "usb_clk0",
> .alias = "usb.clko",
> /* Direct from ULPD, no parent */
> @@ -389,14 +410,14 @@ static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk usb_hhc_ck1510 = {
> +static struct ClkInfo usb_hhc_ck1510 = {
> .name = "usb_hhc_ck",
> /* Direct from ULPD, no parent */
> .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
> };
>
> -static struct clk usb_hhc_ck16xx = {
> +static struct ClkInfo usb_hhc_ck16xx = {
> .name = "usb_hhc_ck",
> /* Direct from ULPD, no parent */
> .rate = 48000000,
> @@ -404,7 +425,7 @@ static struct clk usb_hhc_ck16xx = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk usb_w2fc_mclk = {
> +static struct ClkInfo usb_w2fc_mclk = {
> .name = "usb_w2fc_mclk",
> .alias = "usb_w2fc_ck",
> .parent = &ck_48m,
> @@ -412,45 +433,45 @@ static struct clk usb_w2fc_mclk = {
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk mclk_1510 = {
> +static struct ClkInfo mclk_1510 = {
> .name = "mclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .rate = 12000000,
> .flags = CLOCK_IN_OMAP1510,
> };
>
> -static struct clk bclk_310 = {
> +static struct ClkInfo bclk_310 = {
> .name = "bt_mclk_out", /* Alias midi_mclk_out? */
> .parent = &armper_ck,
> .flags = CLOCK_IN_OMAP310,
> };
>
> -static struct clk mclk_310 = {
> +static struct ClkInfo mclk_310 = {
> .name = "com_mclk_out",
> .parent = &armper_ck,
> .flags = CLOCK_IN_OMAP310,
> };
>
> -static struct clk mclk_16xx = {
> +static struct ClkInfo mclk_16xx = {
> .name = "mclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk bclk_1510 = {
> +static struct ClkInfo bclk_1510 = {
> .name = "bclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .rate = 12000000,
> .flags = CLOCK_IN_OMAP1510,
> };
>
> -static struct clk bclk_16xx = {
> +static struct ClkInfo bclk_16xx = {
> .name = "bclk",
> /* Direct from ULPD, no parent. May be enabled by ext hardware. */
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk mmc1_ck = {
> +static struct ClkInfo mmc1_ck = {
> .name = "mmc_ck",
> .id = 1,
> /* Functional clock is direct from ULPD, interface clock is ARMPER */
> @@ -459,7 +480,7 @@ static struct clk mmc1_ck = {
> .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
> };
>
> -static struct clk mmc2_ck = {
> +static struct ClkInfo mmc2_ck = {
> .name = "mmc_ck",
> .id = 2,
> /* Functional clock is direct from ULPD, interface clock is ARMPER */
> @@ -468,25 +489,25 @@ static struct clk mmc2_ck = {
> .flags = CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk cam_mclk = {
> +static struct ClkInfo cam_mclk = {
> .name = "cam.mclk",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> .rate = 12000000,
> };
>
> -static struct clk cam_exclk = {
> +static struct ClkInfo cam_exclk = {
> .name = "cam.exclk",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> /* Either 12M from cam.mclk or 48M from dpll4 */
> .parent = &cam_mclk,
> };
>
> -static struct clk cam_lclk = {
> +static struct ClkInfo cam_lclk = {
> .name = "cam.lclk",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
> };
>
> -static struct clk i2c_fck = {
> +static struct ClkInfo i2c_fck = {
> .name = "i2c_fck",
> .id = 1,
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> @@ -494,349 +515,349 @@ static struct clk i2c_fck = {
> .parent = &armxor_ck,
> };
>
> -static struct clk i2c_ick = {
> +static struct ClkInfo i2c_ick = {
> .name = "i2c_ick",
> .id = 1,
> .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
> .parent = &armper_ck,
> };
>
> -static struct clk clk32k = {
> +static struct ClkInfo clk32k = {
> .name = "clk32-kHz",
> .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
> CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .parent = &xtal_osc32k,
> };
>
> -static struct clk ref_clk = {
> +static struct ClkInfo ref_clk = {
> .name = "ref_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 12000000, /* 12 MHz or 13 MHz or 19.2 MHz */
> /*.parent = sys.xtalin */
> };
>
> -static struct clk apll_96m = {
> +static struct ClkInfo apll_96m = {
> .name = "apll_96m",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 96000000,
> /*.parent = ref_clk */
> };
>
> -static struct clk apll_54m = {
> +static struct ClkInfo apll_54m = {
> .name = "apll_54m",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 54000000,
> /*.parent = ref_clk */
> };
>
> -static struct clk sys_clk = {
> +static struct ClkInfo sys_clk = {
> .name = "sys_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 32768,
> /*.parent = sys.xtalin */
> };
>
> -static struct clk sleep_clk = {
> +static struct ClkInfo sleep_clk = {
> .name = "sleep_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 32768,
> /*.parent = sys.xtalin */
> };
>
> -static struct clk dpll_ck = {
> +static struct ClkInfo dpll_ck = {
> .name = "dpll",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .parent = &ref_clk,
> };
>
> -static struct clk dpll_x2_ck = {
> +static struct ClkInfo dpll_x2_ck = {
> .name = "dpll_x2",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .parent = &ref_clk,
> };
>
> -static struct clk wdt1_sys_clk = {
> +static struct ClkInfo wdt1_sys_clk = {
> .name = "wdt1_sys_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
> .rate = 32768,
> /*.parent = sys.xtalin */
> };
>
> -static struct clk func_96m_clk = {
> +static struct ClkInfo func_96m_clk = {
> .name = "func_96m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 1,
> .parent = &apll_96m,
> };
>
> -static struct clk func_48m_clk = {
> +static struct ClkInfo func_48m_clk = {
> .name = "func_48m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 2,
> .parent = &apll_96m,
> };
>
> -static struct clk func_12m_clk = {
> +static struct ClkInfo func_12m_clk = {
> .name = "func_12m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 8,
> .parent = &apll_96m,
> };
>
> -static struct clk func_54m_clk = {
> +static struct ClkInfo func_54m_clk = {
> .name = "func_54m_clk",
> .flags = CLOCK_IN_OMAP242X,
> .divisor = 1,
> .parent = &apll_54m,
> };
>
> -static struct clk sys_clkout = {
> +static struct ClkInfo sys_clkout = {
> .name = "clkout",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk sys_clkout2 = {
> +static struct ClkInfo sys_clkout2 = {
> .name = "clkout2",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_clk = {
> +static struct ClkInfo core_clk = {
> .name = "core_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &dpll_x2_ck, /* Switchable between dpll_ck and clk32k */
> };
>
> -static struct clk l3_clk = {
> +static struct ClkInfo l3_clk = {
> .name = "l3_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_clk,
> };
>
> -static struct clk core_l4_iclk = {
> +static struct ClkInfo core_l4_iclk = {
> .name = "core_l4_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &l3_clk,
> };
>
> -static struct clk wu_l4_iclk = {
> +static struct ClkInfo wu_l4_iclk = {
> .name = "wu_l4_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &l3_clk,
> };
>
> -static struct clk core_l3_iclk = {
> +static struct ClkInfo core_l3_iclk = {
> .name = "core_l3_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_clk,
> };
>
> -static struct clk core_l4_usb_clk = {
> +static struct ClkInfo core_l4_usb_clk = {
> .name = "core_l4_usb_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &l3_clk,
> };
>
> -static struct clk wu_gpt1_clk = {
> +static struct ClkInfo wu_gpt1_clk = {
> .name = "wu_gpt1_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk wu_32k_clk = {
> +static struct ClkInfo wu_32k_clk = {
> .name = "wu_32k_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk uart1_fclk = {
> +static struct ClkInfo uart1_fclk = {
> .name = "uart1_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &func_48m_clk,
> };
>
> -static struct clk uart1_iclk = {
> +static struct ClkInfo uart1_iclk = {
> .name = "uart1_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l4_iclk,
> };
>
> -static struct clk uart2_fclk = {
> +static struct ClkInfo uart2_fclk = {
> .name = "uart2_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &func_48m_clk,
> };
>
> -static struct clk uart2_iclk = {
> +static struct ClkInfo uart2_iclk = {
> .name = "uart2_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l4_iclk,
> };
>
> -static struct clk uart3_fclk = {
> +static struct ClkInfo uart3_fclk = {
> .name = "uart3_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &func_48m_clk,
> };
>
> -static struct clk uart3_iclk = {
> +static struct ClkInfo uart3_iclk = {
> .name = "uart3_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l4_iclk,
> };
>
> -static struct clk mpu_fclk = {
> +static struct ClkInfo mpu_fclk = {
> .name = "mpu_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_clk,
> };
>
> -static struct clk mpu_iclk = {
> +static struct ClkInfo mpu_iclk = {
> .name = "mpu_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_clk,
> };
>
> -static struct clk int_m_fclk = {
> +static struct ClkInfo int_m_fclk = {
> .name = "int_m_fclk",
> .alias = "mpu_intc_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_clk,
> };
>
> -static struct clk int_m_iclk = {
> +static struct ClkInfo int_m_iclk = {
> .name = "int_m_iclk",
> .alias = "mpu_intc_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_clk,
> };
>
> -static struct clk core_gpt2_clk = {
> +static struct ClkInfo core_gpt2_clk = {
> .name = "core_gpt2_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt3_clk = {
> +static struct ClkInfo core_gpt3_clk = {
> .name = "core_gpt3_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt4_clk = {
> +static struct ClkInfo core_gpt4_clk = {
> .name = "core_gpt4_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt5_clk = {
> +static struct ClkInfo core_gpt5_clk = {
> .name = "core_gpt5_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt6_clk = {
> +static struct ClkInfo core_gpt6_clk = {
> .name = "core_gpt6_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt7_clk = {
> +static struct ClkInfo core_gpt7_clk = {
> .name = "core_gpt7_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt8_clk = {
> +static struct ClkInfo core_gpt8_clk = {
> .name = "core_gpt8_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt9_clk = {
> +static struct ClkInfo core_gpt9_clk = {
> .name = "core_gpt9_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt10_clk = {
> +static struct ClkInfo core_gpt10_clk = {
> .name = "core_gpt10_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt11_clk = {
> +static struct ClkInfo core_gpt11_clk = {
> .name = "core_gpt11_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk core_gpt12_clk = {
> +static struct ClkInfo core_gpt12_clk = {
> .name = "core_gpt12_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &sys_clk,
> };
>
> -static struct clk mcbsp1_clk = {
> +static struct ClkInfo mcbsp1_clk = {
> .name = "mcbsp1_cg",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 2,
> .parent = &func_96m_clk,
> };
>
> -static struct clk mcbsp2_clk = {
> +static struct ClkInfo mcbsp2_clk = {
> .name = "mcbsp2_cg",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .divisor = 2,
> .parent = &func_96m_clk,
> };
>
> -static struct clk emul_clk = {
> +static struct ClkInfo emul_clk = {
> .name = "emul_ck",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &func_54m_clk,
> };
>
> -static struct clk sdma_fclk = {
> +static struct ClkInfo sdma_fclk = {
> .name = "sdma_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &l3_clk,
> };
>
> -static struct clk sdma_iclk = {
> +static struct ClkInfo sdma_iclk = {
> .name = "sdma_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l3_iclk, /* core_l4_iclk for the configuration port */
> };
>
> -static struct clk i2c1_fclk = {
> +static struct ClkInfo i2c1_fclk = {
> .name = "i2c1.fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &func_12m_clk,
> .divisor = 1,
> };
>
> -static struct clk i2c1_iclk = {
> +static struct ClkInfo i2c1_iclk = {
> .name = "i2c1.iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l4_iclk,
> };
>
> -static struct clk i2c2_fclk = {
> +static struct ClkInfo i2c2_fclk = {
> .name = "i2c2.fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &func_12m_clk,
> .divisor = 1,
> };
>
> -static struct clk i2c2_iclk = {
> +static struct ClkInfo i2c2_iclk = {
> .name = "i2c2.iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l4_iclk,
> };
>
> -static struct clk gpio_dbclk[5] = {
> +static struct ClkInfo gpio_dbclk[5] = {
> {
> .name = "gpio1_dbclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -860,25 +881,25 @@ static struct clk gpio_dbclk[5] = {
> },
> };
>
> -static struct clk gpio_iclk = {
> +static struct ClkInfo gpio_iclk = {
> .name = "gpio_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &wu_l4_iclk,
> };
>
> -static struct clk mmc_fck = {
> +static struct ClkInfo mmc_fck = {
> .name = "mmc_fclk",
> .flags = CLOCK_IN_OMAP242X,
> .parent = &func_96m_clk,
> };
>
> -static struct clk mmc_ick = {
> +static struct ClkInfo mmc_ick = {
> .name = "mmc_iclk",
> .flags = CLOCK_IN_OMAP242X,
> .parent = &core_l4_iclk,
> };
>
> -static struct clk spi_fclk[3] = {
> +static struct ClkInfo spi_fclk[3] = {
> {
> .name = "spi1_fclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -894,7 +915,7 @@ static struct clk spi_fclk[3] = {
> },
> };
>
> -static struct clk dss_clk[2] = {
> +static struct ClkInfo dss_clk[2] = {
> {
> .name = "dss_clk1",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -906,25 +927,25 @@ static struct clk dss_clk[2] = {
> },
> };
>
> -static struct clk dss_54m_clk = {
> +static struct ClkInfo dss_54m_clk = {
> .name = "dss_54m_clk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &func_54m_clk,
> };
>
> -static struct clk dss_l3_iclk = {
> +static struct ClkInfo dss_l3_iclk = {
> .name = "dss_l3_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l3_iclk,
> };
>
> -static struct clk dss_l4_iclk = {
> +static struct ClkInfo dss_l4_iclk = {
> .name = "dss_l4_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> .parent = &core_l4_iclk,
> };
>
> -static struct clk spi_iclk[3] = {
> +static struct ClkInfo spi_iclk[3] = {
> {
> .name = "spi1_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> @@ -940,14 +961,14 @@ static struct clk spi_iclk[3] = {
> },
> };
>
> -static struct clk omapctrl_clk = {
> +static struct ClkInfo omapctrl_clk = {
> .name = "omapctrl_iclk",
> .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
> /* XXX Should be in WKUP domain */
> .parent = &core_l4_iclk,
> };
>
> -static struct clk *onchip_clks[] = {
> +static struct ClkInfo *onchip_clks[] = {
> /* OMAP 1 */
>
> /* non-ULPD clocks */
> @@ -1219,7 +1240,9 @@ int64_t omap_clk_getrate(omap_clk clk)
>
> void omap_clk_init(struct omap_mpu_state_s *mpu)
> {
> - struct clk **i, *j, *k;
> + Object *clocks;
> + struct ClkInfo **i;
> + struct clk *j;
> int count;
> int flag;
>
> @@ -1236,29 +1259,57 @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
> else
> return;
>
> - for (i = onchip_clks, count = 0; *i; i ++)
> - if ((*i)->flags & flag)
> - count ++;
> + clocks = object_new("container");
> + object_property_add_child(object_get_root(), "clocks",
> + clocks, NULL);
> +
> + for (i = onchip_clks, count = 0; *i; i++) {
> + if ((*i)->flags & flag) {
> + count++;
> + }
> + }
> mpu->clks = (struct clk *) g_malloc0(sizeof(struct clk) * (count + 1));
> - for (i = onchip_clks, j = mpu->clks; *i; i ++)
> + for (i = onchip_clks, j = mpu->clks; *i; i++) {
> + if ((*i)->flags & flag) {
> + object_initialize(j, TYPE_OMAP_CLK);
> + j->name = (*i)->name;
> + j->alias = (*i)->alias;
> + j->flags = (*i)->flags;
> + j->id = (*i)->id;
> + j->rate = (*i)->rate;
> + j->divisor = (*i)->divisor ?: 1;
> + j->multiplier = (*i)->multiplier ?: 1;
> + object_property_add_child(clocks, j->name, OBJECT(j), NULL);
> + j++;
> + }
> + }
> +
> + for (i = onchip_clks, j = mpu->clks; *i; i++) {
> if ((*i)->flags & flag) {
> - memcpy(j, *i, sizeof(struct clk));
> - for (k = mpu->clks; k < j; k ++)
> - if (j->parent && !strcmp(j->parent->name, k->name)) {
> - j->parent = k;
> - j->sibling = k->child1;
> - k->child1 = j;
> - } else if (k->parent && !strcmp(k->parent->name, j->name)) {
> - k->parent = j;
> - k->sibling = j->child1;
> - j->child1 = k;
> - }
> - j->divisor = j->divisor ?: 1;
> - j->multiplier = j->multiplier ?: 1;
> - j ++;
> + if ((*i)->parent) {
> + j->parent = omap_findclk(mpu, (*i)->parent->name);
> + j->sibling = j->parent->child1;
> + j->parent->child1 = j;
> + }
> + j++;
> }
> - for (j = mpu->clks; count --; j ++) {
> + }
> +
> + for (j = mpu->clks; count--; j++) {
> omap_clk_update(j);
> omap_clk_rate_update(j);
> }
> }
> +
> +void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
> + const char *name, const char *clk)
> +{
> + struct clk *target = omap_findclk(s, clk);
> + qdev_prop_set_ptr(dev, name, target);
> +}
> +
> +static void omap_clk_register(void)
> +{
> + type_register_static(&omap_clk_info);
> +}
> +device_init(omap_clk_register)
> --
> 1.7.7.6
>
>
--
12345678901234567890123456789012345678901234567890123456789012345678901234567890
1 2 3 4 5 6 7 8
^ permalink raw reply [flat|nested] 62+ messages in thread
* [Qemu-devel] [PATCH v2 27/27] omap: remove PROP_PTR properties
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (25 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 26/27] omap_clk: convert to QOM Paolo Bonzini
@ 2012-02-04 8:02 ` Paolo Bonzini
2012-02-06 14:43 ` Anthony Liguori
2012-02-07 13:20 ` [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
27 siblings, 1 reply; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-04 8:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Everything is already in place to turn the clock properties into links.
Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/omap_clk.c | 2 +-
hw/omap_gpio.c | 46 ++++++++++++++++++++++++----------------------
hw/omap_intc.c | 26 +++++++++++++++++++++-----
3 files changed, 46 insertions(+), 28 deletions(-)
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index c4c2b80..4723ac1 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -1305,7 +1305,7 @@ void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
const char *name, const char *clk)
{
struct clk *target = omap_findclk(s, clk);
- qdev_prop_set_ptr(dev, name, target);
+ object_property_set_link(OBJECT(dev), OBJECT(target), name, NULL);
}
static void omap_clk_register(void)
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index 9a9a8e1..e9a0cdb 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -39,7 +39,7 @@ struct omap_gpif_s {
SysBusDevice busdev;
MemoryRegion iomem;
int mpu_model;
- void *clk;
+ struct clk *clk;
struct omap_gpio_s omap1;
};
@@ -207,8 +207,8 @@ struct omap2_gpif_s {
SysBusDevice busdev;
MemoryRegion iomem;
int mpu_model;
- void *iclk;
- void *fclk[6];
+ struct clk *iclk;
+ struct clk *fclk[6];
int modulecount;
struct omap2_gpio_s *modules;
qemu_irq *handler;
@@ -719,21 +719,15 @@ static int omap2_gpio_init(SysBusDevice *dev)
return 0;
}
-/* Using qdev pointer properties for the clocks is not ideal.
- * qdev should support a generic means of defining a 'port' with
- * an arbitrary interface for connecting two devices. Then we
- * could reframe the omap clock API in terms of clock ports,
- * and get some type safety. For now the best qdev provides is
- * passing an arbitrary pointer.
- * (It's not possible to pass in the string which is the clock
- * name, because this device does not have the necessary information
- * (ie the struct omap_mpu_state_s*) to do the clockname to pointer
- * translation.)
- */
+static void omap_gpio_initfn(Object *obj)
+{
+ struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s, SYS_BUS_DEVICE(obj));
+
+ object_property_add_link(obj, "clk", TYPE_OMAP_CLK, (Object **)&s->clk, NULL);
+}
static Property omap_gpio_properties[] = {
DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
- DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
DEFINE_PROP_END_OF_LIST(),
};
@@ -752,17 +746,24 @@ static TypeInfo omap_gpio_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap_gpif_s),
.class_init = omap_gpio_class_init,
+ .instance_init = omap_gpio_initfn,
};
+static void omap2_gpio_initfn(Object *obj)
+{
+ struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s, SYS_BUS_DEVICE(obj));
+
+ object_property_add_link(obj, "iclk", TYPE_OMAP_CLK, (Object **) &s->iclk, NULL);
+ object_property_add_link(obj, "fclk0", TYPE_OMAP_CLK, (Object **) &s->fclk[0], NULL);
+ object_property_add_link(obj, "fclk1", TYPE_OMAP_CLK, (Object **) &s->fclk[1], NULL);
+ object_property_add_link(obj, "fclk2", TYPE_OMAP_CLK, (Object **) &s->fclk[2], NULL);
+ object_property_add_link(obj, "fclk3", TYPE_OMAP_CLK, (Object **) &s->fclk[3], NULL);
+ object_property_add_link(obj, "fclk4", TYPE_OMAP_CLK, (Object **) &s->fclk[4], NULL);
+ object_property_add_link(obj, "fclk5", TYPE_OMAP_CLK, (Object **) &s->fclk[5], NULL);
+}
+
static Property omap2_gpio_properties[] = {
DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
- DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
- DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
- DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
- DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
- DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
- DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
- DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
DEFINE_PROP_END_OF_LIST(),
};
@@ -781,6 +782,7 @@ static TypeInfo omap2_gpio_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap2_gpif_s),
.class_init = omap2_gpio_class_init,
+ .instance_init = omap2_gpio_initfn,
};
static void omap_gpio_register_device(void)
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index 5aa98a8..cc263ef 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -37,8 +37,8 @@ struct omap_intr_handler_s {
qemu_irq *pins;
qemu_irq parent_intr[2];
MemoryRegion mmio;
- void *iclk;
- void *fclk;
+ struct clk *iclk;
+ struct clk *fclk;
unsigned char nbanks;
int level_only;
uint32_t size;
@@ -373,9 +373,16 @@ static int omap_intc_init(SysBusDevice *dev)
return 0;
}
+static void omap_intc_initfn(Object *obj)
+{
+ struct omap_intr_handler_s *s = FROM_SYSBUS(struct omap_intr_handler_s,
+ SYS_BUS_DEVICE(obj));
+
+ object_property_add_link(obj, "clk", TYPE_OMAP_CLK, (Object **)&s->iclk, NULL);
+}
+
static Property omap_intc_properties[] = {
DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100),
- DEFINE_PROP_PTR("clk", struct omap_intr_handler_s, iclk),
DEFINE_PROP_END_OF_LIST(),
};
@@ -394,6 +401,7 @@ static TypeInfo omap_intc_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap_intr_handler_s),
.class_init = omap_intc_class_init,
+ .instance_init = omap_intc_initfn,
};
static uint64_t omap2_inth_read(void *opaque, target_phys_addr_t addr,
@@ -615,11 +623,18 @@ static int omap2_intc_init(SysBusDevice *dev)
return 0;
}
+static void omap2_intc_initfn(Object *obj)
+{
+ struct omap_intr_handler_s *s = FROM_SYSBUS(struct omap_intr_handler_s,
+ SYS_BUS_DEVICE(obj));
+
+ object_property_add_link(obj, "iclk", TYPE_OMAP_CLK, (Object **)&s->iclk, NULL);
+ object_property_add_link(obj, "fclk", TYPE_OMAP_CLK, (Object **)&s->fclk, NULL);
+}
+
static Property omap2_intc_properties[] = {
DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s,
revision, 0x21),
- DEFINE_PROP_PTR("iclk", struct omap_intr_handler_s, iclk),
- DEFINE_PROP_PTR("fclk", struct omap_intr_handler_s, fclk),
DEFINE_PROP_END_OF_LIST(),
};
@@ -638,6 +653,7 @@ static TypeInfo omap2_intc_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(struct omap_intr_handler_s),
.class_init = omap2_intc_class_init,
+ .instance_init = omap2_intc_initfn,
};
static void omap_intc_register_device(void)
--
1.7.7.6
^ permalink raw reply related [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 27/27] omap: remove PROP_PTR properties
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 27/27] omap: remove PROP_PTR properties Paolo Bonzini
@ 2012-02-06 14:43 ` Anthony Liguori
0 siblings, 0 replies; 62+ messages in thread
From: Anthony Liguori @ 2012-02-06 14:43 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Peter Maydell, qemu-devel
On 02/04/2012 02:02 AM, Paolo Bonzini wrote:
> Everything is already in place to turn the clock properties into links.
w00t!
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Regards,
Anthony Liguori
>
> Cc: Peter Maydell<peter.maydell@linaro.org>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> hw/omap_clk.c | 2 +-
> hw/omap_gpio.c | 46 ++++++++++++++++++++++++----------------------
> hw/omap_intc.c | 26 +++++++++++++++++++++-----
> 3 files changed, 46 insertions(+), 28 deletions(-)
>
> diff --git a/hw/omap_clk.c b/hw/omap_clk.c
> index c4c2b80..4723ac1 100644
> --- a/hw/omap_clk.c
> +++ b/hw/omap_clk.c
> @@ -1305,7 +1305,7 @@ void omap_prop_set_clk(struct omap_mpu_state_s *s, DeviceState *dev,
> const char *name, const char *clk)
> {
> struct clk *target = omap_findclk(s, clk);
> - qdev_prop_set_ptr(dev, name, target);
> + object_property_set_link(OBJECT(dev), OBJECT(target), name, NULL);
> }
>
> static void omap_clk_register(void)
> diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
> index 9a9a8e1..e9a0cdb 100644
> --- a/hw/omap_gpio.c
> +++ b/hw/omap_gpio.c
> @@ -39,7 +39,7 @@ struct omap_gpif_s {
> SysBusDevice busdev;
> MemoryRegion iomem;
> int mpu_model;
> - void *clk;
> + struct clk *clk;
> struct omap_gpio_s omap1;
> };
>
> @@ -207,8 +207,8 @@ struct omap2_gpif_s {
> SysBusDevice busdev;
> MemoryRegion iomem;
> int mpu_model;
> - void *iclk;
> - void *fclk[6];
> + struct clk *iclk;
> + struct clk *fclk[6];
> int modulecount;
> struct omap2_gpio_s *modules;
> qemu_irq *handler;
> @@ -719,21 +719,15 @@ static int omap2_gpio_init(SysBusDevice *dev)
> return 0;
> }
>
> -/* Using qdev pointer properties for the clocks is not ideal.
> - * qdev should support a generic means of defining a 'port' with
> - * an arbitrary interface for connecting two devices. Then we
> - * could reframe the omap clock API in terms of clock ports,
> - * and get some type safety. For now the best qdev provides is
> - * passing an arbitrary pointer.
> - * (It's not possible to pass in the string which is the clock
> - * name, because this device does not have the necessary information
> - * (ie the struct omap_mpu_state_s*) to do the clockname to pointer
> - * translation.)
> - */
> +static void omap_gpio_initfn(Object *obj)
> +{
> + struct omap_gpif_s *s = FROM_SYSBUS(struct omap_gpif_s, SYS_BUS_DEVICE(obj));
> +
> + object_property_add_link(obj, "clk", TYPE_OMAP_CLK, (Object **)&s->clk, NULL);
> +}
>
> static Property omap_gpio_properties[] = {
> DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
> - DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> @@ -752,17 +746,24 @@ static TypeInfo omap_gpio_info = {
> .parent = TYPE_SYS_BUS_DEVICE,
> .instance_size = sizeof(struct omap_gpif_s),
> .class_init = omap_gpio_class_init,
> + .instance_init = omap_gpio_initfn,
> };
>
> +static void omap2_gpio_initfn(Object *obj)
> +{
> + struct omap2_gpif_s *s = FROM_SYSBUS(struct omap2_gpif_s, SYS_BUS_DEVICE(obj));
> +
> + object_property_add_link(obj, "iclk", TYPE_OMAP_CLK, (Object **)&s->iclk, NULL);
> + object_property_add_link(obj, "fclk0", TYPE_OMAP_CLK, (Object **)&s->fclk[0], NULL);
> + object_property_add_link(obj, "fclk1", TYPE_OMAP_CLK, (Object **)&s->fclk[1], NULL);
> + object_property_add_link(obj, "fclk2", TYPE_OMAP_CLK, (Object **)&s->fclk[2], NULL);
> + object_property_add_link(obj, "fclk3", TYPE_OMAP_CLK, (Object **)&s->fclk[3], NULL);
> + object_property_add_link(obj, "fclk4", TYPE_OMAP_CLK, (Object **)&s->fclk[4], NULL);
> + object_property_add_link(obj, "fclk5", TYPE_OMAP_CLK, (Object **)&s->fclk[5], NULL);
> +}
> +
> static Property omap2_gpio_properties[] = {
> DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
> - DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
> - DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
> - DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
> - DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
> - DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
> - DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
> - DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> @@ -781,6 +782,7 @@ static TypeInfo omap2_gpio_info = {
> .parent = TYPE_SYS_BUS_DEVICE,
> .instance_size = sizeof(struct omap2_gpif_s),
> .class_init = omap2_gpio_class_init,
> + .instance_init = omap2_gpio_initfn,
> };
>
> static void omap_gpio_register_device(void)
> diff --git a/hw/omap_intc.c b/hw/omap_intc.c
> index 5aa98a8..cc263ef 100644
> --- a/hw/omap_intc.c
> +++ b/hw/omap_intc.c
> @@ -37,8 +37,8 @@ struct omap_intr_handler_s {
> qemu_irq *pins;
> qemu_irq parent_intr[2];
> MemoryRegion mmio;
> - void *iclk;
> - void *fclk;
> + struct clk *iclk;
> + struct clk *fclk;
> unsigned char nbanks;
> int level_only;
> uint32_t size;
> @@ -373,9 +373,16 @@ static int omap_intc_init(SysBusDevice *dev)
> return 0;
> }
>
> +static void omap_intc_initfn(Object *obj)
> +{
> + struct omap_intr_handler_s *s = FROM_SYSBUS(struct omap_intr_handler_s,
> + SYS_BUS_DEVICE(obj));
> +
> + object_property_add_link(obj, "clk", TYPE_OMAP_CLK, (Object **)&s->iclk, NULL);
> +}
> +
> static Property omap_intc_properties[] = {
> DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100),
> - DEFINE_PROP_PTR("clk", struct omap_intr_handler_s, iclk),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> @@ -394,6 +401,7 @@ static TypeInfo omap_intc_info = {
> .parent = TYPE_SYS_BUS_DEVICE,
> .instance_size = sizeof(struct omap_intr_handler_s),
> .class_init = omap_intc_class_init,
> + .instance_init = omap_intc_initfn,
> };
>
> static uint64_t omap2_inth_read(void *opaque, target_phys_addr_t addr,
> @@ -615,11 +623,18 @@ static int omap2_intc_init(SysBusDevice *dev)
> return 0;
> }
>
> +static void omap2_intc_initfn(Object *obj)
> +{
> + struct omap_intr_handler_s *s = FROM_SYSBUS(struct omap_intr_handler_s,
> + SYS_BUS_DEVICE(obj));
> +
> + object_property_add_link(obj, "iclk", TYPE_OMAP_CLK, (Object **)&s->iclk, NULL);
> + object_property_add_link(obj, "fclk", TYPE_OMAP_CLK, (Object **)&s->fclk, NULL);
> +}
> +
> static Property omap2_intc_properties[] = {
> DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s,
> revision, 0x21),
> - DEFINE_PROP_PTR("iclk", struct omap_intr_handler_s, iclk),
> - DEFINE_PROP_PTR("fclk", struct omap_intr_handler_s, fclk),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> @@ -638,6 +653,7 @@ static TypeInfo omap2_intc_info = {
> .parent = TYPE_SYS_BUS_DEVICE,
> .instance_size = sizeof(struct omap_intr_handler_s),
> .class_init = omap2_intc_class_init,
> + .instance_init = omap2_intc_initfn,
> };
>
> static void omap_intc_register_device(void)
^ permalink raw reply [flat|nested] 62+ messages in thread
* Re: [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM
2012-02-04 8:02 [Qemu-devel] [PATCH v2 00/27] next steps for qdev & QOM Paolo Bonzini
` (26 preceding siblings ...)
2012-02-04 8:02 ` [Qemu-devel] [PATCH v2 27/27] omap: remove PROP_PTR properties Paolo Bonzini
@ 2012-02-07 13:20 ` Paolo Bonzini
27 siblings, 0 replies; 62+ messages in thread
From: Paolo Bonzini @ 2012-02-07 13:20 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori
Hi Anthony,
I fixed the two nits you found (static in the middle of the file,
and *strchr) and dropped the OMAP patches for now to give more time
to Peter and Andrzej. I also fixed object_dynamic_cast with TYPE_OBJECT
as the target. With this fix, you can actually browse the OMAP clocks
with qom-list. The fix requires no changes in the OMAP patches.
The following changes since commit c9344f2220ec9878493af5a39b7f0f337e58123a:
Fix build breakage from last commit. (2012-02-03 11:22:35 -0600)
are available in the git repository at:
git://github.com/bonzini/qemu.git qdev-props-for-anthony
I'm attaching the interdiff between v2 and v3. Thanks for the quick
review!
Paolo
Paolo Bonzini (25):
qom: clean up cast macros
qom: more documentation on subclassing
qom: clean up/optimize object_dynamic_cast
qom: avoid useless conversions from string to type
qom: do not include qdev header file
qom: add QObject-based property get/set wrappers
qom: add property get/set wrappers for C types
qom: fix off-by-one
qom: add object_resolve_path_type
qom: use object_resolve_path_type for links
qom: fix canonical paths vs. interfaces
qom: add property get/set wrappers for links
qdev: remove direct calls to print/parse
qdev: allow reusing get/set for legacy property
qdev: remove parse method for string properties
qdev: remove print/parse methods from LostTickPolicy properties
qdev: remove parse/print methods for mac properties
qdev: make the non-legacy pci address property accept an integer
qdev: remove parse/print methods for pointer properties
qdev: let QOM free properties
qdev: fix off-by-one
qdev: access properties via QOM
qdev: inline qdev_prop_set into qdev_prop_set_ptr
qdev: initialize properties via QOM
qdev: remove unused fields from PropertyInfo
hw/qdev-addr.c | 7 +-
hw/qdev-monitor.c | 30 ++--
hw/qdev-properties.c | 510 ++++++++++++++++++++++----------------------
hw/qdev.c | 32 ++--
hw/qdev.h | 39 +---
include/qemu/object.h | 217 ++++++++++++++++++-
include/qemu/qom-qobject.h | 42 ++++
qemu-common.h | 1 +
qerror.c | 4 +
qerror.h | 3 +
qmp.c | 18 +--
qom/Makefile | 2 +-
qom/object.c | 263 ++++++++++++++++++-----
qom/qom-qobject.c | 44 ++++
14 files changed, 810 insertions(+), 402 deletions(-)
create mode 100644 include/qemu/qom-qobject.h
create mode 100644 qom/qom-qobject.c
diff --git a/qom/object.c b/qom/object.c
index e92d4a6..aa7e038 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -69,6 +69,8 @@ typedef struct Interface
#define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE)
+static Type type_interface;
+
static GHashTable *type_table_get(void)
{
static GHashTable *type_table;
@@ -374,11 +376,9 @@ void object_delete(Object *obj)
g_free(obj);
}
-static Type type_interface;
-
-static bool object_is_type(Object *obj, TypeImpl *target_type)
+static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
{
- TypeImpl *type = obj->class->type;
+ assert(target_type);
/* Check if typename is a direct ancestor of type */
while (type) {
@@ -392,21 +392,28 @@ static bool object_is_type(Object *obj, TypeImpl *target_type)
return false;
}
+static bool object_is_type(Object *obj, TypeImpl *target_type)
+{
+ return !target_type || type_is_ancestor(obj->class->type, target_type);
+}
+
Object *object_dynamic_cast(Object *obj, const char *typename)
{
TypeImpl *target_type = type_get_by_name(typename);
GSList *i;
- /* Check if typename is a direct ancestor */
- if (object_is_type(obj, target_type)) {
+ /* Check if typename is a direct ancestor. Special-case TYPE_OBJECT,
+ * we want to go back from interfaces to the parent.
+ */
+ if (target_type && object_is_type(obj, target_type)) {
return obj;
}
/* Check if obj is an interface and its containing object is a direct
* ancestor of typename. In principle we could do this test at the very
* beginning of object_dynamic_cast, avoiding a second call to
* object_is_type. However, casting between interfaces is relatively
- * rare, and object_is_type(obj, TYPE_INTERFACE) would fail almost always.
+ * rare, and object_is_type(obj, type_interface) would fail almost always.
*
* Perhaps we could add a magic value to the object header for increased
* (run-time) type safety and to speed up tests like this one. If we ever
@@ -420,6 +427,10 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
}
}
+ if (!target_type) {
+ return obj;
+ }
+
/* Check if obj has an interface of typename */
for (i = obj->interfaces; i; i = i->next) {
Interface *iface = i->data;
@@ -873,8 +884,8 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
if (strcmp(path, "") != 0) {
Object *target;
- target_type = g_strdup(&type[5]);
- *strchr(target_type, '>') = 0;
+ /* Go from link<FOO> to FOO. */
+ target_type = g_strndup(&type[5], strlen(type) - 6);
target = object_resolve_path_type(path, target_type, &ambiguous);
if (ambiguous) {
^ permalink raw reply related [flat|nested] 62+ messages in thread