diff --git a/qemu/target/m68k/cpu.c b/qemu/target/m68k/cpu.c index 2117fa44..015791ed 100644 --- a/qemu/target/m68k/cpu.c +++ b/qemu/target/m68k/cpu.c @@ -43,6 +43,11 @@ static void m68k_set_feature(CPUM68KState *env, int feature) env->features |= (1u << feature); } +static void m68k_unset_feature(CPUM68KState *env, int feature) +{ + env->features &= (-1u - (1u << feature)); +} + /* CPUClass::reset() */ static void m68k_cpu_reset(CPUState *s) { @@ -118,6 +123,7 @@ static void m68010_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) { M68kCPU *cpu = M68K_CPU(uc, obj); CPUM68KState *env = &cpu->env; + m68000_cpu_initfn(uc, obj, opaque); m68k_set_feature(env, M68K_FEATURE_M68010); m68k_set_feature(env, M68K_FEATURE_RTD); @@ -158,8 +164,20 @@ static void m68020_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) M68kCPU *cpu = M68K_CPU(uc, obj); CPUM68KState *env = &cpu->env; - m680x0_cpu_common(env); + m68010_cpu_initfn(uc, obj, opaque); + m68k_unset_feature(env, M68K_FEATURE_M68010); m68k_set_feature(env, M68K_FEATURE_M68020); + m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV); + m68k_set_feature(env, M68K_FEATURE_BRAL); + m68k_set_feature(env, M68K_FEATURE_BCCL); + m68k_set_feature(env, M68K_FEATURE_BITFIELD); + m68k_set_feature(env, M68K_FEATURE_EXT_FULL); + m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX); + m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV); + m68k_set_feature(env, M68K_FEATURE_FPU); + m68k_set_feature(env, M68K_FEATURE_CAS); + m68k_set_feature(env, M68K_FEATURE_CHK2); + m68k_set_feature(env, M68K_FEATURE_MSP); } /* diff --git a/qemu/target/m68k/cpu.h b/qemu/target/m68k/cpu.h index 9737e98f..ed41c29e 100644 --- a/qemu/target/m68k/cpu.h +++ b/qemu/target/m68k/cpu.h @@ -87,7 +87,13 @@ typedef struct CPUM68KState { uint32_t pc; uint32_t sr; - /* SSP and USP. The current_sp is stored in aregs[7], the other here. */ + /* + * The 68020/30/40 support two supervisor stacks, ISP and MSP. + * The 68000/10, Coldfire, and CPU32 only have USP/SSP. + * + * The current_sp is stored in aregs[7], the other here. + * The USP, SSP, and if used the additional ISP for 68020/30/40. + */ int current_sp; uint32_t sp[3]; diff --git a/qemu/target/m68k/helper.c b/qemu/target/m68k/helper.c index 307a84ad..872fa912 100644 --- a/qemu/target/m68k/helper.c +++ b/qemu/target/m68k/helper.c @@ -332,7 +332,8 @@ void m68k_switch_sp(CPUM68KState *env) env->sp[env->current_sp] = env->aregs[7]; if (m68k_feature(env, M68K_FEATURE_M68000)) { if (env->sr & SR_S) { - if (env->sr & SR_M) { + /* SR:Master-Mode bit unimplemented then ISP is not available */ + if (!m68k_feature(env, M68K_FEATURE_MSP) || env->sr & SR_M) { new_sp = M68K_SSP; } else { new_sp = M68K_ISP;