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 .text 27 .align 3 28/**************************************************************************/ 29/* */ 30/* FUNCTION RELEASE */ 31/* */ 32/* _tx_thread_stack_build ARMv8-A */ 33/* 6.3.0 */ 34/* AUTHOR */ 35/* */ 36/* William E. Lamie, Microsoft Corporation */ 37/* */ 38/* DESCRIPTION */ 39/* */ 40/* This function builds a stack frame on the supplied thread's stack. */ 41/* The stack frame results in a fake interrupt return to the supplied */ 42/* function pointer. */ 43/* */ 44/* INPUT */ 45/* */ 46/* thread_ptr Pointer to thread */ 47/* function_ptr Pointer to entry function */ 48/* */ 49/* OUTPUT */ 50/* */ 51/* None */ 52/* */ 53/* CALLS */ 54/* */ 55/* None */ 56/* */ 57/* CALLED BY */ 58/* */ 59/* _tx_thread_create Create thread service */ 60/* */ 61/* RELEASE HISTORY */ 62/* */ 63/* DATE NAME DESCRIPTION */ 64/* */ 65/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 66/* 01-31-2022 Andres Mlinar Updated comments, */ 67/* resulting in version 6.1.10 */ 68/* 10-31-2023 Tiejun Zhou Modified comment(s), added */ 69/* #include tx_user.h, */ 70/* resulting in version 6.3.0 */ 71/* */ 72/**************************************************************************/ 73// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) 74// { 75 .global _tx_thread_stack_build 76 .type _tx_thread_stack_build, @function 77_tx_thread_stack_build: 78 79 80 /* Build an interrupt frame. On Cortex-A35 it should look like this: 81 82 Stack Top: SSPR Initial SSPR 83 ELR Point of interrupt 84 x28 Initial value for x28 85 not used Not used 86 x26 Initial value for x26 87 x27 Initial value for x27 88 x24 Initial value for x24 89 x25 Initial value for x25 90 x22 Initial value for x22 91 x23 Initial value for x23 92 x20 Initial value for x20 93 x21 Initial value for x21 94 x18 Initial value for x18 95 x19 Initial value for x19 96 x16 Initial value for x16 97 x17 Initial value for x17 98 x14 Initial value for x14 99 x15 Initial value for x15 100 x12 Initial value for x12 101 x13 Initial value for x13 102 x10 Initial value for x10 103 x11 Initial value for x11 104 x8 Initial value for x8 105 x9 Initial value for x9 106 x6 Initial value for x6 107 x7 Initial value for x7 108 x4 Initial value for x4 109 x5 Initial value for x5 110 x2 Initial value for x2 111 x3 Initial value for x3 112 x0 Initial value for x0 113 x1 Initial value for x1 114 x29 Initial value for x29 (frame pointer) 115 x30 Initial value for x30 (link register) 116 0 For stack backtracing 117 118 Stack Bottom: (higher memory address) */ 119 120 LDR x4, [x0, #24] // Pickup end of stack area 121 BIC x4, x4, #0xF // Ensure 16-byte alignment 122 123 /* Actually build the stack frame. */ 124 125 MOV x2, #0 // Build clear value 126 MOV x3, #0 // 127 128 STP x2, x3, [x4, #-16]! // Set backtrace to 0 129 STP x2, x3, [x4, #-16]! // Set initial x29, x30 130 STP x2, x3, [x4, #-16]! // Set initial x0, x1 131 STP x2, x3, [x4, #-16]! // Set initial x2, x3 132 STP x2, x3, [x4, #-16]! // Set initial x4, x5 133 STP x2, x3, [x4, #-16]! // Set initial x6, x7 134 STP x2, x3, [x4, #-16]! // Set initial x8, x9 135 STP x2, x3, [x4, #-16]! // Set initial x10, x11 136 STP x2, x3, [x4, #-16]! // Set initial x12, x13 137 STP x2, x3, [x4, #-16]! // Set initial x14, x15 138 STP x2, x3, [x4, #-16]! // Set initial x16, x17 139 STP x2, x3, [x4, #-16]! // Set initial x18, x19 140 STP x2, x3, [x4, #-16]! // Set initial x20, x21 141 STP x2, x3, [x4, #-16]! // Set initial x22, x23 142 STP x2, x3, [x4, #-16]! // Set initial x24, x25 143 STP x2, x3, [x4, #-16]! // Set initial x26, x27 144 STP x2, x3, [x4, #-16]! // Set initial x28 145#ifdef EL1 146 MOV x2, #0x4 // Build initial SPSR (EL1) 147#else 148#ifdef EL2 149 MOV x2, #0x8 // Build initial SPSR (EL2) 150#else 151 MOV x2, #0xC // Build initial SPSR (EL3) 152#endif 153#endif 154 MOV x3, x1 // Build initial ELR 155 STP x2, x3, [x4, #-16]! // Set initial SPSR & ELR 156 157 /* Setup stack pointer. */ 158 // thread_ptr -> tx_thread_stack_ptr = x2; 159 160 STR x4, [x0, #8] // Save stack pointer in thread's 161 RET // Return to caller 162 163// } 164