]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/ARM_CR5/portASM.S
Update version number in preparation for maintenance release.
[freertos] / FreeRTOS / Source / portable / GCC / ARM_CR5 / portASM.S
1 /*\r
2     FreeRTOS V9.0.1 - Copyright (C) 2017 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 \r
95 .macro portSAVE_CONTEXT\r
96 \r
97         /* Save the LR and SPSR onto the system mode stack before switching to\r
98         system mode to save the remaining system mode registers. */\r
99         SRSDB   sp!, #SYS_MODE\r
100         CPS             #SYS_MODE\r
101         PUSH    {R0-R12, R14}\r
102 \r
103         /* Push the critical nesting count. */\r
104         LDR             R2, ulCriticalNestingConst\r
105         LDR             R1, [R2]\r
106         PUSH    {R1}\r
107 \r
108         /* Does the task have a floating point context that needs saving?  If\r
109         ulPortTaskHasFPUContext is 0 then no. */\r
110         LDR             R2, ulPortTaskHasFPUContextConst\r
111         LDR             R3, [R2]\r
112         CMP             R3, #0\r
113 \r
114         /* Save the floating point context, if any. */\r
115         FMRXNE  R1,  FPSCR\r
116         VPUSHNE {D0-D15}\r
117         /*VPUSHNE       {D16-D31}*/\r
118         PUSHNE  {R1}\r
119 \r
120         /* Save ulPortTaskHasFPUContext itself. */\r
121         PUSH    {R3}\r
122 \r
123         /* Save the stack pointer in the TCB. */\r
124         LDR             R0, pxCurrentTCBConst\r
125         LDR             R1, [R0]\r
126         STR             SP, [R1]\r
127 \r
128         .endm\r
129 \r
130 ; /**********************************************************************/\r
131 \r
132 .macro portRESTORE_CONTEXT\r
133 \r
134         /* Set the SP to point to the stack of the task being restored. */\r
135         LDR             R0, pxCurrentTCBConst\r
136         LDR             R1, [R0]\r
137         LDR             SP, [R1]\r
138 \r
139         /* Is there a floating point context to restore?  If the restored\r
140         ulPortTaskHasFPUContext is zero then no. */\r
141         LDR             R0, ulPortTaskHasFPUContextConst\r
142         POP             {R1}\r
143         STR             R1, [R0]\r
144         CMP             R1, #0\r
145 \r
146         /* Restore the floating point context, if any. */\r
147         POPNE   {R0}\r
148         /*VPOPNE        {D16-D31}*/\r
149         VPOPNE  {D0-D15}\r
150         VMSRNE  FPSCR, R0\r
151 \r
152         /* Restore the critical section nesting depth. */\r
153         LDR             R0, ulCriticalNestingConst\r
154         POP             {R1}\r
155         STR             R1, [R0]\r
156 \r
157         /* Ensure the priority mask is correct for the critical nesting depth. */\r
158         LDR             R2, ulICCPMRConst\r
159         LDR             R2, [R2]\r
160         CMP             R1, #0\r
161         MOVEQ   R4, #255\r
162         LDRNE   R4, ulMaxAPIPriorityMaskConst\r
163         LDRNE   R4, [R4]\r
164         STR             R4, [R2]\r
165 \r
166         /* Restore all system mode registers other than the SP (which is already\r
167         being used). */\r
168         POP             {R0-R12, R14}\r
169 \r
170         /* Return to the task code, loading CPSR on the way. */\r
171         RFEIA   sp!\r
172 \r
173         .endm\r
174 \r
175 \r
176 \r
177 \r
178 /******************************************************************************\r
179  * SVC handler is used to start the scheduler.\r
180  *****************************************************************************/\r
181 .align 4\r
182 .type FreeRTOS_SWI_Handler, %function\r
183 FreeRTOS_SWI_Handler:\r
184         /* Save the context of the current task and select a new task to run. */\r
185         portSAVE_CONTEXT\r
186         LDR R0, vTaskSwitchContextConst\r
187         BLX     R0\r
188         portRESTORE_CONTEXT\r
189 \r
190 \r
191 /******************************************************************************\r
192  * vPortRestoreTaskContext is used to start the scheduler.\r
193  *****************************************************************************/\r
194 .type vPortRestoreTaskContext, %function\r
195 vPortRestoreTaskContext:\r
196         /* Switch to system mode. */\r
197         CPS             #SYS_MODE\r
198         portRESTORE_CONTEXT\r
199 \r
200 .align 4\r
201 .type FreeRTOS_IRQ_Handler, %function\r
202 FreeRTOS_IRQ_Handler:\r
203 \r
204         /* Return to the interrupted instruction. */\r
205         SUB             lr, lr, #4\r
206 \r
207         /* Push the return address and SPSR. */\r
208         PUSH    {lr}\r
209         MRS             lr, SPSR\r
210         PUSH    {lr}\r
211 \r
212         /* Change to supervisor mode to allow reentry. */\r
213         CPS             #SVC_MODE\r
214 \r
215         /* Push used registers. */\r
216         PUSH    {r0-r4, r12}\r
217 \r
218         /* Increment nesting count.  r3 holds the address of ulPortInterruptNesting\r
219         for future use.  r1 holds the original ulPortInterruptNesting value for\r
220         future use. */\r
221         LDR             r3, ulPortInterruptNestingConst\r
222         LDR             r1, [r3]\r
223         ADD             r4, r1, #1\r
224         STR             r4, [r3]\r
225 \r
226         /* Read value from the interrupt acknowledge register, which is stored in r0\r
227         for future parameter and interrupt clearing use. */\r
228         LDR     r2, ulICCIARConst\r
229         LDR             r2, [r2]\r
230         LDR             r0, [r2]\r
231 \r
232         /* Ensure bit 2 of the stack pointer is clear.  r2 holds the bit 2 value for\r
233         future use.  _RB_ Is this ever needed provided the start of the stack is\r
234         alligned on an 8-byte boundary? */\r
235         MOV             r2, sp\r
236         AND             r2, r2, #4\r
237         SUB             sp, sp, r2\r
238 \r
239         /* Call the interrupt handler. */\r
240         PUSH    {r0-r4, lr}\r
241         LDR             r1, vApplicationIRQHandlerConst\r
242         BLX             r1\r
243         POP             {r0-r4, lr}\r
244         ADD             sp, sp, r2\r
245 \r
246         CPSID   i\r
247         DSB\r
248         ISB\r
249 \r
250         /* Write the value read from ICCIAR to ICCEOIR. */\r
251         LDR     r4, ulICCEOIRConst\r
252         LDR             r4, [r4]\r
253         STR             r0, [r4]\r
254 \r
255         /* Restore the old nesting count. */\r
256         STR             r1, [r3]\r
257 \r
258         /* A context switch is never performed if the nesting count is not 0. */\r
259         CMP             r1, #0\r
260         BNE             exit_without_switch\r
261 \r
262         /* Did the interrupt request a context switch?  r1 holds the address of\r
263         ulPortYieldRequired and r0 the value of ulPortYieldRequired for future\r
264         use. */\r
265         LDR             r1, =ulPortYieldRequired\r
266         LDR             r0, [r1]\r
267         CMP             r0, #0\r
268         BNE             switch_before_exit\r
269 \r
270 exit_without_switch:\r
271         /* No context switch.  Restore used registers, LR_irq and SPSR before\r
272         returning. */\r
273         POP             {r0-r4, r12}\r
274         CPS             #IRQ_MODE\r
275         POP             {LR}\r
276         MSR             SPSR_cxsf, LR\r
277         POP             {LR}\r
278         MOVS    PC, LR\r
279 \r
280 switch_before_exit:\r
281         /* A context swtich is to be performed.  Clear the context switch pending\r
282         flag. */\r
283         MOV             r0, #0\r
284         STR             r0, [r1]\r
285 \r
286         /* Restore used registers, LR-irq and SPSR before saving the context\r
287         to the task stack. */\r
288         POP             {r0-r4, r12}\r
289         CPS             #IRQ_MODE\r
290         POP             {LR}\r
291         MSR             SPSR_cxsf, LR\r
292         POP             {LR}\r
293         portSAVE_CONTEXT\r
294 \r
295         /* Call the function that selects the new task to execute.\r
296         vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD\r
297         instructions, or 8 byte aligned stack allocated data.  LR does not need\r
298         saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. */\r
299         LDR             R0, vTaskSwitchContextConst\r
300         BLX             R0\r
301 \r
302         /* Restore the context of, and branch to, the task selected to execute\r
303         next. */\r
304         portRESTORE_CONTEXT\r
305 \r
306 ulICCIARConst:  .word ulICCIAR\r
307 ulICCEOIRConst: .word ulICCEOIR\r
308 ulICCPMRConst: .word ulICCPMR\r
309 pxCurrentTCBConst: .word pxCurrentTCB\r
310 ulCriticalNestingConst: .word ulCriticalNesting\r
311 ulPortTaskHasFPUContextConst: .word ulPortTaskHasFPUContext\r
312 ulMaxAPIPriorityMaskConst: .word ulMaxAPIPriorityMask\r
313 vTaskSwitchContextConst: .word vTaskSwitchContext\r
314 vApplicationIRQHandlerConst: .word vApplicationIRQHandler\r
315 ulPortInterruptNestingConst: .word ulPortInterruptNesting\r
316 \r
317 .end\r
318 \r
319 \r
320 \r
321 \r
322 \r