aboutsummaryrefslogtreecommitdiff
path: root/qom
diff options
context:
space:
mode:
Diffstat (limited to 'qom')
-rw-r--r--qom/cpu.c6
-rw-r--r--qom/object.c50
2 files changed, 38 insertions, 18 deletions
diff --git a/qom/cpu.c b/qom/cpu.c
index 818fb26dd4..9d62479546 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -254,7 +254,11 @@ static void cpu_class_init(ObjectClass *klass, void *data)
k->gdb_read_register = cpu_common_gdb_read_register;
k->gdb_write_register = cpu_common_gdb_write_register;
dc->realize = cpu_common_realizefn;
- dc->no_user = 1;
+ /*
+ * Reason: CPUs still need special care by board code: wiring up
+ * IRQs, adding reset handlers, halting non-first CPUs, ...
+ */
+ dc->cannot_instantiate_with_device_add_yet = true;
}
static const TypeInfo cpu_type_info = {
diff --git a/qom/object.c b/qom/object.c
index 4dee02b6e2..62e7e415d9 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -78,8 +78,11 @@ static GHashTable *type_table_get(void)
return type_table;
}
+static bool enumerating_types;
+
static void type_table_add(TypeImpl *ti)
{
+ assert(!enumerating_types);
g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
}
@@ -88,7 +91,7 @@ static TypeImpl *type_table_lookup(const char *name)
return g_hash_table_lookup(type_table_get(), name);
}
-static TypeImpl *type_register_internal(const TypeInfo *info)
+static TypeImpl *type_new(const TypeInfo *info)
{
TypeImpl *ti = g_malloc0(sizeof(*ti));
int i;
@@ -122,8 +125,15 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
}
ti->num_interfaces = i;
- type_table_add(ti);
+ return ti;
+}
+
+static TypeImpl *type_register_internal(const TypeInfo *info)
+{
+ TypeImpl *ti;
+ ti = type_new(info);
+ type_table_add(ti);
return ti;
}
@@ -206,22 +216,25 @@ static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type)
static void type_initialize(TypeImpl *ti);
-static void type_initialize_interface(TypeImpl *ti, const char *parent)
+static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type,
+ TypeImpl *parent_type)
{
InterfaceClass *new_iface;
TypeInfo info = { };
TypeImpl *iface_impl;
- info.parent = parent;
- info.name = g_strdup_printf("%s::%s", ti->name, info.parent);
+ info.parent = parent_type->name;
+ info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name);
info.abstract = true;
- iface_impl = type_register(&info);
+ iface_impl = type_new(&info);
+ iface_impl->parent_type = parent_type;
type_initialize(iface_impl);
g_free((char *)info.name);
new_iface = (InterfaceClass *)iface_impl->class;
new_iface->concrete_class = ti->class;
+ new_iface->interface_type = interface_type;
ti->class->interfaces = g_slist_append(ti->class->interfaces,
iface_impl->class);
@@ -251,8 +264,10 @@ static void type_initialize(TypeImpl *ti)
ti->class->interfaces = NULL;
for (e = parent->class->interfaces; e; e = e->next) {
- ObjectClass *iface = e->data;
- type_initialize_interface(ti, object_class_get_name(iface));
+ InterfaceClass *iface = e->data;
+ ObjectClass *klass = OBJECT_CLASS(iface);
+
+ type_initialize_interface(ti, iface->interface_type, klass->type);
}
for (i = 0; i < ti->num_interfaces; i++) {
@@ -269,7 +284,7 @@ static void type_initialize(TypeImpl *ti)
continue;
}
- type_initialize_interface(ti, ti->interfaces[i].typename);
+ type_initialize_interface(ti, t, t);
}
}
@@ -285,8 +300,6 @@ static void type_initialize(TypeImpl *ti)
if (ti->class_init) {
ti->class_init(ti->class, ti->class_data);
}
-
-
}
static void object_init_with_type(Object *obj, TypeImpl *ti)
@@ -458,7 +471,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
Object *inst;
for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
- if (obj->class->cast_cache[i] == typename) {
+ if (obj->class->object_cast_cache[i] == typename) {
goto out;
}
}
@@ -475,9 +488,10 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename,
if (obj && obj == inst) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
- obj->class->cast_cache[i - 1] = obj->class->cast_cache[i];
+ obj->class->object_cast_cache[i - 1] =
+ obj->class->object_cast_cache[i];
}
- obj->class->cast_cache[i - 1] = typename;
+ obj->class->object_cast_cache[i - 1] = typename;
}
out:
@@ -547,7 +561,7 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
int i;
for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) {
- if (class->cast_cache[i] == typename) {
+ if (class->class_cast_cache[i] == typename) {
ret = class;
goto out;
}
@@ -568,9 +582,9 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
#ifdef CONFIG_QOM_CAST_DEBUG
if (class && ret == class) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
- class->cast_cache[i - 1] = class->cast_cache[i];
+ class->class_cast_cache[i - 1] = class->class_cast_cache[i];
}
- class->cast_cache[i - 1] = typename;
+ class->class_cast_cache[i - 1] = typename;
}
out:
#endif
@@ -659,7 +673,9 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
{
OCFData data = { fn, implements_type, include_abstract, opaque };
+ enumerating_types = true;
g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
+ enumerating_types = false;
}
int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),