diff mbox

[13/14] target-arm: Don't halt on WFI unless we don't have any work

Message ID 1432060414-5195-14-git-send-email-peter.maydell@linaro.org
State New
Headers show

Commit Message

Peter Maydell May 19, 2015, 6:33 p.m. UTC
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>
---
 target-arm/op_helper.c     | 7 +++++++
 target-arm/translate-a64.c | 4 ++++
 target-arm/translate.c     | 4 ++++
 3 files changed, 15 insertions(+)

Comments

Edgar E. Iglesias May 28, 2015, 5:55 a.m. UTC | #1
On Tue, May 19, 2015 at 07:33:33PM +0100, Peter Maydell wrote:
> 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>


> ---
>  target-arm/op_helper.c     | 7 +++++++
>  target-arm/translate-a64.c | 4 ++++
>  target-arm/translate.c     | 4 ++++
>  3 files changed, 15 insertions(+)
> 
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index 5963f3b..517dacc 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 8d08ccd..ffa6cb8 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 ed2c43d..6493b9a 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);
> -- 
> 1.9.1
>
diff mbox

Patch

diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 5963f3b..517dacc 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 8d08ccd..ffa6cb8 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 ed2c43d..6493b9a 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);