diff options
Diffstat (limited to 'target-m68k/helper.c')
-rw-r--r-- | target-m68k/helper.c | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 423a0e00a..c63964891 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -33,6 +33,8 @@ enum m68k_cpuid { M68K_CPUID_ANY, }; +typedef struct m68k_def_t m68k_def_t; + struct m68k_def_t { const char * name; enum m68k_cpuid id; @@ -51,7 +53,7 @@ static void m68k_set_feature(CPUM68KState *env, int feature) env->features |= (1u << feature); } -int cpu_m68k_set_model(CPUM68KState *env, const char * name) +static int cpu_m68k_set_model(CPUM68KState *env, const char *name) { m68k_def_t *def; @@ -60,7 +62,7 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name) break; } if (!def->name) - return 1; + return -1; switch (def->id) { case M68K_CPUID_M5206: @@ -98,10 +100,48 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name) } register_m68k_insns(env); - return 0; } +void cpu_reset(CPUM68KState *env) +{ + memset(env, 0, offsetof(CPUM68KState, breakpoints)); +#if !defined (CONFIG_USER_ONLY) + env->sr = 0x2700; +#endif + m68k_switch_sp(env); + /* ??? FP regs should be initialized to NaN. */ + env->cc_op = CC_OP_FLAGS; + /* TODO: We should set PC from the interrupt vector. */ + env->pc = 0; + tlb_flush(env, 1); +} + +CPUM68KState *cpu_m68k_init(const char *cpu_model) +{ + CPUM68KState *env; + + env = malloc(sizeof(CPUM68KState)); + if (!env) + return NULL; + cpu_exec_init(env); + + env->cpu_model_str = cpu_model; + + if (cpu_m68k_set_model(env, cpu_model) < 0) { + cpu_m68k_close(env); + return NULL; + } + + cpu_reset(env); + return env; +} + +void cpu_m68k_close(CPUM68KState *env) +{ + qemu_free(env); +} + void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op) { int flags; @@ -217,7 +257,7 @@ float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1) /* +/-inf compares equal against itself, but sub returns nan. */ if (!float64_is_nan(src0) && !float64_is_nan(src1)) { - res = 0; + res = float64_zero; if (float64_lt_quiet(src0, res, &env->fp_status)) res = float64_chs(res); } @@ -301,7 +341,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { env->exception_index = EXCP_ACCESS; env->mmu.ar = address; @@ -311,13 +351,13 @@ int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, #else int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { int prot; address &= TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE; - return tlb_set_page(env, address, address, prot, is_user, is_softmmu); + return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu); } /* Notify CPU of a pending interrupt. Prioritization and vectoring should |