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 */
21void FORCE_O2 idle_thread(void)
22{
23    while (1) {
24        wfi();
25    }
26}
27
28/** DONT_TRANSLATE */
29void 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