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