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