From patchwork Sat Feb 16 15:45:29 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: 221017 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 72C332C0082 for ; Sun, 17 Feb 2013 04:44:29 +1100 (EST) Received: from localhost ([::1]:55333 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U6loJ-0001Yo-NE for incoming@patchwork.ozlabs.org; Sat, 16 Feb 2013 12:44:27 -0500 Received: from eggs.gnu.org ([208.118.235.92]:39189) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U6k1B-0005Fl-CI for qemu-devel@nongnu.org; Sat, 16 Feb 2013 10:49:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1U6k18-0002T6-I0 for qemu-devel@nongnu.org; Sat, 16 Feb 2013 10:49:37 -0500 Received: from cantor2.suse.de ([195.135.220.15]:40418 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1U6k18-0002Sx-1a for qemu-devel@nongnu.org; Sat, 16 Feb 2013 10:49:34 -0500 Received: from relay1.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 7D451A4EB7; Sat, 16 Feb 2013 16:49:33 +0100 (CET) From: =?UTF-8?q?Andreas=20F=C3=A4rber?= To: qemu-devel@nongnu.org Date: Sat, 16 Feb 2013 16:45:29 +0100 Message-Id: <1361029542-8412-35-git-send-email-afaerber@suse.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1361029542-8412-1-git-send-email-afaerber@suse.de> References: <1361029542-8412-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: "Edgar E. Iglesias" , =?UTF-8?q?Andreas=20F=C3=A4rber?= Subject: [Qemu-devel] [PATCH 34/47] target-cris: Introduce CRISCPU 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 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. Acked-by: Edgar E. Iglesias Signed-off-by: Andreas Färber --- 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(-) 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;