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
22#ifdef TX_INCLUDE_USER_DEFINE_FILE
23#include "tx_user.h"
24#endif
25
26    SECTION `.text`:CODE:NOROOT(2)
27    THUMB
28/**************************************************************************/
29/*                                                                        */
30/*  FUNCTION                                               RELEASE        */
31/*                                                                        */
32/*    _tx_thread_stack_build                           Cortex-Mx/IAR      */
33/*                                                           6.3.0        */
34/*  AUTHOR                                                                */
35/*                                                                        */
36/*    Scott Larson, Microsoft Corporation                                 */
37/*                                                                        */
38/*  DESCRIPTION                                                           */
39/*                                                                        */
40/*    This function builds a stack frame on the supplied thread's stack.  */
41/*    The stack frame results in a fake interrupt return to the supplied  */
42/*    function pointer.                                                   */
43/*                                                                        */
44/*  INPUT                                                                 */
45/*                                                                        */
46/*    thread_ptr                            Pointer to thread control blk */
47/*    function_ptr                          Pointer to return function    */
48/*                                                                        */
49/*  OUTPUT                                                                */
50/*                                                                        */
51/*    None                                                                */
52/*                                                                        */
53/*  CALLS                                                                 */
54/*                                                                        */
55/*    None                                                                */
56/*                                                                        */
57/*  CALLED BY                                                             */
58/*                                                                        */
59/*    _tx_thread_create                     Create thread service         */
60/*                                                                        */
61/*  RELEASE HISTORY                                                       */
62/*                                                                        */
63/*    DATE              NAME                      DESCRIPTION             */
64/*                                                                        */
65/*  06-02-2021      Scott Larson            Initial Version 6.1.7         */
66/*  10-31-2023      Tiejun Zhou             Included tx_user.h,           */
67/*                                            resulting in version 6.3.0  */
68/*                                                                        */
69/**************************************************************************/
70// VOID   _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
71// {
72    PUBLIC  _tx_thread_stack_build
73_tx_thread_stack_build:
74
75    /* Build a fake interrupt frame.  The form of the fake interrupt stack
76       on the Cortex-M should look like the following after it is built:
77
78       Stack Top:
79                       LR          Interrupted LR (LR at time of PENDSV)
80                       r4          Initial value for r4
81                       r5          Initial value for r5
82                       r6          Initial value for r6
83                       r7          Initial value for r7
84                       r8          Initial value for r8
85                       r9          Initial value for r9
86                       r10         Initial value for r10
87                       r11         Initial value for r11
88                       r0          Initial value for r0    (Hardware stack starts here!!)
89                       r1          Initial value for r1
90                       r2          Initial value for r2
91                       r3          Initial value for r3
92                       r12         Initial value for r12
93                       lr          Initial value for lr
94                       pc          Initial value for pc
95                       xPSR        Initial value for xPSR
96
97    Stack Bottom: (higher memory address)  */
98
99    LDR     r2, [r0, #16]                           // Pickup end of stack area
100    BIC     r2, r2, #0x7                            // Align frame for 8-byte alignment
101    SUB     r2, r2, #68                             // Subtract frame size
102    LDR     r3, =0xFFFFFFFD                         // Build initial LR value
103    STR     r3, [r2, #0]                            // Save on the stack
104
105    /* Actually build the stack frame.  */
106
107    MOV     r3, #0                                  // Build initial register value
108    STR     r3, [r2, #4]                            // Store initial r4
109    STR     r3, [r2, #8]                            // Store initial r5
110    STR     r3, [r2, #12]                           // Store initial r6
111    STR     r3, [r2, #16]                           // Store initial r7
112    STR     r3, [r2, #20]                           // Store initial r8
113    STR     r3, [r2, #24]                           // Store initial r9
114    STR     r3, [r2, #28]                           // Store initial r10
115    STR     r3, [r2, #32]                           // Store initial r11
116
117    /* Hardware stack follows.  */
118
119    STR     r3, [r2, #36]                           // Store initial r0
120    STR     r3, [r2, #40]                           // Store initial r1
121    STR     r3, [r2, #44]                           // Store initial r2
122    STR     r3, [r2, #48]                           // Store initial r3
123    STR     r3, [r2, #52]                           // Store initial r12
124    MOV     r3, #0xFFFFFFFF                         // Poison EXC_RETURN value
125    STR     r3, [r2, #56]                           // Store initial lr
126    STR     r1, [r2, #60]                           // Store initial pc
127    MOV     r3, #0x01000000                         // Only T-bit need be set
128    STR     r3, [r2, #64]                           // Store initial xPSR
129
130    /* Setup stack pointer.  */
131    // thread_ptr -> tx_thread_stack_ptr =  r2;
132
133    STR     r2, [r0, #8]                            // Save stack pointer in thread's
134                                                    //   control block
135    BX      lr                                      // Return to caller
136// }
137    END
138