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