diff options
Diffstat (limited to 'target-sh4')
-rw-r--r-- | target-sh4/cpu.h | 17 | ||||
-rw-r--r-- | target-sh4/translate.c | 59 |
2 files changed, 76 insertions, 0 deletions
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 01c2a07..686b668 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -27,6 +27,15 @@ #define ELF_MACHINE EM_SH +/* CPU Subtypes */ +#define SH_CPU_SH7750 (1 << 0) +#define SH_CPU_SH7750S (1 << 1) +#define SH_CPU_SH7750R (1 << 2) +#define SH_CPU_SH7751 (1 << 3) +#define SH_CPU_SH7751R (1 << 4) +#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R) +#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R) + #include "cpu-defs.h" #include "softfloat.h" @@ -80,6 +89,8 @@ typedef struct tlb_t { #define NB_MMU_MODES 2 typedef struct CPUSH4State { + int id; /* CPU model */ + uint32_t flags; /* general execution flags */ uint32_t gregs[24]; /* general registers */ float32 fregs[32]; /* floating point registers */ @@ -112,6 +123,10 @@ typedef struct CPUSH4State { uint32_t expevt; /* exception event register */ uint32_t intevt; /* interrupt event register */ + uint32_t pvr; /* Processor Version Register */ + uint32_t prr; /* Processor Revision Register */ + uint32_t cvr; /* Cache Version Register */ + CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; @@ -122,6 +137,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model); int cpu_sh4_exec(CPUSH4State * s); int cpu_sh4_signal_handler(int host_signum, void *pinfo, void *puc); +void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, uint32_t mem_value); @@ -132,6 +148,7 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, #define cpu_exec cpu_sh4_exec #define cpu_gen_code cpu_sh4_gen_code #define cpu_signal_handler cpu_sh4_signal_handler +#define cpu_list sh4_cpu_list /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 80fb24f..8e97696 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -176,16 +176,75 @@ void cpu_sh4_reset(CPUSH4State * env) env->mmucr = 0; } +typedef struct { + const unsigned char *name; + int id; + uint32_t pvr; + uint32_t prr; + uint32_t cvr; +} sh4_def_t; + +static sh4_def_t sh4_defs[] = { + { + .name = "SH7750R", + .id = SH_CPU_SH7750R, + .pvr = 0x00050000, + .prr = 0x00000100, + .cvr = 0x00110000, + }, { + .name = "SH7751R", + .id = SH_CPU_SH7751R, + .pvr = 0x04050005, + .prr = 0x00000113, + .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */ + }, +}; + +static const sh4_def_t *cpu_sh4_find_by_name(const unsigned char *name) +{ + int i; + + if (strcasecmp(name, "any") == 0) + return &sh4_defs[0]; + + for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++) + if (strcasecmp(name, sh4_defs[i].name) == 0) + return &sh4_defs[i]; + + return NULL; +} + +void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) +{ + int i; + + for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++) + (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name); +} + +static int cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def) +{ + env->pvr = def->pvr; + env->prr = def->prr; + env->cvr = def->cvr; + env->id = def->id; +} + CPUSH4State *cpu_sh4_init(const char *cpu_model) { CPUSH4State *env; + const sh4_def_t *def; + def = cpu_sh4_find_by_name(cpu_model); + if (!def) + return NULL; env = qemu_mallocz(sizeof(CPUSH4State)); if (!env) return NULL; cpu_exec_init(env); sh4_translate_init(); cpu_sh4_reset(env); + cpu_sh4_register(env, def); tlb_flush(env, 1); return env; } |