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