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