1/*
2 * Copyright (c) 2009 Corey Tabaka
3 * Copyright (c) 2020 Travis Geiselbrecht
4 *
5 * Use of this source code is governed by a MIT-style
6 * license that can be found in the LICENSE file or at
7 * https://opensource.org/licenses/MIT
8 */
9#include <lk/asm.h>
10
11.text
12
13/* void arch_idle(); */
14FUNCTION(arch_idle)
15    pushf
16    popl %eax
17    andl $0x200, %eax
18    test %eax, %eax
19    je 1f                   /* don't halt if local interrupts are disabled */
20    hlt
211:
22    ret
23
24#if X86_LEGACY
25/* In legacy mode (compiled for i386) the use of builtin atomics in the compiler
26 * ends up emitting calls to various routines that are expected to be provided
27 * by an atomic library. Implement them here.
28 *
29 * Function signatures from https://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary
30 */
31
32/*
33 * I4  __atomic_fetch_add_4  (I4 *mem, I4 val, int model)
34 */
35FUNCTION(__atomic_fetch_add_4)
36    // save old irq disable state and disable irqs
37    pushf
38    cli
39
40    mov 8(%esp), %edx       // mem
41    mov 12(%esp), %ecx      // val
42    mov (%edx),%eax         // edx = *mem
43    add %eax,%ecx           // ecx = edx + val
44    mov %ecx,(%edx)         // *mem = ecx
45    // eax holds the old value
46
47    // restore old irq state
48    popf
49    ret
50
51#endif
52
53