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 ARMv7-A */ 61/* 6.3.0 */ 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/* 04-25-2022 Zhen Kong Updated comments, */ 95/* resulting in version 6.1.11 */ 96/* 10-31-2023 Tiejun Zhou Modified comment(s), added */ 97/* #include tx_user.h, */ 98/* resulting in version 6.3.0 */ 99/* */ 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 the ARMv7-A 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 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 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