Skip to content

Commit 9ba3d31

Browse files
SgrrZhffabiobaltieri
authored andcommitted
arch: arm: Separate common cpu_idle codes
This commit separates cpu_idle.S into two asm files, 'cortex_a_r/cpu_idle.S' and 'cortex_m/cpu_idle.S'. Signed-off-by: Huifeng Zhang <[email protected]>
1 parent 7e5e08b commit 9ba3d31

File tree

5 files changed

+139
-28
lines changed

5 files changed

+139
-28
lines changed

arch/arm/core/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
zephyr_library()
44

55
zephyr_library_sources(
6-
cpu_idle.S
76
fatal.c
87
nmi.c
98
nmi_on_reset.S

arch/arm/core/cortex_a_r/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ zephyr_library_sources(
1717
irq_manage.c
1818
prep_c.c
1919
thread.c
20+
cpu_idle.S
2021
)
2122

2223
zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S)
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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+
22+
GTEXT(z_arm_cpu_idle_init)
23+
GTEXT(arch_cpu_idle)
24+
GTEXT(arch_cpu_atomic_idle)
25+
26+
.macro _sleep_if_allowed wait_instruction
27+
#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK)
28+
push {r0, lr}
29+
bl z_arm_on_enter_cpu_idle
30+
/* Skip the wait instruction if on_enter_cpu_idle() returns false. */
31+
cmp r0, #0
32+
beq _skip_\@
33+
#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */
34+
35+
/*
36+
* Wait for all memory transactions to complete before entering low
37+
* power state.
38+
*/
39+
dsb
40+
\wait_instruction
41+
42+
#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE)
43+
/* Inline the macro provided by SoC-specific code */
44+
SOC_ON_EXIT_CPU_IDLE
45+
#endif /* CONFIG_ARM_ON_EXIT_CPU_IDLE */
46+
47+
#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK)
48+
_skip_\@:
49+
pop {r0, lr}
50+
#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */
51+
.endm
52+
53+
/**
54+
*
55+
* @brief Initialization of CPU idle
56+
*
57+
* Only called by arch_kernel_init(). Sets SEVONPEND bit once for the system's
58+
* duration.
59+
*
60+
* C function prototype:
61+
*
62+
* void z_arm_cpu_idle_init(void);
63+
*/
64+
65+
SECTION_FUNC(TEXT, z_arm_cpu_idle_init)
66+
bx lr
67+
68+
SECTION_FUNC(TEXT, arch_cpu_idle)
69+
#ifdef CONFIG_TRACING
70+
push {r0, lr}
71+
bl sys_trace_idle
72+
pop {r0, lr}
73+
#endif /* CONFIG_TRACING */
74+
75+
/* Enter low power state */
76+
_sleep_if_allowed wfi
77+
78+
/*
79+
* Clear PRIMASK and flush instruction buffer to immediately service
80+
* the wake-up interrupt.
81+
*/
82+
cpsie i
83+
isb
84+
85+
bx lr
86+
87+
SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
88+
#ifdef CONFIG_TRACING
89+
push {r0, lr}
90+
bl sys_trace_idle
91+
pop {r0, lr}
92+
#endif /* CONFIG_TRACING */
93+
94+
/*
95+
* Lock PRIMASK while sleeping: wfe will still get interrupted by
96+
* incoming interrupts but the CPU will not service them right away.
97+
*/
98+
cpsid i
99+
100+
/*
101+
* No need to set SEVONPEND, it's set once in z_arm_cpu_idle_init()
102+
* and never touched again.
103+
*/
104+
105+
/* r0: interrupt mask from caller */
106+
107+
/* No BASEPRI, call wfe directly
108+
* (SEVONPEND is set in z_arm_cpu_idle_init())
109+
*/
110+
_sleep_if_allowed wfe
111+
112+
cmp r0, #0
113+
bne _irq_disabled
114+
cpsie i
115+
_irq_disabled:
116+
117+
bx lr

arch/arm/core/cortex_m/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ zephyr_library_sources(
1717
irq_manage.c
1818
prep_c.c
1919
thread.c
20+
cpu_idle.S
2021
)
2122

2223
zephyr_library_sources_ifdef(CONFIG_GEN_SW_ISR_TABLE isr_wrapper.S)

arch/arm/core/cpu_idle.S renamed to arch/arm/core/cortex_m/cpu_idle.S

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
/**
88
* @file
9-
* @brief ARM Cortex-A, Cortex-M and Cortex-R power management
9+
* @brief ARM Cortex-M power management
1010
*
1111
*/
1212

@@ -23,34 +23,12 @@ GTEXT(z_arm_cpu_idle_init)
2323
GTEXT(arch_cpu_idle)
2424
GTEXT(arch_cpu_atomic_idle)
2525

26-
#if defined(CONFIG_CPU_CORTEX_M)
2726
#define _SCB_SCR 0xE000ED10
2827

2928
#define _SCB_SCR_SEVONPEND (1 << 4)
3029
#define _SCB_SCR_SLEEPDEEP (1 << 2)
3130
#define _SCB_SCR_SLEEPONEXIT (1 << 1)
3231
#define _SCR_INIT_BITS _SCB_SCR_SEVONPEND
33-
#endif
34-
35-
/**
36-
*
37-
* @brief Initialization of CPU idle
38-
*
39-
* Only called by arch_kernel_init(). Sets SEVONPEND bit once for the system's
40-
* duration.
41-
*
42-
* C function prototype:
43-
*
44-
* void z_arm_cpu_idle_init(void);
45-
*/
46-
47-
SECTION_FUNC(TEXT, z_arm_cpu_idle_init)
48-
#if defined(CONFIG_CPU_CORTEX_M)
49-
ldr r1, =_SCB_SCR
50-
movs.n r2, #_SCR_INIT_BITS
51-
str r2, [r1]
52-
#endif
53-
bx lr
5432

5533
.macro _sleep_if_allowed wait_instruction
5634
#if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK)
@@ -84,6 +62,24 @@ _skip_\@:
8462
#endif /* CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK */
8563
.endm
8664

65+
/**
66+
*
67+
* @brief Initialization of CPU idle
68+
*
69+
* Only called by arch_kernel_init(). Sets SEVONPEND bit once for the system's
70+
* duration.
71+
*
72+
* C function prototype:
73+
*
74+
* void z_arm_cpu_idle_init(void);
75+
*/
76+
77+
SECTION_FUNC(TEXT, z_arm_cpu_idle_init)
78+
ldr r1, =_SCB_SCR
79+
movs.n r2, #_SCR_INIT_BITS
80+
str r2, [r1]
81+
bx lr
82+
8783
SECTION_FUNC(TEXT, arch_cpu_idle)
8884
#ifdef CONFIG_TRACING
8985
push {r0, lr}
@@ -162,10 +158,7 @@ SECTION_FUNC(TEXT, arch_cpu_atomic_idle)
162158

163159
/* r0: interrupt mask from caller */
164160

165-
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) \
166-
|| defined(CONFIG_ARMV7_R) \
167-
|| defined(CONFIG_AARCH32_ARMV8_R) \
168-
|| defined(CONFIG_ARMV7_A)
161+
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
169162
/* No BASEPRI, call wfe directly
170163
* (SEVONPEND is set in z_arm_cpu_idle_init())
171164
*/

0 commit comments

Comments
 (0)