target/ppc: Fix nip on power management instructions
Those instructions currently raise an exception from within the helper. This tends to result in a bogus nip value in the env context (typically the beginning of the TB). Such a helper needs a gen_update_nip() first. This fixes it with a different approach which is to throw the exception from translate.c instead of the helper using gen_exception_nip() which does the right thing. Exception EXCP_HLT is also used instead of POWERPC_EXCP_STOP to effectively exit from the CPU execution loop. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> [clg : modified the commit log to comment the use of EXCP_HLT instead of POWERPC_EXCP_STOP] Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20190215161648.9600-2-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
ef80b99ce7
commit
154c69f2b8
@ -958,7 +958,6 @@ void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
|
||||
* but this doesn't seem to be a problem.
|
||||
*/
|
||||
env->msr |= (1ull << MSR_EE);
|
||||
raise_exception(env, EXCP_HLT);
|
||||
}
|
||||
#endif /* defined(TARGET_PPC64) */
|
||||
|
||||
|
@ -3566,7 +3566,8 @@ static void gen_doze(DisasContext *ctx)
|
||||
t = tcg_const_i32(PPC_PM_DOZE);
|
||||
gen_helper_pminsn(cpu_env, t);
|
||||
tcg_temp_free_i32(t);
|
||||
gen_stop_exception(ctx);
|
||||
/* Stop translation, as the CPU is supposed to sleep from now */
|
||||
gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
|
||||
#endif /* defined(CONFIG_USER_ONLY) */
|
||||
}
|
||||
|
||||
@ -3581,7 +3582,8 @@ static void gen_nap(DisasContext *ctx)
|
||||
t = tcg_const_i32(PPC_PM_NAP);
|
||||
gen_helper_pminsn(cpu_env, t);
|
||||
tcg_temp_free_i32(t);
|
||||
gen_stop_exception(ctx);
|
||||
/* Stop translation, as the CPU is supposed to sleep from now */
|
||||
gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
|
||||
#endif /* defined(CONFIG_USER_ONLY) */
|
||||
}
|
||||
|
||||
@ -3601,7 +3603,8 @@ static void gen_sleep(DisasContext *ctx)
|
||||
t = tcg_const_i32(PPC_PM_SLEEP);
|
||||
gen_helper_pminsn(cpu_env, t);
|
||||
tcg_temp_free_i32(t);
|
||||
gen_stop_exception(ctx);
|
||||
/* Stop translation, as the CPU is supposed to sleep from now */
|
||||
gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
|
||||
#endif /* defined(CONFIG_USER_ONLY) */
|
||||
}
|
||||
|
||||
@ -3616,7 +3619,8 @@ static void gen_rvwinkle(DisasContext *ctx)
|
||||
t = tcg_const_i32(PPC_PM_RVWINKLE);
|
||||
gen_helper_pminsn(cpu_env, t);
|
||||
tcg_temp_free_i32(t);
|
||||
gen_stop_exception(ctx);
|
||||
/* Stop translation, as the CPU is supposed to sleep from now */
|
||||
gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
|
||||
#endif /* defined(CONFIG_USER_ONLY) */
|
||||
}
|
||||
#endif /* #if defined(TARGET_PPC64) */
|
||||
|
Loading…
Reference in New Issue
Block a user