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#ifdef TX_INCLUDE_USER_DEFINE_FILE 22#include "tx_user.h" 23#endif 24 25 .arm 26 27SVC_MODE = 0x13 @ SVC mode 28#ifdef TX_ENABLE_FIQ_SUPPORT 29CPSR_MASK = 0xDF @ Mask initial CPSR, IRQ & FIQ interrupts enabled 30#else 31CPSR_MASK = 0x9F @ Mask initial CPSR, IRQ interrupts enabled 32#endif 33@ 34@ 35@/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for 36@ applications calling this function from to 16-bit Thumb mode. */ 37@ 38 .text 39 .align 2 40 .thumb 41 .global $_tx_thread_stack_build 42 .type $_tx_thread_stack_build,function 43$_tx_thread_stack_build: 44 BX pc @ Switch to 32-bit mode 45 NOP @ 46 .arm 47 STMFD sp!, {lr} @ Save return address 48 BL _tx_thread_stack_build @ Call _tx_thread_stack_build function 49 LDMFD sp!, {lr} @ Recover saved return address 50 BX lr @ Return to 16-bit caller 51@ 52@ 53 .text 54 .align 2 55@/**************************************************************************/ 56@/* */ 57@/* FUNCTION RELEASE */ 58@/* */ 59@/* _tx_thread_stack_build ARM11/GNU */ 60@/* 6.2.1 */ 61@/* AUTHOR */ 62@/* */ 63@/* William E. Lamie, Microsoft Corporation */ 64@/* */ 65@/* DESCRIPTION */ 66@/* */ 67@/* This function builds a stack frame on the supplied thread's stack. */ 68@/* The stack frame results in a fake interrupt return to the supplied */ 69@/* function pointer. */ 70@/* */ 71@/* INPUT */ 72@/* */ 73@/* thread_ptr Pointer to thread control blk */ 74@/* function_ptr Pointer to return function */ 75@/* */ 76@/* OUTPUT */ 77@/* */ 78@/* None */ 79@/* */ 80@/* CALLS */ 81@/* */ 82@/* None */ 83@/* */ 84@/* CALLED BY */ 85@/* */ 86@/* _tx_thread_create Create thread service */ 87@/* */ 88@/* RELEASE HISTORY */ 89@/* */ 90@/* DATE NAME DESCRIPTION */ 91@/* */ 92@/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 93@/* 03-08-2023 Cindy Deng Modified comment(s), added */ 94@/* #include tx_user.h, */ 95@/* resulting in version 6.2.1 */ 96@/* */ 97@/**************************************************************************/ 98@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) 99@{ 100 .global _tx_thread_stack_build 101 .type _tx_thread_stack_build,function 102_tx_thread_stack_build: 103@ 104@ 105@ /* Build a fake interrupt frame. The form of the fake interrupt stack 106@ on theARM11 should look like the following after it is built: 107@ 108@ Stack Top: 1 Interrupt stack frame type 109@ CPSR Initial value for CPSR 110@ a1 (r0) Initial value for a1 111@ a2 (r1) Initial value for a2 112@ a3 (r2) Initial value for a3 113@ a4 (r3) Initial value for a4 114@ v1 (r4) Initial value for v1 115@ v2 (r5) Initial value for v2 116@ v3 (r6) Initial value for v3 117@ v4 (r7) Initial value for v4 118@ v5 (r8) Initial value for v5 119@ sb (r9) Initial value for sb 120@ sl (r10) Initial value for sl 121@ fp (r11) Initial value for fp 122@ ip (r12) Initial value for ip 123@ lr (r14) Initial value for lr 124@ pc (r15) Initial value for pc 125@ 0 For stack backtracing 126@ 127@ Stack Bottom: (higher memory address) */ 128@ 129 LDR r2, [r0, #16] @ Pickup end of stack area 130 BIC r2, r2, #7 @ Ensure 8-byte alignment 131 SUB r2, r2, #76 @ Allocate space for the stack frame 132@ 133@ /* Actually build the stack frame. */ 134@ 135 MOV r3, #1 @ Build interrupt stack type 136 STR r3, [r2, #0] @ Store stack type 137 MOV r3, #0 @ Build initial register value 138 STR r3, [r2, #8] @ Store initial r0 139 STR r3, [r2, #12] @ Store initial r1 140 STR r3, [r2, #16] @ Store initial r2 141 STR r3, [r2, #20] @ Store initial r3 142 STR r3, [r2, #24] @ Store initial r4 143 STR r3, [r2, #28] @ Store initial r5 144 STR r3, [r2, #32] @ Store initial r6 145 STR r3, [r2, #36] @ Store initial r7 146 STR r3, [r2, #40] @ Store initial r8 147 STR r3, [r2, #44] @ Store initial r9 148 LDR r3, [r0, #12] @ Pickup stack starting address 149 STR r3, [r2, #48] @ Store initial r10 (sl) 150 LDR r3,=_tx_thread_schedule @ Pickup address of _tx_thread_schedule for GDB backtrace 151 STR r3, [r2, #60] @ Store initial r14 (lr) 152 MOV r3, #0 @ Build initial register value 153 STR r3, [r2, #52] @ Store initial r11 154 STR r3, [r2, #56] @ Store initial r12 155 STR r1, [r2, #64] @ Store initial pc 156 STR r3, [r2, #68] @ 0 for back-trace 157 MRS r1, CPSR @ Pickup CPSR 158 BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR 159 ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled 160 STR r3, [r2, #4] @ Store initial CPSR 161@ 162@ /* Setup stack pointer. */ 163@ thread_ptr -> tx_thread_stack_ptr = r2; 164@ 165 STR r2, [r0, #8] @ Save stack pointer in thread's 166 @ control block 167#ifdef __THUMB_INTERWORK 168 BX lr @ Return to caller 169#else 170 MOV pc, lr @ Return to caller 171#endif 172@} 173 174 175