qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH qom-cpu v2 21/42] target-xtensa: Introduce XtensaCPU


From: Andreas Färber
Subject: [Qemu-devel] [PATCH qom-cpu v2 21/42] target-xtensa: Introduce XtensaCPU subclasses
Date: Sun, 7 Jul 2013 20:26:10 +0200

Register a CPU type per core registered. Save the XtensaConfig in
XtensaCPUClass and copy it from there to CPUXtensaState, to avoid
touching every env->config access for now.

Prepares for storing per-class GDB register count.

Signed-off-by: Andreas Färber <address@hidden>
---
 target-xtensa/cpu-qom.h |  3 +++
 target-xtensa/cpu.c     | 24 +++++++++++++++++++++++-
 target-xtensa/helper.c  | 32 +++++++++++++++++++++-----------
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index b9896f2..1b9479e 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -45,6 +45,7 @@
  * XtensaCPUClass:
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
+ * @config: The CPU core configuration.
  *
  * An Xtensa CPU model.
  */
@@ -55,6 +56,8 @@ typedef struct XtensaCPUClass {
 
     DeviceRealize parent_realize;
     void (*parent_reset)(CPUState *cpu);
+
+    const XtensaConfig *config;
 } XtensaCPUClass;
 
 /**
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index d2bcfc6..5a39971 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -64,6 +64,25 @@ static void xtensa_cpu_reset(CPUState *s)
     reset_mmu(env);
 }
 
+static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
+{
+    ObjectClass *oc;
+    char *typename;
+
+    if (cpu_model == NULL) {
+        return NULL;
+    }
+
+    typename = g_strdup_printf("%s-" TYPE_XTENSA_CPU, cpu_model);
+    oc = object_class_by_name(typename);
+    g_free(typename);
+    if (oc == NULL || !object_class_dynamic_cast(oc, TYPE_XTENSA_CPU) ||
+        object_class_is_abstract(oc)) {
+        return NULL;
+    }
+    return oc;
+}
+
 static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
@@ -75,10 +94,12 @@ static void xtensa_cpu_initfn(Object *obj)
 {
     CPUState *cs = CPU(obj);
     XtensaCPU *cpu = XTENSA_CPU(obj);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(obj);
     CPUXtensaState *env = &cpu->env;
     static bool tcg_inited;
 
     cs->env_ptr = env;
+    env->config = xcc->config;
     cpu_exec_init(env);
 
     if (tcg_enabled() && !tcg_inited) {
@@ -105,6 +126,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void 
*data)
     xcc->parent_reset = cc->reset;
     cc->reset = xtensa_cpu_reset;
 
+    cc->class_by_name = xtensa_cpu_class_by_name;
     cc->do_interrupt = xtensa_cpu_do_interrupt;
     cc->dump_state = xtensa_cpu_dump_state;
     cc->set_pc = xtensa_cpu_set_pc;
@@ -119,7 +141,7 @@ static const TypeInfo xtensa_cpu_type_info = {
     .parent = TYPE_CPU,
     .instance_size = sizeof(XtensaCPU),
     .instance_init = xtensa_cpu_initfn,
-    .abstract = false,
+    .abstract = true,
     .class_size = sizeof(XtensaCPUClass),
     .class_init = xtensa_cpu_class_init,
 };
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index de6cc3b..e309879 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -35,10 +35,27 @@
 
 static struct XtensaConfigList *xtensa_cores;
 
+static void xtensa_core_class_init(ObjectClass *oc, void *data)
+{
+    XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
+    const XtensaConfig *config = data;
+
+    xcc->config = config;
+}
+
 void xtensa_register_core(XtensaConfigList *node)
 {
+    TypeInfo type = {
+        .parent = TYPE_XTENSA_CPU,
+        .class_init = xtensa_core_class_init,
+        .class_data = (void *)node->config,
+    };
+
     node->next = xtensa_cores;
     xtensa_cores = node;
+    type.name = g_strdup_printf("%s-" TYPE_XTENSA_CPU, node->config->name);
+    type_register(&type);
+    g_free((gpointer)type.name);
 }
 
 static uint32_t check_hw_breakpoints(CPUXtensaState *env)
@@ -72,24 +89,17 @@ void xtensa_breakpoint_handler(CPUXtensaState *env)
 
 XtensaCPU *cpu_xtensa_init(const char *cpu_model)
 {
+    ObjectClass *oc;
     XtensaCPU *cpu;
     CPUXtensaState *env;
-    const XtensaConfig *config = NULL;
-    XtensaConfigList *core = xtensa_cores;
-
-    for (; core; core = core->next)
-        if (strcmp(core->config->name, cpu_model) == 0) {
-            config = core->config;
-            break;
-        }
 
-    if (config == NULL) {
+    oc = cpu_class_by_name(TYPE_XTENSA_CPU, cpu_model);
+    if (oc == NULL) {
         return NULL;
     }
 
-    cpu = XTENSA_CPU(object_new(TYPE_XTENSA_CPU));
+    cpu = XTENSA_CPU(object_new(object_class_get_name(oc)));
     env = &cpu->env;
-    env->config = config;
 
     xtensa_irq_init(env);
 
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]