1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-05-12     RT-Thread    init
9  * 2023-07-13     GuEe-GUI     append fpu: Q16 ~ Q31
10  */
11 #include <board.h>
12 #include <rtthread.h>
13 #include <cpuport.h>
14 
15 #include <armv8.h>
16 
17 #define INITIAL_SPSR_EL1 (PSTATE_EL1 | SP_ELx)
18 
19 /**
20  * This function will initialize thread stack
21  *
22  * @param tentry the entry of thread
23  * @param parameter the parameter of entry
24  * @param stack_addr the beginning stack address
25  * @param texit the function will be called when thread exit
26  *
27  * @return stack address
28  */
rt_hw_stack_init(void * tentry,void * parameter,rt_uint8_t * stack_addr,void * texit)29 rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
30                              rt_uint8_t *stack_addr, void *texit)
31 {
32     rt_ubase_t *stk;
33 
34     /* The AAPCS64 requires 128-bit (16 byte) stack alignment */
35     stk = (rt_ubase_t*)RT_ALIGN_DOWN((rt_ubase_t)stack_addr, 16);
36 
37     for (int i = 0; i < 32; ++i)
38     {
39         stk -= sizeof(rt_uint128_t) / sizeof(rt_ubase_t);
40 
41         *(rt_uint128_t *)stk = (rt_uint128_t) { 0 };
42     }
43 
44     *(--stk) = (rt_ubase_t)texit;           /* X20, 2nd param */
45     *(--stk) = (rt_ubase_t)tentry;          /* X19, 1st param */
46     *(--stk) = (rt_ubase_t)22;              /* X22 */
47     *(--stk) = (rt_ubase_t)parameter;       /* X21, 3rd param */
48     *(--stk) = (rt_ubase_t)24;              /* X24 */
49     *(--stk) = (rt_ubase_t)23;              /* X23 */
50     *(--stk) = (rt_ubase_t)26;              /* X26 */
51     *(--stk) = (rt_ubase_t)25;              /* X25 */
52     *(--stk) = (rt_ubase_t)28;              /* X28 */
53     *(--stk) = (rt_ubase_t)27;              /* X27 */
54     *(--stk) = (rt_ubase_t)0;               /* sp_el0 */
55     *(--stk) = (rt_ubase_t)0;               /* X29 - addr 0 as AAPCS64 specified */
56     *(--stk) = (rt_ubase_t)0;               /* FPSR */
57     *(--stk) = (rt_ubase_t)0;               /* FPCR */
58     *(--stk) = INITIAL_SPSR_EL1;            /* Save Processor States */
59     *(--stk) = (rt_ubase_t)_thread_start;   /* Exception return address. */
60 
61     /* return task's current stack address */
62     return (rt_uint8_t *)stk;
63 }
64