aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-05-29 11:28:53 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-05-29 11:28:53 +0100
commit84549b6dcf9147559ec08b066de673587be6b763 (patch)
tree99aefebf556989e4d4b0940cec7e235f4d95170e
parent647f767ba3b37fb229275086187e96242248a4ac (diff)
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. Suggested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
-rw-r--r--target-arm/op_helper.c7
-rw-r--r--target-arm/translate-a64.c4
-rw-r--r--target-arm/translate.c4
3 files changed, 15 insertions, 0 deletions
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 79e7d10055..0ea4ed4bae 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -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);
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 8d08ccdf6a..ffa6cb8e56 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -11113,6 +11113,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
*/
gen_a64_set_pc_im(dc->pc);
gen_helper_wfi(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(0);
break;
}
}
diff --git a/target-arm/translate.c b/target-arm/translate.c
index ed2c43d235..6493b9a523 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -11351,6 +11351,10 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
break;
case DISAS_WFI:
gen_helper_wfi(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(0);
break;
case DISAS_WFE:
gen_helper_wfe(cpu_env);