1/*
2 * Copyright (c) 2013-2014 Wind River Systems, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7/**
8 * @file
9 * @brief ARM Cortex-A and Cortex-R power management
10 *
11 */
12
13#include <zephyr/toolchain.h>
14#include <zephyr/linker/sections.h>
15
16#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE)
17#include <soc_cpu_idle.h>
18#endif
19
20_ASM_FILE_PROLOGUE
21
22GTEXT(arch_cpu_idle)
23GTEXT(arch_cpu_atomic_idle)
24
25.macro _sleep_if_allowed wait_instruction
26#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK)
27	push	{r0, lr}
28	bl	z_arm_on_enter_cpu_idle
29	/* Skip the wait instruction if on_enter_cpu_idle() returns false. */
30	cmp	r0, #0
31	beq	_skip_\@
32#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */
33
34	/*
35	 * Wait for all memory transactions to complete before entering low
36	 * power state.
37	 */
38	dsb
39	\wait_instruction
40
41#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE)
42	/* Inline the macro provided by SoC-specific code */
43	SOC_ON_EXIT_CPU_IDLE
44#endif /* CONFIG_ARM_ON_EXIT_CPU_IDLE */
45
46#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK)
47_skip_\@:
48	pop	{r0, lr}
49#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */
50.endm
51
52#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE
53SECTION_FUNC(TEXT, arch_cpu_idle)
54#ifdef CONFIG_TRACING
55	push	{r0, lr}
56	bl	sys_trace_idle
57	pop	{r0, lr}
58#endif /* CONFIG_TRACING */
59
60	/* Enter low power state */
61	_sleep_if_allowed wfi
62
63	/*
64	 * Clear PRIMASK and flush instruction buffer to immediately service
65	 * the wake-up interrupt.
66	 */
67	cpsie	i
68	isb
69
70	bx	lr
71
72#endif
73
74#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE
75SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
76#ifdef CONFIG_TRACING
77	push	{r0, lr}
78	bl	sys_trace_idle
79	pop	{r0, lr}
80#endif /* CONFIG_TRACING */
81
82	/*
83	 * Lock PRIMASK while sleeping: wfe will still get interrupted by
84	 * incoming interrupts but the CPU will not service them right away.
85	 */
86	cpsid	i
87
88	/* r0: interrupt mask from caller */
89
90	/* No BASEPRI, call wfe directly
91	 */
92	_sleep_if_allowed wfe
93
94	cmp	r0, #0
95	bne	_irq_disabled
96	cpsie	i
97_irq_disabled:
98
99	bx	lr
100#endif
101