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;
23;#define TX_SOURCE_CODE
24;
25;
26;/* Include necessary system files.  */
27;
28;#include "tx_api.h"
29;#include "tx_thread.h"
30;
31;
32SVC_MODE        DEFINE  0x13                    ; SVC mode
33#ifdef TX_ENABLE_FIQ_SUPPORT
34CPSR_MASK       DEFINE  0xDF                    ; Mask initial CPSR, IRQ & FIQ ints enabled
35#else
36CPSR_MASK       DEFINE  0x9F                    ; Mask initial CPSR, IRQ ints enabled
37#endif
38;
39;
40;/**************************************************************************/
41;/*                                                                        */
42;/*  FUNCTION                                               RELEASE        */
43;/*                                                                        */
44;/*    _tx_thread_stack_build                               ARM9/IAR       */
45;/*                                                           6.1          */
46;/*  AUTHOR                                                                */
47;/*                                                                        */
48;/*    William E. Lamie, Microsoft Corporation                             */
49;/*                                                                        */
50;/*  DESCRIPTION                                                           */
51;/*                                                                        */
52;/*    This function builds a stack frame on the supplied thread's stack.  */
53;/*    The stack frame results in a fake interrupt return to the supplied  */
54;/*    function pointer.                                                   */
55;/*                                                                        */
56;/*  INPUT                                                                 */
57;/*                                                                        */
58;/*    thread_ptr                            Pointer to thread control blk */
59;/*    function_ptr                          Pointer to return function    */
60;/*                                                                        */
61;/*  OUTPUT                                                                */
62;/*                                                                        */
63;/*    None                                                                */
64;/*                                                                        */
65;/*  CALLS                                                                 */
66;/*                                                                        */
67;/*    None                                                                */
68;/*                                                                        */
69;/*  CALLED BY                                                             */
70;/*                                                                        */
71;/*    _tx_thread_create                     Create thread service         */
72;/*                                                                        */
73;/*  RELEASE HISTORY                                                       */
74;/*                                                                        */
75;/*    DATE              NAME                      DESCRIPTION             */
76;/*                                                                        */
77;/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
78;/*                                                                        */
79;/**************************************************************************/
80;VOID   _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
81;{
82    RSEG    .text:CODE:NOROOT(2)
83    PUBLIC  _tx_thread_stack_build
84
85    CODE32
86_tx_thread_stack_build
87;
88;
89;    /* Build a fake interrupt frame.  The form of the fake interrupt stack
90;       on the ARM9 should look like the following after it is built:
91;
92;       Stack Top:      1           Interrupt stack frame type
93;                       CPSR        Initial value for CPSR
94;                       a1 (r0)     Initial value for a1
95;                       a2 (r1)     Initial value for a2
96;                       a3 (r2)     Initial value for a3
97;                       a4 (r3)     Initial value for a4
98;                       v1 (r4)     Initial value for v1
99;                       v2 (r5)     Initial value for v2
100;                       v3 (r6)     Initial value for v3
101;                       v4 (r7)     Initial value for v4
102;                       v5 (r8)     Initial value for v5
103;                       sb (r9)     Initial value for sb
104;                       sl (r10)    Initial value for sl
105;                       fp (r11)    Initial value for fp
106;                       ip (r12)    Initial value for ip
107;                       lr (r14)    Initial value for lr
108;                       pc (r15)    Initial value for pc
109;                       0           For stack backtracing
110;
111;    Stack Bottom: (higher memory address)  */
112;
113    LDR     r2, [r0, #16]                       ; Pickup end of stack area
114    BIC     r2, r2, #7                          ; Ensure long-word alignment
115    SUB     r2, r2, #76                         ; Allocate space for the stack frame
116;
117;    /* Actually build the stack frame.  */
118;
119    MOV     r3, #1                              ; Build interrupt stack type
120    STR     r3, [r2, #0]                        ; Store stack type
121    MOV     r3, #0                              ; Build initial register value
122    STR     r3, [r2, #8]                        ; Store initial r0
123    STR     r3, [r2, #12]                       ; Store initial r1
124    STR     r3, [r2, #16]                       ; Store initial r2
125    STR     r3, [r2, #20]                       ; Store initial r3
126    STR     r3, [r2, #24]                       ; Store initial r4
127    STR     r3, [r2, #28]                       ; Store initial r5
128    STR     r3, [r2, #32]                       ; Store initial r6
129    STR     r3, [r2, #36]                       ; Store initial r7
130    STR     r3, [r2, #40]                       ; Store initial r8
131    STR     r3, [r2, #44]                       ; Store initial r9
132    LDR     r3, [r0, #12]                       ; Pickup stack starting address
133    STR     r3, [r2, #48]                       ; Store initial r10 (sl)
134    MOV     r3, #0                              ; Build initial register value
135    STR     r3, [r2, #52]                       ; Store initial r11
136    STR     r3, [r2, #56]                       ; Store initial r12
137    STR     r3, [r2, #60]                       ; Store initial lr
138    STR     r1, [r2, #64]                       ; Store initial pc
139    STR     r3, [r2, #68]                       ; 0 for back-trace
140    MRS     r1, CPSR                            ; Pickup CPSR
141    BIC     r1, r1, #CPSR_MASK                  ; Mask mode bits of CPSR
142    ORR     r3, r1, #SVC_MODE                   ; Build CPSR, SVC mode, interrupts enabled
143    STR     r3, [r2, #4]                        ; Store initial CPSR
144;
145;    /* Setup stack pointer.  */
146;    thread_ptr -> tx_thread_stack_ptr =  r2;
147;
148    STR     r2, [r0, #8]                        ; Save stack pointer in thread's
149                                                ;   control block
150#ifdef TX_THUMB
151    BX      lr                                  ; Return to caller
152#else
153    MOV     pc, lr                              ; Return to caller
154#endif
155;}
156    END
157
158