1 /*
2  * Copyright (c) 2021 KT-Elektronik, Klaucke und Partner GmbH
3  * Copyright (c) 2024 Renesas Electronics Corporation
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/irq.h>
8 #include <zephyr/tracing/tracing.h>
9 
arch_cpu_idle(void)10 void arch_cpu_idle(void)
11 {
12 	sys_trace_idle();
13 
14 	/* The assembler instruction "wait" switches the processor to sleep mode,
15 	 * which stops program execution until an interrupt is triggered.
16 	 * All clocks that are not in a stop state continue operating, including
17 	 * the system timer.
18 	 *
19 	 * Also, "wait" sets the PSW I bit, activating
20 	 * interrupts (otherwise, the processor would never return from sleep
21 	 * mode). This is consistent with the Zephyr API description, according
22 	 * to which "In some architectures, before returning, the function
23 	 * unmasks interrupts unconditionally." - this is such an architecture.
24 	 */
25 	__asm__ volatile("wait");
26 }
27 
arch_cpu_atomic_idle(unsigned int key)28 void arch_cpu_atomic_idle(unsigned int key)
29 {
30 	sys_trace_idle();
31 
32 	/* The assembler instruction "wait" switches the processor to sleep mode,
33 	 * which stops program execution until an interrupt is triggered.
34 	 * All clocks that are not in a stop state continue operating, including
35 	 * the system timer.
36 	 */
37 	__asm__ volatile("wait");
38 
39 	/* "wait" unconditionally unlocks interrupts. To restore the interrupt
40 	 * lockout state before calling arch_cpu_atomic_idle, interrupts have
41 	 * to be locked after returning from "wait" if irq_lock would NOT have
42 	 * unlocked interrupts (i.e. if the key indicates nested interrupt
43 	 * locks)
44 	 */
45 	if (key == 0) {
46 		irq_lock();
47 	}
48 }
49