]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/CCS/ARM_Cortex-R4/portASM.asm
80f0fa7a4aeed28c084e2e8ae747207aaa8a7898
[freertos] / FreeRTOS / Source / portable / CCS / ARM_Cortex-R4 / portASM.asm
1 ;/*\r
2 ; * FreeRTOS Kernel V10.1.0\r
3 ; * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4 ; *\r
5 ; * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6 ; * this software and associated documentation files (the "Software"), to deal in\r
7 ; * the Software without restriction, including without limitation the rights to\r
8 ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9 ; * the Software, and to permit persons to whom the Software is furnished to do so,\r
10 ; * subject to the following conditions:\r
11 ; *\r
12 ; * The above copyright notice and this permission notice shall be included in all\r
13 ; * copies or substantial portions of the Software.\r
14 ; *\r
15 ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16 ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17 ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18 ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19 ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20 ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21 ; *\r
22 ; * http://www.FreeRTOS.org\r
23 ; * http://aws.amazon.com/freertos\r
24 ; *\r
25 ; * 1 tab == 4 spaces!\r
26 ; */\r
27 \r
28         .text\r
29         .arm\r
30         .ref vTaskSwitchContext\r
31         .ref xTaskIncrementTick\r
32         .ref ulTaskHasFPUContext\r
33                 .ref pxCurrentTCB\r
34 \r
35 ;/*-----------------------------------------------------------*/\r
36 ;\r
37 ; Save Task Context\r
38 ;\r
39 portSAVE_CONTEXT .macro\r
40                 DSB\r
41 \r
42                 ; Push R0 as we are going to use it\r
43                 STMDB   SP!, {R0}\r
44 \r
45                 ; Set R0 to point to the task stack pointer.\r
46                 STMDB   SP,{SP}^\r
47                 SUB     SP, SP, #4\r
48                 LDMIA   SP!,{R0}\r
49 \r
50                 ; Push the return address onto the stack.\r
51                 STMDB   R0!, {LR}\r
52 \r
53                 ; Now LR has been saved, it can be used instead of R0.\r
54                 MOV     LR, R0\r
55 \r
56                 ; Pop R0 so it can be saved onto the task stack.\r
57                 LDMIA   SP!, {R0}\r
58 \r
59                 ; Push all the system mode registers onto the task stack.\r
60                 STMDB   LR,{R0-LR}^\r
61                 SUB     LR, LR, #60\r
62 \r
63                 ; Push the SPSR onto the task stack.\r
64                 MRS     R0, SPSR\r
65                 STMDB   LR!, {R0}\r
66 \r
67     .if (__TI_VFP_SUPPORT__)\r
68                 ;Determine if the task maintains an FPU context.\r
69                 LDR     R0, ulFPUContextConst\r
70                 LDR     R0, [R0]\r
71 \r
72                 ; Test the flag\r
73                 CMP             R0, #0\r
74 \r
75                 ; If the task is not using a floating point context then skip the\r
76                 ; saving of the FPU registers.\r
77                 BEQ             $+16\r
78                 FSTMDBD LR!, {D0-D15}\r
79                 FMRX    R1,  FPSCR\r
80                 STMFD   LR!, {R1}\r
81 \r
82                 ; Save the flag\r
83                 STMDB   LR!, {R0}\r
84         .endif\r
85 \r
86                 ; Store the new top of stack for the task.\r
87                 LDR     R0, pxCurrentTCBConst\r
88                 LDR     R0, [R0]\r
89                 STR     LR, [R0]\r
90 \r
91         .endm\r
92 \r
93 ;/*-----------------------------------------------------------*/\r
94 ;\r
95 ; Restore Task Context\r
96 ;\r
97 portRESTORE_CONTEXT .macro\r
98                 LDR             R0, pxCurrentTCBConst\r
99                 LDR             R0, [R0]\r
100                 LDR             LR, [R0]\r
101 \r
102         .if (__TI_VFP_SUPPORT__)\r
103                 ; The floating point context flag is the first thing on the stack.\r
104                 LDR             R0, ulFPUContextConst\r
105                 LDMFD   LR!, {R1}\r
106                 STR             R1, [R0]\r
107 \r
108                 ; Test the flag\r
109                 CMP             R1, #0\r
110 \r
111                 ; If the task is not using a floating point context then skip the\r
112                 ; VFP register loads.\r
113                 BEQ             $+16\r
114 \r
115                 ; Restore the floating point context.\r
116                 LDMFD   LR!, {R0}\r
117                 FLDMIAD LR!, {D0-D15}\r
118                 FMXR    FPSCR, R0\r
119         .endif\r
120 \r
121                 ; Get the SPSR from the stack.\r
122                 LDMFD   LR!, {R0}\r
123                 MSR             SPSR_CSXF, R0\r
124 \r
125                 ; Restore all system mode registers for the task.\r
126                 LDMFD   LR, {R0-R14}^\r
127 \r
128                 ; Restore the return address.\r
129                 LDR             LR, [LR, #+60]\r
130 \r
131                 ; And return - correcting the offset in the LR to obtain the\r
132                 ; correct address.\r
133                 SUBS    PC, LR, #4\r
134         .endm\r
135 \r
136 ;/*-----------------------------------------------------------*/\r
137 ; Start the first task by restoring its context.\r
138 \r
139         .def vPortStartFirstTask\r
140 \r
141 vPortStartFirstTask:\r
142         portRESTORE_CONTEXT\r
143 \r
144 ;/*-----------------------------------------------------------*/\r
145 ; Yield to another task.\r
146 \r
147         .def vPortYieldProcessor\r
148 \r
149 vPortYieldProcessor:\r
150                 ; Within an IRQ ISR the link register has an offset from the true return\r
151                 ; address.  SWI doesn't do this. Add the offset manually so the ISR\r
152                 ; return code can be used.\r
153         ADD     LR, LR, #4\r
154 \r
155         ; First save the context of the current task.\r
156         portSAVE_CONTEXT\r
157 \r
158         ; Select the next task to execute. */\r
159         BL      vTaskSwitchContext\r
160 \r
161         ; Restore the context of the task selected to execute.\r
162         portRESTORE_CONTEXT\r
163 \r
164 ;/*-----------------------------------------------------------*/\r
165 ; Yield to another task from within the FreeRTOS API\r
166 \r
167                 .def vPortYeildWithinAPI\r
168 \r
169 vPortYeildWithinAPI:\r
170                 ; Save the context of the current task.\r
171 \r
172         portSAVE_CONTEXT\r
173                 ; Clear SSI flag.\r
174                 MOVW    R0, #0xFFF4\r
175                 MOVT    R0, #0xFFFF\r
176                 LDR     R0, [R0]\r
177 \r
178                 ; Select the next task to execute. */\r
179         BL      vTaskSwitchContext\r
180 \r
181         ; Restore the context of the task selected to execute.\r
182         portRESTORE_CONTEXT\r
183 \r
184 ;/*-----------------------------------------------------------*/\r
185 ; Preemptive Tick\r
186 \r
187         .def vPortPreemptiveTick\r
188 \r
189 vPortPreemptiveTick:\r
190 \r
191                 ; Save the context of the current task.\r
192         portSAVE_CONTEXT\r
193 \r
194         ; Clear interrupt flag\r
195         MOVW    R0, #0xFC88\r
196         MOVT    R0, #0xFFFF\r
197         MOV     R1, #1\r
198         STR     R1, [R0]\r
199 \r
200         ; Increment the tick count, making any adjustments to the blocked lists\r
201         ; that may be necessary.\r
202         BL      xTaskIncrementTick\r
203 \r
204         ; Select the next task to execute.\r
205         CMP     R0, #0\r
206         BLNE    vTaskSwitchContext\r
207 \r
208         ; Restore the context of the task selected to execute.\r
209         portRESTORE_CONTEXT\r
210 \r
211 ;-------------------------------------------------------------------------------\r
212 \r
213         .if (__TI_VFP_SUPPORT__)\r
214 \r
215                 .def vPortInitialiseFPSCR\r
216 \r
217 vPortInitialiseFPSCR:\r
218 \r
219                 MOV             R0, #0\r
220                 FMXR    FPSCR, R0\r
221                 BX              LR\r
222 \r
223         .endif ;__TI_VFP_SUPPORT__\r
224 \r
225 \r
226 pxCurrentTCBConst       .word   pxCurrentTCB\r
227 ulFPUContextConst       .word   ulTaskHasFPUContext\r
228 ;-------------------------------------------------------------------------------\r
229 \r