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