]> begriffs open source - cmsis-freertos/blob - Source/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c
Correct memory allocation and access in osMemoryPoolNew (#142)
[cmsis-freertos] / Source / portable / GCC / ARM_CM35P_NTZ / non_secure / port.c
1 /*
2  * FreeRTOS Kernel V11.2.0
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  * Copyright 2024 Arm Limited and/or its affiliates
5  * <open-source-office@arm.com>
6  *
7  * SPDX-License-Identifier: MIT
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy of
10  * this software and associated documentation files (the "Software"), to deal in
11  * the Software without restriction, including without limitation the rights to
12  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
13  * the Software, and to permit persons to whom the Software is furnished to do so,
14  * subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in all
17  * copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
21  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  * https://www.FreeRTOS.org
27  * https://github.com/FreeRTOS
28  *
29  */
30
31 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
32  * all the API functions to use the MPU wrappers. That should only be done when
33  * task.h is included from an application file. */
34 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
35
36 /* Scheduler includes. */
37 #include "FreeRTOS.h"
38 #include "task.h"
39
40 /* MPU includes. */
41 #include "mpu_wrappers.h"
42 #include "mpu_syscall_numbers.h"
43
44 /* Portasm includes. */
45 #include "portasm.h"
46
47 #if ( configENABLE_TRUSTZONE == 1 )
48     /* Secure components includes. */
49     #include "secure_context.h"
50     #include "secure_init.h"
51 #endif /* configENABLE_TRUSTZONE */
52
53 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
54
55 /**
56  * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only
57  * i.e. the processor boots as secure and never jumps to the non-secure side.
58  * The Trust Zone support in the port must be disabled in order to run FreeRTOS
59  * on the secure side. The following are the valid configuration settings:
60  *
61  * 1. Run FreeRTOS on the Secure Side:
62  *    configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0
63  *
64  * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support:
65  *    configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1
66  *
67  * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support:
68  *    configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0
69  */
70 #if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
71     #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
72 #endif
73
74 /**
75  * Cortex-M23 does not have non-secure PSPLIM. We should use PSPLIM on Cortex-M23
76  * only when FreeRTOS runs on secure side.
77  */
78 #if ( ( portHAS_ARMV8M_MAIN_EXTENSION == 0 ) && ( configRUN_FREERTOS_SECURE_ONLY == 0 ) )
79     #define portUSE_PSPLIM_REGISTER    0
80 #else
81     #define portUSE_PSPLIM_REGISTER    1
82 #endif
83 /*-----------------------------------------------------------*/
84
85 /**
86  * @brief Prototype of all Interrupt Service Routines (ISRs).
87  */
88 typedef void ( * portISR_t )( void );
89 /*-----------------------------------------------------------*/
90
91 /**
92  * @brief Constants required to manipulate the NVIC.
93  */
94 #define portNVIC_SYSTICK_CTRL_REG             ( *( ( volatile uint32_t * ) 0xe000e010 ) )
95 #define portNVIC_SYSTICK_LOAD_REG             ( *( ( volatile uint32_t * ) 0xe000e014 ) )
96 #define portNVIC_SYSTICK_CURRENT_VALUE_REG    ( *( ( volatile uint32_t * ) 0xe000e018 ) )
97 #define portNVIC_SHPR3_REG                    ( *( ( volatile uint32_t * ) 0xe000ed20 ) )
98 #define portNVIC_SYSTICK_ENABLE_BIT           ( 1UL << 0UL )
99 #define portNVIC_SYSTICK_INT_BIT              ( 1UL << 1UL )
100 #define portNVIC_SYSTICK_CLK_BIT              ( 1UL << 2UL )
101 #define portNVIC_SYSTICK_COUNT_FLAG_BIT       ( 1UL << 16UL )
102 #define portNVIC_PEND_SYSTICK_CLEAR_BIT       ( 1UL << 25UL )
103 #define portNVIC_PEND_SYSTICK_SET_BIT         ( 1UL << 26UL )
104 #define portMIN_INTERRUPT_PRIORITY            ( 255UL )
105 #define portNVIC_PENDSV_PRI                   ( portMIN_INTERRUPT_PRIORITY << 16UL )
106 #define portNVIC_SYSTICK_PRI                  ( portMIN_INTERRUPT_PRIORITY << 24UL )
107 /*-----------------------------------------------------------*/
108
109 /**
110  * @brief Constants required to manipulate the SCB.
111  */
112 #define portSCB_VTOR_REG                      ( *( ( portISR_t ** ) 0xe000ed08 ) )
113 #define portSCB_SYS_HANDLER_CTRL_STATE_REG    ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
114 #define portSCB_MEM_FAULT_ENABLE_BIT          ( 1UL << 16UL )
115 #define portSCB_USG_FAULT_ENABLE_BIT          ( 1UL << 18UL )
116 /*-----------------------------------------------------------*/
117
118 /**
119  * @brief Constants used to check the installation of the FreeRTOS interrupt handlers.
120  */
121 #define portVECTOR_INDEX_SVC       ( 11 )
122 #define portVECTOR_INDEX_PENDSV    ( 14 )
123 /*-----------------------------------------------------------*/
124
125 /**
126  * @brief Constants required to check the validity of an interrupt priority.
127  */
128 #define portNVIC_SHPR2_REG                 ( *( ( volatile uint32_t * ) 0xE000ED1C ) )
129 #define portFIRST_USER_INTERRUPT_NUMBER    ( 16 )
130 #define portNVIC_IP_REGISTERS_OFFSET_16    ( 0xE000E3F0 )
131 #define portAIRCR_REG                      ( *( ( volatile uint32_t * ) 0xE000ED0C ) )
132 #define portTOP_BIT_OF_BYTE                ( ( uint8_t ) 0x80 )
133 #define portMAX_PRIGROUP_BITS              ( ( uint8_t ) 7 )
134 #define portPRIORITY_GROUP_MASK            ( 0x07UL << 8UL )
135 #define portPRIGROUP_SHIFT                 ( 8UL )
136 /*-----------------------------------------------------------*/
137
138 /**
139  * @brief Constants used during system call enter and exit.
140  */
141 #define portPSR_STACK_PADDING_MASK              ( 1UL << 9UL )
142 #define portEXC_RETURN_STACK_FRAME_TYPE_MASK    ( 1UL << 4UL )
143 /*-----------------------------------------------------------*/
144
145 /**
146  * @brief Constants required to manipulate the FPU.
147  */
148 #define portCPACR               ( ( volatile uint32_t * ) 0xe000ed88 )              /* Coprocessor Access Control Register. */
149 #define portCPACR_CP10_VALUE    ( 3UL )
150 #define portCPACR_CP11_VALUE    portCPACR_CP10_VALUE
151 #define portCPACR_CP10_POS      ( 20UL )
152 #define portCPACR_CP11_POS      ( 22UL )
153
154 #define portFPCCR               ( ( volatile uint32_t * ) 0xe000ef34 )              /* Floating Point Context Control Register. */
155 #define portFPCCR_ASPEN_POS     ( 31UL )
156 #define portFPCCR_ASPEN_MASK    ( 1UL << portFPCCR_ASPEN_POS )
157 #define portFPCCR_LSPEN_POS     ( 30UL )
158 #define portFPCCR_LSPEN_MASK    ( 1UL << portFPCCR_LSPEN_POS )
159 /*-----------------------------------------------------------*/
160
161 /**
162  * @brief Offsets in the stack to the parameters when inside the SVC handler.
163  */
164 #define portOFFSET_TO_LR     ( 5 )
165 #define portOFFSET_TO_PC     ( 6 )
166 #define portOFFSET_TO_PSR    ( 7 )
167 /*-----------------------------------------------------------*/
168
169 /**
170  * @brief Constants required to manipulate the MPU.
171  */
172 #define portMPU_TYPE_REG                        ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
173 #define portMPU_CTRL_REG                        ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
174 #define portMPU_RNR_REG                         ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
175
176 #define portMPU_RBAR_REG                        ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
177 #define portMPU_RLAR_REG                        ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
178
179 #define portMPU_RBAR_A1_REG                     ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
180 #define portMPU_RLAR_A1_REG                     ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
181
182 #define portMPU_RBAR_A2_REG                     ( *( ( volatile uint32_t * ) 0xe000edac ) )
183 #define portMPU_RLAR_A2_REG                     ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
184
185 #define portMPU_RBAR_A3_REG                     ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
186 #define portMPU_RLAR_A3_REG                     ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
187
188 #define portMPU_MAIR0_REG                       ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
189 #define portMPU_MAIR1_REG                       ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
190
191 #define portMPU_RBAR_ADDRESS_MASK               ( 0xffffffe0 )     /* Must be 32-byte aligned. */
192 #define portMPU_RLAR_ADDRESS_MASK               ( 0xffffffe0 )     /* Must be 32-byte aligned. */
193
194 #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK    ( 3UL << 1UL )
195
196 #define portMPU_MAIR_ATTR0_POS                  ( 0UL )
197 #define portMPU_MAIR_ATTR0_MASK                 ( 0x000000ff )
198
199 #define portMPU_MAIR_ATTR1_POS                  ( 8UL )
200 #define portMPU_MAIR_ATTR1_MASK                 ( 0x0000ff00 )
201
202 #define portMPU_MAIR_ATTR2_POS                  ( 16UL )
203 #define portMPU_MAIR_ATTR2_MASK                 ( 0x00ff0000 )
204
205 #define portMPU_MAIR_ATTR3_POS                  ( 24UL )
206 #define portMPU_MAIR_ATTR3_MASK                 ( 0xff000000 )
207
208 #define portMPU_MAIR_ATTR4_POS                  ( 0UL )
209 #define portMPU_MAIR_ATTR4_MASK                 ( 0x000000ff )
210
211 #define portMPU_MAIR_ATTR5_POS                  ( 8UL )
212 #define portMPU_MAIR_ATTR5_MASK                 ( 0x0000ff00 )
213
214 #define portMPU_MAIR_ATTR6_POS                  ( 16UL )
215 #define portMPU_MAIR_ATTR6_MASK                 ( 0x00ff0000 )
216
217 #define portMPU_MAIR_ATTR7_POS                  ( 24UL )
218 #define portMPU_MAIR_ATTR7_MASK                 ( 0xff000000 )
219
220 #define portMPU_RLAR_ATTR_INDEX0                ( 0UL << 1UL )
221 #define portMPU_RLAR_ATTR_INDEX1                ( 1UL << 1UL )
222 #define portMPU_RLAR_ATTR_INDEX2                ( 2UL << 1UL )
223 #define portMPU_RLAR_ATTR_INDEX3                ( 3UL << 1UL )
224 #define portMPU_RLAR_ATTR_INDEX4                ( 4UL << 1UL )
225 #define portMPU_RLAR_ATTR_INDEX5                ( 5UL << 1UL )
226 #define portMPU_RLAR_ATTR_INDEX6                ( 6UL << 1UL )
227 #define portMPU_RLAR_ATTR_INDEX7                ( 7UL << 1UL )
228
229 #define portMPU_RLAR_REGION_ENABLE              ( 1UL )
230
231 #if ( portARMV8M_MINOR_VERSION >= 1 )
232
233 /* Enable Privileged eXecute Never MPU attribute for the selected memory
234  * region. */
235     #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER    ( 1UL << 4UL )
236 #endif /* portARMV8M_MINOR_VERSION >= 1 */
237
238 /* Enable privileged access to unmapped region. */
239 #define portMPU_PRIV_BACKGROUND_ENABLE_BIT    ( 1UL << 2UL )
240
241 /* Enable MPU. */
242 #define portMPU_ENABLE_BIT                    ( 1UL << 0UL )
243
244 /* Expected value of the portMPU_TYPE register. */
245 #define portEXPECTED_MPU_TYPE_VALUE           ( configTOTAL_MPU_REGIONS << 8UL )
246
247 /* Extract first address of the MPU region as encoded in the
248  * RBAR (Region Base Address Register) value. */
249 #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \
250     ( ( rbar ) & portMPU_RBAR_ADDRESS_MASK )
251
252 /* Extract last address of the MPU region as encoded in the
253  * RLAR (Region Limit Address Register) value. */
254 #define portEXTRACT_LAST_ADDRESS_FROM_RLAR( rlar ) \
255     ( ( ( rlar ) & portMPU_RLAR_ADDRESS_MASK ) | ~portMPU_RLAR_ADDRESS_MASK )
256
257 /* Does addr lies within [start, end] address range? */
258 #define portIS_ADDRESS_WITHIN_RANGE( addr, start, end ) \
259     ( ( ( addr ) >= ( start ) ) && ( ( addr ) <= ( end ) ) )
260
261 /* Is the access request satisfied by the available permissions? */
262 #define portIS_AUTHORIZED( accessRequest, permissions ) \
263     ( ( ( permissions ) & ( accessRequest ) ) == accessRequest )
264
265 /* Max value that fits in a uint32_t type. */
266 #define portUINT32_MAX    ( ~( ( uint32_t ) 0 ) )
267
268 /* Check if adding a and b will result in overflow. */
269 #define portADD_UINT32_WILL_OVERFLOW( a, b )    ( ( a ) > ( portUINT32_MAX - ( b ) ) )
270 /*-----------------------------------------------------------*/
271
272 /**
273  * @brief The maximum 24-bit number.
274  *
275  * It is needed because the systick is a 24-bit counter.
276  */
277 #define portMAX_24_BIT_NUMBER       ( 0xffffffUL )
278
279 /**
280  * @brief A fiddle factor to estimate the number of SysTick counts that would
281  * have occurred while the SysTick counter is stopped during tickless idle
282  * calculations.
283  */
284 #define portMISSED_COUNTS_FACTOR    ( 94UL )
285 /*-----------------------------------------------------------*/
286
287 /**
288  * @brief Constants required to set up the initial stack.
289  */
290 #define portINITIAL_XPSR    ( 0x01000000 )
291
292 #if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
293
294 /**
295  * @brief Initial EXC_RETURN value.
296  *
297  *     FF         FF         FF         FD
298  * 1111 1111  1111 1111  1111 1111  1111 1101
299  *
300  * Bit[6] - 1 --> The exception was taken from the Secure state.
301  * Bit[5] - 1 --> Do not skip stacking of additional state context.
302  * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context.
303  * Bit[3] - 1 --> Return to the Thread mode.
304  * Bit[2] - 1 --> Restore registers from the process stack.
305  * Bit[1] - 0 --> Reserved, 0.
306  * Bit[0] - 1 --> The exception was taken to the Secure state.
307  */
308     #define portINITIAL_EXC_RETURN    ( 0xfffffffd )
309 #else
310
311 /**
312  * @brief Initial EXC_RETURN value.
313  *
314  *     FF         FF         FF         BC
315  * 1111 1111  1111 1111  1111 1111  1011 1100
316  *
317  * Bit[6] - 0 --> The exception was taken from the Non-Secure state.
318  * Bit[5] - 1 --> Do not skip stacking of additional state context.
319  * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context.
320  * Bit[3] - 1 --> Return to the Thread mode.
321  * Bit[2] - 1 --> Restore registers from the process stack.
322  * Bit[1] - 0 --> Reserved, 0.
323  * Bit[0] - 0 --> The exception was taken to the Non-Secure state.
324  */
325     #define portINITIAL_EXC_RETURN    ( 0xffffffbc )
326 #endif /* configRUN_FREERTOS_SECURE_ONLY */
327
328 /**
329  * @brief CONTROL register privileged bit mask.
330  *
331  * Bit[0] in CONTROL register tells the privilege:
332  *  Bit[0] = 0 ==> The task is privileged.
333  *  Bit[0] = 1 ==> The task is not privileged.
334  */
335 #define portCONTROL_PRIVILEGED_MASK         ( 1UL << 0UL )
336
337 /**
338  * @brief Initial CONTROL register values.
339  */
340 #define portINITIAL_CONTROL_UNPRIVILEGED    ( 0x3 )
341 #define portINITIAL_CONTROL_PRIVILEGED      ( 0x2 )
342
343 /**
344  * @brief Let the user override the default SysTick clock rate.  If defined by the
345  * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the
346  * configuration register.
347  */
348 #ifndef configSYSTICK_CLOCK_HZ
349     #define configSYSTICK_CLOCK_HZ             ( configCPU_CLOCK_HZ )
350     /* Ensure the SysTick is clocked at the same frequency as the core. */
351     #define portNVIC_SYSTICK_CLK_BIT_CONFIG    ( portNVIC_SYSTICK_CLK_BIT )
352 #else
353     /* Select the option to clock SysTick not at the same frequency as the core. */
354     #define portNVIC_SYSTICK_CLK_BIT_CONFIG    ( 0 )
355 #endif
356
357 /**
358  * @brief Let the user override the pre-loading of the initial LR with the
359  * address of prvTaskExitError() in case it messes up unwinding of the stack
360  * in the debugger.
361  */
362 #ifdef configTASK_RETURN_ADDRESS
363     #define portTASK_RETURN_ADDRESS    configTASK_RETURN_ADDRESS
364 #else
365     #define portTASK_RETURN_ADDRESS    prvTaskExitError
366 #endif
367
368 /**
369  * @brief If portPRELOAD_REGISTERS then registers will be given an initial value
370  * when a task is created. This helps in debugging at the cost of code size.
371  */
372 #define portPRELOAD_REGISTERS    1
373
374 /**
375  * @brief A task is created without a secure context, and must call
376  * portALLOCATE_SECURE_CONTEXT() to give itself a secure context before it makes
377  * any secure calls.
378  */
379 #define portNO_SECURE_CONTEXT    0
380
381 /**
382  * @brief Constants required to check and configure PACBTI security feature implementation.
383  */
384 #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
385
386     #define portID_ISAR5_REG       ( *( ( volatile uint32_t * ) 0xe000ed74 ) )
387
388     #define portCONTROL_UPAC_EN    ( 1UL << 7UL )
389     #define portCONTROL_PAC_EN     ( 1UL << 6UL )
390     #define portCONTROL_UBTI_EN    ( 1UL << 5UL )
391     #define portCONTROL_BTI_EN     ( 1UL << 4UL )
392
393 #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
394 /*-----------------------------------------------------------*/
395
396 /**
397  * @brief Used to catch tasks that attempt to return from their implementing
398  * function.
399  */
400 static void prvTaskExitError( void );
401
402 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
403
404 /**
405  * @brief Extract MPU region's access permissions from the Region Base Address
406  * Register (RBAR) value.
407  *
408  * @param ulRBARValue RBAR value for the MPU region.
409  *
410  * @return uint32_t Access permissions.
411  */
412     static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION;
413 #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
414
415 #if ( configENABLE_MPU == 1 )
416
417 /**
418  * @brief Setup the Memory Protection Unit (MPU).
419  */
420     static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;
421 #endif /* configENABLE_MPU */
422
423 #if ( configENABLE_FPU == 1 )
424
425 /**
426  * @brief Setup the Floating Point Unit (FPU).
427  */
428     static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
429 #endif /* configENABLE_FPU */
430
431 #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
432
433 /**
434  * @brief Configures PACBTI features.
435  *
436  * This function configures the Pointer Authentication, and Branch Target
437  * Identification security features as per the user configuration. It returns
438  * the value of the special purpose CONTROL register accordingly, and optionally
439  * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M
440  * architecture based) target supports PACBTI security feature.
441  *
442  * @param xWriteControlRegister Used to control whether the special purpose
443  * CONTROL register should be updated or not.
444  *
445  * @return CONTROL register value according to the configured PACBTI option.
446  */
447     static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister );
448
449 #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
450
451 /**
452  * @brief Setup the timer to generate the tick interrupts.
453  *
454  * The implementation in this file is weak to allow application writers to
455  * change the timer used to generate the tick interrupt.
456  */
457 void vPortSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;
458
459 /**
460  * @brief Checks whether the current execution context is interrupt.
461  *
462  * @return pdTRUE if the current execution context is interrupt, pdFALSE
463  * otherwise.
464  */
465 BaseType_t xPortIsInsideInterrupt( void );
466
467 /**
468  * @brief Yield the processor.
469  */
470 void vPortYield( void ) PRIVILEGED_FUNCTION;
471
472 /**
473  * @brief Enter critical section.
474  */
475 void vPortEnterCritical( void ) PRIVILEGED_FUNCTION;
476
477 /**
478  * @brief Exit from critical section.
479  */
480 void vPortExitCritical( void ) PRIVILEGED_FUNCTION;
481
482 /**
483  * @brief SysTick handler.
484  */
485 void SysTick_Handler( void ) PRIVILEGED_FUNCTION;
486
487 /**
488  * @brief C part of SVC handler.
489  */
490 portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIVILEGED_FUNCTION;
491
492 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
493
494 /**
495  * @brief Sets up the system call stack so that upon returning from
496  * SVC, the system call stack is used.
497  *
498  * @param pulTaskStack The current SP when the SVC was raised.
499  * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler.
500  * @param ucSystemCallNumber The system call number of the system call.
501  */
502     void vSystemCallEnter( uint32_t * pulTaskStack,
503                            uint32_t ulLR,
504                            uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION;
505
506 #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
507
508 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
509
510 /**
511  * @brief Raise SVC for exiting from a system call.
512  */
513     void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
514
515 #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
516
517 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
518
519 /**
520  * @brief Sets up the task stack so that upon returning from
521  * SVC, the task stack is used again.
522  *
523  * @param pulSystemCallStack The current SP when the SVC was raised.
524  * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler.
525  */
526     void vSystemCallExit( uint32_t * pulSystemCallStack,
527                           uint32_t ulLR ) PRIVILEGED_FUNCTION;
528
529 #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
530
531 #if ( configENABLE_MPU == 1 )
532
533 /**
534  * @brief Checks whether or not the calling task is privileged.
535  *
536  * @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
537  */
538     BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION;
539
540 #endif /* configENABLE_MPU == 1 */
541 /*-----------------------------------------------------------*/
542
543 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
544
545 /**
546  * @brief This variable is set to pdTRUE when the scheduler is started.
547  */
548     PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE;
549
550 #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
551
552 /**
553  * @brief Each task maintains its own interrupt status in the critical nesting
554  * variable.
555  */
556 PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL;
557
558 #if ( configENABLE_TRUSTZONE == 1 )
559
560 /**
561  * @brief Saved as part of the task context to indicate which context the
562  * task is using on the secure side.
563  */
564     PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT;
565 #endif /* configENABLE_TRUSTZONE */
566
567 /**
568  * @brief Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
569  * FreeRTOS API functions are not called from interrupts that have been assigned
570  * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
571  */
572 #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
573
574     static uint8_t ucMaxSysCallPriority = 0;
575     static uint32_t ulMaxPRIGROUPValue = 0;
576     static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16;
577
578 #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
579
580 #if ( configUSE_TICKLESS_IDLE == 1 )
581
582 /**
583  * @brief The number of SysTick increments that make up one tick period.
584  */
585     PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0;
586
587 /**
588  * @brief The maximum number of tick periods that can be suppressed is
589  * limited by the 24 bit resolution of the SysTick timer.
590  */
591     PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0;
592
593 /**
594  * @brief Compensate for the CPU cycles that pass while the SysTick is
595  * stopped (low power functionality only).
596  */
597     PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0;
598 #endif /* configUSE_TICKLESS_IDLE */
599 /*-----------------------------------------------------------*/
600
601 #if ( configUSE_TICKLESS_IDLE == 1 )
602
603     __attribute__( ( weak ) ) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
604     {
605         uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickDecrementsLeft;
606         TickType_t xModifiableIdleTime;
607
608         /* Make sure the SysTick reload value does not overflow the counter. */
609         if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
610         {
611             xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
612         }
613
614         /* Enter a critical section but don't use the taskENTER_CRITICAL()
615          * method as that will mask interrupts that should exit sleep mode. */
616         __asm volatile ( "cpsid i" ::: "memory" );
617         __asm volatile ( "dsb" );
618         __asm volatile ( "isb" );
619
620         /* If a context switch is pending or a task is waiting for the scheduler
621          * to be unsuspended then abandon the low power entry. */
622         if( eTaskConfirmSleepModeStatus() == eAbortSleep )
623         {
624             /* Re-enable interrupts - see comments above the cpsid instruction
625              * above. */
626             __asm volatile ( "cpsie i" ::: "memory" );
627         }
628         else
629         {
630             /* Stop the SysTick momentarily.  The time the SysTick is stopped for
631              * is accounted for as best it can be, but using the tickless mode will
632              * inevitably result in some tiny drift of the time maintained by the
633              * kernel with respect to calendar time. */
634             portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT );
635
636             /* Use the SysTick current-value register to determine the number of
637              * SysTick decrements remaining until the next tick interrupt.  If the
638              * current-value register is zero, then there are actually
639              * ulTimerCountsForOneTick decrements remaining, not zero, because the
640              * SysTick requests the interrupt when decrementing from 1 to 0. */
641             ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG;
642
643             if( ulSysTickDecrementsLeft == 0 )
644             {
645                 ulSysTickDecrementsLeft = ulTimerCountsForOneTick;
646             }
647
648             /* Calculate the reload value required to wait xExpectedIdleTime
649              * tick periods.  -1 is used because this code normally executes part
650              * way through the first tick period.  But if the SysTick IRQ is now
651              * pending, then clear the IRQ, suppressing the first tick, and correct
652              * the reload value to reflect that the second tick period is already
653              * underway.  The expected idle time is always at least two ticks. */
654             ulReloadValue = ulSysTickDecrementsLeft + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
655
656             if( ( portNVIC_INT_CTRL_REG & portNVIC_PEND_SYSTICK_SET_BIT ) != 0 )
657             {
658                 portNVIC_INT_CTRL_REG = portNVIC_PEND_SYSTICK_CLEAR_BIT;
659                 ulReloadValue -= ulTimerCountsForOneTick;
660             }
661
662             if( ulReloadValue > ulStoppedTimerCompensation )
663             {
664                 ulReloadValue -= ulStoppedTimerCompensation;
665             }
666
667             /* Set the new reload value. */
668             portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
669
670             /* Clear the SysTick count flag and set the count value back to
671              * zero. */
672             portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
673
674             /* Restart SysTick. */
675             portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
676
677             /* Sleep until something happens.  configPRE_SLEEP_PROCESSING() can
678              * set its parameter to 0 to indicate that its implementation contains
679              * its own wait for interrupt or wait for event instruction, and so wfi
680              * should not be executed again.  However, the original expected idle
681              * time variable must remain unmodified, so a copy is taken. */
682             xModifiableIdleTime = xExpectedIdleTime;
683             configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
684
685             if( xModifiableIdleTime > 0 )
686             {
687                 __asm volatile ( "dsb" ::: "memory" );
688                 __asm volatile ( "wfi" );
689                 __asm volatile ( "isb" );
690             }
691
692             configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
693
694             /* Re-enable interrupts to allow the interrupt that brought the MCU
695              * out of sleep mode to execute immediately.  See comments above
696              * the cpsid instruction above. */
697             __asm volatile ( "cpsie i" ::: "memory" );
698             __asm volatile ( "dsb" );
699             __asm volatile ( "isb" );
700
701             /* Disable interrupts again because the clock is about to be stopped
702              * and interrupts that execute while the clock is stopped will increase
703              * any slippage between the time maintained by the RTOS and calendar
704              * time. */
705             __asm volatile ( "cpsid i" ::: "memory" );
706             __asm volatile ( "dsb" );
707             __asm volatile ( "isb" );
708
709             /* Disable the SysTick clock without reading the
710              * portNVIC_SYSTICK_CTRL_REG register to ensure the
711              * portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set.  Again,
712              * the time the SysTick is stopped for is accounted for as best it can
713              * be, but using the tickless mode will inevitably result in some tiny
714              * drift of the time maintained by the kernel with respect to calendar
715              * time*/
716             portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT );
717
718             /* Determine whether the SysTick has already counted to zero. */
719             if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
720             {
721                 uint32_t ulCalculatedLoadValue;
722
723                 /* The tick interrupt ended the sleep (or is now pending), and
724                  * a new tick period has started.  Reset portNVIC_SYSTICK_LOAD_REG
725                  * with whatever remains of the new tick period. */
726                 ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
727
728                 /* Don't allow a tiny value, or values that have somehow
729                  * underflowed because the post sleep hook did something
730                  * that took too long or because the SysTick current-value register
731                  * is zero. */
732                 if( ( ulCalculatedLoadValue <= ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) )
733                 {
734                     ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
735                 }
736
737                 portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
738
739                 /* As the pending tick will be processed as soon as this
740                  * function exits, the tick value maintained by the tick is stepped
741                  * forward by one less than the time spent waiting. */
742                 ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
743             }
744             else
745             {
746                 /* Something other than the tick interrupt ended the sleep. */
747
748                 /* Use the SysTick current-value register to determine the
749                  * number of SysTick decrements remaining until the expected idle
750                  * time would have ended. */
751                 ulSysTickDecrementsLeft = portNVIC_SYSTICK_CURRENT_VALUE_REG;
752                 #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG != portNVIC_SYSTICK_CLK_BIT )
753                 {
754                     /* If the SysTick is not using the core clock, the current-
755                      * value register might still be zero here.  In that case, the
756                      * SysTick didn't load from the reload register, and there are
757                      * ulReloadValue decrements remaining in the expected idle
758                      * time, not zero. */
759                     if( ulSysTickDecrementsLeft == 0 )
760                     {
761                         ulSysTickDecrementsLeft = ulReloadValue;
762                     }
763                 }
764                 #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */
765
766                 /* Work out how long the sleep lasted rounded to complete tick
767                  * periods (not the ulReload value which accounted for part
768                  * ticks). */
769                 ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - ulSysTickDecrementsLeft;
770
771                 /* How many complete tick periods passed while the processor
772                  * was waiting? */
773                 ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
774
775                 /* The reload value is set to whatever fraction of a single tick
776                  * period remains. */
777                 portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
778             }
779
780             /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG again,
781              * then set portNVIC_SYSTICK_LOAD_REG back to its standard value.  If
782              * the SysTick is not using the core clock, temporarily configure it to
783              * use the core clock.  This configuration forces the SysTick to load
784              * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next
785              * cycle of the other clock.  Then portNVIC_SYSTICK_LOAD_REG is ready
786              * to receive the standard value immediately. */
787             portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
788             portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
789             #if ( portNVIC_SYSTICK_CLK_BIT_CONFIG == portNVIC_SYSTICK_CLK_BIT )
790             {
791                 portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
792             }
793             #else
794             {
795                 /* The temporary usage of the core clock has served its purpose,
796                  * as described above.  Resume usage of the other clock. */
797                 portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
798
799                 if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
800                 {
801                     /* The partial tick period already ended.  Be sure the SysTick
802                      * counts it only once. */
803                     portNVIC_SYSTICK_CURRENT_VALUE_REG = 0;
804                 }
805
806                 portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
807                 portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
808             }
809             #endif /* portNVIC_SYSTICK_CLK_BIT_CONFIG */
810
811             /* Step the tick to account for any tick periods that elapsed. */
812             vTaskStepTick( ulCompleteTickPeriods );
813
814             /* Exit with interrupts enabled. */
815             __asm volatile ( "cpsie i" ::: "memory" );
816         }
817     }
818
819 #endif /* configUSE_TICKLESS_IDLE */
820 /*-----------------------------------------------------------*/
821
822 __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void ) /* PRIVILEGED_FUNCTION */
823 {
824     /* Calculate the constants required to configure the tick interrupt. */
825     #if ( configUSE_TICKLESS_IDLE == 1 )
826     {
827         ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
828         xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
829         ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
830     }
831     #endif /* configUSE_TICKLESS_IDLE */
832
833     /* Stop and reset SysTick.
834      *
835      * QEMU versions older than 7.0.0 contain a bug which causes an error if we
836      * enable SysTick without first selecting a valid clock source. We trigger
837      * the bug if we change clock sources from a clock with a zero clock period
838      * to one with a nonzero clock period and enable Systick at the same time.
839      * So we configure the CLKSOURCE bit here, prior to setting the ENABLE bit.
840      * This workaround avoids the bug in QEMU versions older than 7.0.0. */
841     portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG;
842     portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
843
844     /* Configure SysTick to interrupt at the requested rate. */
845     portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
846     portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT_CONFIG | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
847 }
848 /*-----------------------------------------------------------*/
849
850 static void prvTaskExitError( void )
851 {
852     volatile uint32_t ulDummy = 0UL;
853
854     /* A function that implements a task must not exit or attempt to return to
855      * its caller as there is nothing to return to. If a task wants to exit it
856      * should instead call vTaskDelete( NULL ). Artificially force an assert()
857      * to be triggered if configASSERT() is defined, then stop here so
858      * application writers can catch the error. */
859     configASSERT( ulCriticalNesting == ~0UL );
860     portDISABLE_INTERRUPTS();
861
862     while( ulDummy == 0 )
863     {
864         /* This file calls prvTaskExitError() after the scheduler has been
865          * started to remove a compiler warning about the function being
866          * defined but never called.  ulDummy is used purely to quieten other
867          * warnings about code appearing after this function is called - making
868          * ulDummy volatile makes the compiler think the function could return
869          * and therefore not output an 'unreachable code' warning for code that
870          * appears after it. */
871     }
872 }
873 /*-----------------------------------------------------------*/
874
875 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
876
877     static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) /* PRIVILEGED_FUNCTION */
878     {
879         uint32_t ulAccessPermissions = 0;
880
881         if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_ONLY )
882         {
883             ulAccessPermissions = tskMPU_READ_PERMISSION;
884         }
885
886         if( ( ulRBARValue & portMPU_RBAR_ACCESS_PERMISSIONS_MASK ) == portMPU_REGION_READ_WRITE )
887         {
888             ulAccessPermissions = ( tskMPU_READ_PERMISSION | tskMPU_WRITE_PERMISSION );
889         }
890
891         return ulAccessPermissions;
892     }
893
894 #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
895 /*-----------------------------------------------------------*/
896
897 #if ( configENABLE_MPU == 1 )
898
899     static void prvSetupMPU( void ) /* PRIVILEGED_FUNCTION */
900     {
901         #if defined( __ARMCC_VERSION )
902
903             /* Declaration when these variable are defined in code instead of being
904              * exported from linker scripts. */
905             extern uint32_t * __privileged_functions_start__;
906             extern uint32_t * __privileged_functions_end__;
907             extern uint32_t * __syscalls_flash_start__;
908             extern uint32_t * __syscalls_flash_end__;
909             extern uint32_t * __unprivileged_flash_start__;
910             extern uint32_t * __unprivileged_flash_end__;
911             extern uint32_t * __privileged_sram_start__;
912             extern uint32_t * __privileged_sram_end__;
913         #else /* if defined( __ARMCC_VERSION ) */
914             /* Declaration when these variable are exported from linker scripts. */
915             extern uint32_t __privileged_functions_start__[];
916             extern uint32_t __privileged_functions_end__[];
917             extern uint32_t __syscalls_flash_start__[];
918             extern uint32_t __syscalls_flash_end__[];
919             extern uint32_t __unprivileged_flash_start__[];
920             extern uint32_t __unprivileged_flash_end__[];
921             extern uint32_t __privileged_sram_start__[];
922             extern uint32_t __privileged_sram_end__[];
923         #endif /* defined( __ARMCC_VERSION ) */
924
925         /* The only permitted number of regions are 8 or 16. */
926         configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) );
927
928         /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */
929         configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE );
930
931         /* Check that the MPU is present. */
932         if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
933         {
934             /* MAIR0 - Index 0. */
935             portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
936             /* MAIR0 - Index 1. */
937             portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK );
938
939             /* Setup privileged flash as Read Only so that privileged tasks can
940              * read it but not modify. */
941             portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION;
942             portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
943                                ( portMPU_REGION_NON_SHAREABLE ) |
944                                ( portMPU_REGION_PRIVILEGED_READ_ONLY );
945             portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
946                                ( portMPU_RLAR_ATTR_INDEX0 ) |
947                                ( portMPU_RLAR_REGION_ENABLE );
948
949             /* Setup unprivileged flash as Read Only by both privileged and
950              * unprivileged tasks. All tasks can read it but no-one can modify. */
951             portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION;
952             portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
953                                ( portMPU_REGION_NON_SHAREABLE ) |
954                                ( portMPU_REGION_READ_ONLY );
955             portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
956                                ( portMPU_RLAR_ATTR_INDEX0 ) |
957                                ( portMPU_RLAR_REGION_ENABLE );
958
959             /* Setup unprivileged syscalls flash as Read Only by both privileged
960              * and unprivileged tasks. All tasks can read it but no-one can modify. */
961             portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION;
962             portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
963                                ( portMPU_REGION_NON_SHAREABLE ) |
964                                ( portMPU_REGION_READ_ONLY );
965             portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
966                                ( portMPU_RLAR_ATTR_INDEX0 ) |
967                                ( portMPU_RLAR_REGION_ENABLE );
968
969             /* Setup RAM containing kernel data for privileged access only. */
970             portMPU_RNR_REG = portPRIVILEGED_RAM_REGION;
971             portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) |
972                                ( portMPU_REGION_NON_SHAREABLE ) |
973                                ( portMPU_REGION_PRIVILEGED_READ_WRITE ) |
974                                ( portMPU_REGION_EXECUTE_NEVER );
975             portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) |
976                                ( portMPU_RLAR_ATTR_INDEX0 ) |
977                                ( portMPU_RLAR_REGION_ENABLE );
978
979             /* Enable mem fault. */
980             portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT;
981
982             /* Enable MPU with privileged background access i.e. unmapped
983              * regions have privileged access. */
984             portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT );
985         }
986     }
987
988 #endif /* configENABLE_MPU */
989 /*-----------------------------------------------------------*/
990
991 #if ( configENABLE_FPU == 1 )
992
993     static void prvSetupFPU( void ) /* PRIVILEGED_FUNCTION */
994     {
995         #if ( configENABLE_TRUSTZONE == 1 )
996         {
997             /* Enable non-secure access to the FPU. */
998             SecureInit_EnableNSFPUAccess();
999         }
1000         #endif /* configENABLE_TRUSTZONE */
1001
1002         /* CP10 = 11 ==> Full access to FPU i.e. both privileged and
1003          * unprivileged code should be able to access FPU. CP11 should be
1004          * programmed to the same value as CP10. */
1005         *( portCPACR ) |= ( ( portCPACR_CP10_VALUE << portCPACR_CP10_POS ) |
1006                             ( portCPACR_CP11_VALUE << portCPACR_CP11_POS )
1007                             );
1008
1009         /* ASPEN = 1 ==> Hardware should automatically preserve floating point
1010          * context on exception entry and restore on exception return.
1011          * LSPEN = 1 ==> Enable lazy context save of FP state. */
1012         *( portFPCCR ) |= ( portFPCCR_ASPEN_MASK | portFPCCR_LSPEN_MASK );
1013     }
1014
1015 #endif /* configENABLE_FPU */
1016 /*-----------------------------------------------------------*/
1017
1018 void vPortYield( void ) /* PRIVILEGED_FUNCTION */
1019 {
1020     /* Set a PendSV to request a context switch. */
1021     portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
1022
1023     /* Barriers are normally not required but do ensure the code is
1024      * completely within the specified behaviour for the architecture. */
1025     __asm volatile ( "dsb" ::: "memory" );
1026     __asm volatile ( "isb" );
1027 }
1028 /*-----------------------------------------------------------*/
1029
1030 void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */
1031 {
1032     portDISABLE_INTERRUPTS();
1033     ulCriticalNesting++;
1034
1035     /* Barriers are normally not required but do ensure the code is
1036      * completely within the specified behaviour for the architecture. */
1037     __asm volatile ( "dsb" ::: "memory" );
1038     __asm volatile ( "isb" );
1039 }
1040 /*-----------------------------------------------------------*/
1041
1042 void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */
1043 {
1044     configASSERT( ulCriticalNesting );
1045     ulCriticalNesting--;
1046
1047     if( ulCriticalNesting == 0 )
1048     {
1049         portENABLE_INTERRUPTS();
1050     }
1051 }
1052 /*-----------------------------------------------------------*/
1053
1054 void SysTick_Handler( void ) /* PRIVILEGED_FUNCTION */
1055 {
1056     uint32_t ulPreviousMask;
1057
1058     ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();
1059     traceISR_ENTER();
1060     {
1061         /* Increment the RTOS tick. */
1062         if( xTaskIncrementTick() != pdFALSE )
1063         {
1064             traceISR_EXIT_TO_SCHEDULER();
1065             /* Pend a context switch. */
1066             portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
1067         }
1068         else
1069         {
1070             traceISR_EXIT();
1071         }
1072     }
1073     portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );
1074 }
1075 /*-----------------------------------------------------------*/
1076
1077 void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTION portDONT_DISCARD */
1078 {
1079     #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
1080         #if defined( __ARMCC_VERSION )
1081
1082             /* Declaration when these variable are defined in code instead of being
1083              * exported from linker scripts. */
1084             extern uint32_t * __syscalls_flash_start__;
1085             extern uint32_t * __syscalls_flash_end__;
1086         #else
1087             /* Declaration when these variable are exported from linker scripts. */
1088             extern uint32_t __syscalls_flash_start__[];
1089             extern uint32_t __syscalls_flash_end__[];
1090         #endif /* defined( __ARMCC_VERSION ) */
1091     #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
1092
1093     uint32_t ulPC;
1094
1095     #if ( configENABLE_TRUSTZONE == 1 )
1096         uint32_t ulR0, ulR1;
1097         extern TaskHandle_t pxCurrentTCB;
1098         #if ( configENABLE_MPU == 1 )
1099             uint32_t ulControl, ulIsTaskPrivileged;
1100         #endif /* configENABLE_MPU */
1101     #endif /* configENABLE_TRUSTZONE */
1102     uint8_t ucSVCNumber;
1103
1104     /* Register are stored on the stack in the following order - R0, R1, R2, R3,
1105      * R12, LR, PC, xPSR. */
1106     ulPC = pulCallerStackAddress[ portOFFSET_TO_PC ];
1107     ucSVCNumber = ( ( uint8_t * ) ulPC )[ -2 ];
1108
1109     switch( ucSVCNumber )
1110     {
1111         #if ( configENABLE_TRUSTZONE == 1 )
1112             case portSVC_ALLOCATE_SECURE_CONTEXT:
1113
1114                 /* R0 contains the stack size passed as parameter to the
1115                  * vPortAllocateSecureContext function. */
1116                 ulR0 = pulCallerStackAddress[ 0 ];
1117
1118                 #if ( configENABLE_MPU == 1 )
1119                 {
1120                     /* Read the CONTROL register value. */
1121                     __asm volatile ( "mrs %0, control"  : "=r" ( ulControl ) );
1122
1123                     /* The task that raised the SVC is privileged if Bit[0]
1124                      * in the CONTROL register is 0. */
1125                     ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 );
1126
1127                     /* Allocate and load a context for the secure task. */
1128                     xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB );
1129                 }
1130                 #else /* if ( configENABLE_MPU == 1 ) */
1131                 {
1132                     /* Allocate and load a context for the secure task. */
1133                     xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB );
1134                 }
1135                 #endif /* configENABLE_MPU */
1136
1137                 configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID );
1138                 SecureContext_LoadContext( xSecureContext, pxCurrentTCB );
1139                 break;
1140
1141             case portSVC_FREE_SECURE_CONTEXT:
1142
1143                 /* R0 contains TCB being freed and R1 contains the secure
1144                  * context handle to be freed. */
1145                 ulR0 = pulCallerStackAddress[ 0 ];
1146                 ulR1 = pulCallerStackAddress[ 1 ];
1147
1148                 /* Free the secure context. */
1149                 SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 );
1150                 break;
1151         #endif /* configENABLE_TRUSTZONE */
1152
1153         case portSVC_START_SCHEDULER:
1154             #if ( configENABLE_TRUSTZONE == 1 )
1155             {
1156                 /* De-prioritize the non-secure exceptions so that the
1157                  * non-secure pendSV runs at the lowest priority. */
1158                 SecureInit_DePrioritizeNSExceptions();
1159
1160                 /* Initialize the secure context management system. */
1161                 SecureContext_Init();
1162             }
1163             #endif /* configENABLE_TRUSTZONE */
1164
1165             #if ( configENABLE_FPU == 1 )
1166             {
1167                 /* Setup the Floating Point Unit (FPU). */
1168                 prvSetupFPU();
1169             }
1170             #endif /* configENABLE_FPU */
1171
1172             /* Setup the context of the first task so that the first task starts
1173              * executing. */
1174             vRestoreContextOfFirstTask();
1175             break;
1176
1177             #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) )
1178                 case portSVC_RAISE_PRIVILEGE:
1179
1180                     /* Only raise the privilege, if the svc was raised from any of
1181                      * the system calls. */
1182                     if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) &&
1183                         ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) )
1184                     {
1185                         vRaisePrivilege();
1186                     }
1187                     break;
1188             #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */
1189
1190             #if ( configENABLE_MPU == 1 )
1191                 case portSVC_YIELD:
1192                     vPortYield();
1193                     break;
1194             #endif /* configENABLE_MPU == 1 */
1195
1196         default:
1197             /* Incorrect SVC call. */
1198             configASSERT( pdFALSE );
1199     }
1200 }
1201 /*-----------------------------------------------------------*/
1202
1203 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
1204
1205     void vSystemCallEnter( uint32_t * pulTaskStack,
1206                            uint32_t ulLR,
1207                            uint8_t ucSystemCallNumber ) /* PRIVILEGED_FUNCTION */
1208     {
1209         extern TaskHandle_t pxCurrentTCB;
1210         extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ];
1211         xMPU_SETTINGS * pxMpuSettings;
1212         uint32_t * pulSystemCallStack;
1213         uint32_t ulStackFrameSize, ulSystemCallLocation, i;
1214
1215         #if defined( __ARMCC_VERSION )
1216
1217             /* Declaration when these variable are defined in code instead of being
1218              * exported from linker scripts. */
1219             extern uint32_t * __syscalls_flash_start__;
1220             extern uint32_t * __syscalls_flash_end__;
1221         #else
1222             /* Declaration when these variable are exported from linker scripts. */
1223             extern uint32_t __syscalls_flash_start__[];
1224             extern uint32_t __syscalls_flash_end__[];
1225         #endif /* #if defined( __ARMCC_VERSION ) */
1226
1227         ulSystemCallLocation = pulTaskStack[ portOFFSET_TO_PC ];
1228         pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB );
1229
1230         /* Checks:
1231          * 1. SVC is raised from the system call section (i.e. application is
1232          *    not raising SVC directly).
1233          * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must be NULL as
1234          *    it is non-NULL only during the execution of a system call (i.e.
1235          *    between system call enter and exit).
1236          * 3. System call is not for a kernel API disabled by the configuration
1237          *    in FreeRTOSConfig.h.
1238          * 4. We do not need to check that ucSystemCallNumber is within range
1239          *    because the assembly SVC handler checks that before calling
1240          *    this function.
1241          */
1242         if( ( ulSystemCallLocation >= ( uint32_t ) __syscalls_flash_start__ ) &&
1243             ( ulSystemCallLocation <= ( uint32_t ) __syscalls_flash_end__ ) &&
1244             ( pxMpuSettings->xSystemCallStackInfo.pulTaskStack == NULL ) &&
1245             ( uxSystemCallImplementations[ ucSystemCallNumber ] != ( UBaseType_t ) 0 ) )
1246         {
1247             pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack;
1248
1249             #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
1250             {
1251                 if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
1252                 {
1253                     /* Extended frame i.e. FPU in use. */
1254                     ulStackFrameSize = 26;
1255                     __asm volatile (
1256                         " vpush {s0}         \n" /* Trigger lazy stacking. */
1257                         " vpop  {s0}         \n" /* Nullify the affect of the above instruction. */
1258                         ::: "memory"
1259                         );
1260                 }
1261                 else
1262                 {
1263                     /* Standard frame i.e. FPU not in use. */
1264                     ulStackFrameSize = 8;
1265                 }
1266             }
1267             #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
1268             {
1269                 ulStackFrameSize = 8;
1270             }
1271             #endif /* configENABLE_FPU || configENABLE_MVE */
1272
1273             /* Make space on the system call stack for the stack frame. */
1274             pulSystemCallStack = pulSystemCallStack - ulStackFrameSize;
1275
1276             /* Copy the stack frame. */
1277             for( i = 0; i < ulStackFrameSize; i++ )
1278             {
1279                 pulSystemCallStack[ i ] = pulTaskStack[ i ];
1280             }
1281
1282             /* Store the value of the Link Register before the SVC was raised.
1283              * It contains the address of the caller of the System Call entry
1284              * point (i.e. the caller of the MPU_<API>). We need to restore it
1285              * when we exit from the system call. */
1286             pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
1287
1288             /* Store the value of the PSPLIM register before the SVC was raised.
1289              * We need to restore it when we exit from the system call. */
1290             #if ( portUSE_PSPLIM_REGISTER == 1 )
1291             {
1292                 __asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1293             }
1294             #endif
1295
1296             /* Use the pulSystemCallStack in thread mode. */
1297             __asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) );
1298             #if ( portUSE_PSPLIM_REGISTER == 1 )
1299             {
1300                 __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) );
1301             }
1302             #endif
1303
1304             /* Start executing the system call upon returning from this handler. */
1305             pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
1306
1307             /* Raise a request to exit from the system call upon finishing the
1308              * system call. */
1309             pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
1310
1311             /* Remember the location where we should copy the stack frame when we exit from
1312              * the system call. */
1313             pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize;
1314
1315             /* Record if the hardware used padding to force the stack pointer
1316              * to be double word aligned. */
1317             if( ( pulTaskStack[ portOFFSET_TO_PSR ] & portPSR_STACK_PADDING_MASK ) == portPSR_STACK_PADDING_MASK )
1318             {
1319                 pxMpuSettings->ulTaskFlags |= portSTACK_FRAME_HAS_PADDING_FLAG;
1320             }
1321             else
1322             {
1323                 pxMpuSettings->ulTaskFlags &= ( ~portSTACK_FRAME_HAS_PADDING_FLAG );
1324             }
1325
1326             /* We ensure in pxPortInitialiseStack that the system call stack is
1327              * double word aligned and therefore, there is no need of padding.
1328              * Clear the bit[9] of stacked xPSR. */
1329             pulSystemCallStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK );
1330
1331             /* Raise the privilege for the duration of the system call. */
1332             __asm volatile (
1333                 " mrs r0, control     \n" /* Obtain current control value. */
1334                 " movs r1, #1         \n" /* r1 = 1. */
1335                 " bics r0, r1         \n" /* Clear nPRIV bit. */
1336                 " msr control, r0     \n" /* Write back new control value. */
1337                 ::: "r0", "r1", "memory"
1338                 );
1339         }
1340     }
1341
1342 #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
1343 /*-----------------------------------------------------------*/
1344
1345 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
1346
1347     void vRequestSystemCallExit( void ) /* __attribute__( ( naked ) ) PRIVILEGED_FUNCTION */
1348     {
1349         __asm volatile ( "svc %0 \n" ::"i" ( portSVC_SYSTEM_CALL_EXIT ) : "memory" );
1350     }
1351
1352 #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
1353 /*-----------------------------------------------------------*/
1354
1355 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
1356
1357     void vSystemCallExit( uint32_t * pulSystemCallStack,
1358                           uint32_t ulLR ) /* PRIVILEGED_FUNCTION */
1359     {
1360         extern TaskHandle_t pxCurrentTCB;
1361         xMPU_SETTINGS * pxMpuSettings;
1362         uint32_t * pulTaskStack;
1363         uint32_t ulStackFrameSize, ulSystemCallLocation, i;
1364
1365         #if defined( __ARMCC_VERSION )
1366
1367             /* Declaration when these variable are defined in code instead of being
1368              * exported from linker scripts. */
1369             extern uint32_t * __privileged_functions_start__;
1370             extern uint32_t * __privileged_functions_end__;
1371         #else
1372             /* Declaration when these variable are exported from linker scripts. */
1373             extern uint32_t __privileged_functions_start__[];
1374             extern uint32_t __privileged_functions_end__[];
1375         #endif /* #if defined( __ARMCC_VERSION ) */
1376
1377         ulSystemCallLocation = pulSystemCallStack[ portOFFSET_TO_PC ];
1378         pxMpuSettings = xTaskGetMPUSettings( pxCurrentTCB );
1379
1380         /* Checks:
1381          * 1. SVC is raised from the privileged code (i.e. application is not
1382          *    raising SVC directly). This SVC is only raised from
1383          *    vRequestSystemCallExit which is in the privileged code section.
1384          * 2. pxMpuSettings->xSystemCallStackInfo.pulTaskStack must not be NULL -
1385          *    this means that we previously entered a system call and the
1386          *    application is not attempting to exit without entering a system
1387          *    call.
1388          */
1389         if( ( ulSystemCallLocation >= ( uint32_t ) __privileged_functions_start__ ) &&
1390             ( ulSystemCallLocation <= ( uint32_t ) __privileged_functions_end__ ) &&
1391             ( pxMpuSettings->xSystemCallStackInfo.pulTaskStack != NULL ) )
1392         {
1393             pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack;
1394
1395             #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
1396             {
1397                 if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL )
1398                 {
1399                     /* Extended frame i.e. FPU in use. */
1400                     ulStackFrameSize = 26;
1401                     __asm volatile (
1402                         " vpush {s0}         \n" /* Trigger lazy stacking. */
1403                         " vpop  {s0}         \n" /* Nullify the affect of the above instruction. */
1404                         ::: "memory"
1405                         );
1406                 }
1407                 else
1408                 {
1409                     /* Standard frame i.e. FPU not in use. */
1410                     ulStackFrameSize = 8;
1411                 }
1412             }
1413             #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
1414             {
1415                 ulStackFrameSize = 8;
1416             }
1417             #endif /* configENABLE_FPU || configENABLE_MVE */
1418
1419             /* Make space on the task stack for the stack frame. */
1420             pulTaskStack = pulTaskStack - ulStackFrameSize;
1421
1422             /* Copy the stack frame. */
1423             for( i = 0; i < ulStackFrameSize; i++ )
1424             {
1425                 pulTaskStack[ i ] = pulSystemCallStack[ i ];
1426             }
1427
1428             /* Use the pulTaskStack in thread mode. */
1429             __asm volatile ( "msr psp, %0" : : "r" ( pulTaskStack ) );
1430
1431             /* Return to the caller of the System Call entry point (i.e. the
1432              * caller of the MPU_<API>). */
1433             pulTaskStack[ portOFFSET_TO_PC ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry;
1434             /* Ensure that LR has a valid value.*/
1435             pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry;
1436
1437             /* Restore the PSPLIM register to what it was at the time of
1438              * system call entry. */
1439             #if ( portUSE_PSPLIM_REGISTER == 1 )
1440             {
1441                 __asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1442             }
1443             #endif
1444
1445             /* If the hardware used padding to force the stack pointer
1446              * to be double word aligned, set the stacked xPSR bit[9],
1447              * otherwise clear it. */
1448             if( ( pxMpuSettings->ulTaskFlags & portSTACK_FRAME_HAS_PADDING_FLAG ) == portSTACK_FRAME_HAS_PADDING_FLAG )
1449             {
1450                 pulTaskStack[ portOFFSET_TO_PSR ] |= portPSR_STACK_PADDING_MASK;
1451             }
1452             else
1453             {
1454                 pulTaskStack[ portOFFSET_TO_PSR ] &= ( ~portPSR_STACK_PADDING_MASK );
1455             }
1456
1457             /* This is not NULL only for the duration of the system call. */
1458             pxMpuSettings->xSystemCallStackInfo.pulTaskStack = NULL;
1459
1460             /* Drop the privilege before returning to the thread mode. */
1461             __asm volatile (
1462                 " mrs r0, control     \n" /* Obtain current control value. */
1463                 " movs r1, #1         \n" /* r1 = 1. */
1464                 " orrs r0, r1         \n" /* Set nPRIV bit. */
1465                 " msr control, r0     \n" /* Write back new control value. */
1466                 ::: "r0", "r1", "memory"
1467                 );
1468         }
1469     }
1470
1471 #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
1472 /*-----------------------------------------------------------*/
1473
1474 #if ( configENABLE_MPU == 1 )
1475
1476     BaseType_t xPortIsTaskPrivileged( void ) /* PRIVILEGED_FUNCTION */
1477     {
1478         BaseType_t xTaskIsPrivileged = pdFALSE;
1479         const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
1480
1481         if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
1482         {
1483             xTaskIsPrivileged = pdTRUE;
1484         }
1485
1486         return xTaskIsPrivileged;
1487     }
1488
1489 #endif /* configENABLE_MPU == 1 */
1490 /*-----------------------------------------------------------*/
1491
1492 #if ( configENABLE_MPU == 1 )
1493
1494     StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
1495                                          StackType_t * pxEndOfStack,
1496                                          TaskFunction_t pxCode,
1497                                          void * pvParameters,
1498                                          BaseType_t xRunPrivileged,
1499                                          xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */
1500     {
1501         uint32_t ulIndex = 0;
1502         uint32_t ulControl = 0x0;
1503
1504         xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */
1505         ulIndex++;
1506         xMPUSettings->ulContext[ ulIndex ] = 0x05050505; /* r5. */
1507         ulIndex++;
1508         xMPUSettings->ulContext[ ulIndex ] = 0x06060606; /* r6. */
1509         ulIndex++;
1510         xMPUSettings->ulContext[ ulIndex ] = 0x07070707; /* r7. */
1511         ulIndex++;
1512         xMPUSettings->ulContext[ ulIndex ] = 0x08080808; /* r8. */
1513         ulIndex++;
1514         xMPUSettings->ulContext[ ulIndex ] = 0x09090909; /* r9. */
1515         ulIndex++;
1516         xMPUSettings->ulContext[ ulIndex ] = 0x10101010; /* r10. */
1517         ulIndex++;
1518         xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */
1519         ulIndex++;
1520
1521         xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters;            /* r0. */
1522         ulIndex++;
1523         xMPUSettings->ulContext[ ulIndex ] = 0x01010101;                           /* r1. */
1524         ulIndex++;
1525         xMPUSettings->ulContext[ ulIndex ] = 0x02020202;                           /* r2. */
1526         ulIndex++;
1527         xMPUSettings->ulContext[ ulIndex ] = 0x03030303;                           /* r3. */
1528         ulIndex++;
1529         xMPUSettings->ulContext[ ulIndex ] = 0x12121212;                           /* r12. */
1530         ulIndex++;
1531         xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */
1532         ulIndex++;
1533         xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode;                  /* PC. */
1534         ulIndex++;
1535         xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR;                     /* xPSR. */
1536         ulIndex++;
1537
1538         #if ( configENABLE_TRUSTZONE == 1 )
1539         {
1540             xMPUSettings->ulContext[ ulIndex ] = portNO_SECURE_CONTEXT; /* xSecureContext. */
1541             ulIndex++;
1542         }
1543         #endif /* configENABLE_TRUSTZONE */
1544         xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */
1545         ulIndex++;
1546         xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack;         /* PSPLIM. */
1547         ulIndex++;
1548
1549         #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
1550         {
1551             /* Check PACBTI security feature configuration before pushing the
1552              * CONTROL register's value on task's TCB. */
1553             ulControl = prvConfigurePACBTI( pdFALSE );
1554         }
1555         #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
1556
1557         if( xRunPrivileged == pdTRUE )
1558         {
1559             xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG;
1560             xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */
1561             ulIndex++;
1562         }
1563         else
1564         {
1565             xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG );
1566             xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */
1567             ulIndex++;
1568         }
1569
1570         xMPUSettings->ulContext[ ulIndex ] = portINITIAL_EXC_RETURN; /* LR (EXC_RETURN). */
1571         ulIndex++;
1572
1573         #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
1574         {
1575             /* Ensure that the system call stack is double word aligned. */
1576             xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE - 1 ] );
1577             xMPUSettings->xSystemCallStackInfo.pulSystemCallStack = ( uint32_t * ) ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStack ) &
1578                                                                                      ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) );
1579
1580             xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = &( xMPUSettings->xSystemCallStackInfo.ulSystemCallStackBuffer[ 0 ] );
1581             xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit = ( uint32_t * ) ( ( ( uint32_t ) ( xMPUSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) +
1582                                                                                             ( uint32_t ) ( portBYTE_ALIGNMENT - 1 ) ) &
1583                                                                                           ( uint32_t ) ( ~( portBYTE_ALIGNMENT_MASK ) ) );
1584
1585             /* This is not NULL only for the duration of a system call. */
1586             xMPUSettings->xSystemCallStackInfo.pulTaskStack = NULL;
1587         }
1588         #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
1589
1590         #if ( configENABLE_PAC == 1 )
1591         {
1592             uint32_t ulTaskPacKey[ 4 ], i;
1593
1594             vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) );
1595
1596             for( i = 0; i < 4; i++ )
1597             {
1598                 xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ];
1599                 ulIndex++;
1600             }
1601         }
1602         #endif /* configENABLE_PAC */
1603
1604         return &( xMPUSettings->ulContext[ ulIndex ] );
1605     }
1606
1607 #else /* configENABLE_MPU */
1608
1609     StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
1610                                          StackType_t * pxEndOfStack,
1611                                          TaskFunction_t pxCode,
1612                                          void * pvParameters ) /* PRIVILEGED_FUNCTION */
1613     {
1614         /* Simulate the stack frame as it would be created by a context switch
1615          * interrupt. */
1616         #if ( portPRELOAD_REGISTERS == 0 )
1617         {
1618             pxTopOfStack--;                                          /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
1619             *pxTopOfStack = portINITIAL_XPSR;                        /* xPSR. */
1620             pxTopOfStack--;
1621             *pxTopOfStack = ( StackType_t ) pxCode;                  /* PC. */
1622             pxTopOfStack--;
1623             *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */
1624             pxTopOfStack -= 5;                                       /* R12, R3, R2 and R1. */
1625             *pxTopOfStack = ( StackType_t ) pvParameters;            /* R0. */
1626             pxTopOfStack -= 9;                                       /* R11..R4, EXC_RETURN. */
1627             *pxTopOfStack = portINITIAL_EXC_RETURN;
1628             pxTopOfStack--;
1629             *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */
1630
1631             #if ( configENABLE_TRUSTZONE == 1 )
1632             {
1633                 pxTopOfStack--;
1634                 *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
1635             }
1636             #endif /* configENABLE_TRUSTZONE */
1637         }
1638         #else /* portPRELOAD_REGISTERS */
1639         {
1640             pxTopOfStack--;                                          /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
1641             *pxTopOfStack = portINITIAL_XPSR;                        /* xPSR. */
1642             pxTopOfStack--;
1643             *pxTopOfStack = ( StackType_t ) pxCode;                  /* PC. */
1644             pxTopOfStack--;
1645             *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */
1646             pxTopOfStack--;
1647             *pxTopOfStack = ( StackType_t ) 0x12121212UL;            /* R12. */
1648             pxTopOfStack--;
1649             *pxTopOfStack = ( StackType_t ) 0x03030303UL;            /* R3. */
1650             pxTopOfStack--;
1651             *pxTopOfStack = ( StackType_t ) 0x02020202UL;            /* R2. */
1652             pxTopOfStack--;
1653             *pxTopOfStack = ( StackType_t ) 0x01010101UL;            /* R1. */
1654             pxTopOfStack--;
1655             *pxTopOfStack = ( StackType_t ) pvParameters;            /* R0. */
1656             pxTopOfStack--;
1657             *pxTopOfStack = ( StackType_t ) 0x11111111UL;            /* R11. */
1658             pxTopOfStack--;
1659             *pxTopOfStack = ( StackType_t ) 0x10101010UL;            /* R10. */
1660             pxTopOfStack--;
1661             *pxTopOfStack = ( StackType_t ) 0x09090909UL;            /* R09. */
1662             pxTopOfStack--;
1663             *pxTopOfStack = ( StackType_t ) 0x08080808UL;            /* R08. */
1664             pxTopOfStack--;
1665             *pxTopOfStack = ( StackType_t ) 0x07070707UL;            /* R07. */
1666             pxTopOfStack--;
1667             *pxTopOfStack = ( StackType_t ) 0x06060606UL;            /* R06. */
1668             pxTopOfStack--;
1669             *pxTopOfStack = ( StackType_t ) 0x05050505UL;            /* R05. */
1670             pxTopOfStack--;
1671             *pxTopOfStack = ( StackType_t ) 0x04040404UL;            /* R04. */
1672             pxTopOfStack--;
1673             *pxTopOfStack = portINITIAL_EXC_RETURN;                  /* EXC_RETURN. */
1674             pxTopOfStack--;
1675             *pxTopOfStack = ( StackType_t ) pxEndOfStack;            /* Slot used to hold this task's PSPLIM value. */
1676
1677             #if ( configENABLE_TRUSTZONE == 1 )
1678             {
1679                 pxTopOfStack--;
1680                 *pxTopOfStack = portNO_SECURE_CONTEXT; /* Slot used to hold this task's xSecureContext value. */
1681             }
1682             #endif /* configENABLE_TRUSTZONE */
1683         }
1684         #endif /* portPRELOAD_REGISTERS */
1685
1686         #if ( configENABLE_PAC == 1 )
1687         {
1688             uint32_t ulTaskPacKey[ 4 ], i;
1689
1690             vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) );
1691
1692             for( i = 0; i < 4; i++ )
1693             {
1694                 pxTopOfStack--;
1695                 *pxTopOfStack = ulTaskPacKey[ i ];
1696             }
1697         }
1698         #endif /* configENABLE_PAC */
1699
1700         return pxTopOfStack;
1701     }
1702
1703 #endif /* configENABLE_MPU */
1704 /*-----------------------------------------------------------*/
1705
1706 BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
1707 {
1708     /* An application can install FreeRTOS interrupt handlers in one of the
1709      * following ways:
1710      * 1. Direct Routing - Install the functions SVC_Handler and PendSV_Handler
1711      *    for SVCall and PendSV interrupts respectively.
1712      * 2. Indirect Routing - Install separate handlers for SVCall and PendSV
1713      *    interrupts and route program control from those handlers to
1714      *    SVC_Handler and PendSV_Handler functions.
1715      *
1716      * Applications that use Indirect Routing must set
1717      * configCHECK_HANDLER_INSTALLATION to 0 in their FreeRTOSConfig.h. Direct
1718      * routing, which is validated here when configCHECK_HANDLER_INSTALLATION
1719      * is 1, should be preferred when possible. */
1720     #if ( configCHECK_HANDLER_INSTALLATION == 1 )
1721     {
1722         const portISR_t * const pxVectorTable = portSCB_VTOR_REG;
1723
1724         /* Validate that the application has correctly installed the FreeRTOS
1725          * handlers for SVCall and PendSV interrupts. We do not check the
1726          * installation of the SysTick handler because the application may
1727          * choose to drive the RTOS tick using a timer other than the SysTick
1728          * timer by overriding the weak function vPortSetupTimerInterrupt().
1729          *
1730          * Assertion failures here indicate incorrect installation of the
1731          * FreeRTOS handlers. For help installing the FreeRTOS handlers, see
1732          * https://www.freertos.org/Why-FreeRTOS/FAQs.
1733          *
1734          * Systems with a configurable address for the interrupt vector table
1735          * can also encounter assertion failures or even system faults here if
1736          * VTOR is not set correctly to point to the application's vector table. */
1737         configASSERT( pxVectorTable[ portVECTOR_INDEX_SVC ] == SVC_Handler );
1738         configASSERT( pxVectorTable[ portVECTOR_INDEX_PENDSV ] == PendSV_Handler );
1739     }
1740     #endif /* configCHECK_HANDLER_INSTALLATION */
1741
1742     #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
1743     {
1744         volatile uint32_t ulImplementedPrioBits = 0;
1745         volatile uint8_t ucMaxPriorityValue;
1746
1747         /* Determine the maximum priority from which ISR safe FreeRTOS API
1748          * functions can be called. ISR safe functions are those that end in
1749          * "FromISR". FreeRTOS maintains separate thread and ISR API functions to
1750          * ensure interrupt entry is as fast and simple as possible.
1751          *
1752          * First, determine the number of priority bits available. Write to all
1753          * possible bits in the priority setting for SVCall. */
1754         portNVIC_SHPR2_REG = 0xFF000000;
1755
1756         /* Read the value back to see how many bits stuck. */
1757         ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 );
1758
1759         /* Use the same mask on the maximum system call priority. */
1760         ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
1761
1762         /* Check that the maximum system call priority is nonzero after
1763          * accounting for the number of priority bits supported by the
1764          * hardware. A priority of 0 is invalid because setting the BASEPRI
1765          * register to 0 unmasks all interrupts, and interrupts with priority 0
1766          * cannot be masked using BASEPRI.
1767          * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
1768         configASSERT( ucMaxSysCallPriority );
1769
1770         /* Check that the bits not implemented in hardware are zero in
1771          * configMAX_SYSCALL_INTERRUPT_PRIORITY. */
1772         configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U );
1773
1774         /* Calculate the maximum acceptable priority group value for the number
1775          * of bits read back. */
1776         while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
1777         {
1778             ulImplementedPrioBits++;
1779             ucMaxPriorityValue <<= ( uint8_t ) 0x01;
1780         }
1781
1782         if( ulImplementedPrioBits == 8 )
1783         {
1784             /* When the hardware implements 8 priority bits, there is no way for
1785              * the software to configure PRIGROUP to not have sub-priorities. As
1786              * a result, the least significant bit is always used for sub-priority
1787              * and there are 128 preemption priorities and 2 sub-priorities.
1788              *
1789              * This may cause some confusion in some cases - for example, if
1790              * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4
1791              * priority interrupts will be masked in Critical Sections as those
1792              * are at the same preemption priority. This may appear confusing as
1793              * 4 is higher (numerically lower) priority than
1794              * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not
1795              * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY
1796              * to 4, this confusion does not happen and the behaviour remains the same.
1797              *
1798              * The following assert ensures that the sub-priority bit in the
1799              * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned
1800              * confusion. */
1801             configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U );
1802             ulMaxPRIGROUPValue = 0;
1803         }
1804         else
1805         {
1806             ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits;
1807         }
1808
1809         /* Shift the priority group value back to its position within the AIRCR
1810          * register. */
1811         ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
1812         ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
1813     }
1814     #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
1815
1816     /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall
1817      * the highest priority. */
1818     portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;
1819     portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
1820     portNVIC_SHPR2_REG = 0;
1821
1822     #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
1823     {
1824         /* Set the CONTROL register value based on PACBTI security feature
1825          * configuration before starting the first task. */
1826         ( void ) prvConfigurePACBTI( pdTRUE );
1827     }
1828     #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
1829
1830     #if ( configENABLE_MPU == 1 )
1831     {
1832         /* Setup the Memory Protection Unit (MPU). */
1833         prvSetupMPU();
1834     }
1835     #endif /* configENABLE_MPU */
1836
1837     /* Start the timer that generates the tick ISR. Interrupts are disabled
1838      * here already. */
1839     vPortSetupTimerInterrupt();
1840
1841     /* Initialize the critical nesting count ready for the first task. */
1842     ulCriticalNesting = 0;
1843
1844     #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
1845     {
1846         xSchedulerRunning = pdTRUE;
1847     }
1848     #endif /* ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */
1849
1850     /* Start the first task. */
1851     vStartFirstTask();
1852
1853     /* Should never get here as the tasks will now be executing. Call the task
1854      * exit error function to prevent compiler warnings about a static function
1855      * not being called in the case that the application writer overrides this
1856      * functionality by defining configTASK_RETURN_ADDRESS. Call
1857      * vTaskSwitchContext() so link time optimization does not remove the
1858      * symbol. */
1859     vTaskSwitchContext();
1860     prvTaskExitError();
1861
1862     /* Should not get here. */
1863     return 0;
1864 }
1865 /*-----------------------------------------------------------*/
1866
1867 void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
1868 {
1869     /* Not implemented in ports where there is nothing to return to.
1870      * Artificially force an assert. */
1871     configASSERT( ulCriticalNesting == 1000UL );
1872 }
1873 /*-----------------------------------------------------------*/
1874
1875 #if ( configENABLE_MPU == 1 )
1876
1877     void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
1878                                     const struct xMEMORY_REGION * const xRegions,
1879                                     StackType_t * pxBottomOfStack,
1880                                     configSTACK_DEPTH_TYPE uxStackDepth )
1881     {
1882         uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
1883         int32_t lIndex = 0;
1884
1885         #if defined( __ARMCC_VERSION )
1886
1887             /* Declaration when these variable are defined in code instead of being
1888              * exported from linker scripts. */
1889             extern uint32_t * __privileged_sram_start__;
1890             extern uint32_t * __privileged_sram_end__;
1891         #else
1892             /* Declaration when these variable are exported from linker scripts. */
1893             extern uint32_t __privileged_sram_start__[];
1894             extern uint32_t __privileged_sram_end__[];
1895         #endif /* defined( __ARMCC_VERSION ) */
1896
1897         /* Setup MAIR0. */
1898         xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
1899         xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK );
1900
1901         /* This function is called automatically when the task is created - in
1902          * which case the stack region parameters will be valid.  At all other
1903          * times the stack parameters will not be valid and it is assumed that
1904          * the stack region has already been configured. */
1905         if( uxStackDepth > 0 )
1906         {
1907             ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;
1908             ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( uxStackDepth * ( configSTACK_DEPTH_TYPE ) sizeof( StackType_t ) ) - 1;
1909
1910             /* If the stack is within the privileged SRAM, do not protect it
1911              * using a separate MPU region. This is needed because privileged
1912              * SRAM is already protected using an MPU region and ARMv8-M does
1913              * not allow overlapping MPU regions. */
1914             if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) &&
1915                 ( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) )
1916             {
1917                 xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
1918                 xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
1919             }
1920             else
1921             {
1922                 /* Define the region that allows access to the stack. */
1923                 ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;
1924                 ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;
1925
1926                 xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |
1927                                                              ( portMPU_REGION_NON_SHAREABLE ) |
1928                                                              ( portMPU_REGION_READ_WRITE ) |
1929                                                              ( portMPU_REGION_EXECUTE_NEVER );
1930
1931                 xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |
1932                                                              ( portMPU_RLAR_ATTR_INDEX0 ) |
1933                                                              ( portMPU_RLAR_REGION_ENABLE );
1934             }
1935         }
1936
1937         /* User supplied configurable regions. */
1938         for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ )
1939         {
1940             /* If xRegions is NULL i.e. the task has not specified any MPU
1941              * region, the else part ensures that all the configurable MPU
1942              * regions are invalidated. */
1943             if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) )
1944             {
1945                 /* Translate the generic region definition contained in xRegions
1946                  * into the ARMv8 specific MPU settings that are then stored in
1947                  * xMPUSettings. */
1948                 ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK;
1949                 ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1;
1950                 ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;
1951
1952                 /* Start address. */
1953                 xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) |
1954                                                                           ( portMPU_REGION_NON_SHAREABLE );
1955
1956                 /* RO/RW. */
1957                 if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 )
1958                 {
1959                     xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY );
1960                 }
1961                 else
1962                 {
1963                     xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE );
1964                 }
1965
1966                 /* XN. */
1967                 if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 )
1968                 {
1969                     xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER );
1970                 }
1971
1972                 /* End Address. */
1973                 xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) |
1974                                                                           ( portMPU_RLAR_REGION_ENABLE );
1975
1976                 /* PXN. */
1977                 #if ( portARMV8M_MINOR_VERSION >= 1 )
1978                 {
1979                     if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 )
1980                     {
1981                         xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER );
1982                     }
1983                 }
1984                 #endif /* portARMV8M_MINOR_VERSION >= 1 */
1985
1986                 /* Normal memory/ Device memory. */
1987                 if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 )
1988                 {
1989                     /* Attr1 in MAIR0 is configured as device memory. */
1990                     xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1;
1991                 }
1992                 else
1993                 {
1994                     /* Attr0 in MAIR0 is configured as normal memory. */
1995                     xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0;
1996                 }
1997             }
1998             else
1999             {
2000                 /* Invalidate the region. */
2001                 xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL;
2002                 xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL;
2003             }
2004
2005             lIndex++;
2006         }
2007     }
2008
2009 #endif /* configENABLE_MPU */
2010 /*-----------------------------------------------------------*/
2011
2012 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
2013
2014     BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
2015                                                 uint32_t ulBufferLength,
2016                                                 uint32_t ulAccessRequested ) /* PRIVILEGED_FUNCTION */
2017
2018     {
2019         uint32_t i, ulBufferStartAddress, ulBufferEndAddress;
2020         BaseType_t xAccessGranted = pdFALSE;
2021         const xMPU_SETTINGS * xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
2022
2023         if( xSchedulerRunning == pdFALSE )
2024         {
2025             /* Grant access to all the kernel objects before the scheduler
2026              * is started. It is necessary because there is no task running
2027              * yet and therefore, we cannot use the permissions of any
2028              * task. */
2029             xAccessGranted = pdTRUE;
2030         }
2031         else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
2032         {
2033             xAccessGranted = pdTRUE;
2034         }
2035         else
2036         {
2037             if( portADD_UINT32_WILL_OVERFLOW( ( ( uint32_t ) pvBuffer ), ( ulBufferLength - 1UL ) ) == pdFALSE )
2038             {
2039                 ulBufferStartAddress = ( uint32_t ) pvBuffer;
2040                 ulBufferEndAddress = ( ( ( uint32_t ) pvBuffer ) + ulBufferLength - 1UL );
2041
2042                 for( i = 0; i < portTOTAL_NUM_REGIONS; i++ )
2043                 {
2044                     /* Is the MPU region enabled? */
2045                     if( ( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR & portMPU_RLAR_REGION_ENABLE ) == portMPU_RLAR_REGION_ENABLE )
2046                     {
2047                         if( portIS_ADDRESS_WITHIN_RANGE( ulBufferStartAddress,
2048                                                          portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ),
2049                                                          portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) &&
2050                             portIS_ADDRESS_WITHIN_RANGE( ulBufferEndAddress,
2051                                                          portEXTRACT_FIRST_ADDRESS_FROM_RBAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ),
2052                                                          portEXTRACT_LAST_ADDRESS_FROM_RLAR( xTaskMpuSettings->xRegionsSettings[ i ].ulRLAR ) ) &&
2053                             portIS_AUTHORIZED( ulAccessRequested,
2054                                                prvGetRegionAccessPermissions( xTaskMpuSettings->xRegionsSettings[ i ].ulRBAR ) ) )
2055                         {
2056                             xAccessGranted = pdTRUE;
2057                             break;
2058                         }
2059                     }
2060                 }
2061             }
2062         }
2063
2064         return xAccessGranted;
2065     }
2066
2067 #endif /* #if ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
2068 /*-----------------------------------------------------------*/
2069
2070 BaseType_t xPortIsInsideInterrupt( void )
2071 {
2072     uint32_t ulCurrentInterrupt;
2073     BaseType_t xReturn;
2074
2075     /* Obtain the number of the currently executing interrupt. Interrupt Program
2076      * Status Register (IPSR) holds the exception number of the currently-executing
2077      * exception or zero for Thread mode.*/
2078     __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
2079
2080     if( ulCurrentInterrupt == 0 )
2081     {
2082         xReturn = pdFALSE;
2083     }
2084     else
2085     {
2086         xReturn = pdTRUE;
2087     }
2088
2089     return xReturn;
2090 }
2091 /*-----------------------------------------------------------*/
2092
2093 #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) )
2094
2095     void vPortValidateInterruptPriority( void )
2096     {
2097         uint32_t ulCurrentInterrupt;
2098         uint8_t ucCurrentPriority;
2099
2100         /* Obtain the number of the currently executing interrupt. */
2101         __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
2102
2103         /* Is the interrupt number a user defined interrupt? */
2104         if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
2105         {
2106             /* Look up the interrupt's priority. */
2107             ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
2108
2109             /* The following assertion will fail if a service routine (ISR) for
2110              * an interrupt that has been assigned a priority above
2111              * configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
2112              * function.  ISR safe FreeRTOS API functions must *only* be called
2113              * from interrupts that have been assigned a priority at or below
2114              * configMAX_SYSCALL_INTERRUPT_PRIORITY.
2115              *
2116              * Numerically low interrupt priority numbers represent logically high
2117              * interrupt priorities, therefore the priority of the interrupt must
2118              * be set to a value equal to or numerically *higher* than
2119              * configMAX_SYSCALL_INTERRUPT_PRIORITY.
2120              *
2121              * Interrupts that  use the FreeRTOS API must not be left at their
2122              * default priority of  zero as that is the highest possible priority,
2123              * which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
2124              * and  therefore also guaranteed to be invalid.
2125              *
2126              * FreeRTOS maintains separate thread and ISR API functions to ensure
2127              * interrupt entry is as fast and simple as possible.
2128              *
2129              * The following links provide detailed information:
2130              * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html
2131              * https://www.freertos.org/Why-FreeRTOS/FAQs */
2132             configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
2133         }
2134
2135         /* Priority grouping:  The interrupt controller (NVIC) allows the bits
2136          * that define each interrupt's priority to be split between bits that
2137          * define the interrupt's pre-emption priority bits and bits that define
2138          * the interrupt's sub-priority.  For simplicity all bits must be defined
2139          * to be pre-emption priority bits.  The following assertion will fail if
2140          * this is not the case (if some bits represent a sub-priority).
2141          *
2142          * If the application only uses CMSIS libraries for interrupt
2143          * configuration then the correct setting can be achieved on all Cortex-M
2144          * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
2145          * scheduler.  Note however that some vendor specific peripheral libraries
2146          * assume a non-zero priority group setting, in which cases using a value
2147          * of zero will result in unpredictable behaviour. */
2148         configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
2149     }
2150
2151 #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */
2152 /*-----------------------------------------------------------*/
2153
2154 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
2155
2156     void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
2157                                          int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
2158     {
2159         uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
2160         xMPU_SETTINGS * xTaskMpuSettings;
2161
2162         ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
2163         ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
2164
2165         xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
2166
2167         xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit );
2168     }
2169
2170 #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
2171 /*-----------------------------------------------------------*/
2172
2173 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
2174
2175     void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle,
2176                                           int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
2177     {
2178         uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
2179         xMPU_SETTINGS * xTaskMpuSettings;
2180
2181         ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
2182         ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
2183
2184         xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle );
2185
2186         xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit );
2187     }
2188
2189 #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
2190 /*-----------------------------------------------------------*/
2191
2192 #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
2193
2194     #if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
2195
2196         BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
2197         {
2198             uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit;
2199             BaseType_t xAccessGranted = pdFALSE;
2200             const xMPU_SETTINGS * xTaskMpuSettings;
2201
2202             if( xSchedulerRunning == pdFALSE )
2203             {
2204                 /* Grant access to all the kernel objects before the scheduler
2205                  * is started. It is necessary because there is no task running
2206                  * yet and therefore, we cannot use the permissions of any
2207                  * task. */
2208                 xAccessGranted = pdTRUE;
2209             }
2210             else
2211             {
2212                 xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */
2213
2214                 ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS );
2215                 ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS );
2216
2217                 if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG )
2218                 {
2219                     xAccessGranted = pdTRUE;
2220                 }
2221                 else
2222                 {
2223                     if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 )
2224                     {
2225                         xAccessGranted = pdTRUE;
2226                     }
2227                 }
2228             }
2229
2230             return xAccessGranted;
2231         }
2232
2233     #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
2234
2235         BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */
2236         {
2237             ( void ) lInternalIndexOfKernelObject;
2238
2239             /* If Access Control List feature is not used, all the tasks have
2240              * access to all the kernel objects. */
2241             return pdTRUE;
2242         }
2243
2244     #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */
2245
2246 #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */
2247 /*-----------------------------------------------------------*/
2248
2249 #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
2250
2251     static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
2252     {
2253         uint32_t ulControl = 0x0;
2254
2255         /* Ensure that PACBTI is implemented. */
2256         configASSERT( portID_ISAR5_REG != 0x0 );
2257
2258         /* Enable UsageFault exception. */
2259         portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT;
2260
2261         #if ( configENABLE_PAC == 1 )
2262         {
2263             ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
2264         }
2265         #endif
2266
2267         #if ( configENABLE_BTI == 1 )
2268         {
2269             ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
2270         }
2271         #endif
2272
2273         if( xWriteControlRegister == pdTRUE )
2274         {
2275             __asm volatile ( "msr control, %0" : : "r" ( ulControl ) );
2276         }
2277
2278         return ulControl;
2279     }
2280
2281 #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
2282 /*-----------------------------------------------------------*/