Patchwork [qom-cpu-next,v2,1/1] target-cris: Introduce CRISCPU subclasses

login
register
mail settings
Submitter Andreas Färber
Date Feb. 7, 2013, 5:04 p.m.
Message ID <1360256681-8331-2-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/218957/
State New
Headers show

Comments

Andreas Färber - Feb. 7, 2013, 5:04 p.m.
Use class_init functions to initialize the VR in preparation for
overriding v32+ behavior there.

Move cpu_cris_init() to cpu.c and hook up a class_by_name callback.

This change leads to unknown -cpu model names no longer falling back
to a CPU with VR 32 but instead returning NULL.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-cris/cpu-qom.h   |    3 +
 target-cris/cpu.c       |  153 ++++++++++++++++++++++++++++++++++++++++++++++-
 target-cris/translate.c |   48 ---------------
 3 Dateien geändert, 155 Zeilen hinzugefügt(+), 49 Zeilen entfernt(-)
Andreas Färber - Feb. 7, 2013, 5:26 p.m.
Am 07.02.2013 18:04, schrieb Andreas Färber:
> diff --git a/target-cris/cpu.c b/target-cris/cpu.c
> index fedf641..8008988 100644
> --- a/target-cris/cpu.c
> +++ b/target-cris/cpu.c
> @@ -55,6 +55,84 @@ static void cris_cpu_reset(CPUState *s)
>  #endif
>  }
>  
> +static ObjectClass *cris_cpu_class_by_name(const char *cpu_model)
> +{
> +    ObjectClass *oc;
> +    char *typename;
> +
> +    if (cpu_model == NULL) {
> +        return NULL;
> +    }
> +
> +    typename = g_strdup_printf("%s-" TYPE_CRIS_CPU, cpu_model);
> +    oc = object_class_by_name(typename);
> +    g_free(typename);
> +    if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_CRIS_CPU) ||
> +                       object_class_is_abstract(oc))) {
> +        oc = NULL;
> +    }
> +    return oc;
> +}
> +
> +CRISCPU *cpu_cris_init(const char *cpu_model)
> +{
> +    CRISCPU *cpu;
> +    ObjectClass *oc;
> +
> +    oc = cris_cpu_class_by_name(cpu_model);
> +    if (oc == NULL) {
> +        return NULL;
> +    }
> +    cpu = CRIS_CPU(object_new(object_class_get_name(oc)));
> +
> +    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
> +
> +    return cpu;
> +}
> +
> +/* Sort alphabetically by VR. */
> +static gint cris_cpu_list_compare(gconstpointer a, gconstpointer b)
> +{
> +    CRISCPUClass *ccc_a = CRIS_CPU_CLASS(a);
> +    CRISCPUClass *ccc_b = CRIS_CPU_CLASS(b);
> +
> +    /*  */
> +    if (ccc_a->vr > ccc_b->vr) {
> +        return 1;
> +    } else if (ccc_a->vr < ccc_b->vr) {
> +        return -1;
> +    } else {
> +        return 0;
> +    }
> +}
> +
> +static void cris_cpu_list_entry(gpointer data, gpointer user_data)
> +{
> +    ObjectClass *oc = data;
> +    CPUListState *s = user_data;
> +    const char *typename = object_class_get_name(oc);
> +    char *name;
> +
> +    name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_CRIS_CPU));
> +    (*s->cpu_fprintf)(s->file, "  %s\n", name);
> +    g_free(name);
> +}
> +
> +void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
> +{
> +    CPUListState s = {
> +        .file = f,
> +        .cpu_fprintf = cpu_fprintf,
> +    };
> +    GSList *list;
> +
> +    list = object_class_get_list(TYPE_CRIS_CPU, false);
> +    list = g_slist_sort(list, cris_cpu_list_compare);
> +    (*cpu_fprintf)(f, "Available CPUs:\n");
> +    g_slist_foreach(list, cris_cpu_list_entry, &s);
> +    g_slist_free(list);
> +}
> +
>  static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
>  {
>      CRISCPU *cpu = CRIS_CPU(dev);
> @@ -69,11 +147,14 @@ static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
>  static void cris_cpu_initfn(Object *obj)
>  {
>      CRISCPU *cpu = CRIS_CPU(obj);
> +    CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj);
>      CPUCRISState *env = &cpu->env;
>      static bool tcg_initialized;
>  
>      cpu_exec_init(env);
>  
> +    env->pregs[PR_VR] = ccc->vr;
> +
>      if (tcg_enabled() && !tcg_initialized) {
>          tcg_initialized = true;
>          if (env->pregs[PR_VR] < 32) {
> @@ -84,6 +165,69 @@ static void cris_cpu_initfn(Object *obj)
>      }
>  }
>  
> +static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
> +
> +    ccc->vr = 8;
> +}
> +
> +static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
> +
> +    ccc->vr = 9;
> +}
> +
> +static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
> +
> +    ccc->vr = 10;
> +}
> +
> +static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
> +
> +    ccc->vr = 11;
> +}
> +
> +static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
> +
> +    ccc->vr = 32;
> +}
> +
> +#define TYPE(model) model "-" TYPE_CRIS_CPU

Elsewhere Eduardo just suggested to turn this into a global
<arch>_CPU_TYPE(name) macro, so that it can be used for
g_strdup_printf() and strlen() as well.

Would you prefer me to change it that way?

Andreas

> +
> +static const TypeInfo cris_cpu_model_type_infos[] = {
> +    {
> +        .name = TYPE("crisv8"),
> +        .parent = TYPE_CRIS_CPU,
> +        .class_init = crisv8_cpu_class_init,
> +    }, {
> +        .name = TYPE("crisv9"),
> +        .parent = TYPE_CRIS_CPU,
> +        .class_init = crisv9_cpu_class_init,
> +    }, {
> +        .name = TYPE("crisv10"),
> +        .parent = TYPE_CRIS_CPU,
> +        .class_init = crisv10_cpu_class_init,
> +    }, {
> +        .name = TYPE("crisv11"),
> +        .parent = TYPE_CRIS_CPU,
> +        .class_init = crisv11_cpu_class_init,
> +    }, {
> +        .name = TYPE("crisv32"),
> +        .parent = TYPE_CRIS_CPU,
> +        .class_init = crisv32_cpu_class_init,
> +    }
> +};
> +
> +#undef TYPE
> +
>  static void cris_cpu_class_init(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
> @@ -95,6 +239,8 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
>  
>      ccc->parent_reset = cc->reset;
>      cc->reset = cris_cpu_reset;
> +
> +    cc->class_by_name = cris_cpu_class_by_name;
>  }
>  
>  static const TypeInfo cris_cpu_type_info = {
> @@ -102,14 +248,19 @@ static const TypeInfo cris_cpu_type_info = {
>      .parent = TYPE_CPU,
>      .instance_size = sizeof(CRISCPU),
>      .instance_init = cris_cpu_initfn,
> -    .abstract = false,
> +    .abstract = true,
>      .class_size = sizeof(CRISCPUClass),
>      .class_init = cris_cpu_class_init,
>  };
>  
>  static void cris_cpu_register_types(void)
>  {
> +    int i;
> +
>      type_register_static(&cris_cpu_type_info);
> +    for (i = 0; i < ARRAY_SIZE(cris_cpu_model_type_infos); i++) {
> +        type_register_static(&cris_cpu_model_type_infos[i]);
> +    }
>  }
>  
>  type_init(cris_cpu_register_types)
> diff --git a/target-cris/translate.c b/target-cris/translate.c
> index 25a43fa..04a5379 100644
> --- a/target-cris/translate.c
> +++ b/target-cris/translate.c
> @@ -3513,54 +3513,6 @@ void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
>  
>  }
>  
> -struct
> -{
> -    uint32_t vr;
> -    const char *name;
> -} cris_cores[] = {
> -    {8, "crisv8"},
> -    {9, "crisv9"},
> -    {10, "crisv10"},
> -    {11, "crisv11"},
> -    {32, "crisv32"},
> -};
> -
> -void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
> -{
> -    unsigned int i;
> -
> -    (*cpu_fprintf)(f, "Available CPUs:\n");
> -    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
> -        (*cpu_fprintf)(f, "  %s\n", cris_cores[i].name);
> -    }
> -}
> -
> -static uint32_t vr_by_name(const char *name)
> -{
> -    unsigned int i;
> -    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
> -        if (strcmp(name, cris_cores[i].name) == 0) {
> -            return cris_cores[i].vr;
> -        }
> -    }
> -    return 32;
> -}
> -
> -CRISCPU *cpu_cris_init(const char *cpu_model)
> -{
> -    CRISCPU *cpu;
> -    CPUCRISState *env;
> -
> -    cpu = CRIS_CPU(object_new(TYPE_CRIS_CPU));
> -    env = &cpu->env;
> -
> -    env->pregs[PR_VR] = vr_by_name(cpu_model);
> -
> -    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
> -
> -    return cpu;
> -}
> -
>  void cris_initialize_tcg(void)
>  {
>      int i;
>

Patch

diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index 7ad8398..2bac71f 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -35,6 +35,7 @@ 
  * CRISCPUClass:
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
+ * @vr: Version Register value.
  *
  * A CRIS CPU model.
  */
@@ -45,6 +46,8 @@  typedef struct CRISCPUClass {
 
     DeviceRealize parent_realize;
     void (*parent_reset)(CPUState *cpu);
+
+    uint32_t vr;
 } CRISCPUClass;
 
 /**
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index fedf641..8008988 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -55,6 +55,84 @@  static void cris_cpu_reset(CPUState *s)
 #endif
 }
 
+static ObjectClass *cris_cpu_class_by_name(const char *cpu_model)
+{
+    ObjectClass *oc;
+    char *typename;
+
+    if (cpu_model == NULL) {
+        return NULL;
+    }
+
+    typename = g_strdup_printf("%s-" TYPE_CRIS_CPU, cpu_model);
+    oc = object_class_by_name(typename);
+    g_free(typename);
+    if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_CRIS_CPU) ||
+                       object_class_is_abstract(oc))) {
+        oc = NULL;
+    }
+    return oc;
+}
+
+CRISCPU *cpu_cris_init(const char *cpu_model)
+{
+    CRISCPU *cpu;
+    ObjectClass *oc;
+
+    oc = cris_cpu_class_by_name(cpu_model);
+    if (oc == NULL) {
+        return NULL;
+    }
+    cpu = CRIS_CPU(object_new(object_class_get_name(oc)));
+
+    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+
+    return cpu;
+}
+
+/* Sort alphabetically by VR. */
+static gint cris_cpu_list_compare(gconstpointer a, gconstpointer b)
+{
+    CRISCPUClass *ccc_a = CRIS_CPU_CLASS(a);
+    CRISCPUClass *ccc_b = CRIS_CPU_CLASS(b);
+
+    /*  */
+    if (ccc_a->vr > ccc_b->vr) {
+        return 1;
+    } else if (ccc_a->vr < ccc_b->vr) {
+        return -1;
+    } else {
+        return 0;
+    }
+}
+
+static void cris_cpu_list_entry(gpointer data, gpointer user_data)
+{
+    ObjectClass *oc = data;
+    CPUListState *s = user_data;
+    const char *typename = object_class_get_name(oc);
+    char *name;
+
+    name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_CRIS_CPU));
+    (*s->cpu_fprintf)(s->file, "  %s\n", name);
+    g_free(name);
+}
+
+void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+{
+    CPUListState s = {
+        .file = f,
+        .cpu_fprintf = cpu_fprintf,
+    };
+    GSList *list;
+
+    list = object_class_get_list(TYPE_CRIS_CPU, false);
+    list = g_slist_sort(list, cris_cpu_list_compare);
+    (*cpu_fprintf)(f, "Available CPUs:\n");
+    g_slist_foreach(list, cris_cpu_list_entry, &s);
+    g_slist_free(list);
+}
+
 static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     CRISCPU *cpu = CRIS_CPU(dev);
@@ -69,11 +147,14 @@  static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
 static void cris_cpu_initfn(Object *obj)
 {
     CRISCPU *cpu = CRIS_CPU(obj);
+    CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj);
     CPUCRISState *env = &cpu->env;
     static bool tcg_initialized;
 
     cpu_exec_init(env);
 
+    env->pregs[PR_VR] = ccc->vr;
+
     if (tcg_enabled() && !tcg_initialized) {
         tcg_initialized = true;
         if (env->pregs[PR_VR] < 32) {
@@ -84,6 +165,69 @@  static void cris_cpu_initfn(Object *obj)
     }
 }
 
+static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
+{
+    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
+
+    ccc->vr = 8;
+}
+
+static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
+{
+    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
+
+    ccc->vr = 9;
+}
+
+static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
+{
+    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
+
+    ccc->vr = 10;
+}
+
+static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
+{
+    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
+
+    ccc->vr = 11;
+}
+
+static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
+{
+    CRISCPUClass *ccc = CRIS_CPU_CLASS(oc);
+
+    ccc->vr = 32;
+}
+
+#define TYPE(model) model "-" TYPE_CRIS_CPU
+
+static const TypeInfo cris_cpu_model_type_infos[] = {
+    {
+        .name = TYPE("crisv8"),
+        .parent = TYPE_CRIS_CPU,
+        .class_init = crisv8_cpu_class_init,
+    }, {
+        .name = TYPE("crisv9"),
+        .parent = TYPE_CRIS_CPU,
+        .class_init = crisv9_cpu_class_init,
+    }, {
+        .name = TYPE("crisv10"),
+        .parent = TYPE_CRIS_CPU,
+        .class_init = crisv10_cpu_class_init,
+    }, {
+        .name = TYPE("crisv11"),
+        .parent = TYPE_CRIS_CPU,
+        .class_init = crisv11_cpu_class_init,
+    }, {
+        .name = TYPE("crisv32"),
+        .parent = TYPE_CRIS_CPU,
+        .class_init = crisv32_cpu_class_init,
+    }
+};
+
+#undef TYPE
+
 static void cris_cpu_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -95,6 +239,8 @@  static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
     ccc->parent_reset = cc->reset;
     cc->reset = cris_cpu_reset;
+
+    cc->class_by_name = cris_cpu_class_by_name;
 }
 
 static const TypeInfo cris_cpu_type_info = {
@@ -102,14 +248,19 @@  static const TypeInfo cris_cpu_type_info = {
     .parent = TYPE_CPU,
     .instance_size = sizeof(CRISCPU),
     .instance_init = cris_cpu_initfn,
-    .abstract = false,
+    .abstract = true,
     .class_size = sizeof(CRISCPUClass),
     .class_init = cris_cpu_class_init,
 };
 
 static void cris_cpu_register_types(void)
 {
+    int i;
+
     type_register_static(&cris_cpu_type_info);
+    for (i = 0; i < ARRAY_SIZE(cris_cpu_model_type_infos); i++) {
+        type_register_static(&cris_cpu_model_type_infos[i]);
+    }
 }
 
 type_init(cris_cpu_register_types)
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 25a43fa..04a5379 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3513,54 +3513,6 @@  void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
 
 }
 
-struct
-{
-    uint32_t vr;
-    const char *name;
-} cris_cores[] = {
-    {8, "crisv8"},
-    {9, "crisv9"},
-    {10, "crisv10"},
-    {11, "crisv11"},
-    {32, "crisv32"},
-};
-
-void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
-{
-    unsigned int i;
-
-    (*cpu_fprintf)(f, "Available CPUs:\n");
-    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
-        (*cpu_fprintf)(f, "  %s\n", cris_cores[i].name);
-    }
-}
-
-static uint32_t vr_by_name(const char *name)
-{
-    unsigned int i;
-    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
-        if (strcmp(name, cris_cores[i].name) == 0) {
-            return cris_cores[i].vr;
-        }
-    }
-    return 32;
-}
-
-CRISCPU *cpu_cris_init(const char *cpu_model)
-{
-    CRISCPU *cpu;
-    CPUCRISState *env;
-
-    cpu = CRIS_CPU(object_new(TYPE_CRIS_CPU));
-    env = &cpu->env;
-
-    env->pregs[PR_VR] = vr_by_name(cpu_model);
-
-    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
-
-    return cpu;
-}
-
 void cris_initialize_tcg(void)
 {
     int i;