From 62724a3773b5553a696ebc5cdd212908f7572c6a Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sun, 25 Mar 2007 07:55:52 +0000 Subject: [PATCH] Sparc32/64 CPU selection git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2534 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/sun4m.c | 9 +++++++ hw/sun4u.c | 10 +++++++ target-sparc/cpu.h | 14 +++++----- target-sparc/translate.c | 70 +++++++++++++++++++++++++++++++++++++++++++++--- vl.c | 2 ++ 5 files changed, 96 insertions(+), 9 deletions(-) diff --git a/hw/sun4m.c b/hw/sun4m.c index c5f6ddda8b..bc49c73c6b 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -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; diff --git a/hw/sun4u.c b/hw/sun4u.c index 2357dc974a..906695690f 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -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); diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 3e8d71c204..499d5cd96d 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -152,6 +152,8 @@ /* 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) | \ diff --git a/target-sparc/translate.c b/target-sparc/translate.c index d1de266f6f..03466ce87f 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -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 87bb1bcd50..6c5dbc8010 100644 --- 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 { -- 2.11.0