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