1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#include <autoconf.h>
14#include <utils/gen_config.h>
15#include <utils/stack.h>
16
17void *
18utils_run_on_stack(void *stack_top, void * (*func)(void *arg), void *arg)
19{
20#ifdef CONFIG_ARCH_AARCH64
21    void *ret;
22    asm volatile (
23        "mov x20, sp\n\t"               /* Save sp - x20 is callee saved so we don't need to save it. */
24        "mov sp, %[new_stack]\n\t"      /* Switch to new stack. */
25        "mov x0, %[arg]\n\t"            /* Setup argument to func. */
26        "blr %[func]\n\t"
27        "mov sp, x20\n\t"
28        "mov %[ret], x0\n\t"
29        : [ret] "=r" (ret)
30        : [new_stack] "r" (stack_top),
31        [func] "r" (func),
32        [arg] "r" (arg)
33        /* x9 - x15 caller saved registers */
34        /* x20 and LR */
35        : "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x20", "x30");
36#else
37    void *ret;
38    asm volatile (
39        "mov r4, sp\n\t"                /* Save sp - r4 is callee saved so we don't need to save it. */
40        "mov sp, %[new_stack]\n\t"      /* Switch to new stack. */
41        "mov r0, %[arg]\n\t"            /* Setup argument to func. */
42        "blx %[func]\n\t"
43        "mov sp, r4\n\t"
44        "mov %[ret], r0\n\t"
45        : [ret] "=r" (ret)
46        : [new_stack] "r" (stack_top),
47        [func] "r" (func),
48        [arg] "r" (arg)
49        /* r0 - r3 are caller saved, so they will be clobbered by blx.
50         * blx clobbers lr
51         * we clobber r4 to save the return value in it */
52        : "r0", "r1", "r2", "r3", "r4", "lr");
53#endif /* CONFIG_ARCH_AARCH64 */
54    return ret;
55}
56