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 23#ifdef TX_INCLUDE_USER_DEFINE_FILE 24#include "tx_user.h" 25#endif 26 27/**************************************************************************/ 28/* */ 29/* FUNCTION RELEASE */ 30/* */ 31/* _tx_thread_stack_build Cortex-Mxx/AC6 */ 32/* 6.2.1 */ 33/* AUTHOR */ 34/* */ 35/* Scott Larson, Microsoft Corporation */ 36/* */ 37/* DESCRIPTION */ 38/* */ 39/* This function builds a stack frame on the supplied thread's stack. */ 40/* The stack frame results in a fake interrupt return to the supplied */ 41/* function pointer. */ 42/* */ 43/* INPUT */ 44/* */ 45/* thread_ptr Pointer to thread control blk */ 46/* function_ptr Pointer to return function */ 47/* */ 48/* OUTPUT */ 49/* */ 50/* None */ 51/* */ 52/* CALLS */ 53/* */ 54/* None */ 55/* */ 56/* CALLED BY */ 57/* */ 58/* _tx_thread_create Create thread service */ 59/* */ 60/* RELEASE HISTORY */ 61/* */ 62/* DATE NAME DESCRIPTION */ 63/* */ 64/* 09-30-2020 Scott Larson Initial Version 6.1 */ 65/* 03-08-2023 Scott Larson Include tx_user.h, */ 66/* resulting in version 6.2.1 */ 67/* */ 68/**************************************************************************/ 69// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) 70// { 71 .section .text 72 .balign 4 73 .syntax unified 74 .eabi_attribute Tag_ABI_align_preserved, 1 75 .global _tx_thread_stack_build 76 .thumb_func 77.type _tx_thread_stack_build, function 78_tx_thread_stack_build: 79 /* Build a fake interrupt frame. The form of the fake interrupt stack 80 on the Cortex-M should look like the following after it is built: 81 82 Stack Top: 83 LR Interrupted LR (LR at time of PENDSV) 84 r4 Initial value for r4 85 r5 Initial value for r5 86 r6 Initial value for r6 87 r7 Initial value for r7 88 r8 Initial value for r8 89 r9 Initial value for r9 90 r10 Initial value for r10 91 r11 Initial value for r11 92 r0 Initial value for r0 (Hardware stack starts here!!) 93 r1 Initial value for r1 94 r2 Initial value for r2 95 r3 Initial value for r3 96 r12 Initial value for r12 97 lr Initial value for lr 98 pc Initial value for pc 99 xPSR Initial value for xPSR 100 101 Stack Bottom: (higher memory address) */ 102 103 LDR r2, [r0, #16] // Pickup end of stack area 104 BIC r2, r2, #0x7 // Align frame for 8-byte alignment 105 SUB r2, r2, #68 // Subtract frame size 106#ifdef TX_SINGLE_MODE_SECURE 107 LDR r3, =0xFFFFFFFD // Build initial LR value for secure mode 108#else 109 LDR r3, =0xFFFFFFBC // Build initial LR value to return to non-secure PSP 110#endif 111 STR r3, [r2, #0] // Save on the stack 112 113 /* Actually build the stack frame. */ 114 115 MOV r3, #0 // Build initial register value 116 STR r3, [r2, #4] // Store initial r4 117 STR r3, [r2, #8] // Store initial r5 118 STR r3, [r2, #12] // Store initial r6 119 STR r3, [r2, #16] // Store initial r7 120 STR r3, [r2, #20] // Store initial r8 121 STR r3, [r2, #24] // Store initial r9 122 STR r3, [r2, #28] // Store initial r10 123 STR r3, [r2, #32] // Store initial r11 124 125 /* Hardware stack follows. */ 126 127 STR r3, [r2, #36] // Store initial r0 128 STR r3, [r2, #40] // Store initial r1 129 STR r3, [r2, #44] // Store initial r2 130 STR r3, [r2, #48] // Store initial r3 131 STR r3, [r2, #52] // Store initial r12 132 MOV r3, #0xFFFFFFFF // Poison EXC_RETURN value 133 STR r3, [r2, #56] // Store initial lr 134 STR r1, [r2, #60] // Store initial pc 135 MOV r3, #0x01000000 // Only T-bit need be set 136 STR r3, [r2, #64] // Store initial xPSR 137 138 /* Setup stack pointer. */ 139 // thread_ptr -> tx_thread_stack_ptr = r2; 140 141 STR r2, [r0, #8] // Save stack pointer in thread's 142 // control block 143 BX lr // Return to caller 144// } 145 .end 146