mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-04-17 08:32:07 +00:00
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:
parent
4729b633f1
commit
97b525a794
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue