From c48fcb47518befb79b5cc75a2cad024c2d6e4bef Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sat, 29 Mar 2008 15:46:56 +0000 Subject: [PATCH] Move CPU stuff unrelated to translation to helper.c git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4133 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/cpu.h | 1 + target-sparc/helper.c | 527 ++++++++++++++++++++++++++++++++++++++- target-sparc/translate.c | 516 +------------------------------------- 3 files changed, 524 insertions(+), 520 deletions(-) diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index a575bfd006..2002a05dea 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -286,6 +286,7 @@ typedef struct CPUSPARCState { #endif CPUSPARCState *cpu_sparc_init(const char *cpu_model); +void gen_intermediate_code_init(CPUSPARCState *env); int cpu_sparc_exec(CPUSPARCState *s); int cpu_sparc_close(CPUSPARCState *s); void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 3437d13f66..a788ef633e 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -30,6 +30,22 @@ //#define DEBUG_MMU +typedef struct sparc_def_t sparc_def_t; + +struct sparc_def_t { + const unsigned char *name; + target_ulong iu_version; + uint32_t fpu_version; + uint32_t mmu_version; + uint32_t mmu_bm; + uint32_t mmu_ctpr_mask; + uint32_t mmu_cxr_mask; + uint32_t mmu_sfsr_mask; + uint32_t mmu_trcr_mask; +}; + +static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name); + /* Sparc MMU emulation */ /* thread support */ @@ -98,9 +114,9 @@ static const int perm_table[2][8] = { } }; -int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, - int *access_index, target_ulong address, int rw, - int mmu_idx) +static int get_physical_address(CPUState *env, target_phys_addr_t *physical, + int *prot, int *access_index, + target_ulong address, int rw, int mmu_idx) { int access_perms = 0; target_phys_addr_t pde_ptr; @@ -483,9 +499,9 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical return 1; } -int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot, - int *access_index, target_ulong address, int rw, - int mmu_idx) +static int get_physical_address(CPUState *env, target_phys_addr_t *physical, + int *prot, int *access_index, + target_ulong address, int rw, int mmu_idx) { int is_user = mmu_idx == MMU_USER_IDX; @@ -593,6 +609,30 @@ void dump_mmu(CPUState *env) #endif /* TARGET_SPARC64 */ #endif /* !CONFIG_USER_ONLY */ + +#if defined(CONFIG_USER_ONLY) +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) +{ + return addr; +} + +#else +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) +{ + target_phys_addr_t phys_addr; + int prot, access_index; + + if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, + MMU_KERNEL_IDX) != 0) + if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, + 0, MMU_KERNEL_IDX) != 0) + return -1; + if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED) + return -1; + return phys_addr; +} +#endif + void memcpy32(target_ulong *dst, const target_ulong *src) { dst[0] = src[0]; @@ -605,6 +645,481 @@ void memcpy32(target_ulong *dst, const target_ulong *src) dst[7] = src[7]; } +void helper_flush(target_ulong addr) +{ + addr &= ~7; + tb_invalidate_page_range(addr, addr + 8); +} + +void cpu_reset(CPUSPARCState *env) +{ + tlb_flush(env, 1); + env->cwp = 0; + env->wim = 1; + env->regwptr = env->regbase + (env->cwp * 16); +#if defined(CONFIG_USER_ONLY) + env->user_mode_only = 1; +#ifdef TARGET_SPARC64 + env->cleanwin = NWINDOWS - 2; + env->cansave = NWINDOWS - 2; + env->pstate = PS_RMO | PS_PEF | PS_IE; + env->asi = 0x82; // Primary no-fault +#endif +#else + env->psret = 0; + env->psrs = 1; + env->psrps = 1; +#ifdef TARGET_SPARC64 + env->pstate = PS_PRIV; + env->hpstate = HS_PRIV; + env->pc = 0x1fff0000000ULL; + env->tsptr = &env->ts[env->tl]; +#else + env->pc = 0; + env->mmuregs[0] &= ~(MMU_E | MMU_NF); + env->mmuregs[0] |= env->mmu_bm; +#endif + env->npc = env->pc + 4; +#endif +} + +CPUSPARCState *cpu_sparc_init(const char *cpu_model) +{ + CPUSPARCState *env; + const sparc_def_t *def; + + def = cpu_sparc_find_by_name(cpu_model); + if (!def) + return NULL; + + env = qemu_mallocz(sizeof(CPUSPARCState)); + if (!env) + return NULL; + cpu_exec_init(env); + env->cpu_model_str = cpu_model; + env->version = def->iu_version; + env->fsr = def->fpu_version; +#if !defined(TARGET_SPARC64) + env->mmu_bm = def->mmu_bm; + env->mmu_ctpr_mask = def->mmu_ctpr_mask; + env->mmu_cxr_mask = def->mmu_cxr_mask; + env->mmu_sfsr_mask = def->mmu_sfsr_mask; + env->mmu_trcr_mask = def->mmu_trcr_mask; + env->mmuregs[0] |= def->mmu_version; + cpu_sparc_set_id(env, 0); +#endif + + gen_intermediate_code_init(env); + + cpu_reset(env); + + return env; +} + +void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu) +{ +#if !defined(TARGET_SPARC64) + env->mxccregs[7] = ((cpu + 8) & 0xf) << 24; +#endif +} + +static const sparc_def_t sparc_defs[] = { +#ifdef TARGET_SPARC64 + { + .name = "Fujitsu Sparc64", + .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Fujitsu Sparc64 III", + .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Fujitsu Sparc64 IV", + .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Fujitsu Sparc64 V", + .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "TI UltraSparc I", + .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "TI UltraSparc II", + .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "TI UltraSparc IIi", + .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "TI UltraSparc IIe", + .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Sun UltraSparc III", + .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Sun UltraSparc III Cu", + .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Sun UltraSparc IIIi", + .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Sun UltraSparc IV", + .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Sun UltraSparc IV+", + .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "Sun UltraSparc IIIi+", + .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, + { + .name = "NEC UltraSparc I", + .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) + | (MAXTL << 8) | (NWINDOWS - 1)), + .fpu_version = 0x00000000, + .mmu_version = 0, + }, +#else + { + .name = "Fujitsu MB86900", + .iu_version = 0x00 << 24, /* Impl 0, ver 0 */ + .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ + .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */ + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .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 */ + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x00ffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016fff, + .mmu_trcr_mask = 0x00ffffff, + }, + { + .name = "Fujitsu MB86907", + .iu_version = 0x05 << 24, /* Impl 0, ver 5 */ + .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ + .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */ + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016fff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "LSI L64811", + .iu_version = 0x10 << 24, /* Impl 1, ver 0 */ + .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */ + .mmu_version = 0x10 << 24, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "Cypress CY7C601", + .iu_version = 0x11 << 24, /* Impl 1, ver 1 */ + .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ + .mmu_version = 0x10 << 24, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "Cypress CY7C611", + .iu_version = 0x13 << 24, /* Impl 1, ver 3 */ + .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ + .mmu_version = 0x10 << 24, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "TI SuperSparc II", + .iu_version = 0x40000000, + .fpu_version = 0 << 17, + .mmu_version = 0x04000000, + .mmu_bm = 0x00002000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x0000ffff, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "TI MicroSparc I", + .iu_version = 0x41000000, + .fpu_version = 4 << 17, + .mmu_version = 0x41000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0x00016fff, + .mmu_trcr_mask = 0x0000003f, + }, + { + .name = "TI MicroSparc II", + .iu_version = 0x42000000, + .fpu_version = 4 << 17, + .mmu_version = 0x02000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x00ffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016fff, + .mmu_trcr_mask = 0x00ffffff, + }, + { + .name = "TI MicroSparc IIep", + .iu_version = 0x42000000, + .fpu_version = 4 << 17, + .mmu_version = 0x04000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x00ffffc0, + .mmu_cxr_mask = 0x000000ff, + .mmu_sfsr_mask = 0x00016bff, + .mmu_trcr_mask = 0x00ffffff, + }, + { + .name = "TI SuperSparc 51", + .iu_version = 0x43000000, + .fpu_version = 0 << 17, + .mmu_version = 0x04000000, + .mmu_bm = 0x00002000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x0000ffff, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "TI SuperSparc 61", + .iu_version = 0x44000000, + .fpu_version = 0 << 17, + .mmu_version = 0x04000000, + .mmu_bm = 0x00002000, + .mmu_ctpr_mask = 0xffffffc0, + .mmu_cxr_mask = 0x0000ffff, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "Ross RT625", + .iu_version = 0x1e000000, + .fpu_version = 1 << 17, + .mmu_version = 0x1e000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "Ross RT620", + .iu_version = 0x1f000000, + .fpu_version = 1 << 17, + .mmu_version = 0x1f000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "BIT B5010", + .iu_version = 0x20000000, + .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */ + .mmu_version = 0x20000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "Matsushita MN10501", + .iu_version = 0x50000000, + .fpu_version = 0 << 17, + .mmu_version = 0x50000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "Weitek W8601", + .iu_version = 0x90 << 24, /* Impl 9, ver 0 */ + .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */ + .mmu_version = 0x10 << 24, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "LEON2", + .iu_version = 0xf2000000, + .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ + .mmu_version = 0xf2000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, + { + .name = "LEON3", + .iu_version = 0xf3000000, + .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ + .mmu_version = 0xf3000000, + .mmu_bm = 0x00004000, + .mmu_ctpr_mask = 0x007ffff0, + .mmu_cxr_mask = 0x0000003f, + .mmu_sfsr_mask = 0xffffffff, + .mmu_trcr_mask = 0xffffffff, + }, +#endif +}; + +static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name) +{ + unsigned int i; + + for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { + if (strcasecmp(name, sparc_defs[i].name) == 0) { + return &sparc_defs[i]; + } + } + return NULL; +} + +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); + } +} + +#define GET_FLAG(a,b) ((env->psr & a)?b:'-') + +void cpu_dump_state(CPUState *env, FILE *f, + int (*cpu_fprintf)(FILE *f, const char *fmt, ...), + int flags) +{ + int i, x; + + cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, env->npc); + cpu_fprintf(f, "General Registers:\n"); + for (i = 0; i < 4; i++) + cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]); + cpu_fprintf(f, "\n"); + for (; i < 8; i++) + cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]); + cpu_fprintf(f, "\nCurrent Register Window:\n"); + for (x = 0; x < 3; x++) { + for (i = 0; i < 4; i++) + cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t", + (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i, + env->regwptr[i + x * 8]); + cpu_fprintf(f, "\n"); + for (; i < 8; i++) + cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t", + (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i, + env->regwptr[i + x * 8]); + cpu_fprintf(f, "\n"); + } + cpu_fprintf(f, "\nFloating Point Registers:\n"); + for (i = 0; i < 32; i++) { + if ((i & 3) == 0) + cpu_fprintf(f, "%%f%02d:", i); + cpu_fprintf(f, " %016lf", env->fpr[i]); + if ((i & 3) == 3) + cpu_fprintf(f, "\n"); + } +#ifdef TARGET_SPARC64 + cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n", + env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs); + cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n", + env->cansave, env->canrestore, env->otherwin, env->wstate, + env->cleanwin, NWINDOWS - 1 - env->cwp); +#else + cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env), + GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'), + GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'), + env->psrs?'S':'-', env->psrps?'P':'-', + env->psret?'E':'-', env->wim); +#endif + cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env)); +} + #ifdef TARGET_SPARC64 #if !defined(CONFIG_USER_ONLY) #include "qemu-common.h" diff --git a/target-sparc/translate.c b/target-sparc/translate.c index d49902312b..edb2b23128 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -65,22 +65,6 @@ typedef struct DisasContext { struct TranslationBlock *tb; } DisasContext; -typedef struct sparc_def_t sparc_def_t; - -struct sparc_def_t { - const unsigned char *name; - target_ulong iu_version; - uint32_t fpu_version; - uint32_t mmu_version; - uint32_t mmu_bm; - uint32_t mmu_ctpr_mask; - uint32_t mmu_cxr_mask; - uint32_t mmu_sfsr_mask; - uint32_t mmu_trcr_mask; -}; - -static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name); - extern FILE *logfile; extern int loglevel; @@ -4661,44 +4645,10 @@ int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb) return gen_intermediate_code_internal(tb, 1, env); } -void cpu_reset(CPUSPARCState *env) +void gen_intermediate_code_init(CPUSPARCState *env) { - tlb_flush(env, 1); - env->cwp = 0; - env->wim = 1; - env->regwptr = env->regbase + (env->cwp * 16); -#if defined(CONFIG_USER_ONLY) - env->user_mode_only = 1; -#ifdef TARGET_SPARC64 - env->cleanwin = NWINDOWS - 2; - env->cansave = NWINDOWS - 2; - env->pstate = PS_RMO | PS_PEF | PS_IE; - env->asi = 0x82; // Primary no-fault -#endif -#else - env->psret = 0; - env->psrs = 1; - env->psrps = 1; -#ifdef TARGET_SPARC64 - env->pstate = PS_PRIV; - env->hpstate = HS_PRIV; - env->pc = 0x1fff0000000ULL; - env->tsptr = &env->ts[env->tl]; -#else - env->pc = 0; - env->mmuregs[0] &= ~(MMU_E | MMU_NF); - env->mmuregs[0] |= env->mmu_bm; -#endif - env->npc = env->pc + 4; -#endif -} - -CPUSPARCState *cpu_sparc_init(const char *cpu_model) -{ - CPUSPARCState *env; - const sparc_def_t *def; - static int inited; unsigned int i; + static int inited; static const char * const gregnames[8] = { NULL, // g0 not used "g1", @@ -4710,27 +4660,6 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model) "g7", }; - def = cpu_sparc_find_by_name(cpu_model); - if (!def) - return NULL; - - env = qemu_mallocz(sizeof(CPUSPARCState)); - if (!env) - return NULL; - cpu_exec_init(env); - env->cpu_model_str = cpu_model; - env->version = def->iu_version; - env->fsr = def->fpu_version; -#if !defined(TARGET_SPARC64) - env->mmu_bm = def->mmu_bm; - env->mmu_ctpr_mask = def->mmu_ctpr_mask; - env->mmu_cxr_mask = def->mmu_cxr_mask; - env->mmu_sfsr_mask = def->mmu_sfsr_mask; - env->mmu_trcr_mask = def->mmu_trcr_mask; - env->mmuregs[0] |= def->mmu_version; - cpu_sparc_set_id(env, 0); -#endif - /* init various static tables */ if (!inited) { inited = 1; @@ -4782,445 +4711,4 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model) offsetof(CPUState, gregs[i]), gregnames[i]); } - - cpu_reset(env); - - return env; -} - -void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu) -{ -#if !defined(TARGET_SPARC64) - env->mxccregs[7] = ((cpu + 8) & 0xf) << 24; -#endif -} - -static const sparc_def_t sparc_defs[] = { -#ifdef TARGET_SPARC64 - { - .name = "Fujitsu Sparc64", - .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Fujitsu Sparc64 III", - .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Fujitsu Sparc64 IV", - .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Fujitsu Sparc64 V", - .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "TI UltraSparc I", - .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "TI UltraSparc II", - .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "TI UltraSparc IIi", - .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "TI UltraSparc IIe", - .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Sun UltraSparc III", - .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Sun UltraSparc III Cu", - .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Sun UltraSparc IIIi", - .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Sun UltraSparc IV", - .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Sun UltraSparc IV+", - .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "Sun UltraSparc IIIi+", - .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, - { - .name = "NEC UltraSparc I", - .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), - .fpu_version = 0x00000000, - .mmu_version = 0, - }, -#else - { - .name = "Fujitsu MB86900", - .iu_version = 0x00 << 24, /* Impl 0, ver 0 */ - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */ - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .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 */ - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x00ffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0x00ffffff, - }, - { - .name = "Fujitsu MB86907", - .iu_version = 0x05 << 24, /* Impl 0, ver 5 */ - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */ - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "LSI L64811", - .iu_version = 0x10 << 24, /* Impl 1, ver 0 */ - .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "Cypress CY7C601", - .iu_version = 0x11 << 24, /* Impl 1, ver 1 */ - .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "Cypress CY7C611", - .iu_version = 0x13 << 24, /* Impl 1, ver 3 */ - .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "TI SuperSparc II", - .iu_version = 0x40000000, - .fpu_version = 0 << 17, - .mmu_version = 0x04000000, - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "TI MicroSparc I", - .iu_version = 0x41000000, - .fpu_version = 4 << 17, - .mmu_version = 0x41000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0x0000003f, - }, - { - .name = "TI MicroSparc II", - .iu_version = 0x42000000, - .fpu_version = 4 << 17, - .mmu_version = 0x02000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x00ffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016fff, - .mmu_trcr_mask = 0x00ffffff, - }, - { - .name = "TI MicroSparc IIep", - .iu_version = 0x42000000, - .fpu_version = 4 << 17, - .mmu_version = 0x04000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x00ffffc0, - .mmu_cxr_mask = 0x000000ff, - .mmu_sfsr_mask = 0x00016bff, - .mmu_trcr_mask = 0x00ffffff, - }, - { - .name = "TI SuperSparc 51", - .iu_version = 0x43000000, - .fpu_version = 0 << 17, - .mmu_version = 0x04000000, - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "TI SuperSparc 61", - .iu_version = 0x44000000, - .fpu_version = 0 << 17, - .mmu_version = 0x04000000, - .mmu_bm = 0x00002000, - .mmu_ctpr_mask = 0xffffffc0, - .mmu_cxr_mask = 0x0000ffff, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "Ross RT625", - .iu_version = 0x1e000000, - .fpu_version = 1 << 17, - .mmu_version = 0x1e000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "Ross RT620", - .iu_version = 0x1f000000, - .fpu_version = 1 << 17, - .mmu_version = 0x1f000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "BIT B5010", - .iu_version = 0x20000000, - .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */ - .mmu_version = 0x20000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "Matsushita MN10501", - .iu_version = 0x50000000, - .fpu_version = 0 << 17, - .mmu_version = 0x50000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "Weitek W8601", - .iu_version = 0x90 << 24, /* Impl 9, ver 0 */ - .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */ - .mmu_version = 0x10 << 24, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "LEON2", - .iu_version = 0xf2000000, - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0xf2000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, - { - .name = "LEON3", - .iu_version = 0xf3000000, - .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ - .mmu_version = 0xf3000000, - .mmu_bm = 0x00004000, - .mmu_ctpr_mask = 0x007ffff0, - .mmu_cxr_mask = 0x0000003f, - .mmu_sfsr_mask = 0xffffffff, - .mmu_trcr_mask = 0xffffffff, - }, -#endif -}; - -static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name) -{ - unsigned int i; - - for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { - if (strcasecmp(name, sparc_defs[i].name) == 0) { - return &sparc_defs[i]; - } - } - return NULL; -} - -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); - } -} - -#define GET_FLAG(a,b) ((env->psr & a)?b:'-') - -void cpu_dump_state(CPUState *env, FILE *f, - int (*cpu_fprintf)(FILE *f, const char *fmt, ...), - int flags) -{ - int i, x; - - cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, env->npc); - cpu_fprintf(f, "General Registers:\n"); - for (i = 0; i < 4; i++) - cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]); - cpu_fprintf(f, "\n"); - for (; i < 8; i++) - cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]); - cpu_fprintf(f, "\nCurrent Register Window:\n"); - for (x = 0; x < 3; x++) { - for (i = 0; i < 4; i++) - cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t", - (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i, - env->regwptr[i + x * 8]); - cpu_fprintf(f, "\n"); - for (; i < 8; i++) - cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t", - (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i, - env->regwptr[i + x * 8]); - cpu_fprintf(f, "\n"); - } - cpu_fprintf(f, "\nFloating Point Registers:\n"); - for (i = 0; i < 32; i++) { - if ((i & 3) == 0) - cpu_fprintf(f, "%%f%02d:", i); - cpu_fprintf(f, " %016lf", env->fpr[i]); - if ((i & 3) == 3) - cpu_fprintf(f, "\n"); - } -#ifdef TARGET_SPARC64 - cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n", - env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs); - cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n", - env->cansave, env->canrestore, env->otherwin, env->wstate, - env->cleanwin, NWINDOWS - 1 - env->cwp); -#else - cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env), - GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'), - GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'), - env->psrs?'S':'-', env->psrps?'P':'-', - env->psret?'E':'-', env->wim); -#endif - cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env)); -} - -#if defined(CONFIG_USER_ONLY) -target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) -{ - return addr; -} - -#else -extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, - int *access_index, target_ulong address, int rw, - int mmu_idx); - -target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) -{ - target_phys_addr_t phys_addr; - int prot, access_index; - - if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, - MMU_KERNEL_IDX) != 0) - if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, - 0, MMU_KERNEL_IDX) != 0) - return -1; - if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED) - return -1; - return phys_addr; -} -#endif - -void helper_flush(target_ulong addr) -{ - addr &= ~7; - tb_invalidate_page_range(addr, addr + 8); }