On Wed, 2012-03-14 at 02:39 +0100, Andreas Färber wrote: > Embed CPUUniCore32State into UniCore32CPU. > > Contributed under GPLv2+. > > Signed-off-by: Andreas Färber <afaer...@suse.de> > --- > Makefile.target | 1 + > target-unicore32/cpu-qom.h | 72 ++++++++++++++++++++++++++++++++++ > target-unicore32/cpu.c | 91 > ++++++++++++++++++++++++++++++++++++++++++++ I hope the gpl information for cpu.c and cpu-qom.h could be consistent with other files.
Guan Xuetao > target-unicore32/cpu.h | 1 + > target-unicore32/helper.c | 43 +++----------------- > 5 files changed, 172 insertions(+), 36 deletions(-) > create mode 100644 target-unicore32/cpu-qom.h > create mode 100644 target-unicore32/cpu.c > > diff --git a/Makefile.target b/Makefile.target > index cbf62c0..7033df0 100644 > --- a/Makefile.target > +++ b/Makefile.target > @@ -94,6 +94,7 @@ libobj-y += cpu_init.o > endif > libobj-$(TARGET_SPARC) += int32_helper.o > libobj-$(TARGET_SPARC64) += int64_helper.o > +libobj-$(TARGET_UNICORE32) += cpu.o > > libobj-y += disas.o > libobj-$(CONFIG_TCI_DIS) += tci-dis.o > diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h > new file mode 100644 > index 0000000..afe47e8 > --- /dev/null > +++ b/target-unicore32/cpu-qom.h > @@ -0,0 +1,72 @@ > +/* > + * QEMU UniCore32 CPU > + * > + * Copyright (c) 2012 SUSE LINUX Products GmbH > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, see > + * <http://www.gnu.org/licenses/gpl-2.0.html> > + */ > +#ifndef QEMU_UC32_CPU_QOM_H > +#define QEMU_UC32_CPU_QOM_H > + > +#include "qemu/cpu.h" > +#include "cpu.h" > + > +#define TYPE_UNICORE32_CPU "unicore32-cpu" > + > +#define UNICORE32_CPU_CLASS(klass) \ > + OBJECT_CLASS_CHECK(UniCore32CPUClass, (klass), TYPE_UNICORE32_CPU) > +#define UNICORE32_CPU(obj) \ > + OBJECT_CHECK(UniCore32CPU, (obj), TYPE_UNICORE32_CPU) > +#define UNICORE32_CPU_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(UniCore32CPUClass, (obj), TYPE_UNICORE32_CPU) > + > +/** > + * UniCore32CPUClass: > + * > + * A UniCore32 CPU model. > + */ > +typedef struct UniCore32CPUClass { > + /*< private >*/ > + CPUClass parent_class; > + /*< public >*/ > + > + struct { > + uint32_t c0_cpuid; > + } cp0; > +} UniCore32CPUClass; > + > +/** > + * UniCore32CPU: > + * @env: Legacy CPU state. > + * > + * A UniCore32 CPU. > + */ > +typedef struct UniCore32CPU { > + /*< private >*/ > + CPUState parent_obj; > + /*< public >*/ > + > + CPUUniCore32State env; > +} UniCore32CPU; > + > +static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env) > +{ > + return UNICORE32_CPU(container_of(env, UniCore32CPU, env)); > +} > + > +#define ENV_GET_CPU(e) CPU(uc32_env_get_cpu(e)) > + > + > +#endif > diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c > new file mode 100644 > index 0000000..b89a1c6 > --- /dev/null > +++ b/target-unicore32/cpu.c > @@ -0,0 +1,91 @@ > +/* > + * QEMU UniCore32 CPU > + * > + * Copyright (c) 2010-2011 GUAN Xue-tao > + * Copyright (c) 2012 SUSE LINUX Products GmbH > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#include "cpu-qom.h" > +#include "qemu-common.h" > + > +/* CPU models */ > + > +typedef struct UniCore32CPUInfo { > + const char *name; > + uint32_t cp0_c0_cpuid; > +} UniCore32CPUInfo; > + > +static const UniCore32CPUInfo uc32_cpus[] = { > + { > + .name = "UniCore-II", > + .cp0_c0_cpuid = 0x40010863, > + }, > + { > + .name = "any", > + .cp0_c0_cpuid = 0xffffffff, > + } > +}; > + > +static void uc32_cpu_initfn(Object *obj) > +{ > + UniCore32CPU *cpu = UNICORE32_CPU(obj); > + UniCore32CPUClass *klass = UNICORE32_CPU_GET_CLASS(cpu); > + CPUUniCore32State *env = &cpu->env; > + > + memset(env, 0, sizeof(CPUUniCore32State)); > + cpu_exec_init(env); > + env->cpu_model_str = object_get_typename(obj); > + env->cp0.c0_cpuid = klass->cp0.c0_cpuid; > + > + env->uncached_asr = ASR_MODE_USER; > + env->regs[31] = 0; > + > + tlb_flush(env, 1); > +} > + > +static void uc32_cpu_class_init(ObjectClass *klass, void *data) > +{ > + UniCore32CPUClass *k = UNICORE32_CPU_CLASS(klass); > + const UniCore32CPUInfo *info = data; > + > + k->cp0.c0_cpuid = info->cp0_c0_cpuid; > +} > + > +static void uc32_register_cpu(const UniCore32CPUInfo *info) > +{ > + TypeInfo type = { > + .name = info->name, > + .parent = TYPE_UNICORE32_CPU, > + .instance_size = sizeof(UniCore32CPU), > + .class_size = sizeof(UniCore32CPUClass), > + .class_init = uc32_cpu_class_init, > + .class_data = (void *)info, > + }; > + > + type_register_static(&type); > +} > + > +static const TypeInfo uc32_cpu_info = { > + .name = TYPE_UNICORE32_CPU, > + .parent = TYPE_CPU, > + .instance_size = sizeof(UniCore32CPU), > + .instance_init = uc32_cpu_initfn, > + .abstract = true, > + .class_size = sizeof(UniCore32CPUClass), > +}; > + > +static void uc32_cpu_register_types(void) > +{ > + int i; > + > + type_register_static(&uc32_cpu_info); > + for (i = 0; i < ARRAY_SIZE(uc32_cpus); i++) { > + uc32_register_cpu(&uc32_cpus[i]); > + } > +} > + > +type_init(uc32_cpu_register_types) > diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h > index 9cbee7a..1ddd272 100644 > --- a/target-unicore32/cpu.h > +++ b/target-unicore32/cpu.h > @@ -158,6 +158,7 @@ static inline void cpu_set_tls(CPUUniCore32State *env, > target_ulong newtls) > } > > #include "cpu-all.h" > +#include "cpu-qom.h" > #include "exec-all.h" > > static inline void cpu_pc_from_tb(CPUUniCore32State *env, TranslationBlock > *tb) > diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c > index 6af492d..44b7842 100644 > --- a/target-unicore32/helper.c > +++ b/target-unicore32/helper.c > @@ -16,43 +16,20 @@ static inline void set_feature(CPUUniCore32State *env, > int feature) > env->features |= feature; > } > > -struct uc32_cpu_t { > - uint32_t id; > - const char *name; > -}; > - > -static const struct uc32_cpu_t uc32_cpu_names[] = { > - { UC32_CPUID_UCV2, "UniCore-II"}, > - { UC32_CPUID_ANY, "any"}, > - { 0, NULL} > -}; > - > -/* return 0 if not found */ > -static uint32_t uc32_cpu_find_by_name(const char *name) > -{ > - int i; > - uint32_t id; > - > - id = 0; > - for (i = 0; uc32_cpu_names[i].name; i++) { > - if (strcmp(name, uc32_cpu_names[i].name) == 0) { > - id = uc32_cpu_names[i].id; > - break; > - } > - } > - return id; > -} > - > CPUUniCore32State *uc32_cpu_init(const char *cpu_model) > { > + UniCore32CPU *cpu; > CPUUniCore32State *env; > uint32_t id; > static int inited = 1; > > - env = g_malloc0(sizeof(CPUUniCore32State)); > - cpu_exec_init(env); > + if (object_class_by_name(cpu_model) == NULL) { > + return NULL; > + } > + cpu = UNICORE32_CPU(object_new(cpu_model)); > + env = &cpu->env; > > - id = uc32_cpu_find_by_name(cpu_model); > + id = env->cp0.c0_cpuid; > switch (id) { > case UC32_CPUID_UCV2: > set_feature(env, UC32_HWCAP_CMOV); > @@ -69,17 +46,11 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model) > cpu_abort(env, "Bad CPU ID: %x\n", id); > } > > - env->cpu_model_str = cpu_model; > - env->cp0.c0_cpuid = id; > - env->uncached_asr = ASR_MODE_USER; > - env->regs[31] = 0; > - > if (inited) { > inited = 0; > uc32_translate_init(); > } > > - tlb_flush(env, 1); > qemu_init_vcpu(env); > return env; > }