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