Sparc32/64 CPU selection
authorblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 25 Mar 2007 07:55:52 +0000 (07:55 +0000)
committerblueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 25 Mar 2007 07:55:52 +0000 (07:55 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2534 c046a42c-6fe2-441c-8c8c-71466251a162

hw/sun4m.c
hw/sun4u.c
target-sparc/cpu.h
target-sparc/translate.c
vl.c

index c5f6ddd..bc49c73 100644 (file)
@@ -219,12 +219,21 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
     unsigned int i;
     long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
     void *iommu, *dma, *main_esp, *main_lance = NULL;
+    const sparc_def_t *def;
 
     linux_boot = (kernel_filename != NULL);
 
     /* init CPUs */
+    if (cpu_model == NULL)
+        cpu_model = "Fujitsu MB86904";
+    sparc_find_by_name(cpu_model, &def);
+    if (def == NULL) {
+        fprintf(stderr, "Unable to find Sparc CPU definition\n");
+        exit(1);
+    }
     for(i = 0; i < smp_cpus; i++) {
         env = cpu_init();
+        cpu_sparc_register(env, def);
         envs[i] = env;
         if (i != 0)
             env->halted = 1;
index 2357dc9..9066956 100644 (file)
@@ -266,10 +266,20 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
     unsigned int i;
     long prom_offset, initrd_size, kernel_size;
     PCIBus *pci_bus;
+    const sparc_def_t *def;
 
     linux_boot = (kernel_filename != NULL);
 
+    /* init CPUs */
+    if (cpu_model == NULL)
+        cpu_model = "TI UltraSparc II";
+    sparc_find_by_name(cpu_model, &def);
+    if (def == NULL) {
+        fprintf(stderr, "Unable to find Sparc CPU definition\n");
+        exit(1);
+    }
     env = cpu_init();
+    cpu_sparc_register(env, def);
     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
     qemu_register_reset(main_cpu_reset, env);
 
index 3e8d71c..499d5cd 100644 (file)
 /* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */
 #define NWINDOWS  8
 
+typedef struct sparc_def_t sparc_def_t;
+
 typedef struct CPUSPARCState {
     target_ulong gregs[8]; /* general registers */
     target_ulong *regwptr; /* pointer to current register window */
@@ -170,6 +172,7 @@ typedef struct CPUSPARCState {
     int      psret;    /* enable traps */
     uint32_t psrpil;   /* interrupt level */
     int      psref;    /* enable fpu */
+    target_ulong version;
     jmp_buf  jmp_env;
     int user_mode_only;
     int exception_index;
@@ -215,7 +218,6 @@ typedef struct CPUSPARCState {
     uint64_t bgregs[8]; /* backup for normal global registers */
     uint64_t igregs[8]; /* interrupt general registers */
     uint64_t mgregs[8]; /* mmu general registers */
-    uint64_t version;
     uint64_t fprs;
     uint64_t tick_cmpr, stick_cmpr;
     uint64_t gsr;
@@ -233,9 +235,6 @@ typedef struct CPUSPARCState {
 #define PUT_FSR64(env, val) do { uint64_t _tmp = val;  \
        env->fsr = _tmp & 0x3fcfc1c3ffULL;              \
     } while (0)
-// Manuf 0x17, version 0x11, mask 0 (UltraSparc-II)
-#define GET_VER(env) ((0x17ULL << 48) | (0x11ULL << 32) |              \
-                     (0 << 24) | (MAXTL << 8) | (NWINDOWS - 1))
 #else
 #define GET_FSR32(env) (env->fsr)
 #define PUT_FSR32(env, val) do { uint32_t _tmp = val;                   \
@@ -246,9 +245,12 @@ typedef struct CPUSPARCState {
 CPUSPARCState *cpu_sparc_init(void);
 int cpu_sparc_exec(CPUSPARCState *s);
 int cpu_sparc_close(CPUSPARCState *s);
+int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
+void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
+                                                 ...));
+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def);
 
-/* Fake impl 0, version 4 */
-#define GET_PSR(env) ((0 << 28) | (4 << 24) | (env->psr & PSR_ICC) |   \
+#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) |             \
                      (env->psref? PSR_EF : 0) |                        \
                      (env->psrpil << 8) |                              \
                      (env->psrs? PSR_S : 0) |                          \
index d1de266..03466ce 100644 (file)
@@ -55,6 +55,13 @@ typedef struct DisasContext {
     struct TranslationBlock *tb;
 } DisasContext;
 
+struct sparc_def_t {
+    const unsigned char *name;
+    target_ulong iu_version;
+    uint32_t fpu_version;
+    uint32_t mmu_version;
+};
+
 static uint16_t *gen_opc_ptr;
 static uint32_t *gen_opparam_ptr;
 extern FILE *logfile;
@@ -2751,11 +2758,8 @@ void cpu_reset(CPUSPARCState *env)
     env->gregs[1] = ram_size;
 #ifdef TARGET_SPARC64
     env->pstate = PS_PRIV;
-    env->version = GET_VER(env);
     env->pc = 0x1fff0000000ULL;
 #else
-    env->fsr = 4 << 17; /* FPU version 4 (Meiko) */
-    env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
     env->pc = 0xffd00000;
 #endif
     env->npc = env->pc + 4;
@@ -2774,6 +2778,66 @@ CPUSPARCState *cpu_sparc_init(void)
     return (env);
 }
 
+static const sparc_def_t sparc_defs[] = {
+#ifdef TARGET_SPARC64
+    {
+        .name = "TI UltraSparc II",
+        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0 << 24)
+                       | (MAXTL << 8) | (NWINDOWS - 1)),
+        .fpu_version = 0x00000000,
+        .mmu_version = 0,
+    },
+#else
+    {
+        .name = "Fujitsu MB86904",
+        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
+        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
+    },
+#endif
+};
+
+int sparc_find_by_name(const unsigned char *name, const sparc_def_t **def)
+{
+    int ret;
+    unsigned int i;
+
+    ret = -1;
+    *def = NULL;
+    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
+        if (strcasecmp(name, sparc_defs[i].name) == 0) {
+            *def = &sparc_defs[i];
+            ret = 0;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
+        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
+                       sparc_defs[i].name,
+                       sparc_defs[i].iu_version,
+                       sparc_defs[i].fpu_version,
+                       sparc_defs[i].mmu_version);
+    }
+}
+
+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def)
+{
+    env->version = def->iu_version;
+    env->fsr = def->fpu_version;
+#if !defined(TARGET_SPARC64)
+    env->mmuregs[0] = def->mmu_version;
+#endif
+    return 0;
+}
+
 #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
 
 void cpu_dump_state(CPUState *env, FILE *f, 
diff --git a/vl.c b/vl.c
index 87bb1bc..6c5dbc8 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -7007,6 +7007,8 @@ int main(int argc, char **argv)
                     arm_cpu_list();
 #elif defined(TARGET_MIPS)
                     mips_cpu_list(stdout, &fprintf);
+#elif defined(TARGET_SPARC)
+                    sparc_cpu_list(stdout, &fprintf);
 #endif
                     exit(1);
                 } else {