From 97b525a7945d409badaecc420cecef6182764d39 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 5 Mar 2018 00:38:03 -0500 Subject: [PATCH] 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 --- qemu/header_gen.py | 2 + qemu/mips.h | 2 + qemu/mips64.h | 2 + qemu/mips64el.h | 2 + qemu/mipsel.h | 2 + qemu/target/mips/cpu-qom.h | 1 + qemu/target/mips/cpu.c | 72 +++++++++++++++++++++++++++++-- qemu/target/mips/internal.h | 58 +++++++++++++++++++++++++ qemu/target/mips/translate.c | 13 +++--- qemu/target/mips/translate_init.c | 58 +------------------------ 10 files changed, 146 insertions(+), 66 deletions(-) diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 4fa20500..48096d17 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -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', diff --git a/qemu/mips.h b/qemu/mips.h index 81c9f208..cccc840e 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -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 diff --git a/qemu/mips64.h b/qemu/mips64.h index 549d9aff..ba1c5352 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -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 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 576fbb0b..30a1b5fb 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -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 diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 7bfa5a3a..a8e34774 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -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 diff --git a/qemu/target/mips/cpu-qom.h b/qemu/target/mips/cpu-qom.h index 76b852ef..9a8ea387 100644 --- a/qemu/target/mips/cpu-qom.h +++ b/qemu/target/mips/cpu-qom.h @@ -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; diff --git a/qemu/target/mips/cpu.c b/qemu/target/mips/cpu.c index 053f2231..2dfdd4c4 100644 --- a/qemu/target/mips/cpu.c +++ b/qemu/target/mips/cpu.c @@ -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]); + } } diff --git a/qemu/target/mips/internal.h b/qemu/target/mips/internal.h index b65e164d..b8351d0a 100644 --- a/qemu/target/mips/internal.h +++ b/qemu/target/mips/internal.h @@ -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, diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index 51b17eb6..ca677b55 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -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); diff --git a/qemu/target/mips/translate_init.c b/qemu/target/mips/translate_init.c index c0628f8a..751a26e0 100644 --- a/qemu/target/mips/translate_init.c +++ b/qemu/target/mips/translate_init.c @@ -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) {