1 /*
2  * FreeRTOS Kernel V11.1.0
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  *
27  */
28 
29 EXTERN pxCurrentTCB
30 EXTERN ulCriticalNesting
31 
32 ;
33 Context save and restore macro definitions
34 ;
35 
36 portSAVE_CONTEXT MACRO
37 
38 ;
39 Push R0 as we are going to use the register.
40    STMDB SP !, {
41     R0
42 }
43 
44 Set R0 to point to the task stack pointer.
45    STMDB SP, {
46     SP
47 }
48 ^
49 NOP
50 SUB SP, SP, # 4
51 LDMIA SP !, {
52     R0
53 }
54 
55 ;
56 Push the return address onto the stack.
57           STMDB R0 !, {
58            LR
59        }
60 
61        Now we have saved LR we can use it instead of R0.
62           MOV LR, R0
63 
64 ;
65 
66 Pop R0 so we can save it onto the system mode stack.
67    LDMIA SP !, {
68     R0
69 }
70 
71 Push all the system mode registers onto the task stack.
72    STMDB LR, {
73     R0 - LR
74 }
75 ^
76 NOP
77 SUB LR, LR, # 60
78 
79 ;
80 Push the SPSR onto the task stack.
81    MRS R0, SPSR
82 STMDB LR !, {
83     R0
84 }
85 
86 LDR R0, = ulCriticalNesting
87           LDR R0, [ R0 ]
88 STMDB LR !, {
89     R0
90 }
91 
92 Store the new top of stack
93 
94 for the task.
95    LDR R1, = pxCurrentTCB
96              LDR R0, [ R1 ]
97 STR LR, [ R0 ]
98 
99 ENDM
100 
101 
102 portRESTORE_CONTEXT MACRO
103 
104 ;
105 Set the LR to the task stack.
106    LDR R1, = pxCurrentTCB
107              LDR R0, [ R1 ]
108 LDR LR, [ R0 ]
109 
110 ;
111 The critical nesting depth is the first item on the stack.
112    ;
113 Load it into the ulCriticalNesting variable.
114    LDR R0, = ulCriticalNesting
115              LDMFD LR !, {
116     R1
117 }
118 
119 STR R1, [ R0 ]
120 
121 ;
122 Get the SPSR from the stack.
123    LDMFD LR !, {
124     R0
125 }
126 MSR SPSR_cxsf, R0
127 
128 ;
129 Restore all system mode registers
130 
131 for the task.
132    LDMFD LR, {
133     R0 - R14
134 }
135 
136 ^
137 NOP
138 
139 ;
140 Restore the return address.
141           LDR LR, [ LR, # + 60 ]
142 
143 ;
144 
145 And return -correcting the offset in the LR to obtain the
146 ;
147 
148 correct address.
149    SUBS PC, LR, # 4
150 
151 ENDM
152