2 FreeRTOS V8.2.3 - Copyright (C) 2015 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
116 /* Save the ELR. */
\r
119 STP X2, X3, [SP, #-0x10]!
\r
121 /* Save the critical section nesting depth. */
\r
122 LDR X0, ullCriticalNestingConst
\r
125 /* Save the FPU context indicator. */
\r
126 LDR X0, ullPortTaskHasFPUContextConst
\r
129 /* Save the FPU context, if any (32 128-bit registers). */
\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
150 /* Store the critical nesting count and FPU context indicator. */
\r
151 STP X2, X3, [SP, #-0x10]!
\r
153 LDR X0, pxCurrentTCBConst
\r
155 MOV X0, SP /* Move SP into X0 for saving. */
\r
158 /* Switch to use the ELx stack pointer. */
\r
163 ; /**********************************************************************/
\r
165 .macro portRESTORE_CONTEXT
\r
167 /* Switch to use the EL0 stack pointer. */
\r
170 /* Set the SP to point to the stack of the task being restored. */
\r
171 LDR X0, pxCurrentTCBConst
\r
176 LDP X2, X3, [SP], #0x10 /* Critical nesting and FPU context. */
\r
178 /* Set the PMR register to be correct for the current critical nesting
\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
184 LDR X5, [X4] /* X5 holds the address of the ICCPMR register. */
\r
186 LDR X6, ullMaxAPIPriorityMaskConst
\r
187 LDR X1, [X6] /* X1 holds the mask value. */
\r
189 STR W1, [X5] /* Write the mask value to ICCPMR. */
\r
190 DSB SY /* _RB_Barriers probably not required here. */
\r
192 STR X3, [X0] /* Restore the task's critical nesting count. */
\r
194 /* Restore the FPU context indicator. */
\r
195 LDR X0, ullPortTaskHasFPUContextConst
\r
198 /* Restore the FPU context, if any. */
\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
218 LDP X2, X3, [SP], #0x10 /* SPSR and ELR. */
\r
220 /* Restore the SPSR. */
\r
221 MSR SPSR_EL3, X3 /*_RB_ Assumes started in EL3. */
\r
223 /* Restore the ELR. */
\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
243 /* Switch to use the ELx stack pointer. _RB_ Might not be required. */
\r
251 /******************************************************************************
\r
252 * FreeRTOS_SWI_Handler handler is used to perform a context switch.
\r
253 *****************************************************************************/
\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
262 CMP X1, #0x17 /* 0x17 = SMC instruction. */
\r
263 B.NE FreeRTOS_Abort
\r
264 BL vTaskSwitchContext
\r
266 portRESTORE_CONTEXT
\r
269 /* Full ESR is in X0, exception class code is in X1. */
\r
272 /******************************************************************************
\r
273 * vPortRestoreTaskContext is used to start the scheduler.
\r
274 *****************************************************************************/
\r
276 .type vPortRestoreTaskContext, %function
\r
277 vPortRestoreTaskContext:
\r
278 .set freertos_vector_base, _freertos_vector_table
\r
280 /* Install the FreeRTOS interrupt handlers. */
\r
281 LDR X1, =freertos_vector_base
\r
286 /* Start the first task. */
\r
287 portRESTORE_CONTEXT
\r
290 /******************************************************************************
\r
291 * FreeRTOS_IRQ_Handler handles IRQ entry and exit.
\r
292 *****************************************************************************/
\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
309 /* Save the SPSR and ELR. */
\r
312 STP X2, X3, [SP, #-0x10]!
\r
314 /* Increment the interrupt nesting counter. */
\r
315 LDR X5, ullPortInterruptNestingConst
\r
316 LDR X1, [X5] /* Old nesting count in X1. */
\r
318 STR X6, [X5] /* Address of nesting count variable in X5. */
\r
320 /* Maintain the interrupt nesting information across the function call. */
\r
321 STP X1, X5, [SP, #-0x10]!
\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
327 LDR W0, [X3] /* ICCIAR in W0 as parameter. */
\r
329 /* Maintain the ICCIAR value across the function call. */
\r
330 STP X0, X1, [SP, #-0x10]!
\r
332 /* Call the C handler. */
\r
333 BL vApplicationIRQHandler
\r
335 /* Disable interrupts. */
\r
340 /* Restore the ICCIAR value. */
\r
341 LDP X0, X1, [SP], #0x10
\r
343 /* End IRQ processing by writing ICCIAR to the EOI register. */
\r
344 LDR X4, ullICCEOIRConst
\r
348 /* Restore the critical nesting count. */
\r
349 LDP X1, X5, [SP], #0x10
\r
352 /* Has interrupt nesting unwound? */
\r
354 B.NE Exit_IRQ_No_Context_Switch
\r
356 /* Is a context switch required? */
\r
357 LDR X0, ullPortYieldRequiredConst
\r
360 B.EQ Exit_IRQ_No_Context_Switch
\r
362 /* Reset ullPortYieldRequired to 0. */
\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
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
385 /* Save the context of the current task and select a new task to run. */
\r
387 BL vTaskSwitchContext
\r
388 portRESTORE_CONTEXT
\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
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
416 pxCurrentTCBConst: .dword pxCurrentTCB
\r
417 ullCriticalNestingConst: .dword ullCriticalNesting
\r
418 ullPortTaskHasFPUContextConst: .dword ullPortTaskHasFPUContext
\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