1/**************************************************************************/
2/*                                                                        */
3/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4/*                                                                        */
5/*       This software is licensed under the Microsoft Software License   */
6/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8/*       and in the root directory of this software.                      */
9/*                                                                        */
10/**************************************************************************/
11
12
13/**************************************************************************/
14/**************************************************************************/
15/**                                                                       */
16/** ThreadX Component                                                     */
17/**                                                                       */
18/**   Thread                                                              */
19/**                                                                       */
20/**************************************************************************/
21/**************************************************************************/
22#ifdef TX_INCLUDE_USER_DEFINE_FILE
23#include "tx_user.h"
24#endif
25
26    .arm
27
28SVC_MODE        =       0x13                    // SVC mode
29#ifdef TX_ENABLE_FIQ_SUPPORT
30CPSR_MASK       =       0xDF                    // Mask initial CPSR, IRQ & FIQ interrupts enabled
31#else
32CPSR_MASK       =       0x9F                    // Mask initial CPSR, IRQ interrupts enabled
33#endif
34
35
36/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for
37   applications calling this function from to 16-bit Thumb mode.  */
38
39    .text
40    .align 2
41    .thumb
42    .global $_tx_thread_stack_build
43    .type    $_tx_thread_stack_build,function
44$_tx_thread_stack_build:
45     BX        pc                               // Switch to 32-bit mode
46     NOP                                        //
47    .arm
48     STMFD     sp!, {lr}                        // Save return address
49     BL        _tx_thread_stack_build           // Call _tx_thread_stack_build function
50     LDMFD     sp!, {lr}                        // Recover saved return address
51     BX        lr                               // Return to 16-bit caller
52
53
54    .text
55    .align 2
56/**************************************************************************/
57/*                                                                        */
58/*  FUNCTION                                               RELEASE        */
59/*                                                                        */
60/*    _tx_thread_stack_build                               ARMv7-A        */
61/*                                                           6.3.0        */
62/*  AUTHOR                                                                */
63/*                                                                        */
64/*    William E. Lamie, Microsoft Corporation                             */
65/*                                                                        */
66/*  DESCRIPTION                                                           */
67/*                                                                        */
68/*    This function builds a stack frame on the supplied thread's stack.  */
69/*    The stack frame results in a fake interrupt return to the supplied  */
70/*    function pointer.                                                   */
71/*                                                                        */
72/*  INPUT                                                                 */
73/*                                                                        */
74/*    thread_ptr                            Pointer to thread control blk */
75/*    function_ptr                          Pointer to return function    */
76/*                                                                        */
77/*  OUTPUT                                                                */
78/*                                                                        */
79/*    None                                                                */
80/*                                                                        */
81/*  CALLS                                                                 */
82/*                                                                        */
83/*    None                                                                */
84/*                                                                        */
85/*  CALLED BY                                                             */
86/*                                                                        */
87/*    _tx_thread_create                     Create thread service         */
88/*                                                                        */
89/*  RELEASE HISTORY                                                       */
90/*                                                                        */
91/*    DATE              NAME                      DESCRIPTION             */
92/*                                                                        */
93/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
94/*  04-25-2022     Zhen Kong                Updated comments,             */
95/*                                            resulting in version 6.1.11 */
96/*  10-31-2023     Tiejun Zhou              Modified comment(s), added    */
97/*                                            #include tx_user.h,         */
98/*                                            resulting in version 6.3.0  */
99/*                                                                        */
100/**************************************************************************/
101    .global  _tx_thread_stack_build
102    .type    _tx_thread_stack_build,function
103_tx_thread_stack_build:
104
105
106    /* Build a fake interrupt frame.  The form of the fake interrupt stack
107       on the ARMv7-A should look like the following after it is built:
108
109       Stack Top:      1           Interrupt stack frame type
110                       CPSR        Initial value for CPSR
111                       a1 (r0)     Initial value for a1
112                       a2 (r1)     Initial value for a2
113                       a3 (r2)     Initial value for a3
114                       a4 (r3)     Initial value for a4
115                       v1 (r4)     Initial value for v1
116                       v2 (r5)     Initial value for v2
117                       v3 (r6)     Initial value for v3
118                       v4 (r7)     Initial value for v4
119                       v5 (r8)     Initial value for v5
120                       sb (r9)     Initial value for sb
121                       sl (r10)    Initial value for sl
122                       fp (r11)    Initial value for fp
123                       ip (r12)    Initial value for ip
124                       lr (r14)    Initial value for lr
125                       pc (r15)    Initial value for
126                       0       For stack backtracing
127
128    Stack Bottom: (higher memory address)  */
129
130    LDR     r2, [r0, #16]                   // Pickup end of stack area
131    BIC     r2, r2, #7                      // Ensure 8-byte alignment
132    SUB     r2, r2, #76                     // Allocate space for the stack frame
133
134    /* Actually build the stack frame.  */
135
136    MOV     r3, #1                          // Build interrupt stack type
137    STR     r3, [r2, #0]                    // Store stack type
138    MOV     r3, #0                          // Build initial register value
139    STR     r3, [r2, #8]                    // Store initial r0
140    STR     r3, [r2, #12]                   // Store initial r1
141    STR     r3, [r2, #16]                   // Store initial r2
142    STR     r3, [r2, #20]                   // Store initial r3
143    STR     r3, [r2, #24]                   // Store initial r4
144    STR     r3, [r2, #28]                   // Store initial r5
145    STR     r3, [r2, #32]                   // Store initial r6
146    STR     r3, [r2, #36]                   // Store initial r7
147    STR     r3, [r2, #40]                   // Store initial r8
148    STR     r3, [r2, #44]                   // Store initial r9
149    LDR     r3, [r0, #12]                   // Pickup stack starting address
150    STR     r3, [r2, #48]                   // Store initial r10 (sl)
151    LDR     r3,=_tx_thread_schedule         // Pickup address of _tx_thread_schedule for GDB backtrace
152    STR     r3, [r2, #60]                   // Store initial r14 (lr)
153    MOV     r3, #0                          // Build initial register value
154    STR     r3, [r2, #52]                   // Store initial r11
155    STR     r3, [r2, #56]                   // Store initial r12
156    STR     r1, [r2, #64]                   // Store initial pc
157    STR     r3, [r2, #68]                   // 0 for back-trace
158    MRS     r1, CPSR                        // Pickup CPSR
159    BIC     r1, r1, #CPSR_MASK              // Mask mode bits of CPSR
160    ORR     r3, r1, #SVC_MODE               // Build CPSR, SVC mode, interrupts enabled
161    STR     r3, [r2, #4]                    // Store initial CPSR
162
163    /* Setup stack pointer.  */
164
165    STR     r2, [r0, #8]                    // Save stack pointer in thread's
166                                            //   control block
167#ifdef __THUMB_INTERWORK
168    BX      lr                              // Return to caller
169#else
170    MOV     pc, lr                          // Return to caller
171#endif
172