arch: arm: aarch32: Introduce z_arm_on_enter_cpu_idle_prepare() hook

Introduce an optional hook to be called when the CPU is made idle.
If needed, this hook can be used to prepare data for upcoming
call to z_arm_on_enter_cpu_idle(). The main difference is that
z_arm_on_enter_cpu_idle_prepare() hook is called before interrupts
are disabled.

Signed-off-by: Andrzej Kuroś <andrzej.kuros@nordicsemi.no>
This commit is contained in:
Andrzej Kuros 2023-09-26 14:28:36 +02:00 committed by Carles Cufí
commit 3d89d58cb8
3 changed files with 39 additions and 5 deletions

View file

@ -53,6 +53,16 @@ config ARM_ON_ENTER_CPU_IDLE_HOOK
If needed, this hook can be used to prevent the CPU from actually
entering sleep by skipping the WFE/WFI instruction.
config ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK
bool
help
Enables a hook (z_arm_on_enter_cpu_idle_prepare()) that is called when
the CPU is made idle (by k_cpu_idle() or k_cpu_atomic_idle()).
If needed, this hook can prepare data to upcoming call to
z_arm_on_enter_cpu_idle(). The z_arm_on_enter_cpu_idle_prepare differs
from z_arm_on_enter_cpu_idle because it is called before interrupts are
disabled.
config ARM_ON_EXIT_CPU_IDLE
bool
help

View file

@ -81,16 +81,24 @@ SECTION_FUNC(TEXT, z_arm_cpu_idle_init)
bx lr
SECTION_FUNC(TEXT, arch_cpu_idle)
#ifdef CONFIG_TRACING
#if defined(CONFIG_TRACING) || \
defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK)
push {r0, lr}
#ifdef CONFIG_TRACING
bl sys_trace_idle
#endif
#ifdef CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK
bl z_arm_on_enter_cpu_idle_prepare
#endif
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
pop {r0, r1}
mov lr, r1
#else
pop {r0, lr}
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
#endif /* CONFIG_TRACING */
#endif
#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)
/*
@ -134,17 +142,24 @@ SECTION_FUNC(TEXT, arch_cpu_idle)
bx lr
SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
#ifdef CONFIG_TRACING
#if defined(CONFIG_TRACING) || \
defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK)
push {r0, lr}
#ifdef CONFIG_TRACING
bl sys_trace_idle
#endif
#ifdef CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK
bl z_arm_on_enter_cpu_idle_prepare
#endif
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
pop {r0, r1}
mov lr, r1
#else
pop {r0, lr}
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
#endif /* CONFIG_TRACING */
#endif
/*
* Lock PRIMASK while sleeping: wfe will still get interrupted by
* incoming interrupts but the CPU will not service them right away.

View file

@ -51,6 +51,15 @@ extern bool z_arm_thread_is_in_user_mode(void);
bool z_arm_on_enter_cpu_idle(void);
#endif
#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_PREPARE_HOOK)
/* Prototype of a hook that can be enabled to be called every time the CPU is
* made idle (the calls will be done from k_cpu_idle() and k_cpu_atomic_idle()).
* The function is called before interrupts are disabled and can prepare to
* upcoming call to z_arm_on_enter_cpu_idle.
*/
void z_arm_on_enter_cpu_idle_prepare(void);
#endif
#endif
#ifdef __cplusplus