diff options
-rw-r--r-- | hw/r2d.c | 2 | ||||
-rw-r--r-- | hw/sh7750.c | 43 | ||||
-rw-r--r-- | target-sh4/cpu.h | 17 | ||||
-rw-r--r-- | target-sh4/translate.c | 59 |
4 files changed, 94 insertions, 27 deletions
@@ -39,7 +39,7 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size, struct SH7750State *s; if (!cpu_model) - cpu_model = "any"; + cpu_model = "SH7751R"; env = cpu_init(cpu_model); if (!env) { diff --git a/hw/sh7750.c b/hw/sh7750.c index 04a7437530..62c226e371 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -249,12 +249,12 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) return s->cpu->intevt; case SH7750_CCR_A7: return s->ccr; - case 0x1f000030: /* Processor version PVR */ - return 0x00050000; /* SH7750R */ - case 0x1f000040: /* Processor version CVR */ - return 0x00110000; /* Minimum caches */ - case 0x1f000044: /* Processor version PRR */ - return 0x00000100; /* SH7750R */ + case 0x1f000030: /* Processor version */ + return s->cpu->pvr; + case 0x1f000040: /* Cache version */ + return s->cpu->cvr; + case 0x1f000044: /* Processor revision */ + return s->cpu->prr; default: error_access("long read", addr); assert(0); @@ -529,14 +529,6 @@ static struct intc_group groups_pci[] = { PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), }; -#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) - /********************************************************************** Memory mapped cache and TLB **********************************************************************/ @@ -644,7 +636,6 @@ SH7750State *sh7750_init(CPUSH4State * cpu) SH7750State *s; int sh7750_io_memory; int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */ - int cpu_model = SH_CPU_SH7751R; /* for now */ s = qemu_mallocz(sizeof(SH7750State)); s->cpu = cpu; @@ -664,7 +655,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu) _INTC_ARRAY(mask_registers), _INTC_ARRAY(prio_registers)); - sh_intc_register_sources(&s->intc, + sh_intc_register_sources(&s->intc, _INTC_ARRAY(vectors), _INTC_ARRAY(groups)); @@ -692,20 +683,20 @@ SH7750State *sh7750_init(CPUSH4State * cpu) sh_intc_source(&s->intc, TMU2_TUNI), sh_intc_source(&s->intc, TMU2_TICPI)); - if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) { - sh_intc_register_sources(&s->intc, + if (cpu->id & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) { + sh_intc_register_sources(&s->intc, _INTC_ARRAY(vectors_dma4), _INTC_ARRAY(groups_dma4)); } - if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751R)) { - sh_intc_register_sources(&s->intc, + if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751R)) { + sh_intc_register_sources(&s->intc, _INTC_ARRAY(vectors_dma8), _INTC_ARRAY(groups_dma8)); } - if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) { - sh_intc_register_sources(&s->intc, + if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) { + sh_intc_register_sources(&s->intc, _INTC_ARRAY(vectors_tmu34), NULL, 0); tmu012_init(0x1e100000, 0, s->periph_freq, @@ -714,14 +705,14 @@ SH7750State *sh7750_init(CPUSH4State * cpu) NULL, NULL); } - if (cpu_model & (SH_CPU_SH7751_ALL)) { - sh_intc_register_sources(&s->intc, + if (cpu->id & (SH_CPU_SH7751_ALL)) { + sh_intc_register_sources(&s->intc, _INTC_ARRAY(vectors_pci), _INTC_ARRAY(groups_pci)); } - if (cpu_model & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) { - sh_intc_register_sources(&s->intc, + if (cpu->id & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) { + sh_intc_register_sources(&s->intc, _INTC_ARRAY(vectors_irlm), NULL, 0); } diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 01c2a079de..686b6684d2 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 80fb24f451..8e97696e68 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; } |