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