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