1/***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12/**************************************************************************/
13/**************************************************************************/
14/**                                                                       */
15/** ThreadX Component                                                     */
16/**                                                                       */
17/**   Thread                                                              */
18/**                                                                       */
19/**************************************************************************/
20/**************************************************************************/
21#ifdef TX_INCLUDE_USER_DEFINE_FILE
22#include "tx_user.h"
23#endif
24
25    .text
26    .align 3
27/**************************************************************************/
28/*                                                                        */
29/*  FUNCTION                                               RELEASE        */
30/*                                                                        */
31/*    _tx_thread_stack_build                               ARMv8-A        */
32/*                                                           6.3.0        */
33/*  AUTHOR                                                                */
34/*                                                                        */
35/*    William E. Lamie, Microsoft Corporation                             */
36/*                                                                        */
37/*  DESCRIPTION                                                           */
38/*                                                                        */
39/*    This function builds a stack frame on the supplied thread's stack.  */
40/*    The stack frame results in a fake interrupt return to the supplied  */
41/*    function pointer.                                                   */
42/*                                                                        */
43/*  INPUT                                                                 */
44/*                                                                        */
45/*    thread_ptr                            Pointer to thread             */
46/*    function_ptr                          Pointer to entry function     */
47/*                                                                        */
48/*  OUTPUT                                                                */
49/*                                                                        */
50/*    None                                                                */
51/*                                                                        */
52/*  CALLS                                                                 */
53/*                                                                        */
54/*    None                                                                */
55/*                                                                        */
56/*  CALLED BY                                                             */
57/*                                                                        */
58/*    _tx_thread_create                     Create thread service         */
59/*                                                                        */
60/*  RELEASE HISTORY                                                       */
61/*                                                                        */
62/*    DATE              NAME                      DESCRIPTION             */
63/*                                                                        */
64/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
65/*  01-31-2022     Andres Mlinar            Updated comments,             */
66/*                                            resulting in version 6.1.10 */
67/*  10-31-2023     Tiejun Zhou              Modified comment(s), added    */
68/*                                            #include tx_user.h,         */
69/*                                            resulting in version 6.3.0  */
70/*                                                                        */
71/**************************************************************************/
72// VOID   _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
73// {
74    .global _tx_thread_stack_build
75    .type   _tx_thread_stack_build, @function
76_tx_thread_stack_build:
77
78
79    /* Build an interrupt frame.  On Cortex-A35 it should look like this:
80
81       Stack Top:      SSPR        Initial SSPR
82                       ELR         Point of interrupt
83                       x28         Initial value for x28
84                       not used    Not used
85                       x26         Initial value for x26
86                       x27         Initial value for x27
87                       x24         Initial value for x24
88                       x25         Initial value for x25
89                       x22         Initial value for x22
90                       x23         Initial value for x23
91                       x20         Initial value for x20
92                       x21         Initial value for x21
93                       x18         Initial value for x18
94                       x19         Initial value for x19
95                       x16         Initial value for x16
96                       x17         Initial value for x17
97                       x14         Initial value for x14
98                       x15         Initial value for x15
99                       x12         Initial value for x12
100                       x13         Initial value for x13
101                       x10         Initial value for x10
102                       x11         Initial value for x11
103                       x8          Initial value for x8
104                       x9          Initial value for x9
105                       x6          Initial value for x6
106                       x7          Initial value for x7
107                       x4          Initial value for x4
108                       x5          Initial value for x5
109                       x2          Initial value for x2
110                       x3          Initial value for x3
111                       x0          Initial value for x0
112                       x1          Initial value for x1
113                       x29         Initial value for x29 (frame pointer)
114                       x30         Initial value for x30 (link register)
115                       0           For stack backtracing
116
117    Stack Bottom: (higher memory address)  */
118
119    LDR     x4, [x0, #24]                       // Pickup end of stack area
120    BIC     x4, x4, #0xF                        // Ensure 16-byte alignment
121
122    /* Actually build the stack frame.  */
123
124    MOV     x2, #0                              // Build clear value
125    MOV     x3, #0                              //
126
127    STP     x2, x3, [x4, #-16]!                 // Set backtrace to 0
128    STP     x2, x3, [x4, #-16]!                 // Set initial x29, x30
129    STP     x2, x3, [x4, #-16]!                 // Set initial x0, x1
130    STP     x2, x3, [x4, #-16]!                 // Set initial x2, x3
131    STP     x2, x3, [x4, #-16]!                 // Set initial x4, x5
132    STP     x2, x3, [x4, #-16]!                 // Set initial x6, x7
133    STP     x2, x3, [x4, #-16]!                 // Set initial x8, x9
134    STP     x2, x3, [x4, #-16]!                 // Set initial x10, x11
135    STP     x2, x3, [x4, #-16]!                 // Set initial x12, x13
136    STP     x2, x3, [x4, #-16]!                 // Set initial x14, x15
137    STP     x2, x3, [x4, #-16]!                 // Set initial x16, x17
138    STP     x2, x3, [x4, #-16]!                 // Set initial x18, x19
139    STP     x2, x3, [x4, #-16]!                 // Set initial x20, x21
140    STP     x2, x3, [x4, #-16]!                 // Set initial x22, x23
141    STP     x2, x3, [x4, #-16]!                 // Set initial x24, x25
142    STP     x2, x3, [x4, #-16]!                 // Set initial x26, x27
143    STP     x2, x3, [x4, #-16]!                 // Set initial x28
144#ifdef EL1
145    MOV     x2, #0x4                            // Build initial SPSR  (EL1)
146#else
147#ifdef EL2
148    MOV     x2, #0x8                            // Build initial SPSR  (EL2)
149#else
150    MOV     x2, #0xC                            // Build initial SPSR  (EL3)
151#endif
152#endif
153    MOV     x3, x1                              // Build initial ELR
154    STP     x2, x3, [x4, #-16]!                 // Set initial SPSR & ELR
155
156    /* Setup stack pointer.  */
157    // thread_ptr -> tx_thread_stack_ptr =  x2;
158
159    STR     x4, [x0, #8]                        // Save stack pointer in thread's
160    RET                                         // Return to caller
161
162// }
163