aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/r2d.c2
-rw-r--r--hw/sh7750.c43
-rw-r--r--target-sh4/cpu.h17
-rw-r--r--target-sh4/translate.c59
4 files changed, 94 insertions, 27 deletions
diff --git a/hw/r2d.c b/hw/r2d.c
index 22948745a4..58aeaf5f6a 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -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;
}