1 /*
2  * Copyright 2014, General Dynamics C4 Systems
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #include <config.h>
8 #include <mode/machine.h>
9 #include <api/debug.h>
10 
11 /*
12  * The idle thread currently does not receive a stack pointer and so we rely on
13  * optimisations for correctness here. More specifically, we assume:
14  *  - Ordinary prologue/epilogue stack operations are optimised out
15  *  - All nested function calls are inlined
16  * Note that GCC does not correctly implement optimisation annotations on nested
17  * functions, so FORCE_INLINE is required on the wfi declaration in this case.
18  * Note that Clang doesn't obey FORCE_O2 and relies on the kernel being compiled
19  * with optimisations enabled.
20  */
idle_thread(void)21 void FORCE_O2 idle_thread(void)
22 {
23     while (1) {
24         wfi();
25     }
26 }
27 
28 /** DONT_TRANSLATE */
halt(void)29 void NORETURN NO_INLINE VISIBLE halt(void)
30 {
31     /* halt is actually, idle thread without the interrupts */
32     asm volatile("cpsid iaf");
33 
34 #ifdef CONFIG_PRINTING
35     printf("halting...");
36 #ifdef CONFIG_DEBUG_BUILD
37     debug_printKernelEntryReason();
38 #endif
39 #endif
40     idle_thread();
41     UNREACHABLE();
42 }
43