/*************************************************************************** * Copyright (c) 2024 Microsoft Corporation * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT **************************************************************************/ /**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ /** */ /** Thread */ /** */ /**************************************************************************/ /**************************************************************************/ #ifdef TX_INCLUDE_USER_DEFINE_FILE #include "tx_user.h" #endif .syntax unified #if defined(THUMB_MODE) .thumb #else .arm #endif SVC_MODE = 0x13 // SVC mode THUMB_MASK = 0x20 // Thumb bit mask #ifdef TX_ENABLE_FIQ_SUPPORT CPSR_MASK = 0xFF // Mask initial CPSR, T, IRQ & FIQ interrupts enabled #else CPSR_MASK = 0xBF // Mask initial CPSR, T, IRQ interrupts enabled #endif .text .align 2 /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _tx_thread_stack_build ARMv7-A */ /* 6.4.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ /* This function builds a stack frame on the supplied thread's stack. */ /* The stack frame results in a fake interrupt return to the supplied */ /* function pointer. */ /* */ /* INPUT */ /* */ /* thread_ptr Pointer to thread control blk */ /* function_ptr Pointer to return function */ /* */ /* OUTPUT */ /* */ /* None */ /* */ /* CALLS */ /* */ /* None */ /* */ /* CALLED BY */ /* */ /* _tx_thread_create Create thread service */ /* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ /* */ /* 09-30-2020 William E. Lamie Initial Version 6.1 */ /* 04-25-2022 Zhen Kong Updated comments, */ /* resulting in version 6.1.11 */ /* 10-31-2023 Tiejun Zhou Modified comment(s), added */ /* #include tx_user.h, */ /* resulting in version 6.3.0 */ /* 12-31-2023 Yajun Xia Modified comment(s), */ /* Added thumb mode support, */ /* resulting in version 6.4.0 */ /* */ /**************************************************************************/ #if defined(THUMB_MODE) .thumb_func #endif .global _tx_thread_stack_build .type _tx_thread_stack_build,function _tx_thread_stack_build: /* Build a fake interrupt frame. The form of the fake interrupt stack on the ARMv7-A should look like the following after it is built: Stack Top: 1 Interrupt stack frame type CPSR Initial value for CPSR a1 (r0) Initial value for a1 a2 (r1) Initial value for a2 a3 (r2) Initial value for a3 a4 (r3) Initial value for a4 v1 (r4) Initial value for v1 v2 (r5) Initial value for v2 v3 (r6) Initial value for v3 v4 (r7) Initial value for v4 v5 (r8) Initial value for v5 sb (r9) Initial value for sb sl (r10) Initial value for sl fp (r11) Initial value for fp ip (r12) Initial value for ip lr (r14) Initial value for lr pc (r15) Initial value for 0 For stack backtracing Stack Bottom: (higher memory address) */ LDR r2, [r0, #16] // Pickup end of stack area BIC r2, r2, #7 // Ensure 8-byte alignment SUB r2, r2, #76 // Allocate space for the stack frame /* Actually build the stack frame. */ MOV r3, #1 // Build interrupt stack type STR r3, [r2, #0] // Store stack type MRS r3, CPSR // Pickup CPSR BIC r3, #CPSR_MASK // Mask mode bits of CPSR ORR r3, #SVC_MODE // Build CPSR, SYS mode, interrupts enabled TST r1, #1 // Check if the initial PC is a Thumb function IT NE ORRNE r3, #THUMB_MASK // If the initial PC is a thumb function, CPSR must reflect this STR r3, [r2, #4] // Store initial CPSR MOV r3, #0 // Build initial register value STR r3, [r2, #8] // Store initial r0 STR r3, [r2, #12] // Store initial r1 STR r3, [r2, #16] // Store initial r2 STR r3, [r2, #20] // Store initial r3 STR r3, [r2, #24] // Store initial r4 STR r3, [r2, #28] // Store initial r5 STR r3, [r2, #32] // Store initial r6 STR r3, [r2, #36] // Store initial r7 STR r3, [r2, #40] // Store initial r8 STR r3, [r2, #44] // Store initial r9 STR r3, [r2, #52] // Store initial r11 STR r3, [r2, #56] // Store initial r12 STR r3, [r2, #68] // 0 for back-trace LDR r3, [r0, #12] // Pickup stack starting address STR r3, [r2, #48] // Store initial r10 (sl) LDR r3,=_tx_thread_schedule // Pickup address of _tx_thread_schedule for GDB backtrace STR r3, [r2, #60] // Store initial r14 (lr) STR r1, [r2, #64] // Store initial pc /* Setup stack pointer. */ STR r2, [r0, #8] // Save stack pointer in thread's // control block BX lr // Return to caller