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