1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause 2*d30ea906Sjfb8856606 * Copyright(c) 2017 Cavium, Inc 32bfe3f2eSlogwang */ 42bfe3f2eSlogwang 52bfe3f2eSlogwang #ifndef STACK_H 62bfe3f2eSlogwang #define STACK_H 72bfe3f2eSlogwang 82bfe3f2eSlogwang #ifdef __cplusplus 92bfe3f2eSlogwang extern "C" { 102bfe3f2eSlogwang #endif 112bfe3f2eSlogwang 122bfe3f2eSlogwang #include "lthread_int.h" 132bfe3f2eSlogwang 142bfe3f2eSlogwang /* 152bfe3f2eSlogwang * Sets up the initial stack for the lthread. 162bfe3f2eSlogwang */ 172bfe3f2eSlogwang static inline void arch_set_stack(struct lthread * lt,void * func)182bfe3f2eSlogwangarch_set_stack(struct lthread *lt, void *func) 192bfe3f2eSlogwang { 202bfe3f2eSlogwang void **stack_top = (void *)((char *)(lt->stack) + lt->stack_size); 212bfe3f2eSlogwang 222bfe3f2eSlogwang /* 232bfe3f2eSlogwang * Align stack_top to 16 bytes. Arm64 has the constraint that the 242bfe3f2eSlogwang * stack pointer must always be quad-word aligned. 252bfe3f2eSlogwang */ 262bfe3f2eSlogwang stack_top = (void **)(((unsigned long)(stack_top)) & ~0xfUL); 272bfe3f2eSlogwang 282bfe3f2eSlogwang /* 292bfe3f2eSlogwang * First Stack Frame 302bfe3f2eSlogwang */ 312bfe3f2eSlogwang stack_top[0] = NULL; 322bfe3f2eSlogwang stack_top[-1] = NULL; 332bfe3f2eSlogwang 342bfe3f2eSlogwang /* 352bfe3f2eSlogwang * Initialize the context 362bfe3f2eSlogwang */ 372bfe3f2eSlogwang lt->ctx.fp = &stack_top[-1]; 382bfe3f2eSlogwang lt->ctx.sp = &stack_top[-2]; 392bfe3f2eSlogwang 402bfe3f2eSlogwang /* 412bfe3f2eSlogwang * Here only the address of _lthread_exec is saved as the link 422bfe3f2eSlogwang * register value. The argument to _lthread_exec i.e the address of 432bfe3f2eSlogwang * the lthread struct is not saved. This is because the first 442bfe3f2eSlogwang * argument to ctx_switch is the address of the new context, 452bfe3f2eSlogwang * which also happens to be the address of required lthread struct. 462bfe3f2eSlogwang * So while returning from ctx_switch into _thread_exec, parameter 472bfe3f2eSlogwang * register x0 will always contain the required value. 482bfe3f2eSlogwang */ 492bfe3f2eSlogwang lt->ctx.lr = func; 502bfe3f2eSlogwang } 512bfe3f2eSlogwang 522bfe3f2eSlogwang #ifdef __cplusplus 532bfe3f2eSlogwang } 542bfe3f2eSlogwang #endif 552bfe3f2eSlogwang 562bfe3f2eSlogwang #endif /* STACK_H_ */ 57