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
23
24/* #define TX_SOURCE_CODE  */
25
26
27/* Include necessary system files.  */
28
29/*  #include "tx_api.h"
30    #include "tx_thread.h"  */
31
32    SECTION `.text`:CODE:REORDER:NOROOT(2)
33    CODE
34/**************************************************************************/
35/*                                                                        */
36/*  FUNCTION                                               RELEASE        */
37/*                                                                        */
38/*    _tx_thread_stack_build                             RISC-V32/IAR     */
39/*                                                           6.1          */
40/*  AUTHOR                                                                */
41/*                                                                        */
42/*    William E. Lamie, Microsoft Corporation                             */
43/*    Tom van Leeuwen, Technolution B.V.                                  */
44/*                                                                        */
45/*  DESCRIPTION                                                           */
46/*                                                                        */
47/*    This function builds a stack frame on the supplied thread's stack.  */
48/*    The stack frame results in a fake interrupt return to the supplied  */
49/*    function pointer.                                                   */
50/*                                                                        */
51/*  INPUT                                                                 */
52/*                                                                        */
53/*    thread_ptr                            Pointer to thread control blk */
54/*    function_ptr                          Pointer to return function    */
55/*                                                                        */
56/*  OUTPUT                                                                */
57/*                                                                        */
58/*    None                                                                */
59/*                                                                        */
60/*  CALLS                                                                 */
61/*                                                                        */
62/*    None                                                                */
63/*                                                                        */
64/*  CALLED BY                                                             */
65/*                                                                        */
66/*    _tx_thread_create                     Create thread service         */
67/*                                                                        */
68/*  RELEASE HISTORY                                                       */
69/*                                                                        */
70/*    DATE              NAME                      DESCRIPTION             */
71/*                                                                        */
72/*  09-30-2020      William E. Lamie        Initial Version 6.1           */
73/*                                                                        */
74/**************************************************************************/
75/* VOID   _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
76{  */
77    PUBLIC  _tx_thread_stack_build
78_tx_thread_stack_build:
79
80
81    /* Build a fake interrupt frame.  The form of the fake interrupt stack
82       on the RISC-V RV32 should look like the following after it is built:
83
84       Stack Top:      1       (00)    Interrupt stack frame type
85                       x27     (04)    Initial s11
86                       x26     (08)    Initial s10
87                       x25     (12)    Initial s9
88                       x24     (16)    Initial s8
89                       x23     (20)    Initial s7
90                       x22     (24)    Initial s6
91                       x21     (28)    Initial s5
92                       x20     (32)    Initial s4
93                       x19     (36)    Initial s3
94                       x18     (40)    Initial s2
95                       x9      (44)    Initial s1
96                       x8      (48)    Initial s0
97                       x31     (52)    Initial t6
98                       x30     (56)    Initial t5
99                       x29     (60)    Initial t4
100                       x28     (64)    Initial t3
101                       x7      (68)    Initial t2
102                       x6      (72)    Initial t1
103                       x5      (76)    Initial t0
104                       x17     (80)    Initial a7
105                       x16     (84)    Initial a6
106                       x15     (88)    Initial a5
107                       x14     (92)    Initial a4
108                       x13     (96)    Initial a3
109                       x12     (100)   Initial a2
110                       x11     (104)   Initial a1
111                       x10     (108)   Initial a0
112                       x1      (112)   Initial ra
113                       mepc    (120)   Initial mepc
114If floating point support:
115                       f0      (124)   Inital ft0
116                       f1      (128)   Inital ft1
117                       f2      (132)   Inital ft2
118                       f3      (136)   Inital ft3
119                       f4      (140)   Inital ft4
120                       f5      (144)   Inital ft5
121                       f6      (148)   Inital ft6
122                       f7      (152)   Inital ft7
123                       f8      (156)   Inital fs0
124                       f9      (160)   Inital fs1
125                       f10     (164)   Inital fa0
126                       f11     (168)   Inital fa1
127                       f12     (172)   Inital fa2
128                       f13     (176)   Inital fa3
129                       f14     (180)   Inital fa4
130                       f15     (184)   Inital fa5
131                       f16     (188)   Inital fa6
132                       f17     (192)   Inital fa7
133                       f18     (196)   Inital fs2
134                       f19     (200)   Inital fs3
135                       f20     (204)   Inital fs4
136                       f21     (208)   Inital fs5
137                       f22     (212)   Inital fs6
138                       f23     (216)   Inital fs7
139                       f24     (220)   Inital fs8
140                       f25     (224)   Inital fs9
141                       f26     (228)   Inital fs10
142                       f27     (232)   Inital fs11
143                       f28     (236)   Inital ft8
144                       f29     (240)   Inital ft9
145                       f30     (244)   Inital ft10
146                       f31     (248)   Inital ft11
147                       fscr    (252)   Inital fscr
148
149    Stack Bottom: (higher memory address)  */
150
151    lw      t0, 16(a0)                                  ; Pickup end of stack area
152    li      t1, ~15                                     ; Build 16-byte alignment mask
153    and     t0, t0, t1                                  ; Make sure 16-byte alignment
154
155    /* Actually build the stack frame.  */
156
157#if __iar_riscv_base_isa == rv32e
158    addi    t0, t0, -260
159#else
160    addi    t0, t0, -128                                ; Allocate space for the stack frame
161#endif
162    li      t1, 1                                       ; Build stack type
163    sw      t1, 0(t0)                                   ; Place stack type on the top
164    sw      x0, 4(t0)                                   ; Initial s11
165    sw      x0, 8(t0)                                   ; Initial s10
166    sw      x0, 12(t0)                                  ; Initial s9
167    sw      x0, 16(t0)                                  ; Initial s8
168    sw      x0, 20(t0)                                  ; Initial s7
169    sw      x0, 24(t0)                                  ; Initial s6
170    sw      x0, 28(t0)                                  ; Initial s5
171    sw      x0, 32(t0)                                  ; Initial s4
172    sw      x0, 36(t0)                                  ; Initial s3
173    sw      x0, 40(t0)                                  ; Initial s2
174    sw      x0, 44(t0)                                  ; Initial s1
175    sw      x0, 48(t0)                                  ; Initial s0
176    sw      x0, 52(t0)                                  ; Initial t6
177    sw      x0, 56(t0)                                  ; Initial t5
178    sw      x0, 60(t0)                                  ; Initial t4
179    sw      x0, 64(t0)                                  ; Initial t3
180    sw      x0, 68(t0)                                  ; Initial t2
181    sw      x0, 72(t0)                                  ; Initial t1
182    sw      x0, 76(t0)                                  ; Initial t0
183    sw      x0, 80(t0)                                  ; Initial a7
184    sw      x0, 84(t0)                                  ; Initial a6
185    sw      x0, 88(t0)                                  ; Initial a5
186    sw      x0, 92(t0)                                  ; Initial a4
187    sw      x0, 96(t0)                                  ; Initial a3
188    sw      x0, 100(t0)                                 ; Initial a2
189    sw      x0, 104(t0)                                 ; Initial a1
190    sw      x0, 108(t0)                                 ; Initial a0
191    sw      x0, 112(t0)                                 ; Initial ra
192    sw      a1, 120(t0)                                 ; Initial mepc
193#if __iar_riscv_base_isa == rv32e
194    sw      x0, 124(t0)                                 ; Inital ft0
195    sw      x0, 128(t0)                                 ; Inital ft1
196    sw      x0, 132(t0)                                 ; Inital ft2
197    sw      x0, 136(t0)                                 ; Inital ft3
198    sw      x0, 140(t0)                                 ; Inital ft4
199    sw      x0, 144(t0)                                 ; Inital ft5
200    sw      x0, 148(t0)                                 ; Inital ft6
201    sw      x0, 152(t0)                                 ; Inital ft7
202    sw      x0, 156(t0)                                 ; Inital fs0
203    sw      x0, 160(t0)                                 ; Inital fs1
204    sw      x0, 164(t0)                                 ; Inital fa0
205    sw      x0, 168(t0)                                 ; Inital fa1
206    sw      x0, 172(t0)                                 ; Inital fa2
207    sw      x0, 176(t0)                                 ; Inital fa3
208    sw      x0, 180(t0)                                 ; Inital fa4
209    sw      x0, 184(t0)                                 ; Inital fa5
210    sw      x0, 188(t0)                                 ; Inital fa6
211    sw      x0, 192(t0)                                 ; Inital fa7
212    sw      x0, 196(t0)                                 ; Inital fs2
213    sw      x0, 200(t0)                                 ; Inital fs3
214    sw      x0, 204(t0)                                 ; Inital fs4
215    sw      x0, 208(t0)                                 ; Inital fs5
216    sw      x0, 212(t0)                                 ; Inital fs6
217    sw      x0, 216(t0)                                 ; Inital fs7
218    sw      x0, 220(t0)                                 ; Inital fs8
219    sw      x0, 224(t0)                                 ; Inital fs9
220    sw      x0, 228(t0)                                 ; Inital fs10
221    sw      x0, 232(t0)                                 ; Inital fs11
222    sw      x0, 236(t0)                                 ; Inital ft8
223    sw      x0, 240(t0)                                 ; Inital ft9
224    sw      x0, 244(t0)                                 ; Inital ft10
225    sw      x0, 248(t0)                                 ; Inital ft11
226    csrr    a1, fcsr                                    ; Read fcsr and use it for initial value for each thread
227    sw      a1, 252(t0)                                 ; Initial fscr
228    sw      x0, 256(t0)                                 ; Reserved word (0)
229#else
230    sw      x0, 124(t0)                                 ; Reserved word (0)
231#endif
232
233    /* Setup stack pointer.  */
234    /* thread_ptr -> tx_thread_stack_ptr =  t0;  */
235
236    sw      t0, 8(a0)                                   ; Save stack pointer in thread's
237    ret                                                 ;   control block and return
238/* }  */
239    END
240
241