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