target-arm: Don't halt on WFI unless we don't have any work

Just NOP the WFI instruction if we have work to do.
This doesn't make much difference currently (though it does avoid
jumping out to the top level loop and immediately restarting),
but the distinction between "halt" and "don't halt" will become
more important when the decision to halt requires us to trap
to a higher exception level instead.

Backport commit 84549b6dcf9147559ec08b066de673587be6b763 from qemu
This commit is contained in:
Peter Maydell 2018-02-12 23:08:46 -05:00 committed by Lioncash
parent db727fad68
commit 6d7370457f
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 15 additions and 0 deletions

View file

@ -252,6 +252,13 @@ void HELPER(wfi)(CPUARMState *env)
{
CPUState *cs = CPU(arm_env_get_cpu(env));
if (cpu_has_work(cs)) {
/* Don't bother to go into our "low power state" if
* we would just wake up immediately.
*/
return;
}
cs->exception_index = EXCP_HLT;
cs->halted = 1;
cpu_loop_exit(cs);

View file

@ -11406,6 +11406,10 @@ tb_end:
*/
gen_a64_set_pc_im(dc, dc->pc);
gen_helper_wfi(tcg_ctx, tcg_ctx->cpu_env);
/* The helper doesn't necessarily throw an exception, but we
* must go back to the main loop to check for interrupts anyway.
*/
tcg_gen_exit_tb(tcg_ctx, 0);
break;
}
}

View file

@ -11691,6 +11691,10 @@ tb_end:
break;
case DISAS_WFI:
gen_helper_wfi(tcg_ctx, tcg_ctx->cpu_env);
/* The helper doesn't necessarily throw an exception, but we
* must go back to the main loop to check for interrupts anyway.
*/
tcg_gen_exit_tb(tcg_ctx, 0);
break;
case DISAS_WFE:
gen_helper_wfe(tcg_ctx, tcg_ctx->cpu_env);