Loading target-sh4/cpu-qom.h +7 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #define TYPE_SUPERH_CPU "superh-cpu" #define TYPE_SH7750R_CPU "sh7750r-" TYPE_SUPERH_CPU #define TYPE_SH7751R_CPU "sh7751r-" TYPE_SUPERH_CPU #define TYPE_SH7785_CPU "sh7785-" TYPE_SUPERH_CPU #define SUPERH_CPU_CLASS(klass) \ OBJECT_CLASS_CHECK(SuperHCPUClass, (klass), TYPE_SUPERH_CPU) #define SUPERH_CPU(obj) \ Loading @@ -35,6 +39,7 @@ * SuperHCPUClass: * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * @name: The name. * * A SuperH CPU model. */ Loading @@ -45,6 +50,8 @@ typedef struct SuperHCPUClass { DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); const char *name; } SuperHCPUClass; /** Loading target-sh4/cpu.c +179 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,180 @@ static void superh_cpu_reset(CPUState *s) set_default_nan_mode(1, &env->fp_status); } typedef struct SuperHCPUListState { fprintf_function cpu_fprintf; FILE *file; } SuperHCPUListState; /* Sort alphabetically by type name. */ static gint superh_cpu_list_compare(gconstpointer a, gconstpointer b) { ObjectClass *class_a = (ObjectClass *)a; ObjectClass *class_b = (ObjectClass *)b; const char *name_a, *name_b; name_a = object_class_get_name(class_a); name_b = object_class_get_name(class_b); return strcmp(name_a, name_b); } static void superh_cpu_list_entry(gpointer data, gpointer user_data) { ObjectClass *oc = data; SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); SuperHCPUListState *s = user_data; (*s->cpu_fprintf)(s->file, "%s\n", scc->name); } void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) { SuperHCPUListState s = { .cpu_fprintf = cpu_fprintf, .file = f, }; GSList *list; list = object_class_get_list(TYPE_SUPERH_CPU, false); list = g_slist_sort(list, superh_cpu_list_compare); g_slist_foreach(list, superh_cpu_list_entry, &s); g_slist_free(list); } static gint superh_cpu_name_compare(gconstpointer a, gconstpointer b) { const SuperHCPUClass *scc = SUPERH_CPU_CLASS(a); const char *name = b; return strcasecmp(scc->name, name); } static ObjectClass *superh_cpu_class_by_name(const char *cpu_model) { ObjectClass *oc; GSList *list, *item; if (cpu_model == NULL) { return NULL; } if (strcasecmp(cpu_model, "any") == 0) { return object_class_by_name(TYPE_SH7750R_CPU); } oc = object_class_by_name(cpu_model); if (oc != NULL && object_class_dynamic_cast(oc, TYPE_SUPERH_CPU) != NULL && !object_class_is_abstract(oc)) { return oc; } oc = NULL; list = object_class_get_list(TYPE_SUPERH_CPU, false); item = g_slist_find_custom(list, cpu_model, superh_cpu_name_compare); if (item != NULL) { oc = item->data; } g_slist_free(list); return oc; } SuperHCPU *cpu_sh4_init(const char *cpu_model) { SuperHCPU *cpu; CPUSH4State *env; ObjectClass *oc; oc = superh_cpu_class_by_name(cpu_model); if (oc == NULL) { return NULL; } cpu = SUPERH_CPU(object_new(object_class_get_name(oc))); env = &cpu->env; env->cpu_model_str = cpu_model; object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; } static void sh7750r_cpu_initfn(Object *obj) { SuperHCPU *cpu = SUPERH_CPU(obj); CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7750R; env->pvr = 0x00050000; env->prr = 0x00000100; env->cvr = 0x00110000; env->features = SH_FEATURE_BCR3_AND_BCR4; } static void sh7750r_class_init(ObjectClass *oc, void *data) { SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7750R"; } static const TypeInfo sh7750r_type_info = { .name = TYPE_SH7750R_CPU, .parent = TYPE_SUPERH_CPU, .class_init = sh7750r_class_init, .instance_init = sh7750r_cpu_initfn, }; static void sh7751r_cpu_initfn(Object *obj) { SuperHCPU *cpu = SUPERH_CPU(obj); CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7751R; env->pvr = 0x04050005; env->prr = 0x00000113; env->cvr = 0x00110000; /* Neutered caches, should be 0x20480000 */ env->features = SH_FEATURE_BCR3_AND_BCR4; } static void sh7751r_class_init(ObjectClass *oc, void *data) { SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7751R"; } static const TypeInfo sh7751r_type_info = { .name = TYPE_SH7751R_CPU, .parent = TYPE_SUPERH_CPU, .class_init = sh7751r_class_init, .instance_init = sh7751r_cpu_initfn, }; static void sh7785_cpu_initfn(Object *obj) { SuperHCPU *cpu = SUPERH_CPU(obj); CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7785; env->pvr = 0x10300700; env->prr = 0x00000200; env->cvr = 0x71440211; env->features = SH_FEATURE_SH4A; } static void sh7785_class_init(ObjectClass *oc, void *data) { SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7785"; } static const TypeInfo sh7785_type_info = { .name = TYPE_SH7785_CPU, .parent = TYPE_SUPERH_CPU, .class_init = sh7785_class_init, .instance_init = sh7785_cpu_initfn, }; static void superh_cpu_realizefn(DeviceState *dev, Error **errp) { SuperHCPU *cpu = SUPERH_CPU(dev); Loading Loading @@ -98,6 +272,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) scc->parent_reset = cc->reset; cc->reset = superh_cpu_reset; cc->class_by_name = superh_cpu_class_by_name; dc->vmsd = &vmstate_sh_cpu; } Loading @@ -106,7 +281,7 @@ static const TypeInfo superh_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(SuperHCPU), .instance_init = superh_cpu_initfn, .abstract = false, .abstract = true, .class_size = sizeof(SuperHCPUClass), .class_init = superh_cpu_class_init, }; Loading @@ -114,6 +289,9 @@ static const TypeInfo superh_cpu_type_info = { static void superh_cpu_register_types(void) { type_register_static(&superh_cpu_type_info); type_register_static(&sh7750r_type_info); type_register_static(&sh7751r_type_info); type_register_static(&sh7785_type_info); } type_init(superh_cpu_register_types) target-sh4/translate.c +0 −84 Original line number Diff line number Diff line Loading @@ -175,90 +175,6 @@ void cpu_dump_state(CPUSH4State * env, FILE * f, } } typedef struct { const char *name; int id; uint32_t pvr; uint32_t prr; uint32_t cvr; uint32_t features; } sh4_def_t; static sh4_def_t sh4_defs[] = { { .name = "SH7750R", .id = SH_CPU_SH7750R, .pvr = 0x00050000, .prr = 0x00000100, .cvr = 0x00110000, .features = SH_FEATURE_BCR3_AND_BCR4, }, { .name = "SH7751R", .id = SH_CPU_SH7751R, .pvr = 0x04050005, .prr = 0x00000113, .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */ .features = SH_FEATURE_BCR3_AND_BCR4, }, { .name = "SH7785", .id = SH_CPU_SH7785, .pvr = 0x10300700, .prr = 0x00000200, .cvr = 0x71440211, .features = SH_FEATURE_SH4A, }, }; static const sh4_def_t *cpu_sh4_find_by_name(const char *name) { int i; if (strcasecmp(name, "any") == 0) return &sh4_defs[0]; for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) if (strcasecmp(name, sh4_defs[i].name) == 0) return &sh4_defs[i]; return NULL; } void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) { int i; for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name); } static void cpu_register(CPUSH4State *env, const sh4_def_t *def) { env->pvr = def->pvr; env->prr = def->prr; env->cvr = def->cvr; env->id = def->id; } SuperHCPU *cpu_sh4_init(const char *cpu_model) { SuperHCPU *cpu; CPUSH4State *env; const sh4_def_t *def; def = cpu_sh4_find_by_name(cpu_model); if (!def) return NULL; cpu = SUPERH_CPU(object_new(TYPE_SUPERH_CPU)); env = &cpu->env; env->features = def->features; env->cpu_model_str = cpu_model; cpu_register(env, def); object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; } static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) { TranslationBlock *tb; Loading Loading
target-sh4/cpu-qom.h +7 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #define TYPE_SUPERH_CPU "superh-cpu" #define TYPE_SH7750R_CPU "sh7750r-" TYPE_SUPERH_CPU #define TYPE_SH7751R_CPU "sh7751r-" TYPE_SUPERH_CPU #define TYPE_SH7785_CPU "sh7785-" TYPE_SUPERH_CPU #define SUPERH_CPU_CLASS(klass) \ OBJECT_CLASS_CHECK(SuperHCPUClass, (klass), TYPE_SUPERH_CPU) #define SUPERH_CPU(obj) \ Loading @@ -35,6 +39,7 @@ * SuperHCPUClass: * @parent_realize: The parent class' realize handler. * @parent_reset: The parent class' reset handler. * @name: The name. * * A SuperH CPU model. */ Loading @@ -45,6 +50,8 @@ typedef struct SuperHCPUClass { DeviceRealize parent_realize; void (*parent_reset)(CPUState *cpu); const char *name; } SuperHCPUClass; /** Loading
target-sh4/cpu.c +179 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,180 @@ static void superh_cpu_reset(CPUState *s) set_default_nan_mode(1, &env->fp_status); } typedef struct SuperHCPUListState { fprintf_function cpu_fprintf; FILE *file; } SuperHCPUListState; /* Sort alphabetically by type name. */ static gint superh_cpu_list_compare(gconstpointer a, gconstpointer b) { ObjectClass *class_a = (ObjectClass *)a; ObjectClass *class_b = (ObjectClass *)b; const char *name_a, *name_b; name_a = object_class_get_name(class_a); name_b = object_class_get_name(class_b); return strcmp(name_a, name_b); } static void superh_cpu_list_entry(gpointer data, gpointer user_data) { ObjectClass *oc = data; SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); SuperHCPUListState *s = user_data; (*s->cpu_fprintf)(s->file, "%s\n", scc->name); } void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) { SuperHCPUListState s = { .cpu_fprintf = cpu_fprintf, .file = f, }; GSList *list; list = object_class_get_list(TYPE_SUPERH_CPU, false); list = g_slist_sort(list, superh_cpu_list_compare); g_slist_foreach(list, superh_cpu_list_entry, &s); g_slist_free(list); } static gint superh_cpu_name_compare(gconstpointer a, gconstpointer b) { const SuperHCPUClass *scc = SUPERH_CPU_CLASS(a); const char *name = b; return strcasecmp(scc->name, name); } static ObjectClass *superh_cpu_class_by_name(const char *cpu_model) { ObjectClass *oc; GSList *list, *item; if (cpu_model == NULL) { return NULL; } if (strcasecmp(cpu_model, "any") == 0) { return object_class_by_name(TYPE_SH7750R_CPU); } oc = object_class_by_name(cpu_model); if (oc != NULL && object_class_dynamic_cast(oc, TYPE_SUPERH_CPU) != NULL && !object_class_is_abstract(oc)) { return oc; } oc = NULL; list = object_class_get_list(TYPE_SUPERH_CPU, false); item = g_slist_find_custom(list, cpu_model, superh_cpu_name_compare); if (item != NULL) { oc = item->data; } g_slist_free(list); return oc; } SuperHCPU *cpu_sh4_init(const char *cpu_model) { SuperHCPU *cpu; CPUSH4State *env; ObjectClass *oc; oc = superh_cpu_class_by_name(cpu_model); if (oc == NULL) { return NULL; } cpu = SUPERH_CPU(object_new(object_class_get_name(oc))); env = &cpu->env; env->cpu_model_str = cpu_model; object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; } static void sh7750r_cpu_initfn(Object *obj) { SuperHCPU *cpu = SUPERH_CPU(obj); CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7750R; env->pvr = 0x00050000; env->prr = 0x00000100; env->cvr = 0x00110000; env->features = SH_FEATURE_BCR3_AND_BCR4; } static void sh7750r_class_init(ObjectClass *oc, void *data) { SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7750R"; } static const TypeInfo sh7750r_type_info = { .name = TYPE_SH7750R_CPU, .parent = TYPE_SUPERH_CPU, .class_init = sh7750r_class_init, .instance_init = sh7750r_cpu_initfn, }; static void sh7751r_cpu_initfn(Object *obj) { SuperHCPU *cpu = SUPERH_CPU(obj); CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7751R; env->pvr = 0x04050005; env->prr = 0x00000113; env->cvr = 0x00110000; /* Neutered caches, should be 0x20480000 */ env->features = SH_FEATURE_BCR3_AND_BCR4; } static void sh7751r_class_init(ObjectClass *oc, void *data) { SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7751R"; } static const TypeInfo sh7751r_type_info = { .name = TYPE_SH7751R_CPU, .parent = TYPE_SUPERH_CPU, .class_init = sh7751r_class_init, .instance_init = sh7751r_cpu_initfn, }; static void sh7785_cpu_initfn(Object *obj) { SuperHCPU *cpu = SUPERH_CPU(obj); CPUSH4State *env = &cpu->env; env->id = SH_CPU_SH7785; env->pvr = 0x10300700; env->prr = 0x00000200; env->cvr = 0x71440211; env->features = SH_FEATURE_SH4A; } static void sh7785_class_init(ObjectClass *oc, void *data) { SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc); scc->name = "SH7785"; } static const TypeInfo sh7785_type_info = { .name = TYPE_SH7785_CPU, .parent = TYPE_SUPERH_CPU, .class_init = sh7785_class_init, .instance_init = sh7785_cpu_initfn, }; static void superh_cpu_realizefn(DeviceState *dev, Error **errp) { SuperHCPU *cpu = SUPERH_CPU(dev); Loading Loading @@ -98,6 +272,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data) scc->parent_reset = cc->reset; cc->reset = superh_cpu_reset; cc->class_by_name = superh_cpu_class_by_name; dc->vmsd = &vmstate_sh_cpu; } Loading @@ -106,7 +281,7 @@ static const TypeInfo superh_cpu_type_info = { .parent = TYPE_CPU, .instance_size = sizeof(SuperHCPU), .instance_init = superh_cpu_initfn, .abstract = false, .abstract = true, .class_size = sizeof(SuperHCPUClass), .class_init = superh_cpu_class_init, }; Loading @@ -114,6 +289,9 @@ static const TypeInfo superh_cpu_type_info = { static void superh_cpu_register_types(void) { type_register_static(&superh_cpu_type_info); type_register_static(&sh7750r_type_info); type_register_static(&sh7751r_type_info); type_register_static(&sh7785_type_info); } type_init(superh_cpu_register_types)
target-sh4/translate.c +0 −84 Original line number Diff line number Diff line Loading @@ -175,90 +175,6 @@ void cpu_dump_state(CPUSH4State * env, FILE * f, } } typedef struct { const char *name; int id; uint32_t pvr; uint32_t prr; uint32_t cvr; uint32_t features; } sh4_def_t; static sh4_def_t sh4_defs[] = { { .name = "SH7750R", .id = SH_CPU_SH7750R, .pvr = 0x00050000, .prr = 0x00000100, .cvr = 0x00110000, .features = SH_FEATURE_BCR3_AND_BCR4, }, { .name = "SH7751R", .id = SH_CPU_SH7751R, .pvr = 0x04050005, .prr = 0x00000113, .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */ .features = SH_FEATURE_BCR3_AND_BCR4, }, { .name = "SH7785", .id = SH_CPU_SH7785, .pvr = 0x10300700, .prr = 0x00000200, .cvr = 0x71440211, .features = SH_FEATURE_SH4A, }, }; static const sh4_def_t *cpu_sh4_find_by_name(const char *name) { int i; if (strcasecmp(name, "any") == 0) return &sh4_defs[0]; for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) if (strcasecmp(name, sh4_defs[i].name) == 0) return &sh4_defs[i]; return NULL; } void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) { int i; for (i = 0; i < ARRAY_SIZE(sh4_defs); i++) (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name); } static void cpu_register(CPUSH4State *env, const sh4_def_t *def) { env->pvr = def->pvr; env->prr = def->prr; env->cvr = def->cvr; env->id = def->id; } SuperHCPU *cpu_sh4_init(const char *cpu_model) { SuperHCPU *cpu; CPUSH4State *env; const sh4_def_t *def; def = cpu_sh4_find_by_name(cpu_model); if (!def) return NULL; cpu = SUPERH_CPU(object_new(TYPE_SUPERH_CPU)); env = &cpu->env; env->features = def->features; env->cpu_model_str = cpu_model; cpu_register(env, def); object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; } static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) { TranslationBlock *tb; Loading