1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #ifndef STACK_H 6 #define STACK_H 7 8 #ifdef __cplusplus 9 extern "C" { 10 #endif 11 12 #include "lthread_int.h" 13 14 /* 15 * Sets up the initial stack for the lthread. 16 */ 17 static inline void 18 arch_set_stack(struct lthread *lt, void *func) 19 { 20 void **stack_top = (void *)((char *)(lt->stack) + lt->stack_size); 21 22 /* 23 * Align stack_top to 16 bytes. Arm64 has the constraint that the 24 * stack pointer must always be quad-word aligned. 25 */ 26 stack_top = (void **)(((unsigned long)(stack_top)) & ~0xfUL); 27 28 /* 29 * First Stack Frame 30 */ 31 stack_top[0] = NULL; 32 stack_top[-1] = NULL; 33 34 /* 35 * Initialize the context 36 */ 37 lt->ctx.fp = &stack_top[-1]; 38 lt->ctx.sp = &stack_top[-2]; 39 40 /* 41 * Here only the address of _lthread_exec is saved as the link 42 * register value. The argument to _lthread_exec i.e the address of 43 * the lthread struct is not saved. This is because the first 44 * argument to ctx_switch is the address of the new context, 45 * which also happens to be the address of required lthread struct. 46 * So while returning from ctx_switch into _thread_exec, parameter 47 * register x0 will always contain the required value. 48 */ 49 lt->ctx.lr = func; 50 } 51 52 #ifdef __cplusplus 53 } 54 #endif 55 56 #endif /* STACK_H_ */ 57