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