2 FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
\r
5 VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
\r
7 This file is part of the FreeRTOS distribution.
\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
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
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
25 ***************************************************************************
\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
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
37 ***************************************************************************
\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
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
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
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
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
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
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
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
83 .extern _freertos_vector_table
\r
85 .global FreeRTOS_IRQ_Handler
\r
86 .global FreeRTOS_SWI_Handler
\r
87 .global vPortRestoreTaskContext
\r
90 .macro portSAVE_CONTEXT
\r
92 /* Switch to use the EL0 stack pointer. */
\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
113 /* Save the SPSR. */
\r
119 /* Save the ELR. */
\r
123 STP X2, X3, [SP, #-0x10]!
\r
125 /* Save the critical section nesting depth. */
\r
126 LDR X0, ullCriticalNestingConst
\r
129 /* Save the FPU context indicator. */
\r
130 LDR X0, ullPortTaskHasFPUContextConst
\r
133 /* Save the FPU context, if any (32 128-bit registers). */
\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
154 /* Store the critical nesting count and FPU context indicator. */
\r
155 STP X2, X3, [SP, #-0x10]!
\r
157 LDR X0, pxCurrentTCBConst
\r
159 MOV X0, SP /* Move SP into X0 for saving. */
\r
162 /* Switch to use the ELx stack pointer. */
\r
167 ; /**********************************************************************/
\r
169 .macro portRESTORE_CONTEXT
\r
171 /* Switch to use the EL0 stack pointer. */
\r
174 /* Set the SP to point to the stack of the task being restored. */
\r
175 LDR X0, pxCurrentTCBConst
\r
180 LDP X2, X3, [SP], #0x10 /* Critical nesting and FPU context. */
\r
182 /* Set the PMR register to be correct for the current critical nesting
\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
188 LDR X5, [X4] /* X5 holds the address of the ICCPMR register. */
\r
190 LDR X6, ullMaxAPIPriorityMaskConst
\r
191 LDR X1, [X6] /* X1 holds the mask value. */
\r
193 STR W1, [X5] /* Write the mask value to ICCPMR. */
\r
194 DSB SY /* _RB_Barriers probably not required here. */
\r
196 STR X3, [X0] /* Restore the task's critical nesting count. */
\r
198 /* Restore the FPU context indicator. */
\r
199 LDR X0, ullPortTaskHasFPUContextConst
\r
202 /* Restore the FPU context, if any. */
\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
222 LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */
\r
225 /* Restore the SPSR. */
\r
227 /* Restore the ELR. */
\r
230 /* Restore the SPSR. */
\r
231 MSR SPSR_EL3, X3 /*_RB_ Assumes started in EL3. */
\r
232 /* Restore the ELR. */
\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
253 /* Switch to use the ELx stack pointer. _RB_ Might not be required. */
\r
261 /******************************************************************************
\r
262 * FreeRTOS_SWI_Handler handler is used to perform a context switch.
\r
263 *****************************************************************************/
\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
278 CMP X1, #0x15 /* 0x15 = SVC instruction. */
\r
280 CMP X1, #0x17 /* 0x17 = SMC instruction. */
\r
282 B.NE FreeRTOS_Abort
\r
283 BL vTaskSwitchContext
\r
285 portRESTORE_CONTEXT
\r
288 /* Full ESR is in X0, exception class code is in X1. */
\r
291 /******************************************************************************
\r
292 * vPortRestoreTaskContext is used to start the scheduler.
\r
293 *****************************************************************************/
\r
295 .type vPortRestoreTaskContext, %function
\r
296 vPortRestoreTaskContext:
\r
297 .set freertos_vector_base, _freertos_vector_table
\r
299 /* Install the FreeRTOS interrupt handlers. */
\r
300 LDR X1, =freertos_vector_base
\r
309 /* Start the first task. */
\r
310 portRESTORE_CONTEXT
\r
313 /******************************************************************************
\r
314 * FreeRTOS_IRQ_Handler handles IRQ entry and exit.
\r
315 *****************************************************************************/
\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
332 /* Save the SPSR and ELR. */
\r
340 STP X2, X3, [SP, #-0x10]!
\r
342 /* Increment the interrupt nesting counter. */
\r
343 LDR X5, ullPortInterruptNestingConst
\r
344 LDR X1, [X5] /* Old nesting count in X1. */
\r
346 STR X6, [X5] /* Address of nesting count variable in X5. */
\r
348 /* Maintain the interrupt nesting information across the function call. */
\r
349 STP X1, X5, [SP, #-0x10]!
\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
355 LDR W0, [X3] /* ICCIAR in W0 as parameter. */
\r
357 /* Maintain the ICCIAR value across the function call. */
\r
358 STP X0, X1, [SP, #-0x10]!
\r
360 /* Call the C handler. */
\r
361 BL vApplicationIRQHandler
\r
363 /* Disable interrupts. */
\r
368 /* Restore the ICCIAR value. */
\r
369 LDP X0, X1, [SP], #0x10
\r
371 /* End IRQ processing by writing ICCIAR to the EOI register. */
\r
372 LDR X4, ullICCEOIRConst
\r
376 /* Restore the critical nesting count. */
\r
377 LDP X1, X5, [SP], #0x10
\r
380 /* Has interrupt nesting unwound? */
\r
382 B.NE Exit_IRQ_No_Context_Switch
\r
384 /* Is a context switch required? */
\r
385 LDR X0, ullPortYieldRequiredConst
\r
388 B.EQ Exit_IRQ_No_Context_Switch
\r
390 /* Reset ullPortYieldRequired to 0. */
\r
394 /* Restore volatile registers. */
\r
395 LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */
\r
400 MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */
\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
418 /* Save the context of the current task and select a new task to run. */
\r
420 BL vTaskSwitchContext
\r
421 portRESTORE_CONTEXT
\r
423 Exit_IRQ_No_Context_Switch:
\r
424 /* Restore volatile registers. */
\r
425 LDP X4, X5, [SP], #0x10 /* SPSR and ELR. */
\r
430 MSR SPSR_EL3, X5 /*_RB_ Assumes started in EL3. */
\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
454 pxCurrentTCBConst: .dword pxCurrentTCB
\r
455 ullCriticalNestingConst: .dword ullCriticalNesting
\r
456 ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext
\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