mips: MIPSCPU model subclasses

Register separate QOM types for each mips cpu model,
so it would be possible to reuse generic CPU creation
routines.

Backports commit 41da212c9ce9482fcfd490170c2611470254f8dc from qemu
This commit is contained in:
Igor Mammedov 2018-03-05 00:38:03 -05:00 committed by Lioncash
parent 4729b633f1
commit 97b525a794
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7
10 changed files with 146 additions and 66 deletions

View File

@ -4439,6 +4439,8 @@ mips_symbols = (
'mips_cpu_list',
'mips_cpu_register_types',
'mips_cpu_unassigned_access',
'mips_defs',
'mips_defs_number',
'mips_machine_init',
'mips_reg_read',
'mips_reg_reset',

View File

@ -4373,6 +4373,8 @@
#define mips_cpu_list mips_cpu_list_mips
#define mips_cpu_register_types mips_cpu_register_types_mips
#define mips_cpu_unassigned_access mips_cpu_unassigned_access_mips
#define mips_defs mips_defs_mips
#define mips_defs_number mips_defs_number_mips
#define mips_machine_init mips_machine_init_mips
#define mips_reg_read mips_reg_read_mips
#define mips_reg_reset mips_reg_reset_mips

View File

@ -4373,6 +4373,8 @@
#define mips_cpu_list mips_cpu_list_mips64
#define mips_cpu_register_types mips_cpu_register_types_mips64
#define mips_cpu_unassigned_access mips_cpu_unassigned_access_mips64
#define mips_defs mips_defs_mips64
#define mips_defs_number mips_defs_number_mips64
#define mips_machine_init mips_machine_init_mips64
#define mips_reg_read mips_reg_read_mips64
#define mips_reg_reset mips_reg_reset_mips64

View File

@ -4373,6 +4373,8 @@
#define mips_cpu_list mips_cpu_list_mips64el
#define mips_cpu_register_types mips_cpu_register_types_mips64el
#define mips_cpu_unassigned_access mips_cpu_unassigned_access_mips64el
#define mips_defs mips_defs_mips64el
#define mips_defs_number mips_defs_number_mips64el
#define mips_machine_init mips_machine_init_mips64el
#define mips_reg_read mips_reg_read_mips64el
#define mips_reg_reset mips_reg_reset_mips64el

View File

@ -4373,6 +4373,8 @@
#define mips_cpu_list mips_cpu_list_mipsel
#define mips_cpu_register_types mips_cpu_register_types_mipsel
#define mips_cpu_unassigned_access mips_cpu_unassigned_access_mipsel
#define mips_defs mips_defs_mipsel
#define mips_defs_number mips_defs_number_mipsel
#define mips_machine_init mips_machine_init_mipsel
#define mips_reg_read mips_reg_read_mipsel
#define mips_reg_reset mips_reg_reset_mipsel

View File

@ -48,6 +48,7 @@ typedef struct MIPSCPUClass {
DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
const struct mips_def_t *cpu_def;
} MIPSCPUClass;
typedef struct MIPSCPU MIPSCPU;

View File

@ -126,8 +126,10 @@ static void mips_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)
CPUState *cs = CPU(obj);
MIPSCPU *cpu = MIPS_CPU(uc, obj);
CPUMIPSState *env = &cpu->env;
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(uc, obj);
cs->env_ptr = env;
env->cpu_model = mcc->cpu_def;
cpu_exec_init(cs, opaque);
if (tcg_enabled(uc)) {
@ -135,6 +137,26 @@ static void mips_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque)
}
}
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(struct uc_struct *uc, 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(uc, typename);
g_free(typename);
return oc;
}
static void mips_cpu_class_init(struct uc_struct *uc, ObjectClass *c, void *data)
{
MIPSCPUClass *mcc = MIPS_CPU_CLASS(uc, c);
@ -147,6 +169,7 @@ static void mips_cpu_class_init(struct uc_struct *uc, ObjectClass *c, void *data
mcc->parent_reset = cc->reset;
cc->reset = mips_cpu_reset;
cc->class_by_name = mips_cpu_class_by_name;
cc->has_work = mips_cpu_has_work;
cc->do_interrupt = mips_cpu_do_interrupt;
cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
@ -161,16 +184,56 @@ static void mips_cpu_class_init(struct uc_struct *uc, ObjectClass *c, void *data
#endif
}
static void mips_cpu_cpudef_class_init(struct uc_struct *uc, ObjectClass *oc, void *data)
{
MIPSCPUClass *mcc = MIPS_CPU_CLASS(uc, oc);
mcc->cpu_def = data;
}
static void mips_register_cpudef_type(struct uc_struct *uc, const struct mips_def_t *def)
{
char *typename = mips_cpu_type_name(def->name);
TypeInfo ti = {
typename,
TYPE_MIPS_CPU,
0,
0,
NULL,
NULL,
NULL,
NULL,
(void *)def,
mips_cpu_cpudef_class_init,
NULL,
NULL,
false,
NULL,
NULL,
NULL,
};
type_register(uc, &ti);
g_free(typename);
}
void mips_cpu_register_types(void *opaque)
{
int i;
const TypeInfo mips_cpu_type_info = {
TYPE_MIPS_CPU,
TYPE_CPU,
sizeof(MIPSCPUClass),
sizeof(MIPSCPU),
opaque,
mips_cpu_initfn,
NULL,
NULL,
@ -181,8 +244,11 @@ void mips_cpu_register_types(void *opaque)
NULL,
NULL,
false,
true,
};
type_register_static(opaque, &mips_cpu_type_info);
for (i = 0; i < mips_defs_number; i++) {
mips_register_cpudef_type(opaque, &mips_defs[i]);
}
}

View File

@ -7,6 +7,64 @@
#ifndef 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 {
DF_BYTE = 0,
DF_HALF,

View File

@ -20729,16 +20729,15 @@ void cpu_mips_realize_env(CPUMIPSState *env)
MIPSCPU *cpu_mips_init(struct uc_struct *uc, const char *cpu_model)
{
ObjectClass *oc;
MIPSCPU *cpu;
CPUMIPSState *env;
const mips_def_t *def;
def = cpu_mips_find_by_name(cpu_model);
if (!def)
oc = cpu_class_by_name(uc, TYPE_MIPS_CPU, cpu_model);
if (oc == NULL) {
return NULL;
cpu = MIPS_CPU(uc, object_new(uc, TYPE_MIPS_CPU));
env = &cpu->env;
env->cpu_model = def;
}
cpu = MIPS_CPU(uc, object_new(uc, object_class_get_name(oc)));
object_property_set_bool(uc, OBJECT(cpu), true, "realized", NULL);

View File

@ -51,64 +51,9 @@
#define MIPS_CONFIG5 \
((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 */
static const mips_def_t mips_defs[] =
const mips_def_t mips_defs[] =
{
{
"4Kc",
@ -1099,6 +1044,7 @@ static const mips_def_t mips_defs[] =
},
#endif
};
const int mips_defs_number = ARRAY_SIZE(mips_defs);
static const mips_def_t *cpu_mips_find_by_name (const char *name)
{