summary refs log tree commit diff stats
path: root/target/mips/cpu.c
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2017-09-20 16:49:33 -0300
committerYongbok Kim <yongbok.kim@imgtec.com>2017-09-21 13:25:30 +0100
commit41da212c9ce9482fcfd490170c2611470254f8dc (patch)
treeb6cf842d42b55759a92bf6b04745f815d3fb3c6d /target/mips/cpu.c
parentdf4dc10284e1d871db8adb512816a561473ffe3e (diff)
downloadfocaccia-qemu-41da212c9ce9482fcfd490170c2611470254f8dc.tar.gz
focaccia-qemu-41da212c9ce9482fcfd490170c2611470254f8dc.zip
mips: MIPSCPU model subclasses
Register separate QOM types for each mips cpu model,
so it would be possible to reuse generic CPU creation
routines.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
[PMD: use internal.h, use void* to hold cpu_def in MIPSCPUClass,
 mark MIPSCPU abstract, address Eduardo Habkost review]
Tested-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
Diffstat (limited to 'target/mips/cpu.c')
-rw-r--r--target/mips/cpu.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index e3ef835599..1a9a3ed94d 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -146,14 +146,36 @@ static void mips_cpu_initfn(Object *obj)
     CPUState *cs = CPU(obj);
     MIPSCPU *cpu = MIPS_CPU(obj);
     CPUMIPSState *env = &cpu->env;
+    MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
 
     cs->env_ptr = env;
+    env->cpu_model = mcc->cpu_def;
 
     if (tcg_enabled()) {
         mips_tcg_init();
     }
 }
 
+static char *mips_cpu_type_name(const char *cpu_model)
+{
+    return g_strdup_printf("%s-" TYPE_MIPS_CPU, cpu_model);
+}
+
+static ObjectClass *mips_cpu_class_by_name(const char *cpu_model)
+{
+    ObjectClass *oc;
+    char *typename;
+
+    if (cpu_model == NULL) {
+        return NULL;
+    }
+
+    typename = mips_cpu_type_name(cpu_model);
+    oc = object_class_by_name(typename);
+    g_free(typename);
+    return oc;
+}
+
 static void mips_cpu_class_init(ObjectClass *c, void *data)
 {
     MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
@@ -166,6 +188,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     mcc->parent_reset = cc->reset;
     cc->reset = mips_cpu_reset;
 
+    cc->class_by_name = mips_cpu_class_by_name;
     cc->has_work = mips_cpu_has_work;
     cc->do_interrupt = mips_cpu_do_interrupt;
     cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
@@ -193,14 +216,39 @@ static const TypeInfo mips_cpu_type_info = {
     .parent = TYPE_CPU,
     .instance_size = sizeof(MIPSCPU),
     .instance_init = mips_cpu_initfn,
-    .abstract = false,
+    .abstract = true,
     .class_size = sizeof(MIPSCPUClass),
     .class_init = mips_cpu_class_init,
 };
 
+static void mips_cpu_cpudef_class_init(ObjectClass *oc, void *data)
+{
+    MIPSCPUClass *mcc = MIPS_CPU_CLASS(oc);
+    mcc->cpu_def = data;
+}
+
+static void mips_register_cpudef_type(const struct mips_def_t *def)
+{
+    char *typename = mips_cpu_type_name(def->name);
+    TypeInfo ti = {
+        .name = typename,
+        .parent = TYPE_MIPS_CPU,
+        .class_init = mips_cpu_cpudef_class_init,
+        .class_data = (void *)def,
+    };
+
+    type_register(&ti);
+    g_free(typename);
+}
+
 static void mips_cpu_register_types(void)
 {
+    int i;
+
     type_register_static(&mips_cpu_type_info);
+    for (i = 0; i < mips_defs_number; i++) {
+        mips_register_cpudef_type(&mips_defs[i]);
+    }
 }
 
 type_init(mips_cpu_register_types)