]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/ARM_CA53_64_BIT/portASM.S
Update version number to 9.0.0rc2.
[freertos] / FreeRTOS / Source / portable / GCC / ARM_CA53_64_BIT / portASM.S
1 /*\r
2     FreeRTOS V9.0.0rc2 - 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 \r
72         /* Variables and functions. */\r
73         .extern ullMaxAPIPriorityMask\r
74         .extern pxCurrentTCB\r
75         .extern vTaskSwitchContext\r
76         .extern vApplicationIRQHandler\r
77         .extern ullPortInterruptNesting\r
78         .extern ullPortTaskHasFPUContext\r
79         .extern ullCriticalNesting\r
80         .extern ullPortYieldRequired\r
81         .extern ullICCEOIR\r
82         .extern ullICCIAR\r
83         .extern _freertos_vector_table\r
84 \r
85         .global FreeRTOS_IRQ_Handler\r
86         .global FreeRTOS_SWI_Handler\r
87         .global vPortRestoreTaskContext\r
88 \r
89 \r
90 .macro portSAVE_CONTEXT\r
91 \r
92         /* Switch to use the EL0 stack pointer. */\r
93         MSR     SPSEL, #0\r
94 \r
95         /* Save the entire context. */\r
96         STP     X0, X1, [SP, #-0x10]!\r
97         STP     X2, X3, [SP, #-0x10]!\r
98         STP     X4, X5, [SP, #-0x10]!\r
99         STP     X6, X7, [SP, #-0x10]!\r
100         STP     X8, X9, [SP, #-0x10]!\r
101         STP     X10, X11, [SP, #-0x10]!\r
102         STP     X12, X13, [SP, #-0x10]!\r
103         STP     X14, X15, [SP, #-0x10]!\r
104         STP     X16, X17, [SP, #-0x10]!\r
105         STP     X18, X19, [SP, #-0x10]!\r
106         STP     X20, X21, [SP, #-0x10]!\r
107         STP     X22, X23, [SP, #-0x10]!\r
108         STP     X24, X25, [SP, #-0x10]!\r
109         STP     X26, X27, [SP, #-0x10]!\r
110         STP     X28, X29, [SP, #-0x10]!\r
111         STP     X30, XZR, [SP, #-0x10]!\r
112 \r
113         /* Save the SPSR. */\r
114         MRS             X3, SPSR_EL3\r
115 \r
116         /* Save the ELR. */\r
117         MRS             X2, ELR_EL3\r
118 \r
119         STP     X2, X3, [SP, #-0x10]!\r
120 \r
121         /* Save the critical section nesting depth. */\r
122         LDR             X0, ullCriticalNestingConst\r
123         LDR             X3, [X0]\r
124 \r
125         /* Save the FPU context indicator. */\r
126         LDR             X0, ullPortTaskHasFPUContextConst\r
127         LDR             X2, [X0]\r
128 \r
129         /* Save the FPU context, if any (32 128-bit registers). */\r
130         CMP             X2, #0\r
131         B.EQ    1f\r
132         STP             Q0, Q1, [SP,#-0x20]!\r
133         STP             Q2, Q3, [SP,#-0x20]!\r
134         STP             Q4, Q5, [SP,#-0x20]!\r
135         STP             Q6, Q7, [SP,#-0x20]!\r
136         STP             Q8, Q9, [SP,#-0x20]!\r
137         STP             Q10, Q11, [SP,#-0x20]!\r
138         STP             Q12, Q13, [SP,#-0x20]!\r
139         STP             Q14, Q15, [SP,#-0x20]!\r
140         STP             Q16, Q17, [SP,#-0x20]!\r
141         STP             Q18, Q19, [SP,#-0x20]!\r
142         STP             Q20, Q21, [SP,#-0x20]!\r
143         STP             Q22, Q23, [SP,#-0x20]!\r
144         STP             Q24, Q25, [SP,#-0x20]!\r
145         STP             Q26, Q27, [SP,#-0x20]!\r
146         STP             Q28, Q29, [SP,#-0x20]!\r
147         STP             Q30, Q31, [SP,#-0x20]!\r
148 \r
149 1:\r
150         /* Store the critical nesting count and FPU context indicator. */\r
151         STP     X2, X3, [SP, #-0x10]!\r
152 \r
153         LDR     X0, pxCurrentTCBConst\r
154         LDR     X1, [X0]\r
155         MOV     X0, SP   /* Move SP into X0 for saving. */\r
156         STR     X0, [X1]\r
157 \r
158         /* Switch to use the ELx stack pointer. */\r
159         MSR     SPSEL, #1\r
160 \r
161         .endm\r
162 \r
163 ; /**********************************************************************/\r
164 \r
165 .macro portRESTORE_CONTEXT\r
166 \r
167         /* Switch to use the EL0 stack pointer. */\r
168         MSR     SPSEL, #0\r
169 \r
170         /* Set the SP to point to the stack of the task being restored. */\r
171         LDR             X0, pxCurrentTCBConst\r
172         LDR             X1, [X0]\r
173         LDR             X0, [X1]\r
174         MOV             SP, X0\r
175 \r
176         LDP     X2, X3, [SP], #0x10  /* Critical nesting and FPU context. */\r
177 \r
178         /* Set the PMR register to be correct for the current critical nesting\r
179         depth. */\r
180         LDR             X0, ullCriticalNestingConst /* X0 holds the address of ullCriticalNesting. */\r
181         MOV             X1, #255                                        /* X1 holds the unmask value. */\r
182         LDR             X4, ullICCPMRConst                      /* X4 holds the address of the ICCPMR constant. */\r
183         CMP             X3, #0\r
184         LDR             X5, [X4]                                        /* X5 holds the address of the ICCPMR register. */\r
185         B.EQ    1f\r
186         LDR             X6, ullMaxAPIPriorityMaskConst\r
187         LDR             X1, [X6]                                        /* X1 holds the mask value. */\r
188 1:\r
189         STR             W1, [X5]                                        /* Write the mask value to ICCPMR. */\r
190         DSB     SY                                                      /* _RB_Barriers probably not required here. */\r
191         ISB     SY\r
192         STR             X3, [X0]                                        /* Restore the task's critical nesting count. */\r
193 \r
194         /* Restore the FPU context indicator. */\r
195         LDR             X0, ullPortTaskHasFPUContextConst\r
196         STR             X2, [X0]\r
197 \r
198         /* Restore the FPU context, if any. */\r
199         CMP             X2, #0\r
200         B.EQ    1f\r
201         LDP             Q30, Q31, [SP], #0x20\r
202         LDP             Q28, Q29, [SP], #0x20\r
203         LDP             Q26, Q27, [SP], #0x20\r
204         LDP             Q24, Q25, [SP], #0x20\r
205         LDP             Q22, Q23, [SP], #0x20\r
206         LDP             Q20, Q21, [SP], #0x20\r
207         LDP             Q18, Q19, [SP], #0x20\r
208         LDP             Q16, Q17, [SP], #0x20\r
209         LDP             Q14, Q15, [SP], #0x20\r
210         LDP             Q12, Q13, [SP], #0x20\r
211         LDP             Q10, Q11, [SP], #0x20\r
212         LDP             Q8, Q9, [SP], #0x20\r
213         LDP             Q6, Q7, [SP], #0x20\r
214         LDP             Q4, Q5, [SP], #0x20\r
215         LDP             Q2, Q3, [SP], #0x20\r
216         LDP             Q0, Q1, [SP], #0x20\r
217 1:\r
218         LDP     X2, X3, [SP], #0x10  /* SPSR and ELR. */\r
219 \r
220         /* Restore the SPSR. */\r
221         MSR             SPSR_EL3, X3 /*_RB_ Assumes started in EL3. */\r
222 \r
223         /* Restore the ELR. */\r
224         MSR             ELR_EL3, X2\r
225 \r
226         LDP     X30, XZR, [SP], #0x10\r
227         LDP     X28, X29, [SP], #0x10\r
228         LDP     X26, X27, [SP], #0x10\r
229         LDP     X24, X25, [SP], #0x10\r
230         LDP     X22, X23, [SP], #0x10\r
231         LDP     X20, X21, [SP], #0x10\r
232         LDP     X18, X19, [SP], #0x10\r
233         LDP     X16, X17, [SP], #0x10\r
234         LDP     X14, X15, [SP], #0x10\r
235         LDP     X12, X13, [SP], #0x10\r
236         LDP     X10, X11, [SP], #0x10\r
237         LDP     X8, X9, [SP], #0x10\r
238         LDP     X6, X7, [SP], #0x10\r
239         LDP     X4, X5, [SP], #0x10\r
240         LDP     X2, X3, [SP], #0x10\r
241         LDP     X0, X1, [SP], #0x10\r
242 \r
243         /* Switch to use the ELx stack pointer.  _RB_ Might not be required. */\r
244         MSR     SPSEL, #1\r
245 \r
246         ERET\r
247 \r
248         .endm\r
249 \r
250 \r
251 /******************************************************************************\r
252  * FreeRTOS_SWI_Handler handler is used to perform a context switch.\r
253  *****************************************************************************/\r
254 .align 8\r
255 .type FreeRTOS_SWI_Handler, %function\r
256 FreeRTOS_SWI_Handler:\r
257         /* Save the context of the current task and select a new task to run. */\r
258         portSAVE_CONTEXT\r
259 \r
260         MRS             X0, ESR_EL3\r
261         LSR             X1, X0, #26\r
262         CMP             X1, #0x17 /* 0x17 = SMC instruction. */\r
263         B.NE    FreeRTOS_Abort\r
264         BL              vTaskSwitchContext\r
265 \r
266         portRESTORE_CONTEXT\r
267 \r
268 FreeRTOS_Abort:\r
269         /* Full ESR is in X0, exception class code is in X1. */\r
270         B               .\r
271 \r
272 /******************************************************************************\r
273  * vPortRestoreTaskContext is used to start the scheduler.\r
274  *****************************************************************************/\r
275 .align 8\r
276 .type vPortRestoreTaskContext, %function\r
277 vPortRestoreTaskContext:\r
278 .set freertos_vector_base,      _freertos_vector_table\r
279 \r
280         /* Install the FreeRTOS interrupt handlers. */\r
281         LDR             X1, =freertos_vector_base\r
282         MSR             VBAR_EL3, X1\r
283         DSB             SY\r
284         ISB             SY\r
285 \r
286         /* Start the first task. */\r
287         portRESTORE_CONTEXT\r
288 \r
289 \r
290 /******************************************************************************\r
291  * FreeRTOS_IRQ_Handler handles IRQ entry and exit.\r
292  *****************************************************************************/\r
293 .align 8\r
294 .type FreeRTOS_IRQ_Handler, %function\r
295 FreeRTOS_IRQ_Handler:\r
296         /* Save volatile registers. */\r
297         STP             X0, X1, [SP, #-0x10]!\r
298         STP             X2, X3, [SP, #-0x10]!\r
299         STP             X4, X5, [SP, #-0x10]!\r
300         STP             X6, X7, [SP, #-0x10]!\r
301         STP             X8, X9, [SP, #-0x10]!\r
302         STP             X10, X11, [SP, #-0x10]!\r
303         STP             X12, X13, [SP, #-0x10]!\r
304         STP             X14, X15, [SP, #-0x10]!\r
305         STP             X16, X17, [SP, #-0x10]!\r
306         STP             X18, X19, [SP, #-0x10]!\r
307         STP             X29, X30, [SP, #-0x10]!\r
308 \r
309         /* Save the SPSR and ELR. */\r
310         MRS             X3, SPSR_EL3\r
311         MRS             X2, ELR_EL3\r
312         STP     X2, X3, [SP, #-0x10]!\r
313 \r
314         /* Increment the interrupt nesting counter. */\r
315         LDR             X5, ullPortInterruptNestingConst\r
316         LDR             X1, [X5]        /* Old nesting count in X1. */\r
317         ADD             X6, X1, #1\r
318         STR             X6, [X5]        /* Address of nesting count variable in X5. */\r
319 \r
320         /* Maintain the interrupt nesting information across the function call. */\r
321         STP             X1, X5, [SP, #-0x10]!\r
322 \r
323         /* Read value from the interrupt acknowledge register, which is stored in W0\r
324         for future parameter and interrupt clearing use. */\r
325         LDR     X2, ullICCIARConst\r
326         LDR             X3, [X2]\r
327         LDR             W0, [X3]        /* ICCIAR in W0 as parameter. */\r
328 \r
329         /* Maintain the ICCIAR value across the function call. */\r
330         STP             X0, X1, [SP, #-0x10]!\r
331 \r
332         /* Call the C handler. */\r
333         BL vApplicationIRQHandler\r
334 \r
335         /* Disable interrupts. */\r
336         MSR     DAIFSET, #2\r
337         DSB             SY\r
338         ISB             SY\r
339 \r
340         /* Restore the ICCIAR value. */\r
341         LDP             X0, X1, [SP], #0x10\r
342 \r
343         /* End IRQ processing by writing ICCIAR to the EOI register. */\r
344         LDR     X4, ullICCEOIRConst\r
345         LDR             X4, [X4]\r
346         STR             W0, [X4]\r
347 \r
348         /* Restore the critical nesting count. */\r
349         LDP             X1, X5, [SP], #0x10\r
350         STR             X1, [X5]\r
351 \r
352         /* Has interrupt nesting unwound? */\r
353         CMP             X1, #0\r
354         B.NE    Exit_IRQ_No_Context_Switch\r
355 \r
356         /* Is a context switch required? */\r
357         LDR             X0, ullPortYieldRequiredConst\r
358         LDR             X1, [X0]\r
359         CMP             X1, #0\r
360         B.EQ    Exit_IRQ_No_Context_Switch\r
361 \r
362         /* Reset ullPortYieldRequired to 0. */\r
363         MOV             X2, #0\r
364         STR             X2, [X0]\r
365 \r
366         /* Restore volatile registers. */\r
367         LDP     X4, X5, [SP], #0x10  /* SPSR and ELR. */\r
368         MSR             SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */\r
369         MSR             ELR_EL3, X4\r
370         DSB             SY\r
371         ISB             SY\r
372 \r
373         LDP             X29, X30, [SP], #0x10\r
374         LDP             X18, X19, [SP], #0x10\r
375         LDP             X16, X17, [SP], #0x10\r
376         LDP             X14, X15, [SP], #0x10\r
377         LDP             X12, X13, [SP], #0x10\r
378         LDP             X10, X11, [SP], #0x10\r
379         LDP             X8, X9, [SP], #0x10\r
380         LDP             X6, X7, [SP], #0x10\r
381         LDP             X4, X5, [SP], #0x10\r
382         LDP             X2, X3, [SP], #0x10\r
383         LDP             X0, X1, [SP], #0x10\r
384 \r
385         /* Save the context of the current task and select a new task to run. */\r
386         portSAVE_CONTEXT\r
387         BL vTaskSwitchContext\r
388         portRESTORE_CONTEXT\r
389 \r
390 Exit_IRQ_No_Context_Switch:\r
391         /* Restore volatile registers. */\r
392         LDP     X4, X5, [SP], #0x10  /* SPSR and ELR. */\r
393         MSR             SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */\r
394         MSR             ELR_EL3, X4\r
395         DSB             SY\r
396         ISB             SY\r
397 \r
398         LDP             X29, X30, [SP], #0x10\r
399         LDP             X18, X19, [SP], #0x10\r
400         LDP             X16, X17, [SP], #0x10\r
401         LDP             X14, X15, [SP], #0x10\r
402         LDP             X12, X13, [SP], #0x10\r
403         LDP             X10, X11, [SP], #0x10\r
404         LDP             X8, X9, [SP], #0x10\r
405         LDP             X6, X7, [SP], #0x10\r
406         LDP             X4, X5, [SP], #0x10\r
407         LDP             X2, X3, [SP], #0x10\r
408         LDP             X0, X1, [SP], #0x10\r
409 \r
410         ERET\r
411 \r
412 \r
413 \r
414 \r
415 .align 8\r
416 pxCurrentTCBConst: .dword pxCurrentTCB\r
417 ullCriticalNestingConst: .dword ullCriticalNesting\r
418 ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext\r
419 \r
420 ullICCPMRConst: .dword ullICCPMR\r
421 ullMaxAPIPriorityMaskConst: .dword ullMaxAPIPriorityMask\r
422 vApplicationIRQHandlerConst: .word vApplicationIRQHandler\r
423 ullPortInterruptNestingConst: .dword ullPortInterruptNesting\r
424 ullPortYieldRequiredConst: .dword ullPortYieldRequired\r
425 ullICCIARConst: .dword ullICCIAR\r
426 ullICCEOIRConst: .dword ullICCEOIR\r
427 \r
428 \r
429 \r
430 .end\r
431 \r
432 \r
433 \r
434 \r
435 \r