mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-06 13:15:19 -05:00
Merge 624e0e20a2 into fed39c5ea7
This commit is contained in:
commit
279b95fd94
50 changed files with 24116 additions and 27 deletions
|
|
@ -76,6 +76,10 @@ if(NOT FREERTOS_PORT)
|
||||||
" GCC_ARM_CM35P_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-secure\n"
|
" GCC_ARM_CM35P_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-secure\n"
|
||||||
" GCC_ARM_CM35P_SECURE - Compiler: GCC Target: ARM Cortex-M35P secure\n"
|
" GCC_ARM_CM35P_SECURE - Compiler: GCC Target: ARM Cortex-M35P secure\n"
|
||||||
" GCC_ARM_CM35P_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-trustzone non-secure\n"
|
" GCC_ARM_CM35P_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M35P non-trustzone non-secure\n"
|
||||||
|
" GCC_ARM_CM52_NONSECURE - Compiler: GCC Target: ARM Cortex-M52 non-secure\n"
|
||||||
|
" GCC_ARM_CM52_SECURE - Compiler: GCC Target: ARM Cortex-M52 secure\n"
|
||||||
|
" GCC_ARM_CM52_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M52 non-trustzone non-secure\n"
|
||||||
|
" GCC_ARM_CM52_TFM - Compiler: GCC Target: ARM Cortex-M52 non-secure for TF-M\n"
|
||||||
" GCC_ARM_CM55_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-secure\n"
|
" GCC_ARM_CM55_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-secure\n"
|
||||||
" GCC_ARM_CM55_SECURE - Compiler: GCC Target: ARM Cortex-M55 secure\n"
|
" GCC_ARM_CM55_SECURE - Compiler: GCC Target: ARM Cortex-M55 secure\n"
|
||||||
" GCC_ARM_CM55_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-trustzone non-secure\n"
|
" GCC_ARM_CM55_NTZ_NONSECURE - Compiler: GCC Target: ARM Cortex-M55 non-trustzone non-secure\n"
|
||||||
|
|
@ -143,6 +147,10 @@ if(NOT FREERTOS_PORT)
|
||||||
" IAR_ARM_CM35P_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-secure\n"
|
" IAR_ARM_CM35P_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-secure\n"
|
||||||
" IAR_ARM_CM35P_SECURE - Compiler: IAR Target: ARM Cortex-M35P secure\n"
|
" IAR_ARM_CM35P_SECURE - Compiler: IAR Target: ARM Cortex-M35P secure\n"
|
||||||
" IAR_ARM_CM35P_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-trustzone non-secure\n"
|
" IAR_ARM_CM35P_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-trustzone non-secure\n"
|
||||||
|
" IAR_ARM_CM52_NONSECURE - Compiler: IAR Target: ARM Cortex-M52 non-secure\n"
|
||||||
|
" IAR_ARM_CM52_SECURE - Compiler: IAR Target: ARM Cortex-M52 secure\n"
|
||||||
|
" IAR_ARM_CM52_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M52 non-trustzone non-secure\n"
|
||||||
|
" IAR_ARM_CM52_TFM - Compiler: IAR Target: ARM Cortex-M52 non-secure for TF-M\n"
|
||||||
" IAR_ARM_CM55_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-secure\n"
|
" IAR_ARM_CM55_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-secure\n"
|
||||||
" IAR_ARM_CM55_SECURE - Compiler: IAR Target: ARM Cortex-M55 secure\n"
|
" IAR_ARM_CM55_SECURE - Compiler: IAR Target: ARM Cortex-M55 secure\n"
|
||||||
" IAR_ARM_CM55_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n"
|
" IAR_ARM_CM55_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n"
|
||||||
|
|
|
||||||
|
|
@ -602,10 +602,10 @@
|
||||||
|
|
||||||
/* Set configENABLE_MVE to 1 to enable the M-Profile Vector Extension (MVE)
|
/* Set configENABLE_MVE to 1 to enable the M-Profile Vector Extension (MVE)
|
||||||
* support, or 0 to leave the MVE support disabled. This option is only
|
* support, or 0 to leave the MVE support disabled. This option is only
|
||||||
* applicable to Cortex-M55 and Cortex-M85 ports as M-Profile Vector Extension
|
* applicable to Cortex-M52, Cortex-M55 and Cortex-M85 ports as M-Profile
|
||||||
* (MVE) is available only on these architectures. configENABLE_MVE must be left
|
* Vector Extension (MVE) is available only on these architectures.
|
||||||
* undefined, or defined to 0 for the Cortex-M23,Cortex-M33 and Cortex-M35P
|
* configENABLE_MVE must be left undefined, or defined to 0 for the
|
||||||
* ports. */
|
* Cortex-M23,Cortex-M33 and Cortex-M35P ports. */
|
||||||
#define configENABLE_MVE 1
|
#define configENABLE_MVE 1
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
||||||
Armv8.1-M ports.
|
Armv8.1-M ports.
|
||||||
Do not use the files located here! These file are copied into separate
|
Do not use the files located here! These file are copied into separate
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to each
|
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85]_NNN directories prior to each
|
||||||
FreeRTOS release.
|
FreeRTOS release.
|
||||||
|
|
||||||
If your Armv8-M and Armv8.1-M application uses TrustZone then use the files from the
|
If your Armv8-M and Armv8.1-M application uses TrustZone then use the files from the
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories.
|
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85] directories.
|
||||||
|
|
||||||
If your Armv8-M and Armv8.1-M application does not use TrustZone then use the files from
|
If your Armv8-M and Armv8.1-M application does not use TrustZone then use the files from
|
||||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories.
|
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85]_NTZ directories.
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ _THIS_FILE_DIRECTORY_ = os.path.dirname(os.path.realpath(__file__))
|
||||||
_FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_)
|
_FREERTOS_PORTABLE_DIRECTORY_ = os.path.dirname(_THIS_FILE_DIRECTORY_)
|
||||||
|
|
||||||
_COMPILERS_ = ['GCC', 'IAR']
|
_COMPILERS_ = ['GCC', 'IAR']
|
||||||
_ARCH_NS_ = ['ARM_CM85', 'ARM_CM85_NTZ', 'ARM_CM55', 'ARM_CM55_NTZ', 'ARM_CM35P', 'ARM_CM35P_NTZ', 'ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
|
_ARCH_NS_ = ['ARM_CM85', 'ARM_CM85_NTZ', 'ARM_CM55', 'ARM_CM55_NTZ', 'ARM_CM52', 'ARM_CM52_NTZ', 'ARM_CM35P', 'ARM_CM35P_NTZ', 'ARM_CM33', 'ARM_CM33_NTZ', 'ARM_CM23', 'ARM_CM23_NTZ']
|
||||||
_ARCH_S_ = ['ARM_CM85', 'ARM_CM55', 'ARM_CM35P', 'ARM_CM33', 'ARM_CM23']
|
_ARCH_S_ = ['ARM_CM85', 'ARM_CM55', 'ARM_CM52', 'ARM_CM35P', 'ARM_CM33', 'ARM_CM23']
|
||||||
|
|
||||||
# Files to be compiled in the Secure Project
|
# Files to be compiled in the Secure Project
|
||||||
_SECURE_COMMON_FILE_PATHS_ = [
|
_SECURE_COMMON_FILE_PATHS_ = [
|
||||||
|
|
@ -49,6 +49,7 @@ _SECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM23')],
|
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM23')],
|
||||||
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
|
'ARM_CM52' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')],
|
||||||
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')]
|
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'GCC', 'ARM_CM33')]
|
||||||
},
|
},
|
||||||
|
|
@ -56,6 +57,7 @@ _SECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM23')],
|
'ARM_CM23' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM23')],
|
||||||
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
'ARM_CM33' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
'ARM_CM35P':[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
|
'ARM_CM52' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
'ARM_CM55' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')],
|
||||||
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')]
|
'ARM_CM85' :[os.path.join('secure', 'context', 'portable', 'IAR', 'ARM_CM33')]
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +80,12 @@ _NONSECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM35P', 'portmacro.h')],
|
||||||
|
'ARM_CM52' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM52', 'portmacro.h')],
|
||||||
|
'ARM_CM52_NTZ' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'portasm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.c'),
|
||||||
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM52', 'portmacro.h')],
|
||||||
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'),
|
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'portasm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'),
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM33', 'mpu_wrappers_v2_asm.c'),
|
||||||
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'GCC', 'ARM_CM55', 'portmacro.h')],
|
||||||
|
|
@ -102,6 +110,12 @@ _NONSECURE_PORTABLE_FILE_PATHS_ = {
|
||||||
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
'ARM_CM35P_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM35P', 'portmacro.h')],
|
||||||
|
'ARM_CM52' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM52', 'portmacro.h')],
|
||||||
|
'ARM_CM52_NTZ' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'portasm.s'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33_NTZ', 'mpu_wrappers_v2_asm.S'),
|
||||||
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM52', 'portmacro.h')],
|
||||||
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'),
|
'ARM_CM55' : [os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'portasm.s'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'),
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM33', 'mpu_wrappers_v2_asm.S'),
|
||||||
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')],
|
os.path.join('non_secure', 'portable', 'IAR', 'ARM_CM55', 'portmacro.h')],
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
||||||
Armv8.1-M ports.
|
Armv8.1-M ports.
|
||||||
Do not use the files located here! These file are copied into separate
|
Do not use the files located here! These file are copied into separate
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to
|
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85]_NNN directories prior to
|
||||||
each FreeRTOS release.
|
each FreeRTOS release.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories.
|
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85] directories.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
||||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories.
|
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85]_NTZ directories.
|
||||||
|
|
|
||||||
80
portable/ARMv8M/non_secure/portable/GCC/ARM_CM52/portmacro.h
Normal file
80
portable/ARMv8M/non_secure/portable/GCC/ARM_CM52/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
87
portable/ARMv8M/non_secure/portable/IAR/ARM_CM52/portmacro.h
Normal file
87
portable/ARMv8M/non_secure/portable/IAR/ARM_CM52/portmacro.h
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __root
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
* the source code because to do so would cause other compilers to generate
|
||||||
|
* warnings. */
|
||||||
|
#pragma diag_suppress=Be006
|
||||||
|
#pragma diag_suppress=Pa082
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
This directory tree contains the master copy of the FreeRTOS Armv8-M and
|
||||||
Armv8.1-M ports.
|
Armv8.1-M ports.
|
||||||
Do not use the files located here! These file are copied into separate
|
Do not use the files located here! These file are copied into separate
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NNN directories prior to
|
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85]_NNN directories prior to
|
||||||
each FreeRTOS release.
|
each FreeRTOS release.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
If your Armv8-M/Armv8.1-M application uses TrustZone then use the files from the
|
||||||
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85] directories.
|
FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85] directories.
|
||||||
|
|
||||||
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
If your Armv8-M/Armv8.1-M application does not use TrustZone then use the files from
|
||||||
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|55|85]_NTZ directories.
|
the FreeRTOS/Source/portable/[compiler]/ARM_CM[23|33|52|55|85]_NTZ directories.
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,28 @@ add_library(freertos_kernel_port OBJECT
|
||||||
GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NONSECURE>:
|
||||||
|
GCC/ARM_CM52/non_secure/port.c
|
||||||
|
GCC/ARM_CM52/non_secure/portasm.c
|
||||||
|
GCC/ARM_CM52/non_secure/mpu_wrappers_v2_asm.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_SECURE>:
|
||||||
|
GCC/ARM_CM52/secure/secure_context_port.c
|
||||||
|
GCC/ARM_CM52/secure/secure_context.c
|
||||||
|
GCC/ARM_CM52/secure/secure_heap.c
|
||||||
|
GCC/ARM_CM52/secure/secure_init.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NTZ_NONSECURE>:
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/portasm.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_TFM>:
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/portasm.c
|
||||||
|
GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c
|
||||||
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:
|
||||||
GCC/ARM_CM85/non_secure/port.c
|
GCC/ARM_CM85/non_secure/port.c
|
||||||
GCC/ARM_CM85/non_secure/portasm.c
|
GCC/ARM_CM85/non_secure/portasm.c
|
||||||
|
|
@ -503,6 +525,28 @@ add_library(freertos_kernel_port OBJECT
|
||||||
IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
||||||
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NONSECURE>:
|
||||||
|
IAR/ARM_CM52/non_secure/port.c
|
||||||
|
IAR/ARM_CM52/non_secure/portasm.s
|
||||||
|
IAR/ARM_CM52/non_secure/mpu_wrappers_v2_asm.S>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_SECURE>:
|
||||||
|
IAR/ARM_CM52/secure/secure_context_port_asm.s
|
||||||
|
IAR/ARM_CM52/secure/secure_context.c
|
||||||
|
IAR/ARM_CM52/secure/secure_heap.c
|
||||||
|
IAR/ARM_CM52/secure/secure_init.c>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NTZ_NONSECURE>:
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/portasm.s
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.S>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_TFM>:
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/port.c
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/portasm.s
|
||||||
|
IAR/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.S
|
||||||
|
ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:
|
||||||
IAR/ARM_CM85/non_secure/port.c
|
IAR/ARM_CM85/non_secure/port.c
|
||||||
IAR/ARM_CM85/non_secure/portasm.s
|
IAR/ARM_CM85/non_secure/portasm.s
|
||||||
|
|
@ -775,12 +819,12 @@ if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR
|
||||||
FREERTOS_PORT STREQUAL "IAR_ARM_CM4F_MPU" OR
|
FREERTOS_PORT STREQUAL "IAR_ARM_CM4F_MPU" OR
|
||||||
FREERTOS_PORT STREQUAL "RVDS_ARM_CM4_MPU" OR
|
FREERTOS_PORT STREQUAL "RVDS_ARM_CM4_MPU" OR
|
||||||
FREERTOS_PORT STREQUAL "GCC_ARM_CRX_MPU" OR
|
FREERTOS_PORT STREQUAL "GCC_ARM_CRX_MPU" OR
|
||||||
FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR
|
FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|52|55|85)_NTZ_NONSECURE" OR
|
||||||
FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NONSECURE" OR
|
FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|52|55|85)_NONSECURE" OR
|
||||||
FREERTOS_PORT MATCHES "GCC_ARM_CM(33|55|85)_TFM" OR
|
FREERTOS_PORT MATCHES "GCC_ARM_CM(33|52|55|85)_TFM" OR
|
||||||
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR
|
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|52|55|85)_NTZ_NONSECURE" OR
|
||||||
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE" OR
|
FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|52|55|85)_NONSECURE" OR
|
||||||
FREERTOS_PORT MATCHES "IAR_ARM_CM(33|55|85)_TFM"
|
FREERTOS_PORT MATCHES "IAR_ARM_CM(33|52|55|85)_TFM"
|
||||||
)
|
)
|
||||||
target_sources(freertos_kernel_port PRIVATE
|
target_sources(freertos_kernel_port PRIVATE
|
||||||
Common/mpu_wrappers.c
|
Common/mpu_wrappers.c
|
||||||
|
|
@ -794,7 +838,7 @@ if (DEFINED FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG )
|
||||||
message(FATAL_ERROR "ARMv8.1-M PACBTI support in the kernel is not yet enabled for GNU toolchain due to known issues.")
|
message(FATAL_ERROR "ARMv8.1-M PACBTI support in the kernel is not yet enabled for GNU toolchain due to known issues.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FREERTOS_PORT MATCHES ".*ARM_CM85")
|
if(FREERTOS_PORT MATCHES ".*ARM_CM(52|85)")
|
||||||
if(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_STANDARD")
|
if(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_STANDARD")
|
||||||
target_compile_options(freertos_kernel_port PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},ARMClang>:-mbranch-protection=standard>)
|
target_compile_options(freertos_kernel_port PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},ARMClang>:-mbranch-protection=standard>)
|
||||||
target_compile_options(freertos_kernel_port PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},IAR>:$<$<COMPILE_LANGUAGE:C,CXX>:--branch_protection=bti+pac-ret>>)
|
target_compile_options(freertos_kernel_port PUBLIC $<$<STREQUAL:${CMAKE_C_COMPILER_ID},IAR>:$<$<COMPILE_LANGUAGE:C,CXX>:--branch_protection=bti+pac-ret>>)
|
||||||
|
|
@ -881,7 +925,7 @@ if (DEFINED FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG )
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option is currently only supported on ARM Cortex-M85 FreeRTOS port.")
|
message(FATAL_ERROR "FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option is currently only supported on ARM Cortex-M85|M52 FreeRTOS port.")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -959,6 +1003,11 @@ target_include_directories(freertos_kernel_port_headers INTERFACE
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM55_NTZ/non_secure>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_SECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52/secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52_NTZ/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM52_TFM>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM52_NTZ/non_secure>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85/secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/GCC/ARM_CM85_NTZ/non_secure>
|
||||||
|
|
@ -1094,6 +1143,11 @@ target_include_directories(freertos_kernel_port_headers INTERFACE
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM55_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure>
|
||||||
|
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_SECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52/secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52_NTZ/non_secure>
|
||||||
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM52_TFM>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM52_NTZ/non_secure>
|
||||||
|
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/non_secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_SECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/secure>
|
||||||
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure>
|
$<$<STREQUAL:${FREERTOS_PORT},IAR_ARM_CM85_NTZ_NONSECURE>:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure>
|
||||||
|
|
|
||||||
2056
portable/GCC/ARM_CM52/non_secure/mpu_wrappers_v2_asm.c
Normal file
2056
portable/GCC/ARM_CM52/non_secure/mpu_wrappers_v2_asm.c
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/GCC/ARM_CM52/non_secure/port.c
Normal file
2280
portable/GCC/ARM_CM52/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
621
portable/GCC/ARM_CM52/non_secure/portasm.c
Normal file
621
portable/GCC/ARM_CM52/non_secure/portasm.c
Normal file
|
|
@ -0,0 +1,621 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
|
||||||
|
* is defined correctly and privileged functions are placed in correct sections. */
|
||||||
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
/* Portasm includes. */
|
||||||
|
#include "portasm.h"
|
||||||
|
|
||||||
|
/* System call numbers includes. */
|
||||||
|
#include "mpu_syscall_numbers.h"
|
||||||
|
|
||||||
|
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
|
||||||
|
* header files. */
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" program_mpu_first_task: \n"
|
||||||
|
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB. */
|
||||||
|
" \n"
|
||||||
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
" ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
" ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
" ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
" \n"
|
||||||
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" \n"
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
" \n"
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" orr r2, #1 \n" /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
|
" \n"
|
||||||
|
" restore_context_first_task: \n"
|
||||||
|
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||||
|
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||||
|
" \n"
|
||||||
|
" restore_special_regs_first_task: \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
" msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_1, r4 \n"
|
||||||
|
" msr PAC_KEY_P_2, r5 \n"
|
||||||
|
" msr PAC_KEY_P_3, r6 \n"
|
||||||
|
" clrm {r3-r6} \n" /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||||
|
" msr psp, r3 \n"
|
||||||
|
" msr psplim, r4 \n"
|
||||||
|
" msr control, r5 \n"
|
||||||
|
" ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs_first_task: \n"
|
||||||
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
|
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
|
" \n"
|
||||||
|
" restore_context_done_first_task: \n"
|
||||||
|
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx lr \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
|
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */
|
||||||
|
" msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_2, r2 \n"
|
||||||
|
" msr PAC_KEY_P_1, r3 \n"
|
||||||
|
" msr PAC_KEY_P_0, r4 \n"
|
||||||
|
" clrm {r1-r4} \n" /* Clear r1-r4. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" \n"
|
||||||
|
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||||
|
" ldr r4, =xSecureContext \n"
|
||||||
|
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
|
||||||
|
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
|
||||||
|
" mrs r1, control \n" /* Obtain current control register value. */
|
||||||
|
" orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */
|
||||||
|
" msr control, r1 \n" /* Write back the new control register value. */
|
||||||
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
|
" isb \n"
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx r3 \n" /* Finally, branch to EXC_RETURN. */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
" ite ne \n"
|
||||||
|
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
|
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
|
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||||
|
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||||
|
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
|
" nop \n"
|
||||||
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||||
|
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" .extern SecureContext_SaveContext \n"
|
||||||
|
" .extern SecureContext_LoadContext \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
|
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||||
|
" ldr r2, [r1] \n" /* r2 = Location in TCB where the context should be saved. */
|
||||||
|
" \n"
|
||||||
|
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||||
|
" save_s_context: \n"
|
||||||
|
" push {r0-r2, lr} \n"
|
||||||
|
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
" pop {r0-r2, lr} \n"
|
||||||
|
" \n"
|
||||||
|
" save_ns_context: \n"
|
||||||
|
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||||
|
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
" bmi save_special_regs \n" /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
" \n"
|
||||||
|
" save_general_regs: \n"
|
||||||
|
" mrs r3, psp \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
|
||||||
|
" tst lr, #0x10 \n"
|
||||||
|
" ittt eq \n"
|
||||||
|
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
|
||||||
|
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||||
|
" vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||||
|
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */
|
||||||
|
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||||
|
" stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||||
|
" \n"
|
||||||
|
" save_special_regs: \n"
|
||||||
|
" mrs r3, psp \n" /* r3 = PSP. */
|
||||||
|
" mrs r4, psplim \n" /* r4 = PSPLIM. */
|
||||||
|
" mrs r5, control \n" /* r5 = CONTROL. */
|
||||||
|
" stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
" mrs r4, PAC_KEY_P_1 \n"
|
||||||
|
" mrs r5, PAC_KEY_P_2 \n"
|
||||||
|
" mrs r6, PAC_KEY_P_3 \n"
|
||||||
|
" stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */
|
||||||
|
" clrm {r3-r6} \n" /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
|
" \n"
|
||||||
|
" select_next_task: \n"
|
||||||
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
|
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bl vTaskSwitchContext \n"
|
||||||
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
|
" \n"
|
||||||
|
" program_mpu: \n"
|
||||||
|
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r0, [r3] \n" /* r0 = pxCurrentTCB.*/
|
||||||
|
" \n"
|
||||||
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
" ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
" ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
" ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
" \n"
|
||||||
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" \n"
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
" \n"
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
|
" \n"
|
||||||
|
" restore_context: \n"
|
||||||
|
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/
|
||||||
|
" ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
|
||||||
|
" \n"
|
||||||
|
" restore_special_regs: \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
" msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_1, r4 \n"
|
||||||
|
" msr PAC_KEY_P_2, r5 \n"
|
||||||
|
" msr PAC_KEY_P_3, r6 \n"
|
||||||
|
" clrm {r3-r6} \n" /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||||
|
" msr psp, r3 \n"
|
||||||
|
" msr psplim, r4 \n"
|
||||||
|
" msr control, r5 \n"
|
||||||
|
" ldr r4, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
" str r0, [r4] \n" /* Restore xSecureContext. */
|
||||||
|
" cbz r0, restore_ns_context \n" /* No secure context to restore. */
|
||||||
|
" \n"
|
||||||
|
" restore_s_context: \n"
|
||||||
|
" push {r1-r3, lr} \n"
|
||||||
|
" bl SecureContext_LoadContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
" pop {r1-r3, lr} \n"
|
||||||
|
" \n"
|
||||||
|
" restore_ns_context: \n"
|
||||||
|
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||||
|
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs: \n"
|
||||||
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
|
" stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
|
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" tst lr, #0x10 \n"
|
||||||
|
" ittt eq \n"
|
||||||
|
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||||
|
" vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||||
|
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
" restore_context_done: \n"
|
||||||
|
" str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
" bx lr \n"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" .extern SecureContext_SaveContext \n"
|
||||||
|
" .extern SecureContext_LoadContext \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
" ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
|
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||||
|
" mrs r2, psp \n" /* Read PSP in r2. */
|
||||||
|
" \n"
|
||||||
|
" cbz r0, save_ns_context \n" /* No secure context to save. */
|
||||||
|
" save_s_context: \n"
|
||||||
|
" push {r0-r2, lr} \n"
|
||||||
|
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
" pop {r0-r2, lr} \n"
|
||||||
|
" \n"
|
||||||
|
" save_ns_context: \n"
|
||||||
|
" mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
|
||||||
|
" lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
" bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */
|
||||||
|
" \n"
|
||||||
|
" save_general_regs: \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
" it eq \n"
|
||||||
|
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
|
||||||
|
" \n"
|
||||||
|
" save_special_regs: \n"
|
||||||
|
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||||
|
" stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
" mrs r4, PAC_KEY_P_2 \n"
|
||||||
|
" mrs r5, PAC_KEY_P_1 \n"
|
||||||
|
" mrs r6, PAC_KEY_P_0 \n"
|
||||||
|
" stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */
|
||||||
|
" clrm {r3-r6} \n" /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" \n"
|
||||||
|
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
|
||||||
|
" \n"
|
||||||
|
" select_next_task: \n"
|
||||||
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
|
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bl vTaskSwitchContext \n"
|
||||||
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
|
" \n"
|
||||||
|
" restore_context: \n"
|
||||||
|
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
|
||||||
|
" ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||||
|
" \n"
|
||||||
|
" restore_special_regs: \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */
|
||||||
|
" msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_2, r4 \n"
|
||||||
|
" msr PAC_KEY_P_1, r5 \n"
|
||||||
|
" msr PAC_KEY_P_0, r6 \n"
|
||||||
|
" clrm {r3-r6} \n" /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */
|
||||||
|
" msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */
|
||||||
|
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
" str r0, [r3] \n" /* Restore the task's xSecureContext. */
|
||||||
|
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
|
||||||
|
" \n"
|
||||||
|
" restore_s_context: \n"
|
||||||
|
" push {r1-r3, lr} \n"
|
||||||
|
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
" pop {r1-r3, lr} \n"
|
||||||
|
" \n"
|
||||||
|
" restore_ns_context: \n"
|
||||||
|
" mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
|
||||||
|
" lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
" bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs: \n"
|
||||||
|
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
" it eq \n"
|
||||||
|
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
" restore_context_done: \n"
|
||||||
|
" msr psp, r2 \n" /* Remember the new top of stack for the task. */
|
||||||
|
" bx lr \n"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
".syntax unified \n"
|
||||||
|
".extern vPortSVCHandler_C \n"
|
||||||
|
".extern vSystemCallEnter \n"
|
||||||
|
".extern vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
"tst lr, #4 \n"
|
||||||
|
"ite eq \n"
|
||||||
|
"mrseq r0, msp \n"
|
||||||
|
"mrsne r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
"ldr r1, [r0, #24] \n"
|
||||||
|
"ldrb r2, [r1, #-2] \n"
|
||||||
|
"cmp r2, %0 \n"
|
||||||
|
"blt syscall_enter \n"
|
||||||
|
"cmp r2, %1 \n"
|
||||||
|
"beq syscall_exit \n"
|
||||||
|
"b vPortSVCHandler_C \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_enter: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallEnter \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_exit: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
: /* No outputs. */
|
||||||
|
: "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
|
: "r0", "r1", "r2", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" tst lr, #4 \n"
|
||||||
|
" ite eq \n"
|
||||||
|
" mrseq r0, msp \n"
|
||||||
|
" mrsne r0, psp \n"
|
||||||
|
" ldr r1, =vPortSVCHandler_C \n"
|
||||||
|
" bx r1 \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" svc %0 \n" /* Secure context is allocated in the supervisor call. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( portSVC_ALLOCATE_SECURE_CONTEXT ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */
|
||||||
|
" ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */
|
||||||
|
" cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */
|
||||||
|
" it ne \n"
|
||||||
|
" svcne %0 \n" /* Secure context is freed in the supervisor call. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
114
portable/GCC/ARM_CM52/non_secure/portasm.h
Normal file
114
portable/GCC/ARM_CM52/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PORT_ASM_H__
|
||||||
|
#define __PORT_ASM_H__
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
/* MPU wrappers includes. */
|
||||||
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Restore the context of the first task so that the first task starts
|
||||||
|
* executing.
|
||||||
|
*/
|
||||||
|
void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* @note This is a privileged function and should only be called from the kernel
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vResetPrivilege( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the first task.
|
||||||
|
*/
|
||||||
|
void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables interrupts.
|
||||||
|
*/
|
||||||
|
uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables interrupts.
|
||||||
|
*/
|
||||||
|
void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PendSV Exception handler.
|
||||||
|
*/
|
||||||
|
void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC Handler.
|
||||||
|
*/
|
||||||
|
void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
80
portable/GCC/ARM_CM52/non_secure/portmacro.h
Normal file
80
portable/GCC/ARM_CM52/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/GCC/ARM_CM52/non_secure/portmacrocommon.h
Normal file
582
portable/GCC/ARM_CM52/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_MPU
|
||||||
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type definitions.
|
||||||
|
*/
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE uint32_t
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
|
typedef uint16_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
|
typedef uint32_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
* not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
#else
|
||||||
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portNOP()
|
||||||
|
#define portINLINE __inline
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
|
#endif
|
||||||
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extern declarations.
|
||||||
|
*/
|
||||||
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates 128-bit task's random PAC key.
|
||||||
|
*
|
||||||
|
* @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be
|
||||||
|
* filled with a 128-bit random number.
|
||||||
|
*/
|
||||||
|
void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey );
|
||||||
|
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU specific constants.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
|
#else
|
||||||
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
|
||||||
|
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||||
|
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System call stack.
|
||||||
|
*/
|
||||||
|
typedef struct SYSTEM_CALL_STACK_INFO
|
||||||
|
{
|
||||||
|
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||||
|
uint32_t * pulSystemCallStack;
|
||||||
|
uint32_t * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
|
||||||
|
* 16 17 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 71
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||||
|
* 16 17 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 55
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><-----------><---->
|
||||||
|
* 16 17 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 70
|
||||||
|
|
||||||
|
#else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||||
|
* 16 17 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 54
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><-----------><---->
|
||||||
|
* 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 38
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><---->
|
||||||
|
* 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 22
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><-----------><---->
|
||||||
|
* 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 37
|
||||||
|
|
||||||
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><---->
|
||||||
|
* 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||||
|
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||||
|
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||||
|
|
||||||
|
/* Size of an Access Control List (ACL) entry in bits. */
|
||||||
|
#define portACL_ENTRY_SIZE_BITS ( 32U )
|
||||||
|
|
||||||
|
typedef struct MPU_SETTINGS
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_CONTEXT_SIZE ];
|
||||||
|
uint32_t ulTaskFlags;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
|
||||||
|
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||||
|
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} xMPU_SETTINGS;
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler utilities.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portYIELD() __asm volatile ( "svc %0" ::"i" ( portSVC_YIELD ) : "memory" )
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#else
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tickless idle/low power functionality.
|
||||||
|
*/
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
|
*/
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raise an SVC request to raise privilege.
|
||||||
|
*
|
||||||
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
|
* then it raises the privilege. If this is called from any other place,
|
||||||
|
* the privilege is not raised.
|
||||||
|
*/
|
||||||
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
|
#else
|
||||||
|
#define portIS_PRIVILEGED()
|
||||||
|
#define portRAISE_PRIVILEGE()
|
||||||
|
#define portRESET_PRIVILEGE()
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Barriers.
|
||||||
|
*/
|
||||||
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store/clear the ready priorities in a bit map.
|
||||||
|
*/
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
354
portable/GCC/ARM_CM52/secure/secure_context.c
Normal file
354
portable/GCC/ARM_CM52/secure/secure_context.c
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Secure context includes. */
|
||||||
|
#include "secure_context.h"
|
||||||
|
|
||||||
|
/* Secure heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 0 --> Thread mode is privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for un-privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 1 --> Thread mode is un-privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Size of stack seal values in bytes.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_SIZE 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stack seal value as recommended by ARM.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum number of secure contexts.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||||
|
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pre-allocated array of secure contexts.
|
||||||
|
*/
|
||||||
|
SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a free secure context for a task from the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* This function ensures that only one secure context is allocated for a task.
|
||||||
|
*
|
||||||
|
* @param[in] pvTaskHandle The task handle for which the secure context is allocated.
|
||||||
|
*
|
||||||
|
* @return Index of a free secure context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the secure context to the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex );
|
||||||
|
|
||||||
|
/* These are implemented in assembly. */
|
||||||
|
extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Start with invalid index. */
|
||||||
|
uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackLimit == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackStart == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pvTaskHandle == NULL ) &&
|
||||||
|
( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = i;
|
||||||
|
}
|
||||||
|
else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* A task can only have one secure context. Do not allocate a second
|
||||||
|
* context for the same task. */
|
||||||
|
ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulSecureContextIndex;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex )
|
||||||
|
{
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, i;
|
||||||
|
static uint32_t ulSecureContextsInitialized = 0;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) )
|
||||||
|
{
|
||||||
|
/* Ensure to initialize secure contexts only once. */
|
||||||
|
ulSecureContextsInitialized = 1;
|
||||||
|
|
||||||
|
/* No stack for thread mode until a task's context is loaded. */
|
||||||
|
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||||
|
secureportSET_PSP( securecontextNO_STACK );
|
||||||
|
|
||||||
|
/* Initialize all secure contexts. */
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
xSecureContexts[ i ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ i ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be privileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
uint8_t * pucStackMemory = NULL;
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
uint32_t * pulCurrentStackPointer = NULL;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
|
||||||
|
* Register (PSPLIM) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode.
|
||||||
|
* Also do nothing, if a secure context us already loaded. PSPLIM is set to
|
||||||
|
* securecontextNO_STACK when no secure context is loaded. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) )
|
||||||
|
{
|
||||||
|
/* Obtain a free secure context. */
|
||||||
|
ulSecureContextIndex = ulGetSecureContext( pvTaskHandle );
|
||||||
|
|
||||||
|
/* Were we able to get a free context? */
|
||||||
|
if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
|
||||||
|
{
|
||||||
|
/* Allocate the stack space. */
|
||||||
|
pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE );
|
||||||
|
|
||||||
|
if( pucStackMemory != NULL )
|
||||||
|
{
|
||||||
|
/* Since stack grows down, the starting point will be the last
|
||||||
|
* location. Note that this location is next to the last
|
||||||
|
* allocated byte for stack (excluding the space for seal values)
|
||||||
|
* because the hardware decrements the stack pointer before
|
||||||
|
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||||
|
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||||
|
|
||||||
|
/* Seal the created secure process stack. */
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
|
||||||
|
/* The stack cannot go beyond this location. This value is
|
||||||
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
|
||||||
|
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
|
* This value is programmed in the CONTROL register on
|
||||||
|
* context switch. */
|
||||||
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
|
if( ulIsTaskPrivileged )
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the current stack pointer. This value is programmed in
|
||||||
|
* the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Current SP is set to the starting of the stack. This
|
||||||
|
* value programmed in the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Ensure to never return 0 as a valid context handle. */
|
||||||
|
xSecureContextHandle = ulSecureContextIndex + 1UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xSecureContextHandle;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* Only free if a valid context handle is passed. */
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
/* Ensure that the secure context being deleted is associated with
|
||||||
|
* the task. */
|
||||||
|
if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Free the stack space. */
|
||||||
|
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
|
||||||
|
|
||||||
|
/* Return the secure context back to the free secure contexts pool. */
|
||||||
|
vReturnSecureContext( ulSecureContextIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that no secure context is loaded and the task is loading it's
|
||||||
|
* own context. */
|
||||||
|
if( ( pucStackLimit == securecontextNO_STACK ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that task's context is loaded and the task is saving it's own
|
||||||
|
* context. */
|
||||||
|
if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
138
portable/GCC/ARM_CM52/secure/secure_context.h
Normal file
138
portable/GCC/ARM_CM52/secure/secure_context.h
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_CONTEXT_H__
|
||||||
|
#define __SECURE_CONTEXT_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PSP value when no secure context is loaded.
|
||||||
|
*/
|
||||||
|
#define securecontextNO_STACK 0x0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Invalid context ID.
|
||||||
|
*/
|
||||||
|
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure to represent a secure context.
|
||||||
|
*
|
||||||
|
* @note Since stack grows down, pucStackStart is the highest address while
|
||||||
|
* pucStackLimit is the first address of the allocated memory.
|
||||||
|
*/
|
||||||
|
typedef struct SecureContext
|
||||||
|
{
|
||||||
|
uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||||
|
uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||||
|
uint8_t * pucStackStart; /**< First location of the stack memory. */
|
||||||
|
void * pvTaskHandle; /**< Task handle of the task this context is associated with. */
|
||||||
|
} SecureContext_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opaque handle for a secure context.
|
||||||
|
*/
|
||||||
|
typedef uint32_t SecureContextHandle_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the secure context management system.
|
||||||
|
*
|
||||||
|
* PSP is set to NULL and therefore a task must allocate and load a context
|
||||||
|
* before calling any secure side function in the thread mode.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureContext_Init( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates a context on the secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
|
||||||
|
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
|
||||||
|
*
|
||||||
|
* @return Opaque context handle if context is successfully allocated, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||||
|
* context to be freed.
|
||||||
|
*/
|
||||||
|
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be loaded.
|
||||||
|
*/
|
||||||
|
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be saved.
|
||||||
|
*/
|
||||||
|
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
#endif /* __SECURE_CONTEXT_H__ */
|
||||||
97
portable/GCC/ARM_CM52/secure/secure_context_port.c
Normal file
97
portable/GCC/ARM_CM52/secure/secure_context_port.c
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Secure context includes. */
|
||||||
|
#include "secure_context.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||||
|
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
|
||||||
|
{
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||||
|
" cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
" ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
" ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||||
|
" msr control, r3 \n" /* CONTROL = r3. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
" \n"
|
||||||
|
" msr psplim, r2 \n" /* PSPLIM = r2. */
|
||||||
|
" msr psp, r1 \n" /* PSP = r1. */
|
||||||
|
" \n"
|
||||||
|
" load_ctx_therad_mode: \n"
|
||||||
|
" bx lr \n"
|
||||||
|
" \n"
|
||||||
|
::: "r0", "r1", "r2"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext )
|
||||||
|
{
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r1, ipsr \n" /* r1 = IPSR. */
|
||||||
|
" cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
" mrs r1, psp \n" /* r1 = PSP. */
|
||||||
|
" \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" vstmdb r1!, {s0} \n" /* Trigger the deferred stacking of FPU registers. */
|
||||||
|
" vldmia r1!, {s0} \n" /* Nullify the effect of the previous statement. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
" mrs r2, control \n" /* r2 = CONTROL. */
|
||||||
|
" stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
" \n"
|
||||||
|
" str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
|
||||||
|
" movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
|
||||||
|
" msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
|
||||||
|
" msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
||||||
|
" \n"
|
||||||
|
" save_ctx_therad_mode: \n"
|
||||||
|
" bx lr \n"
|
||||||
|
" \n"
|
||||||
|
::"i" ( securecontextNO_STACK ) : "r1", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
485
portable/GCC/ARM_CM52/secure/secure_heap.c
Normal file
485
portable/GCC/ARM_CM52/secure/secure_heap.c
Normal file
|
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Configuration includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* Secure context heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total heap size.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigTOTAL_HEAP_SIZE
|
||||||
|
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No test marker by default. */
|
||||||
|
#ifndef mtCOVERAGE_TEST_MARKER
|
||||||
|
#define mtCOVERAGE_TEST_MARKER()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceMALLOC
|
||||||
|
#define traceMALLOC( pvReturn, xWantedSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceFREE
|
||||||
|
#define traceFREE( pv, xBlockSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Block sizes must not get too small. */
|
||||||
|
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
|
||||||
|
|
||||||
|
/* Assumes 8bit bytes! */
|
||||||
|
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||||
|
|
||||||
|
/* Max value that fits in a size_t type. */
|
||||||
|
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||||
|
|
||||||
|
/* Check if adding a and b will result in overflow. */
|
||||||
|
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||||
|
|
||||||
|
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||||
|
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||||
|
* an BlockLink_t structure is set then the block belongs to the application.
|
||||||
|
* When the bit is free the block is still part of the free heap space. */
|
||||||
|
#define secureheapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ) )
|
||||||
|
#define secureheapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) == 0 )
|
||||||
|
#define secureheapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) != 0 )
|
||||||
|
#define secureheapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
#define secureheapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Allocate the memory for the heap. */
|
||||||
|
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
||||||
|
|
||||||
|
/* The application writer has already defined the array used for the RTOS
|
||||||
|
* heap - probably so it can be placed in a special segment or address. */
|
||||||
|
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The linked list structure.
|
||||||
|
*
|
||||||
|
* This is used to link free blocks in order of their memory address.
|
||||||
|
*/
|
||||||
|
typedef struct A_BLOCK_LINK
|
||||||
|
{
|
||||||
|
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
|
||||||
|
size_t xBlockSize; /**< The size of the free block. */
|
||||||
|
} BlockLink_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called automatically to setup the required heap structures the first
|
||||||
|
* time pvPortMalloc() is called.
|
||||||
|
*/
|
||||||
|
static void prvHeapInit( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a block of memory that is being freed into the correct
|
||||||
|
* position in the list of free memory blocks.
|
||||||
|
*
|
||||||
|
* The block being freed will be merged with the block in front it and/or the
|
||||||
|
* block behind it if the memory blocks are adjacent to each other.
|
||||||
|
*
|
||||||
|
* @param[in] pxBlockToInsert The block being freed.
|
||||||
|
*/
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The size of the structure placed at the beginning of each allocated
|
||||||
|
* memory block must by correctly byte aligned.
|
||||||
|
*/
|
||||||
|
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a couple of list links to mark the start and end of the list.
|
||||||
|
*/
|
||||||
|
static BlockLink_t xStart;
|
||||||
|
static BlockLink_t * pxEnd = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
||||||
|
* about fragmentation.
|
||||||
|
*/
|
||||||
|
static size_t xFreeBytesRemaining = 0U;
|
||||||
|
static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHeapInit( void )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxFirstFreeBlock;
|
||||||
|
uint8_t * pucAlignedHeap;
|
||||||
|
size_t uxAddress;
|
||||||
|
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
|
|
||||||
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
|
uxAddress = ( size_t ) ucHeap;
|
||||||
|
|
||||||
|
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
|
||||||
|
{
|
||||||
|
uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
pucAlignedHeap = ( uint8_t * ) uxAddress;
|
||||||
|
|
||||||
|
/* xStart is used to hold a pointer to the first item in the list of free
|
||||||
|
* blocks. The void cast is used to prevent compiler warnings. */
|
||||||
|
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
xStart.xBlockSize = ( size_t ) 0;
|
||||||
|
|
||||||
|
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
||||||
|
* at the end of the heap space. */
|
||||||
|
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
|
||||||
|
uxAddress -= xHeapStructSize;
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
pxEnd = ( void * ) uxAddress;
|
||||||
|
pxEnd->xBlockSize = 0;
|
||||||
|
pxEnd->pxNextFreeBlock = NULL;
|
||||||
|
|
||||||
|
/* To start with there is a single free block that is sized to take up the
|
||||||
|
* entire heap space, minus the space taken by pxEnd. */
|
||||||
|
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
|
||||||
|
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
||||||
|
|
||||||
|
/* Only one block exists - and it covers the entire usable heap space. */
|
||||||
|
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxIterator;
|
||||||
|
uint8_t * puc;
|
||||||
|
|
||||||
|
/* Iterate through the list until a block is found that has a higher address
|
||||||
|
* than the block being inserted. */
|
||||||
|
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
/* Nothing to do here, just iterate to the right position. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted after
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxIterator;
|
||||||
|
|
||||||
|
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||||
|
pxBlockToInsert = pxIterator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted before
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxBlockToInsert;
|
||||||
|
|
||||||
|
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Form one big block from the two blocks. */
|
||||||
|
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the block being inserted plugged a gap, so was merged with the block
|
||||||
|
* before and the block after, then it's pxNextFreeBlock pointer will have
|
||||||
|
* already been set, and should not be set here as that would make it point
|
||||||
|
* to itself. */
|
||||||
|
if( pxIterator != pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void * pvPortMalloc( size_t xWantedSize )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxBlock;
|
||||||
|
BlockLink_t * pxPreviousBlock;
|
||||||
|
BlockLink_t * pxNewBlockLink;
|
||||||
|
void * pvReturn = NULL;
|
||||||
|
size_t xAdditionalRequiredSize;
|
||||||
|
size_t xAllocatedBlockSize = 0;
|
||||||
|
|
||||||
|
/* If this is the first call to malloc then the heap will require
|
||||||
|
* initialisation to setup the list of free blocks. */
|
||||||
|
if( pxEnd == NULL )
|
||||||
|
{
|
||||||
|
prvHeapInit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xWantedSize > 0 )
|
||||||
|
{
|
||||||
|
/* The wanted size must be increased so it can contain a BlockLink_t
|
||||||
|
* structure in addition to the requested amount of bytes. */
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xHeapStructSize;
|
||||||
|
|
||||||
|
/* Ensure that blocks are always aligned to the required number
|
||||||
|
* of bytes. */
|
||||||
|
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
|
||||||
|
{
|
||||||
|
/* Byte alignment required. */
|
||||||
|
xAdditionalRequiredSize = secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xAdditionalRequiredSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the requested block size is not so large that the top bit is set.
|
||||||
|
* The top bit of the block size member of the BlockLink_t structure is used
|
||||||
|
* to determine who owns the block - the application or the kernel, so it
|
||||||
|
* must be free. */
|
||||||
|
if( secureheapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
|
||||||
|
{
|
||||||
|
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
||||||
|
{
|
||||||
|
/* Traverse the list from the start (lowest address) block until
|
||||||
|
* one of adequate size is found. */
|
||||||
|
pxPreviousBlock = &xStart;
|
||||||
|
pxBlock = xStart.pxNextFreeBlock;
|
||||||
|
|
||||||
|
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||||
|
{
|
||||||
|
pxPreviousBlock = pxBlock;
|
||||||
|
pxBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the end marker was reached then a block of adequate size was
|
||||||
|
* not found. */
|
||||||
|
if( pxBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Return the memory space pointed to - jumping over the
|
||||||
|
* BlockLink_t structure at its start. */
|
||||||
|
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
|
||||||
|
|
||||||
|
/* This block is being returned for use so must be taken out
|
||||||
|
* of the list of free blocks. */
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
|
||||||
|
/* If the block is larger than required it can be split into
|
||||||
|
* two. */
|
||||||
|
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
|
||||||
|
{
|
||||||
|
/* This block is to be split into two. Create a new
|
||||||
|
* block following the number of bytes requested. The void
|
||||||
|
* cast is used to prevent byte alignment warnings from the
|
||||||
|
* compiler. */
|
||||||
|
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
|
||||||
|
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
||||||
|
/* Calculate the sizes of two blocks split from the single
|
||||||
|
* block. */
|
||||||
|
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
||||||
|
pxBlock->xBlockSize = xWantedSize;
|
||||||
|
|
||||||
|
/* Insert the new block into the list of free blocks. */
|
||||||
|
pxNewBlockLink->pxNextFreeBlock = pxPreviousBlock->pxNextFreeBlock;
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxNewBlockLink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||||
|
|
||||||
|
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
|
||||||
|
{
|
||||||
|
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
xAllocatedBlockSize = pxBlock->xBlockSize;
|
||||||
|
|
||||||
|
/* The block is being returned - it is allocated and owned by
|
||||||
|
* the application and has no "next" block. */
|
||||||
|
secureheapALLOCATE_BLOCK( pxBlock );
|
||||||
|
pxBlock->pxNextFreeBlock = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
traceMALLOC( pvReturn, xAllocatedBlockSize );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xAllocatedBlockSize;
|
||||||
|
|
||||||
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
|
{
|
||||||
|
extern void vApplicationMallocFailedHook( void );
|
||||||
|
vApplicationMallocFailedHook();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
return pvReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFree( void * pv )
|
||||||
|
{
|
||||||
|
uint8_t * puc = ( uint8_t * ) pv;
|
||||||
|
BlockLink_t * pxLink;
|
||||||
|
|
||||||
|
if( pv != NULL )
|
||||||
|
{
|
||||||
|
/* The memory being freed will have an BlockLink_t structure immediately
|
||||||
|
* before it. */
|
||||||
|
puc -= xHeapStructSize;
|
||||||
|
|
||||||
|
/* This casting is to keep the compiler from issuing warnings. */
|
||||||
|
pxLink = ( void * ) puc;
|
||||||
|
|
||||||
|
/* Check the block is actually allocated. */
|
||||||
|
secureportASSERT( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
|
||||||
|
secureportASSERT( pxLink->pxNextFreeBlock == NULL );
|
||||||
|
|
||||||
|
if( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
|
||||||
|
{
|
||||||
|
if( pxLink->pxNextFreeBlock == NULL )
|
||||||
|
{
|
||||||
|
/* The block is being returned to the heap - it is no longer
|
||||||
|
* allocated. */
|
||||||
|
secureheapFREE_BLOCK( pxLink );
|
||||||
|
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
/* Add this block to the list of free blocks. */
|
||||||
|
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||||
|
traceFREE( pv, pxLink->xBlockSize );
|
||||||
|
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||||
|
}
|
||||||
|
secureportENABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xMinimumEverFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
66
portable/GCC/ARM_CM52/secure/secure_heap.h
Normal file
66
portable/GCC/ARM_CM52/secure/secure_heap.h
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_HEAP_H__
|
||||||
|
#define __SECURE_HEAP_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates memory from heap.
|
||||||
|
*
|
||||||
|
* @param[in] xWantedSize The size of the memory to be allocated.
|
||||||
|
*
|
||||||
|
* @return Pointer to the memory region if the allocation is successful, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
void * pvPortMalloc( size_t xWantedSize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the previously allocated memory.
|
||||||
|
*
|
||||||
|
* @param[in] pv Pointer to the memory to be freed.
|
||||||
|
*/
|
||||||
|
void vPortFree( void * pv );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the free heap size.
|
||||||
|
*
|
||||||
|
* @return Free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetFreeHeapSize( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the minimum ever free heap size.
|
||||||
|
*
|
||||||
|
* @return Minimum ever free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_HEAP_H__ */
|
||||||
106
portable/GCC/ARM_CM52/secure/secure_init.c
Normal file
106
portable/GCC/ARM_CM52/secure/secure_init.c
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Secure init includes. */
|
||||||
|
#include "secure_init.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the SCB.
|
||||||
|
*/
|
||||||
|
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the FPU.
|
||||||
|
*/
|
||||||
|
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
|
||||||
|
#define secureinitFPCCR_LSPENS_POS ( 29UL )
|
||||||
|
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
|
||||||
|
#define secureinitFPCCR_TS_POS ( 26UL )
|
||||||
|
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
|
||||||
|
|
||||||
|
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
|
||||||
|
#define secureinitNSACR_CP10_POS ( 10UL )
|
||||||
|
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
|
||||||
|
#define secureinitNSACR_CP11_POS ( 11UL )
|
||||||
|
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
|
||||||
|
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
|
||||||
|
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
|
||||||
|
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||||
|
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||||
|
|
||||||
|
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||||
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
|
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
||||||
|
* registers (S16-S31) are also pushed to stack on exception entry and
|
||||||
|
* restored on exception return. */
|
||||||
|
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
54
portable/GCC/ARM_CM52/secure/secure_init.h
Normal file
54
portable/GCC/ARM_CM52/secure/secure_init.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_INIT_H__
|
||||||
|
#define __SECURE_INIT_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-prioritizes the non-secure exceptions.
|
||||||
|
*
|
||||||
|
* This is needed to ensure that the non-secure PendSV runs at the lowest
|
||||||
|
* priority. Context switch is done in the non-secure PendSV handler.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_DePrioritizeNSExceptions( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets up the Floating Point Unit (FPU) for Non-Secure access.
|
||||||
|
*
|
||||||
|
* Also sets FPCCR.TS=1 to ensure that the content of the Floating Point
|
||||||
|
* Registers are not leaked to the non-secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_EnableNSFPUAccess( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_INIT_H__ */
|
||||||
140
portable/GCC/ARM_CM52/secure/secure_port_macros.h
Normal file
140
portable/GCC/ARM_CM52/secure/secure_port_macros.h
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_PORT_MACROS_H__
|
||||||
|
#define __SECURE_PORT_MACROS_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Byte alignment requirements.
|
||||||
|
*/
|
||||||
|
#define secureportBYTE_ALIGNMENT 8
|
||||||
|
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Macro to declare a function as non-secure callable.
|
||||||
|
*/
|
||||||
|
#if defined( __IAR_SYSTEMS_ICC__ )
|
||||||
|
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
||||||
|
#else
|
||||||
|
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the non-secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSP value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSP( pucCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSPLIM value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSPLIM( pucOutStackLimit ) \
|
||||||
|
__asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSPLIM to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSPLIM( pucStackLimit ) \
|
||||||
|
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the NonSecure MSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_MSP_NS( pucMainStackPointer ) \
|
||||||
|
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the CONTROL register to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_CONTROL( ulControl ) \
|
||||||
|
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the Interrupt Program Status Register (IPSR) value in the given
|
||||||
|
* variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_IPSR( ulIPSR ) \
|
||||||
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to enable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to disable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable non-secure interrupts.
|
||||||
|
*
|
||||||
|
* This effectively disables context switches.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable non-secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert definition.
|
||||||
|
*/
|
||||||
|
#define secureportASSERT( x ) \
|
||||||
|
if( ( x ) == 0 ) \
|
||||||
|
{ \
|
||||||
|
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||||
|
for( ; ; ) {; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||||
2055
portable/GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c
Normal file
2055
portable/GCC/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.c
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/GCC/ARM_CM52_NTZ/non_secure/port.c
Normal file
2280
portable/GCC/ARM_CM52_NTZ/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
524
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.c
Normal file
524
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.c
Normal file
|
|
@ -0,0 +1,524 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE ensures that PRIVILEGED_FUNCTION
|
||||||
|
* is defined correctly and privileged functions are placed in correct sections. */
|
||||||
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
/* Portasm includes. */
|
||||||
|
#include "portasm.h"
|
||||||
|
|
||||||
|
/* System call numbers includes. */
|
||||||
|
#include "mpu_syscall_numbers.h"
|
||||||
|
|
||||||
|
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE is needed to be defined only for the
|
||||||
|
* header files. */
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" program_mpu_first_task: \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
|
" \n"
|
||||||
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
" ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
" ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
" ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
" \n"
|
||||||
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" \n"
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
" \n"
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
|
" \n"
|
||||||
|
" restore_context_first_task: \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
|
" \n"
|
||||||
|
" restore_special_regs_first_task: \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
" msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_1, r3 \n"
|
||||||
|
" msr PAC_KEY_P_2, r4 \n"
|
||||||
|
" msr PAC_KEY_P_3, r5 \n"
|
||||||
|
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||||
|
" msr psp, r2 \n"
|
||||||
|
" msr psplim, r3 \n"
|
||||||
|
" msr control, r4 \n"
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs_first_task: \n"
|
||||||
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
|
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
|
" \n"
|
||||||
|
" restore_context_done_first_task: \n"
|
||||||
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx lr \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
|
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */
|
||||||
|
" msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_2, r2 \n"
|
||||||
|
" msr PAC_KEY_P_1, r3 \n"
|
||||||
|
" msr PAC_KEY_P_0, r4 \n"
|
||||||
|
" clrm {r1-r4} \n" /* Clear r1-r4. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" \n"
|
||||||
|
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
|
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
|
||||||
|
" mrs r1, control \n" /* Obtain current control register value. */
|
||||||
|
" orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */
|
||||||
|
" msr control, r1 \n" /* Write back the new control register value. */
|
||||||
|
" adds r0, #32 \n" /* Discard everything up to r0. */
|
||||||
|
" msr psp, r0 \n" /* This is now the new top of stack to use in the task. */
|
||||||
|
" isb \n"
|
||||||
|
" mov r0, #0 \n"
|
||||||
|
" msr basepri, r0 \n" /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
" bx r2 \n" /* Finally, branch to EXC_RETURN. */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" tst r0, #1 \n" /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
" ite ne \n"
|
||||||
|
" movne r0, #0 \n" /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
|
" moveq r0, #1 \n" /* CONTROL[0]==0. Return true to indicate that the processor is privileged. */
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vRaisePrivilege( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* Read the CONTROL register. */
|
||||||
|
" bic r0, #1 \n" /* Clear the bit 0. */
|
||||||
|
" msr control, r0 \n" /* Write back the new CONTROL value. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vResetPrivilege( void ) /* __attribute__ (( naked )) */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, control \n" /* r0 = CONTROL. */
|
||||||
|
" orr r0, #1 \n" /* r0 = r0 | 1. */
|
||||||
|
" msr control, r0 \n" /* CONTROL = r0. */
|
||||||
|
" bx lr \n" /* Return to the caller. */
|
||||||
|
::: "r0", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vStartFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r0, =0xe000ed08 \n" /* Use the NVIC offset register to locate the stack. */
|
||||||
|
" ldr r0, [r0] \n" /* Read the VTOR register which gives the address of vector table. */
|
||||||
|
" ldr r0, [r0] \n" /* The first entry in vector table is stack pointer. */
|
||||||
|
" msr msp, r0 \n" /* Set the MSP back to the start of the stack. */
|
||||||
|
" cpsie i \n" /* Globally enable interrupts. */
|
||||||
|
" cpsie f \n"
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" svc %0 \n" /* System call to start the first task. */
|
||||||
|
" nop \n"
|
||||||
|
::"i" ( portSVC_START_SCHEDULER ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */
|
||||||
|
" mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" msr basepri, r0 \n" /* basepri = ulMask. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bx lr \n" /* Return. */
|
||||||
|
::: "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
|
" ldr r1, [r0] \n" /* r1 = Location in TCB where the context should be saved. */
|
||||||
|
" mrs r2, psp \n" /* r2 = PSP. */
|
||||||
|
" \n"
|
||||||
|
" save_general_regs: \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
|
||||||
|
" tst lr, #0x10 \n"
|
||||||
|
" ittt eq \n"
|
||||||
|
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
|
||||||
|
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
|
||||||
|
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */
|
||||||
|
" sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */
|
||||||
|
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */
|
||||||
|
" stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */
|
||||||
|
" \n"
|
||||||
|
" save_special_regs: \n"
|
||||||
|
" mrs r3, psplim \n" /* r3 = PSPLIM. */
|
||||||
|
" mrs r4, control \n" /* r4 = CONTROL. */
|
||||||
|
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
" mrs r3, PAC_KEY_P_1 \n"
|
||||||
|
" mrs r4, PAC_KEY_P_2 \n"
|
||||||
|
" mrs r5, PAC_KEY_P_3 \n"
|
||||||
|
" stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */
|
||||||
|
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
|
" \n"
|
||||||
|
" select_next_task: \n"
|
||||||
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
|
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bl vTaskSwitchContext \n"
|
||||||
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
|
" \n"
|
||||||
|
" program_mpu: \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB. */
|
||||||
|
" \n"
|
||||||
|
" dmb \n" /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" bic r2, #1 \n" /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Disable MPU. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
" ldr r1, [r0] \n" /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
" ldr r2, =0xe000edc0 \n" /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
" str r1, [r2] \n" /* Program MAIR0. */
|
||||||
|
" \n"
|
||||||
|
" adds r0, #4 \n" /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
" ldr r1, =0xe000ed98 \n" /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
" ldr r2, =0xe000ed9c \n" /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
" \n"
|
||||||
|
" movs r3, #4 \n" /* r3 = 4. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 4. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" \n"
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
" movs r3, #8 \n" /* r3 = 8. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 8. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
" movs r3, #12 \n" /* r3 = 12. */
|
||||||
|
" str r3, [r1] \n" /* Program RNR = 12. */
|
||||||
|
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
" stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
" \n"
|
||||||
|
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
" ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */
|
||||||
|
" orr r2, #1 \n" /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
" str r2, [r1] \n" /* Enable MPU. */
|
||||||
|
" dsb \n" /* Force memory writes before continuing. */
|
||||||
|
" \n"
|
||||||
|
" restore_context: \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/
|
||||||
|
" ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
|
||||||
|
" \n"
|
||||||
|
" restore_special_regs: \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
" msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_1, r3 \n"
|
||||||
|
" msr PAC_KEY_P_2, r4 \n"
|
||||||
|
" msr PAC_KEY_P_3, r5 \n"
|
||||||
|
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||||
|
" msr psp, r2 \n"
|
||||||
|
" msr psplim, r3 \n"
|
||||||
|
" msr control, r4 \n"
|
||||||
|
" \n"
|
||||||
|
" restore_general_regs: \n"
|
||||||
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */
|
||||||
|
" stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
|
||||||
|
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" tst lr, #0x10 \n"
|
||||||
|
" ittt eq \n"
|
||||||
|
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */
|
||||||
|
" vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
|
||||||
|
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
" restore_context_done: \n"
|
||||||
|
" str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
" bx lr \n"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
void PendSV_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" mrs r0, psp \n" /* Read PSP in r0. */
|
||||||
|
" \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
" it eq \n"
|
||||||
|
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
" mrs r2, psplim \n" /* r2 = PSPLIM. */
|
||||||
|
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
|
||||||
|
" stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
" mrs r2, PAC_KEY_P_2 \n"
|
||||||
|
" mrs r3, PAC_KEY_P_1 \n"
|
||||||
|
" mrs r4, PAC_KEY_P_0 \n"
|
||||||
|
" stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */
|
||||||
|
" clrm {r1-r4} \n" /* Clear r1-r4. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
|
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
|
||||||
|
" \n"
|
||||||
|
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
|
||||||
|
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" bl vTaskSwitchContext \n"
|
||||||
|
" mov r0, #0 \n" /* r0 = 0. */
|
||||||
|
" msr basepri, r0 \n" /* Enable interrupts. */
|
||||||
|
" \n"
|
||||||
|
" ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
|
||||||
|
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
|
" \n"
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
" ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */
|
||||||
|
" msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
" msr PAC_KEY_P_2, r3 \n"
|
||||||
|
" msr PAC_KEY_P_1, r4 \n"
|
||||||
|
" msr PAC_KEY_P_0, r5 \n"
|
||||||
|
" clrm {r2-r5} \n" /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
" \n"
|
||||||
|
" ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||||
|
" \n"
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
" tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
" it eq \n"
|
||||||
|
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
" \n"
|
||||||
|
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
|
||||||
|
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
|
||||||
|
" bx r3 \n"
|
||||||
|
::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
".syntax unified \n"
|
||||||
|
".extern vPortSVCHandler_C \n"
|
||||||
|
".extern vSystemCallEnter \n"
|
||||||
|
".extern vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
"tst lr, #4 \n"
|
||||||
|
"ite eq \n"
|
||||||
|
"mrseq r0, msp \n"
|
||||||
|
"mrsne r0, psp \n"
|
||||||
|
" \n"
|
||||||
|
"ldr r1, [r0, #24] \n"
|
||||||
|
"ldrb r2, [r1, #-2] \n"
|
||||||
|
"cmp r2, %0 \n"
|
||||||
|
"blt syscall_enter \n"
|
||||||
|
"cmp r2, %1 \n"
|
||||||
|
"beq syscall_exit \n"
|
||||||
|
"b vPortSVCHandler_C \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_enter: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallEnter \n"
|
||||||
|
" \n"
|
||||||
|
"syscall_exit: \n"
|
||||||
|
" mov r1, lr \n"
|
||||||
|
" b vSystemCallExit \n"
|
||||||
|
" \n"
|
||||||
|
: /* No outputs. */
|
||||||
|
: "i" ( NUM_SYSTEM_CALLS ), "i" ( portSVC_SYSTEM_CALL_EXIT )
|
||||||
|
: "r0", "r1", "r2", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
void SVC_Handler( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */
|
||||||
|
{
|
||||||
|
__asm volatile
|
||||||
|
(
|
||||||
|
" .syntax unified \n"
|
||||||
|
" \n"
|
||||||
|
" tst lr, #4 \n"
|
||||||
|
" ite eq \n"
|
||||||
|
" mrseq r0, msp \n"
|
||||||
|
" mrsne r0, psp \n"
|
||||||
|
" ldr r1, =vPortSVCHandler_C \n"
|
||||||
|
" bx r1 \n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
114
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.h
Normal file
114
portable/GCC/ARM_CM52_NTZ/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PORT_ASM_H__
|
||||||
|
#define __PORT_ASM_H__
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
/* MPU wrappers includes. */
|
||||||
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Restore the context of the first task so that the first task starts
|
||||||
|
* executing.
|
||||||
|
*/
|
||||||
|
void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* @note This is a privileged function and should only be called from the kernel
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vResetPrivilege( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the first task.
|
||||||
|
*/
|
||||||
|
void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables interrupts.
|
||||||
|
*/
|
||||||
|
uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables interrupts.
|
||||||
|
*/
|
||||||
|
void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PendSV Exception handler.
|
||||||
|
*/
|
||||||
|
void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC Handler.
|
||||||
|
*/
|
||||||
|
void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
80
portable/GCC/ARM_CM52_NTZ/non_secure/portmacro.h
Normal file
80
portable/GCC/ARM_CM52_NTZ/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __attribute__( ( used ) )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/GCC/ARM_CM52_NTZ/non_secure/portmacrocommon.h
Normal file
582
portable/GCC/ARM_CM52_NTZ/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_MPU
|
||||||
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type definitions.
|
||||||
|
*/
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE uint32_t
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
|
typedef uint16_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
|
typedef uint32_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
* not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
#else
|
||||||
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portNOP()
|
||||||
|
#define portINLINE __inline
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
|
#endif
|
||||||
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extern declarations.
|
||||||
|
*/
|
||||||
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates 128-bit task's random PAC key.
|
||||||
|
*
|
||||||
|
* @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be
|
||||||
|
* filled with a 128-bit random number.
|
||||||
|
*/
|
||||||
|
void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey );
|
||||||
|
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU specific constants.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
|
#else
|
||||||
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
|
||||||
|
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||||
|
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System call stack.
|
||||||
|
*/
|
||||||
|
typedef struct SYSTEM_CALL_STACK_INFO
|
||||||
|
{
|
||||||
|
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||||
|
uint32_t * pulSystemCallStack;
|
||||||
|
uint32_t * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
|
||||||
|
* 16 17 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 71
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||||
|
* 16 17 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 55
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><-----------><---->
|
||||||
|
* 16 17 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 70
|
||||||
|
|
||||||
|
#else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||||
|
* 16 17 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 54
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><-----------><---->
|
||||||
|
* 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 38
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><---->
|
||||||
|
* 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 22
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><-----------><---->
|
||||||
|
* 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 37
|
||||||
|
|
||||||
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><---->
|
||||||
|
* 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||||
|
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||||
|
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||||
|
|
||||||
|
/* Size of an Access Control List (ACL) entry in bits. */
|
||||||
|
#define portACL_ENTRY_SIZE_BITS ( 32U )
|
||||||
|
|
||||||
|
typedef struct MPU_SETTINGS
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_CONTEXT_SIZE ];
|
||||||
|
uint32_t ulTaskFlags;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
|
||||||
|
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||||
|
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} xMPU_SETTINGS;
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler utilities.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portYIELD() __asm volatile ( "svc %0" ::"i" ( portSVC_YIELD ) : "memory" )
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#else
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tickless idle/low power functionality.
|
||||||
|
*/
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
|
*/
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raise an SVC request to raise privilege.
|
||||||
|
*
|
||||||
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
|
* then it raises the privilege. If this is called from any other place,
|
||||||
|
* the privilege is not raised.
|
||||||
|
*/
|
||||||
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
|
#else
|
||||||
|
#define portIS_PRIVILEGED()
|
||||||
|
#define portRAISE_PRIVILEGE()
|
||||||
|
#define portRESET_PRIVILEGE()
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Barriers.
|
||||||
|
*/
|
||||||
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store/clear the ready priorities in a bit map.
|
||||||
|
*/
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
1242
portable/IAR/ARM_CM52/non_secure/mpu_wrappers_v2_asm.S
Normal file
1242
portable/IAR/ARM_CM52/non_secure/mpu_wrappers_v2_asm.S
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/IAR/ARM_CM52/non_secure/port.c
Normal file
2280
portable/IAR/ARM_CM52/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
114
portable/IAR/ARM_CM52/non_secure/portasm.h
Normal file
114
portable/IAR/ARM_CM52/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PORT_ASM_H__
|
||||||
|
#define __PORT_ASM_H__
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
/* MPU wrappers includes. */
|
||||||
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Restore the context of the first task so that the first task starts
|
||||||
|
* executing.
|
||||||
|
*/
|
||||||
|
void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* @note This is a privileged function and should only be called from the kernel
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vResetPrivilege( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the first task.
|
||||||
|
*/
|
||||||
|
void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables interrupts.
|
||||||
|
*/
|
||||||
|
uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables interrupts.
|
||||||
|
*/
|
||||||
|
void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PendSV Exception handler.
|
||||||
|
*/
|
||||||
|
void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC Handler.
|
||||||
|
*/
|
||||||
|
void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
543
portable/IAR/ARM_CM52/non_secure/portasm.s
Normal file
543
portable/IAR/ARM_CM52/non_secure/portasm.s
Normal file
|
|
@ -0,0 +1,543 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Including FreeRTOSConfig.h here will cause build errors if the header file
|
||||||
|
contains code not understood by the assembler - for example the 'extern' keyword.
|
||||||
|
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
|
||||||
|
the code is included in C files but excluded by the preprocessor in assembly
|
||||||
|
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* System call numbers includes. */
|
||||||
|
#include "mpu_syscall_numbers.h"
|
||||||
|
|
||||||
|
#ifndef configUSE_MPU_WRAPPERS_V1
|
||||||
|
#define configUSE_MPU_WRAPPERS_V1 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN pxCurrentTCB
|
||||||
|
EXTERN xSecureContext
|
||||||
|
EXTERN vTaskSwitchContext
|
||||||
|
EXTERN vPortSVCHandler_C
|
||||||
|
EXTERN SecureContext_SaveContext
|
||||||
|
EXTERN SecureContext_LoadContext
|
||||||
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
EXTERN vSystemCallEnter
|
||||||
|
EXTERN vSystemCallExit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PUBLIC xIsPrivileged
|
||||||
|
PUBLIC vResetPrivilege
|
||||||
|
PUBLIC vPortAllocateSecureContext
|
||||||
|
PUBLIC vRestoreContextOfFirstTask
|
||||||
|
PUBLIC vRaisePrivilege
|
||||||
|
PUBLIC vStartFirstTask
|
||||||
|
PUBLIC ulSetInterruptMask
|
||||||
|
PUBLIC vClearInterruptMask
|
||||||
|
PUBLIC PendSV_Handler
|
||||||
|
PUBLIC SVC_Handler
|
||||||
|
PUBLIC vPortFreeSecureContext
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*---------------- Unprivileged Functions -------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
SECTION .text:CODE:NOROOT(2)
|
||||||
|
THUMB
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
xIsPrivileged:
|
||||||
|
mrs r0, control /* r0 = CONTROL. */
|
||||||
|
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
ite ne
|
||||||
|
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
|
moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vResetPrivilege:
|
||||||
|
mrs r0, control /* r0 = CONTROL. */
|
||||||
|
orr r0, r0, #1 /* r0 = r0 | 1. */
|
||||||
|
msr control, r0 /* CONTROL = r0. */
|
||||||
|
bx lr /* Return to the caller. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vPortAllocateSecureContext:
|
||||||
|
svc 100 /* Secure context is allocated in the supervisor call. portSVC_ALLOCATE_SECURE_CONTEXT = 100. */
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*----------------- Privileged Functions --------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
SECTION privileged_functions:CODE:NOROOT(2)
|
||||||
|
THUMB
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
vRestoreContextOfFirstTask:
|
||||||
|
program_mpu_first_task:
|
||||||
|
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r0, [r3] /* r0 = pxCurrentTCB. */
|
||||||
|
|
||||||
|
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Disable MPU. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
str r1, [r2] /* Program MAIR0. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
|
||||||
|
movs r3, #4 /* r3 = 4. */
|
||||||
|
str r3, [r1] /* Program RNR = 4. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
movs r3, #8 /* r3 = 8. */
|
||||||
|
str r3, [r1] /* Program RNR = 8. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
movs r3, #12 /* r3 = 12. */
|
||||||
|
str r3, [r1] /* Program RNR = 12. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 set of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
orr r2, #1 /* r2 = r1 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Enable MPU. */
|
||||||
|
dsb /* Force memory writes before continuing. */
|
||||||
|
|
||||||
|
restore_context_first_task:
|
||||||
|
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r3] /* r1 = pxCurrentTCB.*/
|
||||||
|
ldr r2, [r1] /* r2 = Location of saved context in TCB. */
|
||||||
|
|
||||||
|
restore_special_regs_first_task:
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_1, r4
|
||||||
|
msr PAC_KEY_P_2, r5
|
||||||
|
msr PAC_KEY_P_3, r6
|
||||||
|
clrm {r3-r6} /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||||
|
msr psp, r3
|
||||||
|
msr psplim, r4
|
||||||
|
msr control, r5
|
||||||
|
ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
str r0, [r4] /* Restore xSecureContext. */
|
||||||
|
|
||||||
|
restore_general_regs_first_task:
|
||||||
|
ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */
|
||||||
|
stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */
|
||||||
|
ldmdb r2!, {r4-r11} /* r4-r11 restored. */
|
||||||
|
|
||||||
|
restore_context_done_first_task:
|
||||||
|
str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
mov r0, #0
|
||||||
|
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
vRestoreContextOfFirstTask:
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r3, [r2] /* Read pxCurrentTCB. */
|
||||||
|
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */
|
||||||
|
msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_2, r2
|
||||||
|
msr PAC_KEY_P_1, r3
|
||||||
|
msr PAC_KEY_P_0, r4
|
||||||
|
clrm {r1-r4} /* Clear r1-r4. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
|
||||||
|
ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
|
||||||
|
ldr r4, =xSecureContext
|
||||||
|
str r1, [r4] /* Set xSecureContext to this task's value for the same. */
|
||||||
|
msr psplim, r2 /* Set this task's PSPLIM value. */
|
||||||
|
mrs r1, control /* Obtain current control register value. */
|
||||||
|
orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */
|
||||||
|
msr control, r1 /* Write back the new control register value. */
|
||||||
|
adds r0, #32 /* Discard everything up to r0. */
|
||||||
|
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||||
|
isb
|
||||||
|
mov r0, #0
|
||||||
|
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
bx r3 /* Finally, branch to EXC_RETURN. */
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vRaisePrivilege:
|
||||||
|
mrs r0, control /* Read the CONTROL register. */
|
||||||
|
bic r0, r0, #1 /* Clear the bit 0. */
|
||||||
|
msr control, r0 /* Write back the new CONTROL value. */
|
||||||
|
bx lr /* Return to the caller. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vStartFirstTask:
|
||||||
|
ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */
|
||||||
|
ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */
|
||||||
|
ldr r0, [r0] /* The first entry in vector table is stack pointer. */
|
||||||
|
msr msp, r0 /* Set the MSP back to the start of the stack. */
|
||||||
|
cpsie i /* Globally enable interrupts. */
|
||||||
|
cpsie f
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
svc 102 /* System call to start the first task. portSVC_START_SCHEDULER = 102. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
ulSetInterruptMask:
|
||||||
|
mrs r0, basepri /* r0 = basepri. Return original basepri value. */
|
||||||
|
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
|
msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vClearInterruptMask:
|
||||||
|
msr basepri, r0 /* basepri = ulMask. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
PendSV_Handler:
|
||||||
|
ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
|
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||||
|
ldr r2, [r1] /* r2 = Location in TCB where the context should be saved. */
|
||||||
|
|
||||||
|
cbz r0, save_ns_context /* No secure context to save. */
|
||||||
|
save_s_context:
|
||||||
|
push {r0-r2, lr}
|
||||||
|
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
pop {r0-r2, lr}
|
||||||
|
|
||||||
|
save_ns_context:
|
||||||
|
mov r3, lr /* r3 = LR (EXC_RETURN). */
|
||||||
|
lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
bmi save_special_regs /* r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
|
||||||
|
save_general_regs:
|
||||||
|
mrs r3, psp
|
||||||
|
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
add r3, r3, #0x20 /* Move r3 to location where s0 is saved. */
|
||||||
|
tst lr, #0x10
|
||||||
|
ittt eq
|
||||||
|
vstmiaeq r2!, {s16-s31} /* Store s16-s31. */
|
||||||
|
vldmiaeq r3, {s0-s16} /* Copy hardware saved FP context into s0-s16. */
|
||||||
|
vstmiaeq r2!, {s0-s16} /* Store hardware saved FP context. */
|
||||||
|
sub r3, r3, #0x20 /* Set r3 back to the location of hardware saved context. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
|
stmia r2!, {r4-r11} /* Store r4-r11. */
|
||||||
|
ldmia r3, {r4-r11} /* Copy the hardware saved context into r4-r11. */
|
||||||
|
stmia r2!, {r4-r11} /* Store the hardware saved context. */
|
||||||
|
|
||||||
|
save_special_regs:
|
||||||
|
mrs r3, psp /* r3 = PSP. */
|
||||||
|
mrs r4, psplim /* r4 = PSPLIM. */
|
||||||
|
mrs r5, control /* r5 = CONTROL. */
|
||||||
|
stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
mrs r4, PAC_KEY_P_1
|
||||||
|
mrs r5, PAC_KEY_P_2
|
||||||
|
mrs r6, PAC_KEY_P_3
|
||||||
|
stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */
|
||||||
|
clrm {r3-r6} /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
|
||||||
|
str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
|
|
||||||
|
select_next_task:
|
||||||
|
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
|
msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
mov r0, #0 /* r0 = 0. */
|
||||||
|
msr basepri, r0 /* Enable interrupts. */
|
||||||
|
|
||||||
|
program_mpu:
|
||||||
|
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r0, [r3] /* r0 = pxCurrentTCB.*/
|
||||||
|
|
||||||
|
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Disable MPU. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
str r1, [r2] /* Program MAIR0. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
|
||||||
|
movs r3, #4 /* r3 = 4. */
|
||||||
|
str r3, [r1] /* Program RNR = 4. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
movs r3, #8 /* r3 = 8. */
|
||||||
|
str r3, [r1] /* Program RNR = 8. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
movs r3, #12 /* r3 = 12. */
|
||||||
|
str r3, [r1] /* Program RNR = 12. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Enable MPU. */
|
||||||
|
dsb /* Force memory writes before continuing. */
|
||||||
|
|
||||||
|
restore_context:
|
||||||
|
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r3] /* r1 = pxCurrentTCB.*/
|
||||||
|
ldr r2, [r1] /* r2 = Location of saved context in TCB. */
|
||||||
|
|
||||||
|
restore_special_regs:
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_1, r4
|
||||||
|
msr PAC_KEY_P_2, r5
|
||||||
|
msr PAC_KEY_P_3, r6
|
||||||
|
clrm {r3-r6} /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
|
||||||
|
msr psp, r3
|
||||||
|
msr psplim, r4
|
||||||
|
msr control, r5
|
||||||
|
ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
str r0, [r4] /* Restore xSecureContext. */
|
||||||
|
cbz r0, restore_ns_context /* No secure context to restore. */
|
||||||
|
|
||||||
|
restore_s_context:
|
||||||
|
push {r1-r3, lr}
|
||||||
|
bl SecureContext_LoadContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
pop {r1-r3, lr}
|
||||||
|
|
||||||
|
restore_ns_context:
|
||||||
|
mov r0, lr /* r0 = LR (EXC_RETURN). */
|
||||||
|
lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
|
||||||
|
restore_general_regs:
|
||||||
|
ldmdb r2!, {r4-r11} /* r4-r11 contain hardware saved context. */
|
||||||
|
stmia r3!, {r4-r11} /* Copy the hardware saved context on the task stack. */
|
||||||
|
ldmdb r2!, {r4-r11} /* r4-r11 restored. */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
tst lr, #0x10
|
||||||
|
ittt eq
|
||||||
|
vldmdbeq r2!, {s0-s16} /* s0-s16 contain hardware saved FP context. */
|
||||||
|
vstmiaeq r3!, {s0-s16} /* Copy hardware saved FP context on the task stack. */
|
||||||
|
vldmdbeq r2!, {s16-s31} /* Restore s16-s31. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
|
restore_context_done:
|
||||||
|
str r2, [r1] /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
PendSV_Handler:
|
||||||
|
ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
ldr r0, [r3] /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */
|
||||||
|
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r3] /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */
|
||||||
|
mrs r2, psp /* Read PSP in r2. */
|
||||||
|
|
||||||
|
cbz r0, save_ns_context /* No secure context to save. */
|
||||||
|
save_s_context:
|
||||||
|
push {r0-r2, lr}
|
||||||
|
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
pop {r0-r2, lr}
|
||||||
|
|
||||||
|
save_ns_context:
|
||||||
|
mov r3, lr /* r3 = LR. */
|
||||||
|
lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */
|
||||||
|
|
||||||
|
save_general_regs:
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
it eq
|
||||||
|
vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */
|
||||||
|
|
||||||
|
save_special_regs:
|
||||||
|
mrs r3, psplim /* r3 = PSPLIM. */
|
||||||
|
stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
mrs r4, PAC_KEY_P_2
|
||||||
|
mrs r5, PAC_KEY_P_1
|
||||||
|
mrs r6, PAC_KEY_P_0
|
||||||
|
stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */
|
||||||
|
clrm {r3-r6} /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
|
||||||
|
str r2, [r1] /* Save the new top of stack in TCB. */
|
||||||
|
|
||||||
|
select_next_task:
|
||||||
|
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
|
msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
mov r0, #0 /* r0 = 0. */
|
||||||
|
msr basepri, r0 /* Enable interrupts. */
|
||||||
|
|
||||||
|
restore_context:
|
||||||
|
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r3] /* Read pxCurrentTCB. */
|
||||||
|
ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
|
||||||
|
|
||||||
|
restore_special_regs:
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */
|
||||||
|
msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_2, r4
|
||||||
|
msr PAC_KEY_P_1, r5
|
||||||
|
msr PAC_KEY_P_0, r6
|
||||||
|
clrm {r3-r6} /* Clear r3-r6. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */
|
||||||
|
msr psplim, r3 /* Restore the PSPLIM register value for the task. */
|
||||||
|
ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
|
||||||
|
str r0, [r3] /* Restore the task's xSecureContext. */
|
||||||
|
cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */
|
||||||
|
|
||||||
|
restore_s_context:
|
||||||
|
push {r1-r3, lr}
|
||||||
|
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
|
||||||
|
pop {r1-r3, lr}
|
||||||
|
|
||||||
|
restore_ns_context:
|
||||||
|
mov r0, lr /* r0 = LR (EXC_RETURN). */
|
||||||
|
lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */
|
||||||
|
bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
|
||||||
|
|
||||||
|
restore_general_regs:
|
||||||
|
ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
it eq
|
||||||
|
vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
|
restore_context_done:
|
||||||
|
msr psp, r2 /* Remember the new top of stack for the task. */
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
|
SVC_Handler:
|
||||||
|
tst lr, #4
|
||||||
|
ite eq
|
||||||
|
mrseq r0, msp
|
||||||
|
mrsne r0, psp
|
||||||
|
|
||||||
|
ldr r1, [r0, #24]
|
||||||
|
ldrb r2, [r1, #-2]
|
||||||
|
cmp r2, #NUM_SYSTEM_CALLS
|
||||||
|
blt syscall_enter
|
||||||
|
cmp r2, #104 /* portSVC_SYSTEM_CALL_EXIT. */
|
||||||
|
beq syscall_exit
|
||||||
|
b vPortSVCHandler_C
|
||||||
|
|
||||||
|
syscall_enter:
|
||||||
|
mov r1, lr
|
||||||
|
b vSystemCallEnter
|
||||||
|
|
||||||
|
syscall_exit:
|
||||||
|
mov r1, lr
|
||||||
|
b vSystemCallExit
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
SVC_Handler:
|
||||||
|
tst lr, #4
|
||||||
|
ite eq
|
||||||
|
mrseq r0, msp
|
||||||
|
mrsne r0, psp
|
||||||
|
b vPortSVCHandler_C
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vPortFreeSecureContext:
|
||||||
|
/* r0 = uint32_t *pulTCB. */
|
||||||
|
ldr r2, [r0] /* The first item in the TCB is the top of the stack. */
|
||||||
|
ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */
|
||||||
|
cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */
|
||||||
|
it ne
|
||||||
|
svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
END
|
||||||
87
portable/IAR/ARM_CM52/non_secure/portmacro.h
Normal file
87
portable/IAR/ARM_CM52/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __root
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
* the source code because to do so would cause other compilers to generate
|
||||||
|
* warnings. */
|
||||||
|
#pragma diag_suppress=Be006
|
||||||
|
#pragma diag_suppress=Pa082
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/IAR/ARM_CM52/non_secure/portmacrocommon.h
Normal file
582
portable/IAR/ARM_CM52/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_MPU
|
||||||
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type definitions.
|
||||||
|
*/
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE uint32_t
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
|
typedef uint16_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
|
typedef uint32_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
* not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
#else
|
||||||
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portNOP()
|
||||||
|
#define portINLINE __inline
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
|
#endif
|
||||||
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extern declarations.
|
||||||
|
*/
|
||||||
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates 128-bit task's random PAC key.
|
||||||
|
*
|
||||||
|
* @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be
|
||||||
|
* filled with a 128-bit random number.
|
||||||
|
*/
|
||||||
|
void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey );
|
||||||
|
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU specific constants.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
|
#else
|
||||||
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
|
||||||
|
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||||
|
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System call stack.
|
||||||
|
*/
|
||||||
|
typedef struct SYSTEM_CALL_STACK_INFO
|
||||||
|
{
|
||||||
|
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||||
|
uint32_t * pulSystemCallStack;
|
||||||
|
uint32_t * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
|
||||||
|
* 16 17 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 71
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||||
|
* 16 17 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 55
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><-----------><---->
|
||||||
|
* 16 17 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 70
|
||||||
|
|
||||||
|
#else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||||
|
* 16 17 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 54
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><-----------><---->
|
||||||
|
* 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 38
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><---->
|
||||||
|
* 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 22
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><-----------><---->
|
||||||
|
* 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 37
|
||||||
|
|
||||||
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><---->
|
||||||
|
* 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||||
|
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||||
|
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||||
|
|
||||||
|
/* Size of an Access Control List (ACL) entry in bits. */
|
||||||
|
#define portACL_ENTRY_SIZE_BITS ( 32U )
|
||||||
|
|
||||||
|
typedef struct MPU_SETTINGS
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_CONTEXT_SIZE ];
|
||||||
|
uint32_t ulTaskFlags;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
|
||||||
|
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||||
|
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} xMPU_SETTINGS;
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler utilities.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portYIELD() __asm volatile ( "svc %0" ::"i" ( portSVC_YIELD ) : "memory" )
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#else
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tickless idle/low power functionality.
|
||||||
|
*/
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
|
*/
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raise an SVC request to raise privilege.
|
||||||
|
*
|
||||||
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
|
* then it raises the privilege. If this is called from any other place,
|
||||||
|
* the privilege is not raised.
|
||||||
|
*/
|
||||||
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
|
#else
|
||||||
|
#define portIS_PRIVILEGED()
|
||||||
|
#define portRAISE_PRIVILEGE()
|
||||||
|
#define portRESET_PRIVILEGE()
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Barriers.
|
||||||
|
*/
|
||||||
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store/clear the ready priorities in a bit map.
|
||||||
|
*/
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
354
portable/IAR/ARM_CM52/secure/secure_context.c
Normal file
354
portable/IAR/ARM_CM52/secure/secure_context.c
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Secure context includes. */
|
||||||
|
#include "secure_context.h"
|
||||||
|
|
||||||
|
/* Secure heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 0 --> Thread mode is privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CONTROL value for un-privileged tasks.
|
||||||
|
*
|
||||||
|
* Bit[0] - 1 --> Thread mode is un-privileged.
|
||||||
|
* Bit[1] - 1 --> Thread mode uses PSP.
|
||||||
|
*/
|
||||||
|
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Size of stack seal values in bytes.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_SIZE 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stack seal value as recommended by ARM.
|
||||||
|
*/
|
||||||
|
#define securecontextSTACK_SEAL_VALUE 0xFEF5EDA5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum number of secure contexts.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigMAX_SECURE_CONTEXTS
|
||||||
|
#define secureconfigMAX_SECURE_CONTEXTS 8UL
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pre-allocated array of secure contexts.
|
||||||
|
*/
|
||||||
|
SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a free secure context for a task from the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* This function ensures that only one secure context is allocated for a task.
|
||||||
|
*
|
||||||
|
* @param[in] pvTaskHandle The task handle for which the secure context is allocated.
|
||||||
|
*
|
||||||
|
* @return Index of a free secure context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the secure context to the secure context pool (xSecureContexts).
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
|
||||||
|
*/
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex );
|
||||||
|
|
||||||
|
/* These are implemented in assembly. */
|
||||||
|
extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static uint32_t ulGetSecureContext( void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Start with invalid index. */
|
||||||
|
uint32_t i, ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
if( ( xSecureContexts[ i ].pucCurrentStackPointer == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackLimit == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pucStackStart == NULL ) &&
|
||||||
|
( xSecureContexts[ i ].pvTaskHandle == NULL ) &&
|
||||||
|
( ulSecureContextIndex == secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = i;
|
||||||
|
}
|
||||||
|
else if( xSecureContexts[ i ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* A task can only have one secure context. Do not allocate a second
|
||||||
|
* context for the same task. */
|
||||||
|
ulSecureContextIndex = secureconfigMAX_SECURE_CONTEXTS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulSecureContextIndex;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void vReturnSecureContext( uint32_t ulSecureContextIndex )
|
||||||
|
{
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, i;
|
||||||
|
static uint32_t ulSecureContextsInitialized = 0;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( ulSecureContextsInitialized == 0 ) )
|
||||||
|
{
|
||||||
|
/* Ensure to initialize secure contexts only once. */
|
||||||
|
ulSecureContextsInitialized = 1;
|
||||||
|
|
||||||
|
/* No stack for thread mode until a task's context is loaded. */
|
||||||
|
secureportSET_PSPLIM( securecontextNO_STACK );
|
||||||
|
secureportSET_PSP( securecontextNO_STACK );
|
||||||
|
|
||||||
|
/* Initialize all secure contexts. */
|
||||||
|
for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
|
||||||
|
{
|
||||||
|
xSecureContexts[ i ].pucCurrentStackPointer = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackLimit = NULL;
|
||||||
|
xSecureContexts[ i ].pucStackStart = NULL;
|
||||||
|
xSecureContexts[ i ].pvTaskHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be unprivileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Configure thread mode to use PSP and to be privileged. */
|
||||||
|
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
uint8_t * pucStackMemory = NULL;
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
SecureContextHandle_t xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
uint32_t * pulCurrentStackPointer = NULL;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) and Process Stack Limit
|
||||||
|
* Register (PSPLIM) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode.
|
||||||
|
* Also do nothing, if a secure context us already loaded. PSPLIM is set to
|
||||||
|
* securecontextNO_STACK when no secure context is loaded. */
|
||||||
|
if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) )
|
||||||
|
{
|
||||||
|
/* Obtain a free secure context. */
|
||||||
|
ulSecureContextIndex = ulGetSecureContext( pvTaskHandle );
|
||||||
|
|
||||||
|
/* Were we able to get a free context? */
|
||||||
|
if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
|
||||||
|
{
|
||||||
|
/* Allocate the stack space. */
|
||||||
|
pucStackMemory = pvPortMalloc( ulSecureStackSize + securecontextSTACK_SEAL_SIZE );
|
||||||
|
|
||||||
|
if( pucStackMemory != NULL )
|
||||||
|
{
|
||||||
|
/* Since stack grows down, the starting point will be the last
|
||||||
|
* location. Note that this location is next to the last
|
||||||
|
* allocated byte for stack (excluding the space for seal values)
|
||||||
|
* because the hardware decrements the stack pointer before
|
||||||
|
* writing i.e. if stack pointer is 0x2, a push operation will
|
||||||
|
* decrement the stack pointer to 0x1 and then write at 0x1. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
|
||||||
|
|
||||||
|
/* Seal the created secure process stack. */
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
*( uint32_t * ) ( pucStackMemory + ulSecureStackSize + 4 ) = securecontextSTACK_SEAL_VALUE;
|
||||||
|
|
||||||
|
/* The stack cannot go beyond this location. This value is
|
||||||
|
* programmed in the PSPLIM register on context switch.*/
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
|
||||||
|
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pvTaskHandle = pvTaskHandle;
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
{
|
||||||
|
/* Store the correct CONTROL value for the task on the stack.
|
||||||
|
* This value is programmed in the CONTROL register on
|
||||||
|
* context switch. */
|
||||||
|
pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
pulCurrentStackPointer--;
|
||||||
|
|
||||||
|
if( ulIsTaskPrivileged )
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the current stack pointer. This value is programmed in
|
||||||
|
* the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
|
||||||
|
}
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
{
|
||||||
|
/* Current SP is set to the starting of the stack. This
|
||||||
|
* value programmed in the PSP register on context switch. */
|
||||||
|
xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
|
||||||
|
}
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* Ensure to never return 0 as a valid context handle. */
|
||||||
|
xSecureContextHandle = ulSecureContextIndex + 1UL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xSecureContextHandle;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR, ulSecureContextIndex;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* Only free if a valid context handle is passed. */
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
/* Ensure that the secure context being deleted is associated with
|
||||||
|
* the task. */
|
||||||
|
if( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle )
|
||||||
|
{
|
||||||
|
/* Free the stack space. */
|
||||||
|
vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
|
||||||
|
|
||||||
|
/* Return the secure context back to the free secure contexts pool. */
|
||||||
|
vReturnSecureContext( ulSecureContextIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that no secure context is loaded and the task is loading it's
|
||||||
|
* own context. */
|
||||||
|
if( ( pucStackLimit == securecontextNO_STACK ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle )
|
||||||
|
{
|
||||||
|
uint8_t * pucStackLimit;
|
||||||
|
uint32_t ulSecureContextIndex;
|
||||||
|
|
||||||
|
if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
|
||||||
|
{
|
||||||
|
ulSecureContextIndex = xSecureContextHandle - 1UL;
|
||||||
|
|
||||||
|
secureportREAD_PSPLIM( pucStackLimit );
|
||||||
|
|
||||||
|
/* Ensure that task's context is loaded and the task is saving it's own
|
||||||
|
* context. */
|
||||||
|
if( ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == pucStackLimit ) &&
|
||||||
|
( xSecureContexts[ ulSecureContextIndex ].pvTaskHandle == pvTaskHandle ) )
|
||||||
|
{
|
||||||
|
SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
138
portable/IAR/ARM_CM52/secure/secure_context.h
Normal file
138
portable/IAR/ARM_CM52/secure/secure_context.h
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_CONTEXT_H__
|
||||||
|
#define __SECURE_CONTEXT_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PSP value when no secure context is loaded.
|
||||||
|
*/
|
||||||
|
#define securecontextNO_STACK 0x0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Invalid context ID.
|
||||||
|
*/
|
||||||
|
#define securecontextINVALID_CONTEXT_ID 0UL
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure to represent a secure context.
|
||||||
|
*
|
||||||
|
* @note Since stack grows down, pucStackStart is the highest address while
|
||||||
|
* pucStackLimit is the first address of the allocated memory.
|
||||||
|
*/
|
||||||
|
typedef struct SecureContext
|
||||||
|
{
|
||||||
|
uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
|
||||||
|
uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
|
||||||
|
uint8_t * pucStackStart; /**< First location of the stack memory. */
|
||||||
|
void * pvTaskHandle; /**< Task handle of the task this context is associated with. */
|
||||||
|
} SecureContext_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Opaque handle for a secure context.
|
||||||
|
*/
|
||||||
|
typedef uint32_t SecureContextHandle_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the secure context management system.
|
||||||
|
*
|
||||||
|
* PSP is set to NULL and therefore a task must allocate and load a context
|
||||||
|
* before calling any secure side function in the thread mode.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureContext_Init( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates a context on the secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
|
||||||
|
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
|
||||||
|
*
|
||||||
|
* @return Opaque context handle if context is successfully allocated, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
uint32_t ulIsTaskPrivileged,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the
|
||||||
|
* context to be freed.
|
||||||
|
*/
|
||||||
|
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be loaded.
|
||||||
|
*/
|
||||||
|
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves the given context.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*
|
||||||
|
* @param[in] xSecureContextHandle Context handle corresponding to the context
|
||||||
|
* to be saved.
|
||||||
|
*/
|
||||||
|
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle,
|
||||||
|
void * pvTaskHandle );
|
||||||
|
|
||||||
|
#endif /* __SECURE_CONTEXT_H__ */
|
||||||
86
portable/IAR/ARM_CM52/secure/secure_context_port_asm.s
Normal file
86
portable/IAR/ARM_CM52/secure/secure_context_port_asm.s
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
SECTION .text:CODE:NOROOT(2)
|
||||||
|
THUMB
|
||||||
|
|
||||||
|
/* Including FreeRTOSConfig.h here will cause build errors if the header file
|
||||||
|
contains code not understood by the assembler - for example the 'extern' keyword.
|
||||||
|
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
|
||||||
|
the code is included in C files but excluded by the preprocessor in assembly
|
||||||
|
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
PUBLIC SecureContext_LoadContextAsm
|
||||||
|
PUBLIC SecureContext_SaveContextAsm
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
SecureContext_LoadContextAsm:
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
mrs r1, ipsr /* r1 = IPSR. */
|
||||||
|
cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
|
||||||
|
msr control, r3 /* CONTROL = r3. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
msr psplim, r2 /* PSPLIM = r2. */
|
||||||
|
msr psp, r1 /* PSP = r1. */
|
||||||
|
|
||||||
|
load_ctx_therad_mode:
|
||||||
|
bx lr
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
SecureContext_SaveContextAsm:
|
||||||
|
/* pxSecureContext value is in r0. */
|
||||||
|
mrs r1, ipsr /* r1 = IPSR. */
|
||||||
|
cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
|
||||||
|
mrs r1, psp /* r1 = PSP. */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
vstmdb r1!, {s0} /* Trigger the deferred stacking of FPU registers. */
|
||||||
|
vldmia r1!, {s0} /* Nullify the effect of the previous statement. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
mrs r2, control /* r2 = CONTROL. */
|
||||||
|
stmdb r1!, {r2} /* Store CONTROL value on the stack. */
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
|
||||||
|
movs r1, #0 /* r1 = securecontextNO_STACK. */
|
||||||
|
msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
|
||||||
|
msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
|
||||||
|
|
||||||
|
save_ctx_therad_mode:
|
||||||
|
bx lr
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
END
|
||||||
485
portable/IAR/ARM_CM52/secure/secure_heap.c
Normal file
485
portable/IAR/ARM_CM52/secure/secure_heap.c
Normal file
|
|
@ -0,0 +1,485 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Configuration includes. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* Secure context heap includes. */
|
||||||
|
#include "secure_heap.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Total heap size.
|
||||||
|
*/
|
||||||
|
#ifndef secureconfigTOTAL_HEAP_SIZE
|
||||||
|
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No test marker by default. */
|
||||||
|
#ifndef mtCOVERAGE_TEST_MARKER
|
||||||
|
#define mtCOVERAGE_TEST_MARKER()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceMALLOC
|
||||||
|
#define traceMALLOC( pvReturn, xWantedSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No tracing by default. */
|
||||||
|
#ifndef traceFREE
|
||||||
|
#define traceFREE( pv, xBlockSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Block sizes must not get too small. */
|
||||||
|
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
|
||||||
|
|
||||||
|
/* Assumes 8bit bytes! */
|
||||||
|
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
|
||||||
|
|
||||||
|
/* Max value that fits in a size_t type. */
|
||||||
|
#define secureheapSIZE_MAX ( ~( ( size_t ) 0 ) )
|
||||||
|
|
||||||
|
/* Check if adding a and b will result in overflow. */
|
||||||
|
#define secureheapADD_WILL_OVERFLOW( a, b ) ( ( a ) > ( secureheapSIZE_MAX - ( b ) ) )
|
||||||
|
|
||||||
|
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
|
||||||
|
* the allocation status of a block. When MSB of the xBlockSize member of
|
||||||
|
* an BlockLink_t structure is set then the block belongs to the application.
|
||||||
|
* When the bit is free the block is still part of the free heap space. */
|
||||||
|
#define secureheapBLOCK_ALLOCATED_BITMASK ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 ) )
|
||||||
|
#define secureheapBLOCK_SIZE_IS_VALID( xBlockSize ) ( ( ( xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) == 0 )
|
||||||
|
#define secureheapBLOCK_IS_ALLOCATED( pxBlock ) ( ( ( pxBlock->xBlockSize ) & secureheapBLOCK_ALLOCATED_BITMASK ) != 0 )
|
||||||
|
#define secureheapALLOCATE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) |= secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
#define secureheapFREE_BLOCK( pxBlock ) ( ( pxBlock->xBlockSize ) &= ~secureheapBLOCK_ALLOCATED_BITMASK )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Allocate the memory for the heap. */
|
||||||
|
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
|
||||||
|
|
||||||
|
/* The application writer has already defined the array used for the RTOS
|
||||||
|
* heap - probably so it can be placed in a special segment or address. */
|
||||||
|
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#else /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
|
||||||
|
#endif /* configAPPLICATION_ALLOCATED_HEAP */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The linked list structure.
|
||||||
|
*
|
||||||
|
* This is used to link free blocks in order of their memory address.
|
||||||
|
*/
|
||||||
|
typedef struct A_BLOCK_LINK
|
||||||
|
{
|
||||||
|
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
|
||||||
|
size_t xBlockSize; /**< The size of the free block. */
|
||||||
|
} BlockLink_t;
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called automatically to setup the required heap structures the first
|
||||||
|
* time pvPortMalloc() is called.
|
||||||
|
*/
|
||||||
|
static void prvHeapInit( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts a block of memory that is being freed into the correct
|
||||||
|
* position in the list of free memory blocks.
|
||||||
|
*
|
||||||
|
* The block being freed will be merged with the block in front it and/or the
|
||||||
|
* block behind it if the memory blocks are adjacent to each other.
|
||||||
|
*
|
||||||
|
* @param[in] pxBlockToInsert The block being freed.
|
||||||
|
*/
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The size of the structure placed at the beginning of each allocated
|
||||||
|
* memory block must by correctly byte aligned.
|
||||||
|
*/
|
||||||
|
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a couple of list links to mark the start and end of the list.
|
||||||
|
*/
|
||||||
|
static BlockLink_t xStart;
|
||||||
|
static BlockLink_t * pxEnd = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Keeps track of the number of free bytes remaining, but says nothing
|
||||||
|
* about fragmentation.
|
||||||
|
*/
|
||||||
|
static size_t xFreeBytesRemaining = 0U;
|
||||||
|
static size_t xMinimumEverFreeBytesRemaining = 0U;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvHeapInit( void )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxFirstFreeBlock;
|
||||||
|
uint8_t * pucAlignedHeap;
|
||||||
|
size_t uxAddress;
|
||||||
|
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
|
||||||
|
|
||||||
|
/* Ensure the heap starts on a correctly aligned boundary. */
|
||||||
|
uxAddress = ( size_t ) ucHeap;
|
||||||
|
|
||||||
|
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
|
||||||
|
{
|
||||||
|
uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
|
||||||
|
}
|
||||||
|
|
||||||
|
pucAlignedHeap = ( uint8_t * ) uxAddress;
|
||||||
|
|
||||||
|
/* xStart is used to hold a pointer to the first item in the list of free
|
||||||
|
* blocks. The void cast is used to prevent compiler warnings. */
|
||||||
|
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
xStart.xBlockSize = ( size_t ) 0;
|
||||||
|
|
||||||
|
/* pxEnd is used to mark the end of the list of free blocks and is inserted
|
||||||
|
* at the end of the heap space. */
|
||||||
|
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
|
||||||
|
uxAddress -= xHeapStructSize;
|
||||||
|
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
pxEnd = ( void * ) uxAddress;
|
||||||
|
pxEnd->xBlockSize = 0;
|
||||||
|
pxEnd->pxNextFreeBlock = NULL;
|
||||||
|
|
||||||
|
/* To start with there is a single free block that is sized to take up the
|
||||||
|
* entire heap space, minus the space taken by pxEnd. */
|
||||||
|
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
|
||||||
|
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
|
||||||
|
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
|
||||||
|
|
||||||
|
/* Only one block exists - and it covers the entire usable heap space. */
|
||||||
|
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxIterator;
|
||||||
|
uint8_t * puc;
|
||||||
|
|
||||||
|
/* Iterate through the list until a block is found that has a higher address
|
||||||
|
* than the block being inserted. */
|
||||||
|
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
/* Nothing to do here, just iterate to the right position. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted after
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxIterator;
|
||||||
|
|
||||||
|
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
|
||||||
|
pxBlockToInsert = pxIterator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the block being inserted, and the block it is being inserted before
|
||||||
|
* make a contiguous block of memory? */
|
||||||
|
puc = ( uint8_t * ) pxBlockToInsert;
|
||||||
|
|
||||||
|
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
|
||||||
|
{
|
||||||
|
if( pxIterator->pxNextFreeBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Form one big block from the two blocks. */
|
||||||
|
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the block being inserted plugged a gap, so was merged with the block
|
||||||
|
* before and the block after, then it's pxNextFreeBlock pointer will have
|
||||||
|
* already been set, and should not be set here as that would make it point
|
||||||
|
* to itself. */
|
||||||
|
if( pxIterator != pxBlockToInsert )
|
||||||
|
{
|
||||||
|
pxIterator->pxNextFreeBlock = pxBlockToInsert;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void * pvPortMalloc( size_t xWantedSize )
|
||||||
|
{
|
||||||
|
BlockLink_t * pxBlock;
|
||||||
|
BlockLink_t * pxPreviousBlock;
|
||||||
|
BlockLink_t * pxNewBlockLink;
|
||||||
|
void * pvReturn = NULL;
|
||||||
|
size_t xAdditionalRequiredSize;
|
||||||
|
size_t xAllocatedBlockSize = 0;
|
||||||
|
|
||||||
|
/* If this is the first call to malloc then the heap will require
|
||||||
|
* initialisation to setup the list of free blocks. */
|
||||||
|
if( pxEnd == NULL )
|
||||||
|
{
|
||||||
|
prvHeapInit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xWantedSize > 0 )
|
||||||
|
{
|
||||||
|
/* The wanted size must be increased so it can contain a BlockLink_t
|
||||||
|
* structure in addition to the requested amount of bytes. */
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xHeapStructSize;
|
||||||
|
|
||||||
|
/* Ensure that blocks are always aligned to the required number
|
||||||
|
* of bytes. */
|
||||||
|
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
|
||||||
|
{
|
||||||
|
/* Byte alignment required. */
|
||||||
|
xAdditionalRequiredSize = secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK );
|
||||||
|
|
||||||
|
if( secureheapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
|
||||||
|
{
|
||||||
|
xWantedSize += xAdditionalRequiredSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xWantedSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the requested block size is not so large that the top bit is set.
|
||||||
|
* The top bit of the block size member of the BlockLink_t structure is used
|
||||||
|
* to determine who owns the block - the application or the kernel, so it
|
||||||
|
* must be free. */
|
||||||
|
if( secureheapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
|
||||||
|
{
|
||||||
|
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
|
||||||
|
{
|
||||||
|
/* Traverse the list from the start (lowest address) block until
|
||||||
|
* one of adequate size is found. */
|
||||||
|
pxPreviousBlock = &xStart;
|
||||||
|
pxBlock = xStart.pxNextFreeBlock;
|
||||||
|
|
||||||
|
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
|
||||||
|
{
|
||||||
|
pxPreviousBlock = pxBlock;
|
||||||
|
pxBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the end marker was reached then a block of adequate size was
|
||||||
|
* not found. */
|
||||||
|
if( pxBlock != pxEnd )
|
||||||
|
{
|
||||||
|
/* Return the memory space pointed to - jumping over the
|
||||||
|
* BlockLink_t structure at its start. */
|
||||||
|
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
|
||||||
|
|
||||||
|
/* This block is being returned for use so must be taken out
|
||||||
|
* of the list of free blocks. */
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
|
||||||
|
|
||||||
|
/* If the block is larger than required it can be split into
|
||||||
|
* two. */
|
||||||
|
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
|
||||||
|
{
|
||||||
|
/* This block is to be split into two. Create a new
|
||||||
|
* block following the number of bytes requested. The void
|
||||||
|
* cast is used to prevent byte alignment warnings from the
|
||||||
|
* compiler. */
|
||||||
|
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
|
||||||
|
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
|
||||||
|
/* Calculate the sizes of two blocks split from the single
|
||||||
|
* block. */
|
||||||
|
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
|
||||||
|
pxBlock->xBlockSize = xWantedSize;
|
||||||
|
|
||||||
|
/* Insert the new block into the list of free blocks. */
|
||||||
|
pxNewBlockLink->pxNextFreeBlock = pxPreviousBlock->pxNextFreeBlock;
|
||||||
|
pxPreviousBlock->pxNextFreeBlock = pxNewBlockLink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
xFreeBytesRemaining -= pxBlock->xBlockSize;
|
||||||
|
|
||||||
|
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
|
||||||
|
{
|
||||||
|
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
xAllocatedBlockSize = pxBlock->xBlockSize;
|
||||||
|
|
||||||
|
/* The block is being returned - it is allocated and owned by
|
||||||
|
* the application and has no "next" block. */
|
||||||
|
secureheapALLOCATE_BLOCK( pxBlock );
|
||||||
|
pxBlock->pxNextFreeBlock = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
traceMALLOC( pvReturn, xAllocatedBlockSize );
|
||||||
|
|
||||||
|
/* Prevent compiler warnings when trace macros are not used. */
|
||||||
|
( void ) xAllocatedBlockSize;
|
||||||
|
|
||||||
|
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
|
||||||
|
{
|
||||||
|
if( pvReturn == NULL )
|
||||||
|
{
|
||||||
|
extern void vApplicationMallocFailedHook( void );
|
||||||
|
vApplicationMallocFailedHook();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
|
||||||
|
|
||||||
|
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
|
||||||
|
return pvReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vPortFree( void * pv )
|
||||||
|
{
|
||||||
|
uint8_t * puc = ( uint8_t * ) pv;
|
||||||
|
BlockLink_t * pxLink;
|
||||||
|
|
||||||
|
if( pv != NULL )
|
||||||
|
{
|
||||||
|
/* The memory being freed will have an BlockLink_t structure immediately
|
||||||
|
* before it. */
|
||||||
|
puc -= xHeapStructSize;
|
||||||
|
|
||||||
|
/* This casting is to keep the compiler from issuing warnings. */
|
||||||
|
pxLink = ( void * ) puc;
|
||||||
|
|
||||||
|
/* Check the block is actually allocated. */
|
||||||
|
secureportASSERT( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
|
||||||
|
secureportASSERT( pxLink->pxNextFreeBlock == NULL );
|
||||||
|
|
||||||
|
if( secureheapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
|
||||||
|
{
|
||||||
|
if( pxLink->pxNextFreeBlock == NULL )
|
||||||
|
{
|
||||||
|
/* The block is being returned to the heap - it is no longer
|
||||||
|
* allocated. */
|
||||||
|
secureheapFREE_BLOCK( pxLink );
|
||||||
|
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
/* Add this block to the list of free blocks. */
|
||||||
|
xFreeBytesRemaining += pxLink->xBlockSize;
|
||||||
|
traceFREE( pv, pxLink->xBlockSize );
|
||||||
|
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
|
||||||
|
}
|
||||||
|
secureportENABLE_NON_SECURE_INTERRUPTS();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void )
|
||||||
|
{
|
||||||
|
return xMinimumEverFreeBytesRemaining;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
66
portable/IAR/ARM_CM52/secure/secure_heap.h
Normal file
66
portable/IAR/ARM_CM52/secure/secure_heap.h
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_HEAP_H__
|
||||||
|
#define __SECURE_HEAP_H__
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates memory from heap.
|
||||||
|
*
|
||||||
|
* @param[in] xWantedSize The size of the memory to be allocated.
|
||||||
|
*
|
||||||
|
* @return Pointer to the memory region if the allocation is successful, NULL
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
void * pvPortMalloc( size_t xWantedSize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the previously allocated memory.
|
||||||
|
*
|
||||||
|
* @param[in] pv Pointer to the memory to be freed.
|
||||||
|
*/
|
||||||
|
void vPortFree( void * pv );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the free heap size.
|
||||||
|
*
|
||||||
|
* @return Free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetFreeHeapSize( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the minimum ever free heap size.
|
||||||
|
*
|
||||||
|
* @return Minimum ever free heap size.
|
||||||
|
*/
|
||||||
|
size_t xPortGetMinimumEverFreeHeapSize( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_HEAP_H__ */
|
||||||
106
portable/IAR/ARM_CM52/secure/secure_init.c
Normal file
106
portable/IAR/ARM_CM52/secure/secure_init.c
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Secure init includes. */
|
||||||
|
#include "secure_init.h"
|
||||||
|
|
||||||
|
/* Secure port macros. */
|
||||||
|
#include "secure_port_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the SCB.
|
||||||
|
*/
|
||||||
|
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
|
||||||
|
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
|
||||||
|
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constants required to manipulate the FPU.
|
||||||
|
*/
|
||||||
|
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
|
||||||
|
#define secureinitFPCCR_LSPENS_POS ( 29UL )
|
||||||
|
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
|
||||||
|
#define secureinitFPCCR_TS_POS ( 26UL )
|
||||||
|
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
|
||||||
|
|
||||||
|
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
|
||||||
|
#define secureinitNSACR_CP10_POS ( 10UL )
|
||||||
|
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
|
||||||
|
#define secureinitNSACR_CP11_POS ( 11UL )
|
||||||
|
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
|
||||||
|
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
|
||||||
|
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
|
||||||
|
{
|
||||||
|
uint32_t ulIPSR;
|
||||||
|
|
||||||
|
/* Read the Interrupt Program Status Register (IPSR) value. */
|
||||||
|
secureportREAD_IPSR( ulIPSR );
|
||||||
|
|
||||||
|
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
|
||||||
|
* when the processor is running in the Thread Mode. */
|
||||||
|
if( ulIPSR != 0 )
|
||||||
|
{
|
||||||
|
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
|
||||||
|
* permitted. CP11 should be programmed to the same value as CP10. */
|
||||||
|
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
|
||||||
|
|
||||||
|
/* LSPENS = 0 ==> LSPEN is writable from non-secure state. This ensures
|
||||||
|
* that we can enable/disable lazy stacking in port.c file. */
|
||||||
|
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
|
||||||
|
|
||||||
|
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
|
||||||
|
* registers (S16-S31) are also pushed to stack on exception entry and
|
||||||
|
* restored on exception return. */
|
||||||
|
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
54
portable/IAR/ARM_CM52/secure/secure_init.h
Normal file
54
portable/IAR/ARM_CM52/secure/secure_init.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_INIT_H__
|
||||||
|
#define __SECURE_INIT_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-prioritizes the non-secure exceptions.
|
||||||
|
*
|
||||||
|
* This is needed to ensure that the non-secure PendSV runs at the lowest
|
||||||
|
* priority. Context switch is done in the non-secure PendSV handler.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_DePrioritizeNSExceptions( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets up the Floating Point Unit (FPU) for Non-Secure access.
|
||||||
|
*
|
||||||
|
* Also sets FPCCR.TS=1 to ensure that the content of the Floating Point
|
||||||
|
* Registers are not leaked to the non-secure side.
|
||||||
|
*
|
||||||
|
* @note This function must be called in the handler mode. It is no-op if called
|
||||||
|
* in the thread mode.
|
||||||
|
*/
|
||||||
|
void SecureInit_EnableNSFPUAccess( void );
|
||||||
|
|
||||||
|
#endif /* __SECURE_INIT_H__ */
|
||||||
140
portable/IAR/ARM_CM52/secure/secure_port_macros.h
Normal file
140
portable/IAR/ARM_CM52/secure/secure_port_macros.h
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __SECURE_PORT_MACROS_H__
|
||||||
|
#define __SECURE_PORT_MACROS_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Byte alignment requirements.
|
||||||
|
*/
|
||||||
|
#define secureportBYTE_ALIGNMENT 8
|
||||||
|
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Macro to declare a function as non-secure callable.
|
||||||
|
*/
|
||||||
|
#if defined( __IAR_SYSTEMS_ICC__ )
|
||||||
|
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
|
||||||
|
#else
|
||||||
|
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the non-secure PRIMASK value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
|
||||||
|
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSP value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSP( pucCurrentStackPointer ) \
|
||||||
|
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the PSPLIM value in the given variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_PSPLIM( pucOutStackLimit ) \
|
||||||
|
__asm volatile ( "mrs %0, psplim" : "=r" ( pucOutStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the PSPLIM to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_PSPLIM( pucStackLimit ) \
|
||||||
|
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the NonSecure MSP to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_MSP_NS( pucMainStackPointer ) \
|
||||||
|
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the CONTROL register to the given value.
|
||||||
|
*/
|
||||||
|
#define secureportSET_CONTROL( ulControl ) \
|
||||||
|
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the Interrupt Program Status Register (IPSR) value in the given
|
||||||
|
* variable.
|
||||||
|
*/
|
||||||
|
#define secureportREAD_IPSR( ulIPSR ) \
|
||||||
|
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to enable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PRIMASK value to disable interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable non-secure interrupts.
|
||||||
|
*
|
||||||
|
* This effectively disables context switches.
|
||||||
|
*/
|
||||||
|
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable non-secure interrupts.
|
||||||
|
*/
|
||||||
|
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert definition.
|
||||||
|
*/
|
||||||
|
#define secureportASSERT( x ) \
|
||||||
|
if( ( x ) == 0 ) \
|
||||||
|
{ \
|
||||||
|
secureportDISABLE_SECURE_INTERRUPTS(); \
|
||||||
|
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
|
||||||
|
for( ; ; ) {; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __SECURE_PORT_MACROS_H__ */
|
||||||
1242
portable/IAR/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.S
Normal file
1242
portable/IAR/ARM_CM52_NTZ/non_secure/mpu_wrappers_v2_asm.S
Normal file
File diff suppressed because it is too large
Load diff
2280
portable/IAR/ARM_CM52_NTZ/non_secure/port.c
Normal file
2280
portable/IAR/ARM_CM52_NTZ/non_secure/port.c
Normal file
File diff suppressed because it is too large
Load diff
114
portable/IAR/ARM_CM52_NTZ/non_secure/portasm.h
Normal file
114
portable/IAR/ARM_CM52_NTZ/non_secure/portasm.h
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PORT_ASM_H__
|
||||||
|
#define __PORT_ASM_H__
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
/* MPU wrappers includes. */
|
||||||
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Restore the context of the first task so that the first task starts
|
||||||
|
* executing.
|
||||||
|
*/
|
||||||
|
void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raises the privilege level by clearing the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* @note This is a privileged function and should only be called from the kernel
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*
|
||||||
|
* Bit 0 of the CONTROL register defines the privilege level of Thread Mode.
|
||||||
|
* Bit[0] = 0 --> The processor is running privileged
|
||||||
|
* Bit[0] = 1 --> The processor is running unprivileged.
|
||||||
|
*/
|
||||||
|
void vResetPrivilege( void ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the first task.
|
||||||
|
*/
|
||||||
|
void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disables interrupts.
|
||||||
|
*/
|
||||||
|
uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables interrupts.
|
||||||
|
*/
|
||||||
|
void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PendSV Exception handler.
|
||||||
|
*/
|
||||||
|
void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC Handler.
|
||||||
|
*/
|
||||||
|
void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a Secure context for the calling task.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the stack to be allocated on the
|
||||||
|
* secure side for the calling task.
|
||||||
|
*/
|
||||||
|
void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free the task's secure context.
|
||||||
|
*
|
||||||
|
* @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task.
|
||||||
|
*/
|
||||||
|
void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#endif /* __PORT_ASM_H__ */
|
||||||
456
portable/IAR/ARM_CM52_NTZ/non_secure/portasm.s
Normal file
456
portable/IAR/ARM_CM52_NTZ/non_secure/portasm.s
Normal file
|
|
@ -0,0 +1,456 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Including FreeRTOSConfig.h here will cause build errors if the header file
|
||||||
|
contains code not understood by the assembler - for example the 'extern' keyword.
|
||||||
|
To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so
|
||||||
|
the code is included in C files but excluded by the preprocessor in assembly
|
||||||
|
files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* System call numbers includes. */
|
||||||
|
#include "mpu_syscall_numbers.h"
|
||||||
|
|
||||||
|
#ifndef configUSE_MPU_WRAPPERS_V1
|
||||||
|
#define configUSE_MPU_WRAPPERS_V1 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN pxCurrentTCB
|
||||||
|
EXTERN vTaskSwitchContext
|
||||||
|
EXTERN vPortSVCHandler_C
|
||||||
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
EXTERN vSystemCallEnter
|
||||||
|
EXTERN vSystemCallExit
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PUBLIC xIsPrivileged
|
||||||
|
PUBLIC vResetPrivilege
|
||||||
|
PUBLIC vRestoreContextOfFirstTask
|
||||||
|
PUBLIC vRaisePrivilege
|
||||||
|
PUBLIC vStartFirstTask
|
||||||
|
PUBLIC ulSetInterruptMask
|
||||||
|
PUBLIC vClearInterruptMask
|
||||||
|
PUBLIC PendSV_Handler
|
||||||
|
PUBLIC SVC_Handler
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*---------------- Unprivileged Functions -------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
SECTION .text:CODE:NOROOT(2)
|
||||||
|
THUMB
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
xIsPrivileged:
|
||||||
|
mrs r0, control /* r0 = CONTROL. */
|
||||||
|
tst r0, #1 /* Perform r0 & 1 (bitwise AND) and update the conditions flag. */
|
||||||
|
ite ne
|
||||||
|
movne r0, #0 /* CONTROL[0]!=0. Return false to indicate that the processor is not privileged. */
|
||||||
|
moveq r0, #1 /* CONTROL[0]==0. Return true to indicate that the processor is not privileged. */
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vResetPrivilege:
|
||||||
|
mrs r0, control /* r0 = CONTROL. */
|
||||||
|
orr r0, r0, #1 /* r0 = r0 | 1. */
|
||||||
|
msr control, r0 /* CONTROL = r0. */
|
||||||
|
bx lr /* Return to the caller. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*----------------- Privileged Functions --------------------*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
SECTION privileged_functions:CODE:NOROOT(2)
|
||||||
|
THUMB
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
vRestoreContextOfFirstTask:
|
||||||
|
program_mpu_first_task:
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r0, [r2] /* r0 = pxCurrentTCB. */
|
||||||
|
|
||||||
|
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Disable MPU. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
str r1, [r2] /* Program MAIR0. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
|
||||||
|
movs r3, #4 /* r3 = 4. */
|
||||||
|
str r3, [r1] /* Program RNR = 4. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
movs r3, #8 /* r3 = 8. */
|
||||||
|
str r3, [r1] /* Program RNR = 8. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
movs r3, #12 /* r3 = 12. */
|
||||||
|
str r3, [r1] /* Program RNR = 12. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Enable MPU. */
|
||||||
|
dsb /* Force memory writes before continuing. */
|
||||||
|
|
||||||
|
restore_context_first_task:
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r0, [r2] /* r0 = pxCurrentTCB.*/
|
||||||
|
ldr r1, [r0] /* r1 = Location of saved context in TCB. */
|
||||||
|
|
||||||
|
restore_special_regs_first_task:
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_1, r3
|
||||||
|
msr PAC_KEY_P_2, r4
|
||||||
|
msr PAC_KEY_P_3, r5
|
||||||
|
clrm {r2-r5} /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||||
|
msr psp, r2
|
||||||
|
msr psplim, r3
|
||||||
|
msr control, r4
|
||||||
|
|
||||||
|
restore_general_regs_first_task:
|
||||||
|
ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */
|
||||||
|
stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */
|
||||||
|
ldmdb r1!, {r4-r11} /* r4-r11 restored. */
|
||||||
|
|
||||||
|
restore_context_done_first_task:
|
||||||
|
str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
mov r0, #0
|
||||||
|
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
vRestoreContextOfFirstTask:
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r2] /* Read pxCurrentTCB. */
|
||||||
|
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */
|
||||||
|
msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_2, r2
|
||||||
|
msr PAC_KEY_P_1, r3
|
||||||
|
msr PAC_KEY_P_0, r4
|
||||||
|
clrm {r1-r4} /* Clear r1-r4. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
|
||||||
|
ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
|
||||||
|
msr psplim, r1 /* Set this task's PSPLIM value. */
|
||||||
|
mrs r1, control /* Obtain current control register value. */
|
||||||
|
orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */
|
||||||
|
msr control, r1 /* Write back the new control register value. */
|
||||||
|
adds r0, #32 /* Discard everything up to r0. */
|
||||||
|
msr psp, r0 /* This is now the new top of stack to use in the task. */
|
||||||
|
isb
|
||||||
|
mov r0, #0
|
||||||
|
msr basepri, r0 /* Ensure that interrupts are enabled when the first task starts. */
|
||||||
|
bx r2 /* Finally, branch to EXC_RETURN. */
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vRaisePrivilege:
|
||||||
|
mrs r0, control /* Read the CONTROL register. */
|
||||||
|
bic r0, r0, #1 /* Clear the bit 0. */
|
||||||
|
msr control, r0 /* Write back the new CONTROL value. */
|
||||||
|
bx lr /* Return to the caller. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vStartFirstTask:
|
||||||
|
ldr r0, =0xe000ed08 /* Use the NVIC offset register to locate the stack. */
|
||||||
|
ldr r0, [r0] /* Read the VTOR register which gives the address of vector table. */
|
||||||
|
ldr r0, [r0] /* The first entry in vector table is stack pointer. */
|
||||||
|
msr msp, r0 /* Set the MSP back to the start of the stack. */
|
||||||
|
cpsie i /* Globally enable interrupts. */
|
||||||
|
cpsie f
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
svc 102 /* System call to start the first task. portSVC_START_SCHEDULER = 102. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
ulSetInterruptMask:
|
||||||
|
mrs r0, basepri /* r0 = basepri. Return original basepri value. */
|
||||||
|
mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
|
msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
vClearInterruptMask:
|
||||||
|
msr basepri, r0 /* basepri = ulMask. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bx lr /* Return. */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
PendSV_Handler:
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r0, [r2] /* r0 = pxCurrentTCB. */
|
||||||
|
ldr r1, [r0] /* r1 = Location in TCB where the context should be saved. */
|
||||||
|
mrs r2, psp /* r2 = PSP. */
|
||||||
|
|
||||||
|
save_general_regs:
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
add r2, r2, #0x20 /* Move r2 to location where s0 is saved. */
|
||||||
|
tst lr, #0x10
|
||||||
|
ittt eq
|
||||||
|
vstmiaeq r1!, {s16-s31} /* Store s16-s31. */
|
||||||
|
vldmiaeq r2, {s0-s16} /* Copy hardware saved FP context into s0-s16. */
|
||||||
|
vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */
|
||||||
|
sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
stmia r1!, {r4-r11} /* Store r4-r11. */
|
||||||
|
ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */
|
||||||
|
stmia r1!, {r4-r11} /* Store the hardware saved context. */
|
||||||
|
|
||||||
|
save_special_regs:
|
||||||
|
mrs r3, psplim /* r3 = PSPLIM. */
|
||||||
|
mrs r4, control /* r4 = CONTROL. */
|
||||||
|
stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
mrs r3, PAC_KEY_P_1
|
||||||
|
mrs r4, PAC_KEY_P_2
|
||||||
|
mrs r5, PAC_KEY_P_3
|
||||||
|
stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */
|
||||||
|
clrm {r2-r5} /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
|
||||||
|
str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */
|
||||||
|
|
||||||
|
select_next_task:
|
||||||
|
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
|
msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
mov r0, #0 /* r0 = 0. */
|
||||||
|
msr basepri, r0 /* Enable interrupts. */
|
||||||
|
|
||||||
|
program_mpu:
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r0, [r2] /* r0 = pxCurrentTCB. */
|
||||||
|
|
||||||
|
dmb /* Complete outstanding transfers before disabling MPU. */
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
bic r2, #1 /* r2 = r2 & ~1 i.e. Clear the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Disable MPU. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to MAIR0 in TCB. */
|
||||||
|
ldr r1, [r0] /* r1 = *r0 i.e. r1 = MAIR0. */
|
||||||
|
ldr r2, =0xe000edc0 /* r2 = 0xe000edc0 [Location of MAIR0]. */
|
||||||
|
str r1, [r2] /* Program MAIR0. */
|
||||||
|
|
||||||
|
adds r0, #4 /* r0 = r0 + 4. r0 now points to first RBAR in TCB. */
|
||||||
|
ldr r1, =0xe000ed98 /* r1 = 0xe000ed98 [Location of RNR]. */
|
||||||
|
ldr r2, =0xe000ed9c /* r2 = 0xe000ed9c [Location of RBAR]. */
|
||||||
|
|
||||||
|
movs r3, #4 /* r3 = 4. */
|
||||||
|
str r3, [r1] /* Program RNR = 4. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
|
||||||
|
#if ( configTOTAL_MPU_REGIONS == 16 )
|
||||||
|
movs r3, #8 /* r3 = 8. */
|
||||||
|
str r3, [r1] /* Program RNR = 8. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
movs r3, #12 /* r3 = 12. */
|
||||||
|
str r3, [r1] /* Program RNR = 12. */
|
||||||
|
ldmia r0!, {r4-r11} /* Read 4 sets of RBAR/RLAR registers from TCB. */
|
||||||
|
stmia r2, {r4-r11} /* Write 4 set of RBAR/RLAR registers using alias registers. */
|
||||||
|
#endif /* configTOTAL_MPU_REGIONS == 16 */
|
||||||
|
|
||||||
|
ldr r1, =0xe000ed94 /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
|
||||||
|
ldr r2, [r1] /* Read the value of MPU_CTRL. */
|
||||||
|
orr r2, #1 /* r2 = r2 | 1 i.e. Set the bit 0 in r2. */
|
||||||
|
str r2, [r1] /* Enable MPU. */
|
||||||
|
dsb /* Force memory writes before continuing. */
|
||||||
|
|
||||||
|
restore_context:
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r0, [r2] /* r0 = pxCurrentTCB.*/
|
||||||
|
ldr r1, [r0] /* r1 = Location of saved context in TCB. */
|
||||||
|
|
||||||
|
restore_special_regs:
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */
|
||||||
|
msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_1, r3
|
||||||
|
msr PAC_KEY_P_2, r4
|
||||||
|
msr PAC_KEY_P_3, r5
|
||||||
|
clrm {r2-r5} /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
|
||||||
|
msr psp, r2
|
||||||
|
msr psplim, r3
|
||||||
|
msr control, r4
|
||||||
|
|
||||||
|
restore_general_regs:
|
||||||
|
ldmdb r1!, {r4-r11} /* r4-r11 contain hardware saved context. */
|
||||||
|
stmia r2!, {r4-r11} /* Copy the hardware saved context on the task stack. */
|
||||||
|
ldmdb r1!, {r4-r11} /* r4-r11 restored. */
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
tst lr, #0x10
|
||||||
|
ittt eq
|
||||||
|
vldmdbeq r1!, {s0-s16} /* s0-s16 contain hardware saved FP context. */
|
||||||
|
vstmiaeq r2!, {s0-s16} /* Copy hardware saved FP context on the task stack. */
|
||||||
|
vldmdbeq r1!, {s16-s31} /* Restore s16-s31. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
|
restore_context_done:
|
||||||
|
str r1, [r0] /* Save the location where the context should be saved next as the first member of TCB. */
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
#else /* configENABLE_MPU */
|
||||||
|
|
||||||
|
PendSV_Handler:
|
||||||
|
mrs r0, psp /* Read PSP in r0. */
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
it eq
|
||||||
|
vstmdbeq r0!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
|
mrs r2, psplim /* r2 = PSPLIM. */
|
||||||
|
mov r3, lr /* r3 = LR/EXC_RETURN. */
|
||||||
|
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */
|
||||||
|
mrs r2, PAC_KEY_P_2
|
||||||
|
mrs r3, PAC_KEY_P_1
|
||||||
|
mrs r4, PAC_KEY_P_0
|
||||||
|
stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */
|
||||||
|
clrm {r1-r4} /* Clear r1-r4. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r2] /* Read pxCurrentTCB. */
|
||||||
|
str r0, [r1] /* Save the new top of stack in TCB. */
|
||||||
|
|
||||||
|
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
|
||||||
|
msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
|
||||||
|
dsb
|
||||||
|
isb
|
||||||
|
bl vTaskSwitchContext
|
||||||
|
mov r0, #0 /* r0 = 0. */
|
||||||
|
msr basepri, r0 /* Enable interrupts. */
|
||||||
|
|
||||||
|
ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
|
||||||
|
ldr r1, [r2] /* Read pxCurrentTCB. */
|
||||||
|
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */
|
||||||
|
msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */
|
||||||
|
msr PAC_KEY_P_2, r3
|
||||||
|
msr PAC_KEY_P_1, r4
|
||||||
|
msr PAC_KEY_P_0, r5
|
||||||
|
clrm {r2-r5} /* Clear r2-r5. */
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
|
||||||
|
ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
tst r3, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
|
||||||
|
it eq
|
||||||
|
vldmiaeq r0!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */
|
||||||
|
#endif /* configENABLE_FPU || configENABLE_MVE */
|
||||||
|
|
||||||
|
msr psplim, r2 /* Restore the PSPLIM register value for the task. */
|
||||||
|
msr psp, r0 /* Remember the new top of stack for the task. */
|
||||||
|
bx r3
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
|
||||||
|
|
||||||
|
SVC_Handler:
|
||||||
|
tst lr, #4
|
||||||
|
ite eq
|
||||||
|
mrseq r0, msp
|
||||||
|
mrsne r0, psp
|
||||||
|
|
||||||
|
ldr r1, [r0, #24]
|
||||||
|
ldrb r2, [r1, #-2]
|
||||||
|
cmp r2, #NUM_SYSTEM_CALLS
|
||||||
|
blt syscall_enter
|
||||||
|
cmp r2, #104 /* portSVC_SYSTEM_CALL_EXIT. */
|
||||||
|
beq syscall_exit
|
||||||
|
b vPortSVCHandler_C
|
||||||
|
|
||||||
|
syscall_enter:
|
||||||
|
mov r1, lr
|
||||||
|
b vSystemCallEnter
|
||||||
|
|
||||||
|
syscall_exit:
|
||||||
|
mov r1, lr
|
||||||
|
b vSystemCallExit
|
||||||
|
|
||||||
|
#else /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
|
||||||
|
SVC_Handler:
|
||||||
|
tst lr, #4
|
||||||
|
ite eq
|
||||||
|
mrseq r0, msp
|
||||||
|
mrsne r0, psp
|
||||||
|
b vPortSVCHandler_C
|
||||||
|
|
||||||
|
#endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
END
|
||||||
87
portable/IAR/ARM_CM52_NTZ/non_secure/portmacro.h
Normal file
87
portable/IAR/ARM_CM52_NTZ/non_secure/portmacro.h
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright (c) 2025 Arm Technology (China) Co., Ltd.All Rights Reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACRO_H
|
||||||
|
#define PORTMACRO_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_MVE
|
||||||
|
#error configENABLE_MVE must be defined in FreeRTOSConfig.h. Set configENABLE_MVE to 1 to enable the MVE or 0 to disable the MVE.
|
||||||
|
#endif /* configENABLE_MVE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portARCH_NAME "Cortex-M52"
|
||||||
|
#define portHAS_ARMV8M_MAIN_EXTENSION 1
|
||||||
|
#define portARMV8M_MINOR_VERSION 1
|
||||||
|
#define portDONT_DISCARD __root
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* ARMv8-M common port configurations. */
|
||||||
|
#include "portmacrocommon.h"
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portDISABLE_INTERRUPTS() ulSetInterruptMask()
|
||||||
|
#define portENABLE_INTERRUPTS() vClearInterruptMask( 0 )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in
|
||||||
|
* the source code because to do so would cause other compilers to generate
|
||||||
|
* warnings. */
|
||||||
|
#pragma diag_suppress=Be006
|
||||||
|
#pragma diag_suppress=Pa082
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACRO_H */
|
||||||
582
portable/IAR/ARM_CM52_NTZ/non_secure/portmacrocommon.h
Normal file
582
portable/IAR/ARM_CM52_NTZ/non_secure/portmacrocommon.h
Normal file
|
|
@ -0,0 +1,582 @@
|
||||||
|
/*
|
||||||
|
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
|
||||||
|
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* Copyright 2024 Arm Limited and/or its affiliates
|
||||||
|
* <open-source-office@arm.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PORTMACROCOMMON_H
|
||||||
|
#define PORTMACROCOMMON_H
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Port specific definitions.
|
||||||
|
*
|
||||||
|
* The settings in this file configure FreeRTOS correctly for the given hardware
|
||||||
|
* and compiler.
|
||||||
|
*
|
||||||
|
* These settings should not be altered.
|
||||||
|
*------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configENABLE_FPU
|
||||||
|
#error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU.
|
||||||
|
#endif /* configENABLE_FPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_MPU
|
||||||
|
#error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU.
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#ifndef configENABLE_TRUSTZONE
|
||||||
|
#error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone.
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type definitions.
|
||||||
|
*/
|
||||||
|
#define portCHAR char
|
||||||
|
#define portFLOAT float
|
||||||
|
#define portDOUBLE double
|
||||||
|
#define portLONG long
|
||||||
|
#define portSHORT short
|
||||||
|
#define portSTACK_TYPE uint32_t
|
||||||
|
#define portBASE_TYPE long
|
||||||
|
|
||||||
|
typedef portSTACK_TYPE StackType_t;
|
||||||
|
typedef long BaseType_t;
|
||||||
|
typedef unsigned long UBaseType_t;
|
||||||
|
|
||||||
|
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
|
||||||
|
typedef uint16_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffff
|
||||||
|
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
|
||||||
|
typedef uint32_t TickType_t;
|
||||||
|
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
|
||||||
|
|
||||||
|
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
|
||||||
|
* not need to be guarded with a critical section. */
|
||||||
|
#define portTICK_TYPE_IS_ATOMIC 1
|
||||||
|
#else
|
||||||
|
#error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architecture specifics.
|
||||||
|
*/
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 8
|
||||||
|
#define portNOP()
|
||||||
|
#define portINLINE __inline
|
||||||
|
#ifndef portFORCE_INLINE
|
||||||
|
#define portFORCE_INLINE inline __attribute__( ( always_inline ) )
|
||||||
|
#endif
|
||||||
|
#define portHAS_STACK_OVERFLOW_CHECKING 1
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extern declarations.
|
||||||
|
*/
|
||||||
|
extern BaseType_t xPortIsInsideInterrupt( void );
|
||||||
|
|
||||||
|
extern void vPortYield( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern void vPortEnterCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vPortExitCritical( void ) /* PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
extern uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); /* __attribute__ (( naked )) */
|
||||||
|
extern void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */;
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
|
||||||
|
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
#if ( configENABLE_PAC == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates 128-bit task's random PAC key.
|
||||||
|
*
|
||||||
|
* @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be
|
||||||
|
* filled with a 128-bit random number.
|
||||||
|
*/
|
||||||
|
void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey );
|
||||||
|
|
||||||
|
#endif /* configENABLE_PAC */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU specific constants.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portUSING_MPU_WRAPPERS 1
|
||||||
|
#define portPRIVILEGE_BIT ( 0x80000000UL )
|
||||||
|
#else
|
||||||
|
#define portPRIVILEGE_BIT ( 0x0UL )
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
|
||||||
|
/* MPU settings that can be overridden in FreeRTOSConfig.h. */
|
||||||
|
#ifndef configTOTAL_MPU_REGIONS
|
||||||
|
/* Define to 8 for backward compatibility. */
|
||||||
|
#define configTOTAL_MPU_REGIONS ( 8UL )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* MPU regions. */
|
||||||
|
#define portPRIVILEGED_FLASH_REGION ( 0UL )
|
||||||
|
#define portUNPRIVILEGED_FLASH_REGION ( 1UL )
|
||||||
|
#define portUNPRIVILEGED_SYSCALLS_REGION ( 2UL )
|
||||||
|
#define portPRIVILEGED_RAM_REGION ( 3UL )
|
||||||
|
#define portSTACK_REGION ( 4UL )
|
||||||
|
#define portFIRST_CONFIGURABLE_REGION ( 5UL )
|
||||||
|
#define portLAST_CONFIGURABLE_REGION ( configTOTAL_MPU_REGIONS - 1UL )
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 )
|
||||||
|
#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */
|
||||||
|
|
||||||
|
/* Device memory attributes used in MPU_MAIR registers.
|
||||||
|
*
|
||||||
|
* 8-bit values encoded as follows:
|
||||||
|
* Bit[7:4] - 0000 - Device Memory
|
||||||
|
* Bit[3:2] - 00 --> Device-nGnRnE
|
||||||
|
* 01 --> Device-nGnRE
|
||||||
|
* 10 --> Device-nGRE
|
||||||
|
* 11 --> Device-GRE
|
||||||
|
* Bit[1:0] - 00, Reserved.
|
||||||
|
*/
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */
|
||||||
|
#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */
|
||||||
|
|
||||||
|
/* Normal memory attributes used in MPU_MAIR registers. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */
|
||||||
|
#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */
|
||||||
|
|
||||||
|
/* Attributes used in MPU_RBAR registers. */
|
||||||
|
#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL )
|
||||||
|
#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL )
|
||||||
|
#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_WRITE ( 1UL << 1UL )
|
||||||
|
#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL )
|
||||||
|
#define portMPU_REGION_READ_ONLY ( 3UL << 1UL )
|
||||||
|
|
||||||
|
#define portMPU_REGION_EXECUTE_NEVER ( 1UL )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Settings to define an MPU region.
|
||||||
|
*/
|
||||||
|
typedef struct MPURegionSettings
|
||||||
|
{
|
||||||
|
uint32_t ulRBAR; /**< RBAR for the region. */
|
||||||
|
uint32_t ulRLAR; /**< RLAR for the region. */
|
||||||
|
} MPURegionSettings_t;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
|
||||||
|
#ifndef configSYSTEM_CALL_STACK_SIZE
|
||||||
|
#error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief System call stack.
|
||||||
|
*/
|
||||||
|
typedef struct SYSTEM_CALL_STACK_INFO
|
||||||
|
{
|
||||||
|
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ];
|
||||||
|
uint32_t * pulSystemCallStack;
|
||||||
|
uint32_t * pulSystemCallStackLimit;
|
||||||
|
uint32_t * pulTaskStack;
|
||||||
|
uint32_t ulLinkRegisterAtSystemCallEntry;
|
||||||
|
uint32_t ulStackLimitRegisterAtSystemCallEntry;
|
||||||
|
} xSYSTEM_CALL_STACK_INFO;
|
||||||
|
|
||||||
|
#endif /* configUSE_MPU_WRAPPERS_V1 == 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MPU settings as stored in the TCB.
|
||||||
|
*/
|
||||||
|
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
|
||||||
|
* 16 17 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 71
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><-----------------------------><---->
|
||||||
|
* 16 17 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 55
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><-----------><---->
|
||||||
|
* 16 17 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 70
|
||||||
|
|
||||||
|
#else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +-----------+---------------+----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <-----------><--------------><---------><----------------><---------------------><---->
|
||||||
|
* 16 17 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 54
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
#if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+------------------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><-----------><---->
|
||||||
|
* 8 8 5 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 38
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | |
|
||||||
|
* | | PC, xPSR | CONTROL, EXC_RETURN | |
|
||||||
|
* +----------+-----------------+------------------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><------------------------------><---->
|
||||||
|
* 8 8 5 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 22
|
||||||
|
|
||||||
|
#elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | | |
|
||||||
|
* +----------+-----------------+----------------------+------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><-----------><---->
|
||||||
|
* 8 8 4 16 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 37
|
||||||
|
|
||||||
|
#else /* #if( configENABLE_TRUSTZONE == 1 ) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
|
||||||
|
* | | PC, xPSR | EXC_RETURN | |
|
||||||
|
* +----------+-----------------+----------------------+-----+
|
||||||
|
*
|
||||||
|
* <---------><----------------><----------------------><---->
|
||||||
|
* 8 8 4 1
|
||||||
|
*/
|
||||||
|
#define MAX_CONTEXT_SIZE 21
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */
|
||||||
|
|
||||||
|
#endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
|
||||||
|
|
||||||
|
/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */
|
||||||
|
#define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
|
||||||
|
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL )
|
||||||
|
|
||||||
|
/* Size of an Access Control List (ACL) entry in bits. */
|
||||||
|
#define portACL_ENTRY_SIZE_BITS ( 32U )
|
||||||
|
|
||||||
|
typedef struct MPU_SETTINGS
|
||||||
|
{
|
||||||
|
uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */
|
||||||
|
MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */
|
||||||
|
uint32_t ulContext[ MAX_CONTEXT_SIZE ];
|
||||||
|
uint32_t ulTaskFlags;
|
||||||
|
|
||||||
|
#if ( configUSE_MPU_WRAPPERS_V1 == 0 )
|
||||||
|
xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo;
|
||||||
|
#if ( configENABLE_ACCESS_CONTROL_LIST == 1 )
|
||||||
|
uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ];
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} xMPU_SETTINGS;
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate priority of ISRs that are allowed to call FreeRTOS
|
||||||
|
* system calls.
|
||||||
|
*/
|
||||||
|
#if ( configASSERT_DEFINED == 1 )
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
void vPortValidateInterruptPriority( void );
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SVC numbers.
|
||||||
|
*/
|
||||||
|
#define portSVC_ALLOCATE_SECURE_CONTEXT 100
|
||||||
|
#define portSVC_FREE_SECURE_CONTEXT 101
|
||||||
|
#define portSVC_START_SCHEDULER 102
|
||||||
|
#define portSVC_RAISE_PRIVILEGE 103
|
||||||
|
#define portSVC_SYSTEM_CALL_EXIT 104
|
||||||
|
#define portSVC_YIELD 105
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scheduler utilities.
|
||||||
|
*/
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
#define portYIELD() __asm volatile ( "svc %0" ::"i" ( portSVC_YIELD ) : "memory" )
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#else
|
||||||
|
#define portYIELD() vPortYield()
|
||||||
|
#define portYIELD_WITHIN_API() vPortYield()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
|
||||||
|
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
|
||||||
|
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if( xSwitchRequired ) \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT_TO_SCHEDULER(); \
|
||||||
|
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
traceISR_EXIT(); \
|
||||||
|
} \
|
||||||
|
} while( 0 )
|
||||||
|
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Critical section management.
|
||||||
|
*/
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMask()
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) vClearInterruptMask( x )
|
||||||
|
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||||
|
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tickless idle/low power functionality.
|
||||||
|
*/
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Task function macros as described on the FreeRTOS.org WEB site.
|
||||||
|
*/
|
||||||
|
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_TRUSTZONE == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate a secure context for the task.
|
||||||
|
*
|
||||||
|
* Tasks are not created with a secure context. Any task that is going to call
|
||||||
|
* secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a
|
||||||
|
* secure context before it calls any secure function.
|
||||||
|
*
|
||||||
|
* @param[in] ulSecureStackSize The size of the secure stack to be allocated.
|
||||||
|
*/
|
||||||
|
#define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a task is deleted to delete the task's secure context,
|
||||||
|
* if it has one.
|
||||||
|
*
|
||||||
|
* @param[in] pxTCB The TCB of the task being deleted.
|
||||||
|
*/
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB )
|
||||||
|
#endif /* configENABLE_TRUSTZONE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the processor is privileged.
|
||||||
|
*
|
||||||
|
* @return 1 if the processor is already privileged, 0 otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_PRIVILEGED() xIsPrivileged()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Raise an SVC request to raise privilege.
|
||||||
|
*
|
||||||
|
* The SVC handler checks that the SVC was raised from a system call and only
|
||||||
|
* then it raises the privilege. If this is called from any other place,
|
||||||
|
* the privilege is not raised.
|
||||||
|
*/
|
||||||
|
#define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" ::"i" ( portSVC_RAISE_PRIVILEGE ) : "memory" );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Lowers the privilege level by setting the bit 0 of the CONTROL
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
#define portRESET_PRIVILEGE() vResetPrivilege()
|
||||||
|
#else
|
||||||
|
#define portIS_PRIVILEGED()
|
||||||
|
#define portRAISE_PRIVILEGE()
|
||||||
|
#define portRESET_PRIVILEGE()
|
||||||
|
#endif /* configENABLE_MPU */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configENABLE_MPU == 1 )
|
||||||
|
|
||||||
|
extern BaseType_t xPortIsTaskPrivileged( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether or not the calling task is privileged.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the calling task is privileged, pdFALSE otherwise.
|
||||||
|
*/
|
||||||
|
#define portIS_TASK_PRIVILEGED() xPortIsTaskPrivileged()
|
||||||
|
|
||||||
|
#endif /* configENABLE_MPU == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Barriers.
|
||||||
|
*/
|
||||||
|
#define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" )
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Select correct value of configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
* based on whether or not Mainline extension is implemented. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 1 )
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
#else
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
#endif /* #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Port-optimised task selection.
|
||||||
|
*/
|
||||||
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Count the number of leading zeros in a 32-bit value.
|
||||||
|
*/
|
||||||
|
static portFORCE_INLINE uint32_t ulPortCountLeadingZeros( uint32_t ulBitmap )
|
||||||
|
{
|
||||||
|
uint32_t ulReturn;
|
||||||
|
|
||||||
|
__asm volatile ( "clz %0, %1" : "=r" ( ulReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configuration. */
|
||||||
|
#if ( configMAX_PRIORITIES > 32 )
|
||||||
|
#error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 different priorities as tasks that share a priority will time slice.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( portHAS_ARMV8M_MAIN_EXTENSION == 0 )
|
||||||
|
#error ARMv8-M baseline implementations (such as Cortex-M23) do not support port-optimised task selection. Please set configUSE_PORT_OPTIMISED_TASK_SELECTION to 0 or leave it undefined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store/clear the ready priorities in a bit map.
|
||||||
|
*/
|
||||||
|
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
|
||||||
|
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the priority of the highest-priority task that is ready to execute.
|
||||||
|
*/
|
||||||
|
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ulPortCountLeadingZeros( ( uxReadyPriorities ) ) )
|
||||||
|
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
#endif /* PORTMACROCOMMON_H */
|
||||||
8
portable/ThirdParty/GCC/ARM_TFM/README.md
vendored
8
portable/ThirdParty/GCC/ARM_TFM/README.md
vendored
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
This port adds the support that FreeRTOS applications can call the secure
|
This port adds the support that FreeRTOS applications can call the secure
|
||||||
services in Trusted Firmware M(TF-M) through Platform Security Architecture
|
services in Trusted Firmware M(TF-M) through Platform Security Architecture
|
||||||
(PSA) API based on the ARM Cortex-M23, Cortex-M33, Cortex-M55 and Cortex-M85
|
(PSA) API based on the ARM Cortex-M23, Cortex-M33, Cortex-M52, Cortex-M55
|
||||||
platform.
|
and Cortex-M85 platform.
|
||||||
|
|
||||||
The Platform Security Architecture (PSA) makes it quicker, easier and cheaper
|
The Platform Security Architecture (PSA) makes it quicker, easier and cheaper
|
||||||
to design security into a device from the ground up. PSA is made up of four key
|
to design security into a device from the ground up. PSA is made up of four key
|
||||||
|
|
@ -38,7 +38,7 @@ _**Note:** `TFM_NS_MANAGE_NSID` must be configured as "OFF" when building TF-M_.
|
||||||
|
|
||||||
## Build the Non-Secure Side
|
## Build the Non-Secure Side
|
||||||
|
|
||||||
Please copy all the files in `freertos_kernel/portable/GCC/ARM_CM[23|33|55|85]_NTZ` into the `freertos_kernel/portable/ThirdParty/GCC/ARM_TFM` folder before using this port. Note that TrustZone is enabled in this port. The TF-M runs in the Secure Side.
|
Please copy all the files in `freertos_kernel/portable/GCC/ARM_CM[23|33|52|55|85]_NTZ` into the `freertos_kernel/portable/ThirdParty/GCC/ARM_TFM` folder before using this port. Note that TrustZone is enabled in this port. The TF-M runs in the Secure Side.
|
||||||
|
|
||||||
Please call the API `tfm_ns_interface_init()` which is defined in `/interface/src/os_wrapper/tfm_ns_interface_rtos.c` by trusted-firmware-m (tag: TF-Mv2.0.0) at the very beginning of your application. Otherwise, it will always fail when calling a TF-M service in the Nonsecure Side.
|
Please call the API `tfm_ns_interface_init()` which is defined in `/interface/src/os_wrapper/tfm_ns_interface_rtos.c` by trusted-firmware-m (tag: TF-Mv2.0.0) at the very beginning of your application. Otherwise, it will always fail when calling a TF-M service in the Nonsecure Side.
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ Please refer to [TF-M documentation](https://trustedfirmware-m.readthedocs.io/en
|
||||||
* `configENABLE_MVE`
|
* `configENABLE_MVE`
|
||||||
The setting of this macro is decided by the setting in Secure Side which is platform-specific.
|
The setting of this macro is decided by the setting in Secure Side which is platform-specific.
|
||||||
If the Secure Side enables Non-Secure access to MVE, then this macro can be configured as 0 or 1. Otherwise, this macro can only be configured as 0.
|
If the Secure Side enables Non-Secure access to MVE, then this macro can be configured as 0 or 1. Otherwise, this macro can only be configured as 0.
|
||||||
Please note that only Cortex-M55 and Cortex-M85 support MVE.
|
Please note that only Cortex-M52, Cortex-M55 and Cortex-M85 support MVE.
|
||||||
Please refer to [TF-M documentation](https://trustedfirmware-m.readthedocs.io/en/latest/integration_guide/tfm_fpu_support.html) for MVE usage on the Non-Secure side.
|
Please refer to [TF-M documentation](https://trustedfirmware-m.readthedocs.io/en/latest/integration_guide/tfm_fpu_support.html) for MVE usage on the Non-Secure side.
|
||||||
|
|
||||||
* `configENABLE_TRUSTZONE`
|
* `configENABLE_TRUSTZONE`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue