]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/ARM_CR5/portASM.S
Update version number ready for version 9 release candidate 1.
[freertos] / FreeRTOS / Source / portable / GCC / ARM_CR5 / portASM.S
1 /*\r
2     FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70         .text\r
71         .arm\r
72 \r
73         .set SYS_MODE,  0x1f\r
74         .set SVC_MODE,  0x13\r
75         .set IRQ_MODE,  0x12\r
76 \r
77         /* Hardware registers. */\r
78         .extern ulICCIAR\r
79         .extern ulICCEOIR\r
80         .extern ulICCPMR\r
81 \r
82         /* Variables and functions. */\r
83         .extern ulMaxAPIPriorityMask\r
84         .extern _freertos_vector_table\r
85         .extern pxCurrentTCB\r
86         .extern vTaskSwitchContext\r
87         .extern vApplicationIRQHandler\r
88         .extern ulPortInterruptNesting\r
89         .extern ulPortTaskHasFPUContext\r
90 \r
91         .global FreeRTOS_IRQ_Handler\r
92         .global FreeRTOS_SWI_Handler\r
93         .global vPortRestoreTaskContext\r
94         .global vPortInstallFreeRTOSVectorTable\r
95 \r
96 \r
97 \r
98 \r
99 .macro portSAVE_CONTEXT\r
100 \r
101         /* Save the LR and SPSR onto the system mode stack before switching to\r
102         system mode to save the remaining system mode registers. */\r
103         SRSDB   sp!, #SYS_MODE\r
104         CPS             #SYS_MODE\r
105         PUSH    {R0-R12, R14}\r
106 \r
107         /* Push the critical nesting count. */\r
108         LDR             R2, ulCriticalNestingConst\r
109         LDR             R1, [R2]\r
110         PUSH    {R1}\r
111 \r
112         /* Does the task have a floating point context that needs saving?  If\r
113         ulPortTaskHasFPUContext is 0 then no. */\r
114         LDR             R2, ulPortTaskHasFPUContextConst\r
115         LDR             R3, [R2]\r
116         CMP             R3, #0\r
117 \r
118         /* Save the floating point context, if any. */\r
119         FMRXNE  R1,  FPSCR\r
120         VPUSHNE {D0-D15}\r
121         /*VPUSHNE       {D16-D31}*/\r
122         PUSHNE  {R1}\r
123 \r
124         /* Save ulPortTaskHasFPUContext itself. */\r
125         PUSH    {R3}\r
126 \r
127         /* Save the stack pointer in the TCB. */\r
128         LDR             R0, pxCurrentTCBConst\r
129         LDR             R1, [R0]\r
130         STR             SP, [R1]\r
131 \r
132         .endm\r
133 \r
134 ; /**********************************************************************/\r
135 \r
136 .macro portRESTORE_CONTEXT\r
137 \r
138         /* Set the SP to point to the stack of the task being restored. */\r
139         LDR             R0, pxCurrentTCBConst\r
140         LDR             R1, [R0]\r
141         LDR             SP, [R1]\r
142 \r
143         /* Is there a floating point context to restore?  If the restored\r
144         ulPortTaskHasFPUContext is zero then no. */\r
145         LDR             R0, ulPortTaskHasFPUContextConst\r
146         POP             {R1}\r
147         STR             R1, [R0]\r
148         CMP             R1, #0\r
149 \r
150         /* Restore the floating point context, if any. */\r
151         POPNE   {R0}\r
152         /*VPOPNE        {D16-D31}*/\r
153         VPOPNE  {D0-D15}\r
154         VMSRNE  FPSCR, R0\r
155 \r
156         /* Restore the critical section nesting depth. */\r
157         LDR             R0, ulCriticalNestingConst\r
158         POP             {R1}\r
159         STR             R1, [R0]\r
160 \r
161         /* Ensure the priority mask is correct for the critical nesting depth. */\r
162         LDR             R2, ulICCPMRConst\r
163         LDR             R2, [R2]\r
164         CMP             R1, #0\r
165         MOVEQ   R4, #255\r
166         LDRNE   R4, ulMaxAPIPriorityMaskConst\r
167         LDRNE   R4, [R4]\r
168         STR             R4, [R2]\r
169 \r
170         /* Restore all system mode registers other than the SP (which is already\r
171         being used). */\r
172         POP             {R0-R12, R14}\r
173 \r
174         /* Return to the task code, loading CPSR on the way. */\r
175         RFEIA   sp!\r
176 \r
177         .endm\r
178 \r
179 \r
180 \r
181 \r
182 /******************************************************************************\r
183  * SVC handler is used to start the scheduler.\r
184  *****************************************************************************/\r
185 .align 4\r
186 .type FreeRTOS_SWI_Handler, %function\r
187 FreeRTOS_SWI_Handler:\r
188         /* Save the context of the current task and select a new task to run. */\r
189         portSAVE_CONTEXT\r
190         LDR R0, vTaskSwitchContextConst\r
191         BLX     R0\r
192         portRESTORE_CONTEXT\r
193 \r
194 \r
195 /******************************************************************************\r
196  * vPortRestoreTaskContext is used to start the scheduler.\r
197  *****************************************************************************/\r
198 .type vPortRestoreTaskContext, %function\r
199 vPortRestoreTaskContext:\r
200         /* Switch to system mode. */\r
201         CPS             #SYS_MODE\r
202         portRESTORE_CONTEXT\r
203 \r
204 .align 4\r
205 .type FreeRTOS_IRQ_Handler, %function\r
206 FreeRTOS_IRQ_Handler:\r
207 \r
208         /* Return to the interrupted instruction. */\r
209         SUB             lr, lr, #4\r
210 \r
211         /* Push the return address and SPSR. */\r
212         PUSH    {lr}\r
213         MRS             lr, SPSR\r
214         PUSH    {lr}\r
215 \r
216         /* Change to supervisor mode to allow reentry. */\r
217         CPS             #SVC_MODE\r
218 \r
219         /* Push used registers. */\r
220         PUSH    {r0-r4, r12}\r
221 \r
222         /* Increment nesting count.  r3 holds the address of ulPortInterruptNesting\r
223         for future use.  r1 holds the original ulPortInterruptNesting value for\r
224         future use. */\r
225         LDR             r3, ulPortInterruptNestingConst\r
226         LDR             r1, [r3]\r
227         ADD             r4, r1, #1\r
228         STR             r4, [r3]\r
229 \r
230         /* Read value from the interrupt acknowledge register, which is stored in r0\r
231         for future parameter and interrupt clearing use. */\r
232         LDR     r2, ulICCIARConst\r
233         LDR             r2, [r2]\r
234         LDR             r0, [r2]\r
235 \r
236         /* Ensure bit 2 of the stack pointer is clear.  r2 holds the bit 2 value for\r
237         future use. */\r
238         MOV             r2, sp\r
239         AND             r2, r2, #4\r
240         SUB             sp, sp, r2\r
241 \r
242         /* Call the interrupt handler. */\r
243         PUSH    {r0-r3, lr}\r
244         LDR             r1, vApplicationIRQHandlerConst\r
245         BLX             r1\r
246         POP             {r0-r3, lr}\r
247         ADD             sp, sp, r2\r
248 \r
249         CPSID   i\r
250         DSB\r
251         ISB\r
252 \r
253         /* Write the value read from ICCIAR to ICCEOIR. */\r
254         LDR     r4, ulICCEOIRConst\r
255         LDR             r4, [r4]\r
256         STR             r0, [r4]\r
257 \r
258         /* Restore the old nesting count. */\r
259         STR             r1, [r3]\r
260 \r
261         /* A context switch is never performed if the nesting count is not 0. */\r
262         CMP             r1, #0\r
263         BNE             exit_without_switch\r
264 \r
265         /* Did the interrupt request a context switch?  r1 holds the address of\r
266         ulPortYieldRequired and r0 the value of ulPortYieldRequired for future\r
267         use. */\r
268         LDR             r1, =ulPortYieldRequired\r
269         LDR             r0, [r1]\r
270         CMP             r0, #0\r
271         BNE             switch_before_exit\r
272 \r
273 exit_without_switch:\r
274         /* No context switch.  Restore used registers, LR_irq and SPSR before\r
275         returning. */\r
276         POP             {r0-r4, r12}\r
277         CPS             #IRQ_MODE\r
278         POP             {LR}\r
279         MSR             SPSR_cxsf, LR\r
280         POP             {LR}\r
281         MOVS    PC, LR\r
282 \r
283 switch_before_exit:\r
284         /* A context swtich is to be performed.  Clear the context switch pending\r
285         flag. */\r
286         MOV             r0, #0\r
287         STR             r0, [r1]\r
288 \r
289         /* Restore used registers, LR-irq and SPSR before saving the context\r
290         to the task stack. */\r
291         POP             {r0-r4, r12}\r
292         CPS             #IRQ_MODE\r
293         POP             {LR}\r
294         MSR             SPSR_cxsf, LR\r
295         POP             {LR}\r
296         portSAVE_CONTEXT\r
297 \r
298         /* Call the function that selects the new task to execute.\r
299         vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD\r
300         instructions, or 8 byte aligned stack allocated data.  LR does not need\r
301         saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */\r
302         LDR             R0, vTaskSwitchContextConst\r
303         BLX             R0\r
304 \r
305         /* Restore the context of, and branch to, the task selected to execute\r
306         next. */\r
307         portRESTORE_CONTEXT\r
308 \r
309 ulICCIARConst:  .word ulICCIAR\r
310 ulICCEOIRConst: .word ulICCEOIR\r
311 ulICCPMRConst: .word ulICCPMR\r
312 pxCurrentTCBConst: .word pxCurrentTCB\r
313 ulCriticalNestingConst: .word ulCriticalNesting\r
314 ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext\r
315 ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask\r
316 vTaskSwitchContextConst: .word vTaskSwitchContext\r
317 vApplicationIRQHandlerConst: .word vApplicationIRQHandler\r
318 ulPortInterruptNestingConst: .word ulPortInterruptNesting\r
319 \r
320 .end\r
321 \r
322 \r
323 \r
324 \r
325 \r