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;/** ThreadX Component                                                     */
15;/**                                                                       */
16;/**   Thread                                                              */
17;/**                                                                       */
18;/**************************************************************************/
19;/**************************************************************************/
20#ifdef TX_INCLUDE_USER_DEFINE_FILE
21#include "tx_user.h"
22#endif
23
24    .equ    LONG_ALIGN_MASK, 0xFFFFFFFC
25    .equ    INT_ENABLE_BITS, 0x8000001E
26
27;/**************************************************************************/
28;/*                                                                        */
29;/*  FUNCTION                                               RELEASE        */
30;/*                                                                        */
31;/*    _tx_thread_stack_build                          ARCv2_EM/MetaWare   */
32;/*                                                           6.2.1        */
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 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;/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
65;/*  04-02-2021     Andres Mlinar            Modified comments,            */
66;/*                                            resulting in version 6.1.6  */
67;/*  03-08-2023     Cindy Deng               Modified comment(s), added    */
68;/*                                            #include tx_user.h,         */
69;/*                                            resulting in version 6.2.1  */
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 a fake interrupt frame.  The form of the fake interrupt stack
80;       on the ARCv2 EM should look like the following after it is built.
81;       Note that the extension registers are always assigned space here.
82;
83;       Stack Top:      1           Interrupt stack frame type
84;                       LP_START    Initial loop start
85;                       LP_END      Initial loop end
86;                       LP_COUNT    Initial loop count
87;                       blink       Initial blink value
88;                       ilink       Initial ilink (point of interrupt)
89;                       fp (r27)    Initial fp (0)
90;                       gp          Initial gp
91;                       r25         Initial r25
92;                       r24         Initial r24
93;                       r23         Initial r23
94;                       r22         Initial r22
95;                       r21         Initial r21
96;                       r20         Initial r20
97;                       r19         Initial r19
98;                       r18         Initial r18
99;                       r17         Initial r17
100;                       r16         Initial r16
101;                       r15         Initial r15
102;                       r14         Initial r14
103;                       r13         Initial r13
104;                       r12         Initial r12
105;                       r11         Initial r11
106;                       r10         Initial r10
107;                       r9          Initial r9
108;                       r8          Initial r8
109;                       r7          Initial r7
110;                       r6          Initial r6
111;                       r5          Initial r5
112;                       r4          Initial r4
113;                       r3          Initial r3
114;                       r2          Initial r2
115;                       r1          Initial r1
116;                       r0          Initial r0
117;                       r30         Initial r30
118;                       r58         Initial r58
119;                       r59         Initial r59
120;                       0           Reserved
121;                       0           Reserved
122;                       0           Initial BTA
123;                       0           Point of Interrupt (thread entry point)
124;                       0           Initial STATUS32
125;                       0           Backtrace
126;                       0           Backtrace
127;                       0           Backtrace
128;                       0           Backtrace
129;
130; *: these registers will only be saved and restored if flag -Xxmac_d16 is passed to hcac
131;
132;    Stack Bottom: (higher memory address)  */
133;
134    ld      r3, [r0, 16]                                ; Pickup end of stack area
135    and     r3, r3, LONG_ALIGN_MASK                     ; Ensure long-word alignment
136    sub     r3, r3, 196                                 ; Allocate an interrupt stack frame (ARCv2 EM)
137;
138;    /* Actually build the stack frame.  */
139;
140    st      1, [r3, 0]                                  ; Store interrupt stack type on the
141                                                        ;   top of the stack
142    mov     r5, 0                                       ; Build initial clear value
143    st      r5, [r3, 4]                                 ; Store initial LP_START
144    st      r5, [r3, 8]                                 ; Store initial LP_END
145    st      r5, [r3, 12]                                ; Store initial LP_COUNT
146    st      r5, [r3, 16]                                ; Store initial blink
147    st      r1, [r3, 20]                                ; Store initial ilink
148    st      r5, [r3, 24]                                ; Store initial fp (0 for backtrace)
149    st      gp, [r3, 28]                                ; Store current gp
150    st      r5, [r3, 32]                                ; Store initial r25
151    st      r5, [r3, 36]                                ; Store initial r24
152    st      r5, [r3, 40]                                ; Store initial r23
153    st      r5, [r3, 44]                                ; Store initial r22
154    st      r5, [r3, 48]                                ; Store initial r21
155    st      r5, [r3, 52]                                ; Store initial r20
156    st      r5, [r3, 56]                                ; Store initial r19
157    st      r5, [r3, 60]                                ; Store initial r18
158    st      r5, [r3, 64]                                ; Store initial r17
159    st      r5, [r3, 68]                                ; Store initial r16
160    st      r5, [r3, 72]                                ; Store initial r15
161    st      r5, [r3, 76]                                ; Store initial r14
162    st      r5, [r3, 80]                                ; Store initial r13
163    st      r5, [r3, 84]                                ; Store initial r12
164    st      r5, [r3, 88]                                ; Store initial r11
165    st      r5, [r3, 92]                                ; Store initial r10
166    st      r5, [r3, 96]                                ; Store initial r9
167    st      r5, [r3, 100]                               ; Store initial r8
168    st      r5, [r3, 104]                               ; Store initial r7
169    st      r5, [r3, 108]                               ; Store initial r6
170    st      r5, [r3, 112]                               ; Store initial r5
171    st      r5, [r3, 116]                               ; Store initial r4
172    st      r5, [r3, 120]                               ; Store initial r3
173    st      r5, [r3, 124]                               ; Store initial r2
174    st      r5, [r3, 128]                               ; Store initial r1
175    st      r5, [r3, 132]                               ; Store initial r0
176    st      r5, [r3, 136]                               ; Store initial r30
177    st      r5, [r3, 140]                               ; Store initial r58
178    st      r5, [r3, 144]                               ; Store initial r59
179    st      r5, [r3, 148]                               ; Reserved
180    st      r5, [r3, 152]                               ; Reserved
181    st      r5, [r3, 156]                               ; Store initial BTA
182    st      r1, [r3, 160]                               ; Store initial point of entry
183    lr      r6, [status32]                              ; Pickup STATUS32
184    or      r6, r6, INT_ENABLE_BITS                     ; Make sure interrupts are enabled
185    st      r6, [r3, 164]                               ; Store initial STATUS32
186    st      r5, [r3, 168]                               ; Backtrace 0
187    st      r5, [r3, 172]                               ; Backtrace 0
188    st      r5, [r3, 176]                               ; Backtrace 0
189    st      r5, [r3, 180]                               ; Backtrace 0
190;
191;    /* Setup stack pointer.  */
192;    thread_ptr -> tx_thread_stack_ptr =  r3;
193;
194    j_s.d   [blink]                                     ; Return to caller
195    st      r3, [r0, 8]                                 ; Save stack pointer in thread's
196                                                        ;   control block
197;}
198    .end
199
200
201