aboutsummaryrefslogtreecommitdiff
path: root/target-sh4
diff options
context:
space:
mode:
Diffstat (limited to 'target-sh4')
-rw-r--r--target-sh4/cpu.h17
-rw-r--r--target-sh4/translate.c59
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;
}