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 If needed, this hook can be used to prevent the CPU from actually
entering sleep by skipping the WFE/WFI instruction. 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 config ARM_ON_EXIT_CPU_IDLE
bool bool
help help

View file

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