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;/** ThreadX Component */ 15;/** */ 16;/** Thread */ 17;/** */ 18;/**************************************************************************/ 19;/**************************************************************************/ 20#ifdef TX_INCLUDE_USER_DEFINE_FILE 21#include "tx_user.h" 22#endif 23 24 .equ LONG_ALIGN_MASK, 0xFFFFFFFC 25 .equ INT_ENABLE_BITS, 0x8000001E 26 27;/**************************************************************************/ 28;/* */ 29;/* FUNCTION RELEASE */ 30;/* */ 31;/* _tx_thread_stack_build ARCv2_EM/MetaWare */ 32;/* 6.2.1 */ 33;/* AUTHOR */ 34;/* */ 35;/* William E. Lamie, Microsoft Corporation */ 36;/* */ 37;/* DESCRIPTION */ 38;/* */ 39;/* This function builds a stack frame on the supplied thread's stack. */ 40;/* The stack frame results in a fake interrupt return to the supplied */ 41;/* function pointer. */ 42;/* */ 43;/* INPUT */ 44;/* */ 45;/* thread_ptr Pointer to thread control blk */ 46;/* function_ptr Pointer to return function */ 47;/* */ 48;/* OUTPUT */ 49;/* */ 50;/* None */ 51;/* */ 52;/* CALLS */ 53;/* */ 54;/* None */ 55;/* */ 56;/* CALLED BY */ 57;/* */ 58;/* _tx_thread_create Create thread service */ 59;/* */ 60;/* RELEASE HISTORY */ 61;/* */ 62;/* DATE NAME DESCRIPTION */ 63;/* */ 64;/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 65;/* 04-02-2021 Andres Mlinar Modified comments, */ 66;/* resulting in version 6.1.6 */ 67;/* 03-08-2023 Cindy Deng Modified comment(s), added */ 68;/* #include tx_user.h, */ 69;/* resulting in version 6.2.1 */ 70;/* */ 71;/**************************************************************************/ 72;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) 73;{ 74 .global _tx_thread_stack_build 75 .type _tx_thread_stack_build, @function 76_tx_thread_stack_build: 77; 78; 79; /* Build a fake interrupt frame. The form of the fake interrupt stack 80; on the ARCv2 EM should look like the following after it is built. 81; Note that the extension registers are always assigned space here. 82; 83; Stack Top: 1 Interrupt stack frame type 84; LP_START Initial loop start 85; LP_END Initial loop end 86; LP_COUNT Initial loop count 87; blink Initial blink value 88; ilink Initial ilink (point of interrupt) 89; fp (r27) Initial fp (0) 90; gp Initial gp 91; r25 Initial r25 92; r24 Initial r24 93; r23 Initial r23 94; r22 Initial r22 95; r21 Initial r21 96; r20 Initial r20 97; r19 Initial r19 98; r18 Initial r18 99; r17 Initial r17 100; r16 Initial r16 101; r15 Initial r15 102; r14 Initial r14 103; r13 Initial r13 104; r12 Initial r12 105; r11 Initial r11 106; r10 Initial r10 107; r9 Initial r9 108; r8 Initial r8 109; r7 Initial r7 110; r6 Initial r6 111; r5 Initial r5 112; r4 Initial r4 113; r3 Initial r3 114; r2 Initial r2 115; r1 Initial r1 116; r0 Initial r0 117; r30 Initial r30 118; r58 Initial r58 119; r59 Initial r59 120; 0 Reserved 121; 0 Reserved 122; 0 Initial BTA 123; 0 Point of Interrupt (thread entry point) 124; 0 Initial STATUS32 125; 0 Backtrace 126; 0 Backtrace 127; 0 Backtrace 128; 0 Backtrace 129; 130; *: these registers will only be saved and restored if flag -Xxmac_d16 is passed to hcac 131; 132; Stack Bottom: (higher memory address) */ 133; 134 ld r3, [r0, 16] ; Pickup end of stack area 135 and r3, r3, LONG_ALIGN_MASK ; Ensure long-word alignment 136 sub r3, r3, 196 ; Allocate an interrupt stack frame (ARCv2 EM) 137; 138; /* Actually build the stack frame. */ 139; 140 st 1, [r3, 0] ; Store interrupt stack type on the 141 ; top of the stack 142 mov r5, 0 ; Build initial clear value 143 st r5, [r3, 4] ; Store initial LP_START 144 st r5, [r3, 8] ; Store initial LP_END 145 st r5, [r3, 12] ; Store initial LP_COUNT 146 st r5, [r3, 16] ; Store initial blink 147 st r1, [r3, 20] ; Store initial ilink 148 st r5, [r3, 24] ; Store initial fp (0 for backtrace) 149 st gp, [r3, 28] ; Store current gp 150 st r5, [r3, 32] ; Store initial r25 151 st r5, [r3, 36] ; Store initial r24 152 st r5, [r3, 40] ; Store initial r23 153 st r5, [r3, 44] ; Store initial r22 154 st r5, [r3, 48] ; Store initial r21 155 st r5, [r3, 52] ; Store initial r20 156 st r5, [r3, 56] ; Store initial r19 157 st r5, [r3, 60] ; Store initial r18 158 st r5, [r3, 64] ; Store initial r17 159 st r5, [r3, 68] ; Store initial r16 160 st r5, [r3, 72] ; Store initial r15 161 st r5, [r3, 76] ; Store initial r14 162 st r5, [r3, 80] ; Store initial r13 163 st r5, [r3, 84] ; Store initial r12 164 st r5, [r3, 88] ; Store initial r11 165 st r5, [r3, 92] ; Store initial r10 166 st r5, [r3, 96] ; Store initial r9 167 st r5, [r3, 100] ; Store initial r8 168 st r5, [r3, 104] ; Store initial r7 169 st r5, [r3, 108] ; Store initial r6 170 st r5, [r3, 112] ; Store initial r5 171 st r5, [r3, 116] ; Store initial r4 172 st r5, [r3, 120] ; Store initial r3 173 st r5, [r3, 124] ; Store initial r2 174 st r5, [r3, 128] ; Store initial r1 175 st r5, [r3, 132] ; Store initial r0 176 st r5, [r3, 136] ; Store initial r30 177 st r5, [r3, 140] ; Store initial r58 178 st r5, [r3, 144] ; Store initial r59 179 st r5, [r3, 148] ; Reserved 180 st r5, [r3, 152] ; Reserved 181 st r5, [r3, 156] ; Store initial BTA 182 st r1, [r3, 160] ; Store initial point of entry 183 lr r6, [status32] ; Pickup STATUS32 184 or r6, r6, INT_ENABLE_BITS ; Make sure interrupts are enabled 185 st r6, [r3, 164] ; Store initial STATUS32 186 st r5, [r3, 168] ; Backtrace 0 187 st r5, [r3, 172] ; Backtrace 0 188 st r5, [r3, 176] ; Backtrace 0 189 st r5, [r3, 180] ; Backtrace 0 190; 191; /* Setup stack pointer. */ 192; thread_ptr -> tx_thread_stack_ptr = r3; 193; 194 j_s.d [blink] ; Return to caller 195 st r3, [r0, 8] ; Save stack pointer in thread's 196 ; control block 197;} 198 .end 199 200 201