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