1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-present Eclipse ThreadX contributors
*
* 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
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build ARMv8-A */
/* 6.3.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 */
/* function_ptr Pointer to entry function */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_thread_create Create thread service */
/* */
/**************************************************************************/
// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
// {
.global _tx_thread_stack_build
.type _tx_thread_stack_build, @function
_tx_thread_stack_build:
/* Build an interrupt frame. On Cortex-A35 it should look like this:
Stack Top: SSPR Initial SSPR
ELR Point of interrupt
x28 Initial value for x28
not used Not used
x26 Initial value for x26
x27 Initial value for x27
x24 Initial value for x24
x25 Initial value for x25
x22 Initial value for x22
x23 Initial value for x23
x20 Initial value for x20
x21 Initial value for x21
x18 Initial value for x18
x19 Initial value for x19
x16 Initial value for x16
x17 Initial value for x17
x14 Initial value for x14
x15 Initial value for x15
x12 Initial value for x12
x13 Initial value for x13
x10 Initial value for x10
x11 Initial value for x11
x8 Initial value for x8
x9 Initial value for x9
x6 Initial value for x6
x7 Initial value for x7
x4 Initial value for x4
x5 Initial value for x5
x2 Initial value for x2
x3 Initial value for x3
x0 Initial value for x0
x1 Initial value for x1
x29 Initial value for x29 (frame pointer)
x30 Initial value for x30 (link register)
0 For stack backtracing
Stack Bottom: (higher memory address) */
LDR x4, [x0, #24] // Pickup end of stack area
BIC x4, x4, #0xF // Ensure 16-byte alignment
/* Actually build the stack frame. */
MOV x2, #0 // Build clear value
MOV x3, #0 //
STP x2, x3, [x4, #-16]! // Set backtrace to 0
STP x2, x3, [x4, #-16]! // Set initial x29, x30
STP x2, x3, [x4, #-16]! // Set initial x0, x1
STP x2, x3, [x4, #-16]! // Set initial x2, x3
STP x2, x3, [x4, #-16]! // Set initial x4, x5
STP x2, x3, [x4, #-16]! // Set initial x6, x7
STP x2, x3, [x4, #-16]! // Set initial x8, x9
STP x2, x3, [x4, #-16]! // Set initial x10, x11
STP x2, x3, [x4, #-16]! // Set initial x12, x13
STP x2, x3, [x4, #-16]! // Set initial x14, x15
STP x2, x3, [x4, #-16]! // Set initial x16, x17
STP x2, x3, [x4, #-16]! // Set initial x18, x19
STP x2, x3, [x4, #-16]! // Set initial x20, x21
STP x2, x3, [x4, #-16]! // Set initial x22, x23
STP x2, x3, [x4, #-16]! // Set initial x24, x25
STP x2, x3, [x4, #-16]! // Set initial x26, x27
STP x2, x3, [x4, #-16]! // Set initial x28
#ifdef EL1
MOV x2, #0x4 // Build initial SPSR (EL1)
#else
#ifdef EL2
MOV x2, #0x8 // Build initial SPSR (EL2)
#else
MOV x2, #0xC // Build initial SPSR (EL3)
#endif
#endif
MOV x3, x1 // Build initial ELR
STP x2, x3, [x4, #-16]! // Set initial SPSR & ELR
/* Setup stack pointer. */
// thread_ptr -> tx_thread_stack_ptr = x2;
STR x4, [x0, #8] // Save stack pointer in thread's
RET // Return to caller
// }
|