qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] sh4: CPU versioning.


From: Paul Mundt
Subject: [Qemu-devel] [PATCH] sh4: CPU versioning.
Date: Tue, 2 Sep 2008 19:11:29 +0900
User-agent: Mutt/1.5.13 (2006-08-11)

Trivial patch adding CPU listing and the ability to do per-subtype
CVR/PVR/PRR values. Presently SH7750R and SH7751R definitions are
provided, as these are the ones in present use in-tree.

The CVR value for SH7751R is intentionally restricted so the kernel
boots, though this will want to be switched to the proper CVR value
once system emulation has sufficiently stabilized.

This also makes it trivial to abstract subtype specific registers like
MMU_PTEA and to set up feature bits in line with the kernel probing for
things like conditionalizing FPU/DSP context.

Signed-off-by: Paul Mundt <address@hidden>

---

 hw/r2d.c               |    2 -
 hw/sh7750.c            |   43 ++++++++++++++---------------------
 target-sh4/cpu.h       |   17 ++++++++++++++
 target-sh4/translate.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 94 insertions(+), 27 deletions(-)

Index: target-sh4/cpu.h
===================================================================
--- target-sh4/cpu.h    (revision 5132)
+++ target-sh4/cpu.h    (working copy)
@@ -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 @@
 #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 @@
     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 @@
 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 @@
 #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
Index: target-sh4/translate.c
===================================================================
--- target-sh4/translate.c      (revision 5132)
+++ target-sh4/translate.c      (working copy)
@@ -176,16 +176,75 @@
     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;
 }
Index: hw/r2d.c
===================================================================
--- hw/r2d.c    (revision 5132)
+++ hw/r2d.c    (working copy)
@@ -39,7 +149,7 @@
     struct SH7750State *s;
 
     if (!cpu_model)
-        cpu_model = "any";
+        cpu_model = "SH7751R";
 
     env = cpu_init(cpu_model);
     if (!env) {
Index: hw/sh7750.c
===================================================================
--- hw/sh7750.c (revision 5132)
+++ hw/sh7750.c (working copy)
@@ -249,12 +249,12 @@
        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 @@
                   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 *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 @@
                 _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 @@
                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 @@
                    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);
     }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]