mirror of https://github.com/xemu-project/xemu.git
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>
This commit is contained in:
parent
df4dc10284
commit
41da212c9c
|
@ -49,6 +49,7 @@ typedef struct MIPSCPUClass {
|
||||||
|
|
||||||
DeviceRealize parent_realize;
|
DeviceRealize parent_realize;
|
||||||
void (*parent_reset)(CPUState *cpu);
|
void (*parent_reset)(CPUState *cpu);
|
||||||
|
const struct mips_def_t *cpu_def;
|
||||||
} MIPSCPUClass;
|
} MIPSCPUClass;
|
||||||
|
|
||||||
typedef struct MIPSCPU MIPSCPU;
|
typedef struct MIPSCPU MIPSCPU;
|
||||||
|
|
|
@ -146,14 +146,36 @@ static void mips_cpu_initfn(Object *obj)
|
||||||
CPUState *cs = CPU(obj);
|
CPUState *cs = CPU(obj);
|
||||||
MIPSCPU *cpu = MIPS_CPU(obj);
|
MIPSCPU *cpu = MIPS_CPU(obj);
|
||||||
CPUMIPSState *env = &cpu->env;
|
CPUMIPSState *env = &cpu->env;
|
||||||
|
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
|
||||||
|
|
||||||
cs->env_ptr = env;
|
cs->env_ptr = env;
|
||||||
|
env->cpu_model = mcc->cpu_def;
|
||||||
|
|
||||||
if (tcg_enabled()) {
|
if (tcg_enabled()) {
|
||||||
mips_tcg_init();
|
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)
|
static void mips_cpu_class_init(ObjectClass *c, void *data)
|
||||||
{
|
{
|
||||||
MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
|
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;
|
mcc->parent_reset = cc->reset;
|
||||||
cc->reset = mips_cpu_reset;
|
cc->reset = mips_cpu_reset;
|
||||||
|
|
||||||
|
cc->class_by_name = mips_cpu_class_by_name;
|
||||||
cc->has_work = mips_cpu_has_work;
|
cc->has_work = mips_cpu_has_work;
|
||||||
cc->do_interrupt = mips_cpu_do_interrupt;
|
cc->do_interrupt = mips_cpu_do_interrupt;
|
||||||
cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
|
cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
|
||||||
|
@ -193,14 +216,39 @@ static const TypeInfo mips_cpu_type_info = {
|
||||||
.parent = TYPE_CPU,
|
.parent = TYPE_CPU,
|
||||||
.instance_size = sizeof(MIPSCPU),
|
.instance_size = sizeof(MIPSCPU),
|
||||||
.instance_init = mips_cpu_initfn,
|
.instance_init = mips_cpu_initfn,
|
||||||
.abstract = false,
|
.abstract = true,
|
||||||
.class_size = sizeof(MIPSCPUClass),
|
.class_size = sizeof(MIPSCPUClass),
|
||||||
.class_init = mips_cpu_class_init,
|
.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)
|
static void mips_cpu_register_types(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
type_register_static(&mips_cpu_type_info);
|
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)
|
type_init(mips_cpu_register_types)
|
||||||
|
|
|
@ -7,6 +7,65 @@
|
||||||
#ifndef MIPS_INTERNAL_H
|
#ifndef MIPS_INTERNAL_H
|
||||||
#define MIPS_INTERNAL_H
|
#define MIPS_INTERNAL_H
|
||||||
|
|
||||||
|
|
||||||
|
/* MMU types, the first four entries have the same layout as the
|
||||||
|
CP0C0_MT field. */
|
||||||
|
enum mips_mmu_types {
|
||||||
|
MMU_TYPE_NONE,
|
||||||
|
MMU_TYPE_R4000,
|
||||||
|
MMU_TYPE_RESERVED,
|
||||||
|
MMU_TYPE_FMT,
|
||||||
|
MMU_TYPE_R3000,
|
||||||
|
MMU_TYPE_R6000,
|
||||||
|
MMU_TYPE_R8000
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mips_def_t {
|
||||||
|
const char *name;
|
||||||
|
int32_t CP0_PRid;
|
||||||
|
int32_t CP0_Config0;
|
||||||
|
int32_t CP0_Config1;
|
||||||
|
int32_t CP0_Config2;
|
||||||
|
int32_t CP0_Config3;
|
||||||
|
int32_t CP0_Config4;
|
||||||
|
int32_t CP0_Config4_rw_bitmask;
|
||||||
|
int32_t CP0_Config5;
|
||||||
|
int32_t CP0_Config5_rw_bitmask;
|
||||||
|
int32_t CP0_Config6;
|
||||||
|
int32_t CP0_Config7;
|
||||||
|
target_ulong CP0_LLAddr_rw_bitmask;
|
||||||
|
int CP0_LLAddr_shift;
|
||||||
|
int32_t SYNCI_Step;
|
||||||
|
int32_t CCRes;
|
||||||
|
int32_t CP0_Status_rw_bitmask;
|
||||||
|
int32_t CP0_TCStatus_rw_bitmask;
|
||||||
|
int32_t CP0_SRSCtl;
|
||||||
|
int32_t CP1_fcr0;
|
||||||
|
int32_t CP1_fcr31_rw_bitmask;
|
||||||
|
int32_t CP1_fcr31;
|
||||||
|
int32_t MSAIR;
|
||||||
|
int32_t SEGBITS;
|
||||||
|
int32_t PABITS;
|
||||||
|
int32_t CP0_SRSConf0_rw_bitmask;
|
||||||
|
int32_t CP0_SRSConf0;
|
||||||
|
int32_t CP0_SRSConf1_rw_bitmask;
|
||||||
|
int32_t CP0_SRSConf1;
|
||||||
|
int32_t CP0_SRSConf2_rw_bitmask;
|
||||||
|
int32_t CP0_SRSConf2;
|
||||||
|
int32_t CP0_SRSConf3_rw_bitmask;
|
||||||
|
int32_t CP0_SRSConf3;
|
||||||
|
int32_t CP0_SRSConf4_rw_bitmask;
|
||||||
|
int32_t CP0_SRSConf4;
|
||||||
|
int32_t CP0_PageGrain_rw_bitmask;
|
||||||
|
int32_t CP0_PageGrain;
|
||||||
|
target_ulong CP0_EBaseWG_rw_bitmask;
|
||||||
|
int insn_flags;
|
||||||
|
enum mips_mmu_types mmu_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct mips_def_t mips_defs[];
|
||||||
|
extern const int mips_defs_number;
|
||||||
|
|
||||||
enum CPUMIPSMSADataFormat {
|
enum CPUMIPSMSADataFormat {
|
||||||
DF_BYTE = 0,
|
DF_BYTE = 0,
|
||||||
DF_HALF,
|
DF_HALF,
|
||||||
|
|
|
@ -20525,16 +20525,15 @@ void cpu_mips_realize_env(CPUMIPSState *env)
|
||||||
|
|
||||||
MIPSCPU *cpu_mips_init(const char *cpu_model)
|
MIPSCPU *cpu_mips_init(const char *cpu_model)
|
||||||
{
|
{
|
||||||
|
ObjectClass *oc;
|
||||||
MIPSCPU *cpu;
|
MIPSCPU *cpu;
|
||||||
CPUMIPSState *env;
|
|
||||||
const mips_def_t *def;
|
|
||||||
|
|
||||||
def = cpu_mips_find_by_name(cpu_model);
|
oc = cpu_class_by_name(TYPE_MIPS_CPU, cpu_model);
|
||||||
if (!def)
|
if (oc == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
|
}
|
||||||
env = &cpu->env;
|
|
||||||
env->cpu_model = def;
|
cpu = MIPS_CPU(object_new(object_class_get_name(oc)));
|
||||||
|
|
||||||
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
|
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
|
||||||
|
|
||||||
|
|
|
@ -51,64 +51,9 @@
|
||||||
#define MIPS_CONFIG5 \
|
#define MIPS_CONFIG5 \
|
||||||
((0 << CP0C5_M))
|
((0 << CP0C5_M))
|
||||||
|
|
||||||
/* MMU types, the first four entries have the same layout as the
|
|
||||||
CP0C0_MT field. */
|
|
||||||
enum mips_mmu_types {
|
|
||||||
MMU_TYPE_NONE,
|
|
||||||
MMU_TYPE_R4000,
|
|
||||||
MMU_TYPE_RESERVED,
|
|
||||||
MMU_TYPE_FMT,
|
|
||||||
MMU_TYPE_R3000,
|
|
||||||
MMU_TYPE_R6000,
|
|
||||||
MMU_TYPE_R8000
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mips_def_t {
|
|
||||||
const char *name;
|
|
||||||
int32_t CP0_PRid;
|
|
||||||
int32_t CP0_Config0;
|
|
||||||
int32_t CP0_Config1;
|
|
||||||
int32_t CP0_Config2;
|
|
||||||
int32_t CP0_Config3;
|
|
||||||
int32_t CP0_Config4;
|
|
||||||
int32_t CP0_Config4_rw_bitmask;
|
|
||||||
int32_t CP0_Config5;
|
|
||||||
int32_t CP0_Config5_rw_bitmask;
|
|
||||||
int32_t CP0_Config6;
|
|
||||||
int32_t CP0_Config7;
|
|
||||||
target_ulong CP0_LLAddr_rw_bitmask;
|
|
||||||
int CP0_LLAddr_shift;
|
|
||||||
int32_t SYNCI_Step;
|
|
||||||
int32_t CCRes;
|
|
||||||
int32_t CP0_Status_rw_bitmask;
|
|
||||||
int32_t CP0_TCStatus_rw_bitmask;
|
|
||||||
int32_t CP0_SRSCtl;
|
|
||||||
int32_t CP1_fcr0;
|
|
||||||
int32_t CP1_fcr31_rw_bitmask;
|
|
||||||
int32_t CP1_fcr31;
|
|
||||||
int32_t MSAIR;
|
|
||||||
int32_t SEGBITS;
|
|
||||||
int32_t PABITS;
|
|
||||||
int32_t CP0_SRSConf0_rw_bitmask;
|
|
||||||
int32_t CP0_SRSConf0;
|
|
||||||
int32_t CP0_SRSConf1_rw_bitmask;
|
|
||||||
int32_t CP0_SRSConf1;
|
|
||||||
int32_t CP0_SRSConf2_rw_bitmask;
|
|
||||||
int32_t CP0_SRSConf2;
|
|
||||||
int32_t CP0_SRSConf3_rw_bitmask;
|
|
||||||
int32_t CP0_SRSConf3;
|
|
||||||
int32_t CP0_SRSConf4_rw_bitmask;
|
|
||||||
int32_t CP0_SRSConf4;
|
|
||||||
int32_t CP0_PageGrain_rw_bitmask;
|
|
||||||
int32_t CP0_PageGrain;
|
|
||||||
target_ulong CP0_EBaseWG_rw_bitmask;
|
|
||||||
int insn_flags;
|
|
||||||
enum mips_mmu_types mmu_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* MIPS CPU definitions */
|
/* MIPS CPU definitions */
|
||||||
static const mips_def_t mips_defs[] =
|
const mips_def_t mips_defs[] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
.name = "4Kc",
|
.name = "4Kc",
|
||||||
|
@ -808,6 +753,7 @@ static const mips_def_t mips_defs[] =
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
const int mips_defs_number = ARRAY_SIZE(mips_defs);
|
||||||
|
|
||||||
static const mips_def_t *cpu_mips_find_by_name (const char *name)
|
static const mips_def_t *cpu_mips_find_by_name (const char *name)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue