From patchwork Mon Jan 21 03:28:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 214024 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 152E72C009D for ; Mon, 21 Jan 2013 14:28:58 +1100 (EST) Received: from localhost ([::1]:41499 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tx848-0005Su-8i for incoming@patchwork.ozlabs.org; Sun, 20 Jan 2013 22:28:56 -0500 Received: from eggs.gnu.org ([208.118.235.92]:35376) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tx83t-0005LM-7v for qemu-devel@nongnu.org; Sun, 20 Jan 2013 22:28:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tx83p-0001HD-Jy for qemu-devel@nongnu.org; Sun, 20 Jan 2013 22:28:41 -0500 Received: from cantor2.suse.de ([195.135.220.15]:46159 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tx83p-0001G5-6t for qemu-devel@nongnu.org; Sun, 20 Jan 2013 22:28:37 -0500 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 9A41AA3CEE; Mon, 21 Jan 2013 04:28:36 +0100 (CET) From: =?UTF-8?q?Andreas=20F=C3=A4rber?= To: qemu-devel@nongnu.org Date: Mon, 21 Jan 2013 04:28:25 +0100 Message-Id: <1358738906-13224-2-git-send-email-afaerber@suse.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1358738906-13224-1-git-send-email-afaerber@suse.de> References: <1358738906-13224-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: =?UTF-8?q?Andreas=20F=C3=A4rber?= , Aurelien Jarno Subject: [Qemu-devel] [RFC qom-cpu v2 1/2] target-sh4: Introduce SuperHCPU subclasses X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Store legacy name in SuperHCPUClass for -cpu ? and for case-insensitive class lookup. List CPUs by iterating over TYPE_SUPERH_CPU subclasses. Signed-off-by: Andreas Färber --- target-sh4/cpu-qom.h | 7 +++ target-sh4/cpu.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++- target-sh4/translate.c | 94 +++++++++++++----------------------- 3 Dateien geändert, 162 Zeilen hinzugefügt(+), 63 Zeilen entfernt(-) diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h index d368db1..8326ceb 100644 --- a/target-sh4/cpu-qom.h +++ b/target-sh4/cpu-qom.h @@ -24,6 +24,10 @@ #define TYPE_SUPERH_CPU "superh-cpu" +#define TYPE_SH7750R_CPU "sh7750r-" TYPE_SUPERH_CPU +#define TYPE_SH7751R_CPU "sh7751r-" TYPE_SUPERH_CPU +#define TYPE_SH7785_CPU "sh7785-" TYPE_SUPERH_CPU + #define SUPERH_CPU_CLASS(klass) \ OBJECT_CLASS_CHECK(SuperHCPUClass, (klass), TYPE_SUPERH_CPU) #define SUPERH_CPU(obj) \ @@ -35,6 +39,7 @@ * SuperHCPUClass: * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. + * @name: The name. * * A SuperH CPU model. */ @@ -45,6 +50,8 @@ typedef struct SuperHCPUClass { DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); + + const char *name; } SuperHCPUClass; /** diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c index 223008a..80804ef 100644 --- a/target-sh4/cpu.c +++ b/target-sh4/cpu.c @@ -53,6 +53,125 @@ static void superh_cpu_reset(CPUState *s) set_default_nan_mode(1, &env->fp_status); } +typedef struct SuperHCPUListState { + fprintf_function cpu_fprintf; + FILE *file; +} SuperHCPUListState; + +/* Sort alphabetically by type name. */ +static gint superh_cpu_list_compare(gconstpointer a, gconstpointer b) +{ + ObjectClass *class_a = (ObjectClass *)a; + ObjectClass *class_b = (ObjectClass *)b; + const char *name_a, *name_b; + + name_a = object_class_get_name(class_a); + name_b = object_class_get_name(class_b); + return strcmp(name_a, name_b); +} + +static void superh_cpu_list_entry(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + SuperHCPUListState *s = user_data; + + (*s->cpu_fprintf)(s->file, "%s\n", + scc->name); +} + +void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) +{ + SuperHCPUListState s = { + .cpu_fprintf = cpu_fprintf, + .file = f, + }; + GSList *list; + + list = object_class_get_list(TYPE_SUPERH_CPU, false); + list = g_slist_sort(list, superh_cpu_list_compare); + g_slist_foreach(list, superh_cpu_list_entry, &s); + g_slist_free(list); +} + +static void sh7750r_cpu_initfn(Object *obj) +{ + SuperHCPU *cpu = SUPERH_CPU(obj); + CPUSH4State *env = &cpu->env; + + env->id = SH_CPU_SH7750R; + env->pvr = 0x00050000; + env->prr = 0x00000100; + env->cvr = 0x00110000; + env->features = SH_FEATURE_BCR3_AND_BCR4; +} + +static void sh7750r_class_init(ObjectClass *oc, void *data) +{ + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + + scc->name = "SH7750R"; +} + +static const TypeInfo sh7750r_type_info = { + .name = TYPE_SH7750R_CPU, + .parent = TYPE_SUPERH_CPU, + .class_init = sh7750r_class_init, + .instance_init = sh7750r_cpu_initfn, +}; + +static void sh7751r_cpu_initfn(Object *obj) +{ + SuperHCPU *cpu = SUPERH_CPU(obj); + CPUSH4State *env = &cpu->env; + + env->id = SH_CPU_SH7751R; + env->pvr = 0x04050005; + env->prr = 0x00000113; + env->cvr = 0x00110000; /* Neutered caches, should be 0x20480000 */ + env->features = SH_FEATURE_BCR3_AND_BCR4; +} + +static void sh7751r_class_init(ObjectClass *oc, void *data) +{ + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + + scc->name = "SH7751R"; +} + +static const TypeInfo sh7751r_type_info = { + .name = TYPE_SH7751R_CPU, + .parent = TYPE_SUPERH_CPU, + .class_init = sh7751r_class_init, + .instance_init = sh7751r_cpu_initfn, +}; + +static void sh7785_cpu_initfn(Object *obj) +{ + SuperHCPU *cpu = SUPERH_CPU(obj); + CPUSH4State *env = &cpu->env; + + env->id = SH_CPU_SH7785; + env->pvr = 0x10300700; + env->prr = 0x00000200; + env->cvr = 0x71440211; + env->features = SH_FEATURE_SH4A; +} + +static void sh7785_class_init(ObjectClass *oc, void *data) +{ + SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); + + scc->name = "SH7785"; +} + +static const TypeInfo sh7785_type_info = { + .name = TYPE_SH7785_CPU, + .parent = TYPE_SUPERH_CPU, + .class_init = sh7785_class_init, + .instance_init = sh7785_cpu_initfn, +}; + static void superh_cpu_realizefn(DeviceState *dev, Error **errp) { SuperHCPU *cpu = SUPERH_CPU(dev); @@ -96,7 +215,7 @@ static const TypeInfo superh_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(SuperHCPU), .instance_init = superh_cpu_initfn, - .abstract = false, + .abstract = true, .class_size = sizeof(SuperHCPUClass), .class_init = superh_cpu_class_init, }; @@ -104,6 +223,9 @@ static const TypeInfo superh_cpu_type_info = { static void superh_cpu_register_types(void) { type_register_static(&superh_cpu_type_info); + type_register_static(&sh7750r_type_info); + type_register_static(&sh7751r_type_info); + type_register_static(&sh7785_type_info); } type_init(superh_cpu_register_types) diff --git a/target-sh4/translate.c b/target-sh4/translate.c index c58d79a..2bdf3b2 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -175,84 +175,54 @@ void cpu_dump_state(CPUSH4State * env, FILE * f, } } -typedef struct { - const char *name; - int id; - uint32_t pvr; - uint32_t prr; - uint32_t cvr; - uint32_t features; -} sh4_def_t; - -static sh4_def_t sh4_defs[] = { - { - .name = "SH7750R", - .id = SH_CPU_SH7750R, - .pvr = 0x00050000, - .prr = 0x00000100, - .cvr = 0x00110000, - .features = SH_FEATURE_BCR3_AND_BCR4, - }, { - .name = "SH7751R", - .id = SH_CPU_SH7751R, - .pvr = 0x04050005, - .prr = 0x00000113, - .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */ - .features = SH_FEATURE_BCR3_AND_BCR4, - }, { - .name = "SH7785", - .id = SH_CPU_SH7785, - .pvr = 0x10300700, - .prr = 0x00000200, - .cvr = 0x71440211, - .features = SH_FEATURE_SH4A, - }, -}; - -static const sh4_def_t *cpu_sh4_find_by_name(const char *name) +static gint superh_cpu_name_compare(gconstpointer a, gconstpointer b) { - int i; + const SuperHCPUClass *scc = SUPERH_CPU_CLASS(a); + const char *name = b; - if (strcasecmp(name, "any") == 0) - return &sh4_defs[0]; - - for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) - if (strcasecmp(name, sh4_defs[i].name) == 0) - return &sh4_defs[i]; - - return NULL; + return strcasecmp(scc->name, name); } -void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) +static ObjectClass *superh_cpu_class_by_name(const char *cpu_model) { - int i; + ObjectClass *oc; + GSList *list, *item; - for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) - (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name); -} + if (cpu_model == NULL) { + return NULL; + } + if (strcasecmp(cpu_model, "any") == 0) { + return object_class_by_name(TYPE_SH7750R_CPU); + } -static void cpu_register(CPUSH4State *env, const sh4_def_t *def) -{ - env->pvr = def->pvr; - env->prr = def->prr; - env->cvr = def->cvr; - env->id = def->id; + oc = object_class_by_name(cpu_model); + if (oc != NULL && object_class_dynamic_cast(oc, TYPE_SUPERH_CPU) != NULL) { + return oc; + } + + oc = NULL; + list = object_class_get_list(TYPE_SUPERH_CPU, false); + item = g_slist_find_custom(list, cpu_model, superh_cpu_name_compare); + if (item != NULL) { + oc = item->data; + } + g_slist_free(list); + return oc; } SuperHCPU *cpu_sh4_init(const char *cpu_model) { SuperHCPU *cpu; CPUSH4State *env; - const sh4_def_t *def; + ObjectClass *oc; - def = cpu_sh4_find_by_name(cpu_model); - if (!def) - return NULL; - cpu = SUPERH_CPU(object_new(TYPE_SUPERH_CPU)); + oc = superh_cpu_class_by_name(cpu_model); + if (oc == NULL) { + return NULL; + } + cpu = SUPERH_CPU(object_new(object_class_get_name(oc))); env = &cpu->env; - env->features = def->features; env->cpu_model_str = cpu_model; - cpu_register(env, def); object_property_set_bool(OBJECT(cpu), true, "realized", NULL);