diff options
author | Linaro Packagers <linaro-pkg@lists.launchpad.net> | 2013-08-02 06:39:45 +0000 |
---|---|---|
committer | Fathi Boudra <fathi.boudra@linaro.org> | 2013-08-05 10:19:57 +0300 |
commit | 3ba5745389cb428bf0f99fdde92ed3876ca5e5c8 (patch) | |
tree | 06dc0389b02c64ce9cb23cad85382745c0d6177c /qom | |
parent | c3565b8703553405641c76a4c40961473d051edd (diff) | |
parent | 86342dcc9b73eac8310b9dc5fd1356bbfa5b9c8e (diff) |
Diffstat (limited to 'qom')
-rw-r--r-- | qom/cpu.c | 128 | ||||
-rw-r--r-- | qom/object.c | 131 |
2 files changed, 233 insertions, 26 deletions
@@ -20,6 +20,108 @@ #include "qom/cpu.h" #include "qemu-common.h" +#include "sysemu/kvm.h" +#include "qemu/notify.h" +#include "sysemu/sysemu.h" + +typedef struct CPUExistsArgs { + int64_t id; + bool found; +} CPUExistsArgs; + +static void cpu_exist_cb(CPUState *cpu, void *data) +{ + CPUClass *klass = CPU_GET_CLASS(cpu); + CPUExistsArgs *arg = data; + + if (klass->get_arch_id(cpu) == arg->id) { + arg->found = true; + } +} + +bool cpu_exists(int64_t id) +{ + CPUExistsArgs data = { + .id = id, + .found = false, + }; + + qemu_for_each_cpu(cpu_exist_cb, &data); + return data.found; +} + +/* CPU hot-plug notifiers */ +static NotifierList cpu_added_notifiers = + NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers); + +void qemu_register_cpu_added_notifier(Notifier *notifier) +{ + notifier_list_add(&cpu_added_notifiers, notifier); +} + +void cpu_reset_interrupt(CPUState *cpu, int mask) +{ + cpu->interrupt_request &= ~mask; +} + +int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + return (*cc->write_elf32_qemunote)(f, cpu, opaque); +} + +static int cpu_common_write_elf32_qemunote(WriteCoreDumpFunction f, + CPUState *cpu, void *opaque) +{ + return -1; +} + +int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + return (*cc->write_elf32_note)(f, cpu, cpuid, opaque); +} + +static int cpu_common_write_elf32_note(WriteCoreDumpFunction f, + CPUState *cpu, int cpuid, + void *opaque) +{ + return -1; +} + +int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu, + void *opaque) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + return (*cc->write_elf64_qemunote)(f, cpu, opaque); +} + +static int cpu_common_write_elf64_qemunote(WriteCoreDumpFunction f, + CPUState *cpu, void *opaque) +{ + return -1; +} + +int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, + int cpuid, void *opaque) +{ + CPUClass *cc = CPU_GET_CLASS(cpu); + + return (*cc->write_elf64_note)(f, cpu, cpuid, opaque); +} + +static int cpu_common_write_elf64_note(WriteCoreDumpFunction f, + CPUState *cpu, int cpuid, + void *opaque) +{ + return -1; +} + void cpu_reset(CPUState *cpu) { @@ -32,6 +134,10 @@ void cpu_reset(CPUState *cpu) static void cpu_common_reset(CPUState *cpu) { + cpu->exit_request = 0; + cpu->interrupt_request = 0; + cpu->current_tb = NULL; + cpu->halted = 0; } ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model) @@ -46,6 +152,22 @@ static ObjectClass *cpu_common_class_by_name(const char *cpu_model) return NULL; } +static void cpu_common_realizefn(DeviceState *dev, Error **errp) +{ + CPUState *cpu = CPU(dev); + + if (dev->hotplugged) { + cpu_synchronize_post_init(cpu); + notifier_list_notify(&cpu_added_notifiers, dev); + cpu_resume(cpu); + } +} + +static int64_t cpu_common_get_arch_id(CPUState *cpu) +{ + return cpu->cpu_index; +} + static void cpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -53,6 +175,12 @@ static void cpu_class_init(ObjectClass *klass, void *data) k->class_by_name = cpu_common_class_by_name; k->reset = cpu_common_reset; + k->get_arch_id = cpu_common_get_arch_id; + k->write_elf32_qemunote = cpu_common_write_elf32_qemunote; + k->write_elf32_note = cpu_common_write_elf32_note; + k->write_elf64_qemunote = cpu_common_write_elf64_qemunote; + k->write_elf64_note = cpu_common_write_elf64_note; + dc->realize = cpu_common_realizefn; dc->no_user = 1; } diff --git a/qom/object.c b/qom/object.c index 563e45b..ec88231 100644 --- a/qom/object.c +++ b/qom/object.c @@ -16,6 +16,7 @@ #include "qapi/string-input-visitor.h" #include "qapi/string-output-visitor.h" #include "qapi/qmp/qerror.h" +#include "trace.h" /* TODO: replace QObject with a simpler visitor to avoid a dependency * of the QOM core on QObject? */ @@ -245,6 +246,7 @@ static void type_initialize(TypeImpl *ti) g_assert(parent->class_size <= ti->class_size); memcpy(ti->class, parent->class, parent->class_size); + ti->class->interfaces = NULL; for (e = parent->class->interfaces; e; e = e->next) { ObjectClass *iface = e->data; @@ -361,13 +363,17 @@ static void object_property_del_child(Object *obj, Object *child, Error **errp) void object_unparent(Object *obj) { - object_ref(obj); - if (obj->parent) { - object_property_del_child(obj->parent, obj, NULL); + if (!obj->parent) { + return; } + + object_ref(obj); if (obj->class->unparent) { (obj->class->unparent)(obj); } + if (obj->parent) { + object_property_del_child(obj->parent, obj, NULL); + } object_unref(obj); } @@ -426,29 +432,69 @@ Object *object_dynamic_cast(Object *obj, const char *typename) return NULL; } -Object *object_dynamic_cast_assert(Object *obj, const char *typename) +Object *object_dynamic_cast_assert(Object *obj, const char *typename, + const char *file, int line, const char *func) { + trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)", + typename, file, line, func); + +#ifdef CONFIG_QOM_CAST_DEBUG + int i; Object *inst; + for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) { + if (obj->class->cast_cache[i] == typename) { + goto out; + } + } + inst = object_dynamic_cast(obj, typename); if (!inst && obj) { - fprintf(stderr, "Object %p is not an instance of type %s\n", - obj, typename); + fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", + file, line, func, obj, typename); abort(); } - return inst; + assert(obj == inst); + + if (obj == inst) { + for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { + obj->class->cast_cache[i - 1] = obj->class->cast_cache[i]; + } + obj->class->cast_cache[i - 1] = typename; + } + +out: +#endif + return obj; } ObjectClass *object_class_dynamic_cast(ObjectClass *class, const char *typename) { - TypeImpl *target_type = type_get_by_name(typename); - TypeImpl *type = class->type; ObjectClass *ret = NULL; + TypeImpl *target_type; + TypeImpl *type; + + if (!class) { + return NULL; + } + + /* A simple fast path that can trigger a lot for leaf classes. */ + type = class->type; + if (type->name == typename) { + return class; + } - if (type->num_interfaces && type_is_ancestor(target_type, type_interface)) { + target_type = type_get_by_name(typename); + if (!target_type) { + /* target class type unknown, so fail the cast */ + return NULL; + } + + if (type->class->interfaces && + type_is_ancestor(target_type, type_interface)) { int found = 0; GSList *i; @@ -473,16 +519,46 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *class, } ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, - const char *typename) + const char *typename, + const char *file, int line, + const char *func) { - ObjectClass *ret = object_class_dynamic_cast(class, typename); + ObjectClass *ret; - if (!ret) { - fprintf(stderr, "Object %p is not an instance of type %s\n", - class, typename); + trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)", + typename, file, line, func); + +#ifdef CONFIG_QOM_CAST_DEBUG + int i; + + for (i = 0; i < OBJECT_CLASS_CAST_CACHE; i++) { + if (class->cast_cache[i] == typename) { + ret = class; + goto out; + } + } +#else + if (!class->interfaces) { + return class; + } +#endif + + ret = object_class_dynamic_cast(class, typename); + if (!ret && class) { + fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n", + file, line, func, class, typename); abort(); } +#ifdef CONFIG_QOM_CAST_DEBUG + if (ret == class) { + for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { + class->cast_cache[i - 1] = class->cast_cache[i]; + } + class->cast_cache[i - 1] = typename; + } +out: +#endif return ret; } @@ -627,7 +703,18 @@ void object_property_add(Object *obj, const char *name, const char *type, ObjectPropertyRelease *release, void *opaque, Error **errp) { - ObjectProperty *prop = g_malloc0(sizeof(*prop)); + ObjectProperty *prop; + + QTAILQ_FOREACH(prop, &obj->properties, node) { + if (strcmp(prop->name, name) == 0) { + error_setg(errp, "attempt to add duplicate property '%s'" + " to object (type '%s')", name, + object_get_typename(obj)); + return; + } + } + + prop = g_malloc0(sizeof(*prop)); prop->name = g_strdup(name); prop->type = g_strdup(type); @@ -1096,21 +1183,13 @@ static Object *object_resolve_partial_path(Object *parent, Object *object_resolve_path_type(const char *path, const char *typename, bool *ambiguous) { - bool partial_path = true; Object *obj; gchar **parts; parts = g_strsplit(path, "/", 0); - if (parts == NULL || parts[0] == NULL) { - g_strfreev(parts); - return object_get_root(); - } - - if (strcmp(parts[0], "") == 0) { - partial_path = false; - } + assert(parts); - if (partial_path) { + if (parts[0] == NULL || strcmp(parts[0], "") != 0) { if (ambiguous) { *ambiguous = false; } |