diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index 42f9196d7d8..d100fcd494b 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -448,6 +448,7 @@ MAINRDY MAIR Mang Mbits +mbranch mcause MCFR MCKA @@ -586,6 +587,8 @@ OWATCOM OWDR OWER OWSR +pacbti +PACBTI PAGEN PCDR PCER @@ -900,6 +903,7 @@ TXTEN TXUBR TXVC TXVDIS +UBTI UDCP UNACKED uncrustify @@ -915,6 +919,7 @@ UNSUB UNSUBACK unsubscriptions unsuspended +UPAC URAD URAT URSTEN diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 4b59512c970..821b55d5d2e 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -3032,6 +3032,18 @@ #define configCONTROL_INFINITE_LOOP() #endif +/* Set configENABLE_PAC and/or configENABLE_BTI to 1 to enable PAC and/or BTI + * support and 0 to disable them. These are currently used in ARMv8.1-M ports. */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + #ifndef configENABLE_PAC + #define configENABLE_PAC 0 + #endif + + #ifndef configENABLE_BTI + #define configENABLE_BTI 0 + #endif +#endif + /* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using * dynamically allocated RAM, in which case when any task is deleted it is known * that both the task's stack and TCB need to be freed. Sometimes the diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h index a7f9db76750..5acf8160f9c 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h index a7f9db76750..5acf8160f9c 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h index 0fc61f23c22..452a4365566 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h index 0fc61f23c22..452a4365566 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h index 4db6e6d4ab9..82b84f92a1b 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h index c6a179c524d..369d6825f32 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h index 7e14f269603..5067aa5737a 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h index 9dfcc91325f..4940e345e67 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h index 9dfcc91325f..4940e345e67 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h index a2a301f0041..3eaa90c96aa 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h index f0d5f2b9c9c..c662361326a 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h index 633da3a6d0b..56062358401 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h index 95b17941313..bc6c69f1d25 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h index efde68dc2c2..999e7666b6e 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt index 0c46ccd8f14..4c39c76bf45 100644 --- a/portable/CMakeLists.txt +++ b/portable/CMakeLists.txt @@ -781,6 +781,104 @@ if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR Common/mpu_wrappers_v2.c ) endif() + +if (DEFINED FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG ) + + if(${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + message(FATAL_ERROR "ARMv8.1-M PACBTI support in the kernel is not yet enabled for GNU toolchain due to known issues.") + endif() + + if(FREERTOS_PORT MATCHES ".*ARM_CM85") + 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 $<$:-mbranch-protection=standard>) + target_compile_options(freertos_kernel_port PUBLIC $<$:$<$:--branch_protection=bti+pac-ret>>) + target_compile_definitions(freertos_config + INTERFACE + configENABLE_PAC=1 + configENABLE_BTI=1 + ) + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(freertos_kernel_port + PUBLIC + -mbranch-protection=bti+pac-ret+leaf + ) + target_compile_definitions(freertos_config + PUBLIC + configENABLE_PAC=1 + configENABLE_BTI=1 + ) + elseif(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + message(FATAL_ERROR "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI PACBTI option is not supported on IAR Compiler.") + endif() + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET") + target_compile_options(freertos_kernel_port PUBLIC $<$:-mbranch-protection=pac-ret>) + target_compile_options(freertos_kernel_port PUBLIC $<$:$<$:--branch_protection=pac-ret>>) + target_compile_definitions(freertos_config + PUBLIC + configENABLE_PAC=1 + ) + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(freertos_kernel_port + PUBLIC + -mbranch-protection=pac-ret+leaf + ) + target_compile_definitions(freertos_config + PUBLIC + configENABLE_PAC=1 + ) + elseif(${CMAKE_C_COMPILER_ID} STREQUAL "IAR") + message(FATAL_ERROR "ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF PACBTI option is not supported on IAR Compiler.") + endif() + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_BTI") + target_compile_options(freertos_kernel_port PUBLIC $<$:-mbranch-protection=bti>) + target_compile_options(freertos_kernel_port PUBLIC $<$:$<$:--branch_protection=bti>>) + target_compile_definitions(freertos_config + PUBLIC + configENABLE_BTI=1 + ) + elseif(FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_NONE") + if(${CMAKE_C_COMPILER_ID} STREQUAL "ARMClang") + target_compile_options(freertos_kernel_port + PUBLIC + -mbranch-protection=none + ) + endif() + target_compile_definitions(freertos_config + PUBLIC + configENABLE_PAC=0 + configENABLE_BTI=0 + ) + else() + message(FATAL_ERROR "Invalid FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG configuration, the supported configurations are + ARM_V_8_1_M_PACBTI_CONFIG_STANDARD, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET, + ARM_V_8_1_M_PACBTI_CONFIG_PACRET_LEAF, + ARM_V_8_1_M_PACBTI_CONFIG_BTI, + ARM_V_8_1_M_PACBTI_CONFIG_NONE + ") + endif() + if(NOT FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG STREQUAL "ARM_V_8_1_M_PACBTI_CONFIG_NONE") + # The reason why `--library_security=pacbti-m` link option is defined for both `freertos_kernel_port`, and + # `freertos_kernel` targets even though `freertos_kernel_port` gets linked to `freertos_kernel` is that the + # `freertos_kernel_port` is an object library where its linker options don't propagate to the targets that + # link against it. + target_link_options(freertos_kernel_port + PUBLIC + --library_security=pacbti-m + ) + target_link_options(freertos_kernel + PUBLIC + --library_security=pacbti-m + ) + endif() + else() + message(FATAL_ERROR "FREERTOS_ARM_V_8_1_M_PACBTI_CONFIG option is currently only supported on ARM Cortex-M85 FreeRTOS port.") + endif() +endif() + add_library(freertos_kernel_port_headers INTERFACE) target_include_directories(freertos_kernel_port_headers INTERFACE diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacro.h b/portable/GCC/ARM_CM23/non_secure/portmacro.h index a7f9db76750..5acf8160f9c 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h index a7f9db76750..5acf8160f9c 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacro.h b/portable/GCC/ARM_CM33/non_secure/portmacro.h index 0fc61f23c22..452a4365566 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h index 0fc61f23c22..452a4365566 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacro.h b/portable/GCC/ARM_CM35P/non_secure/portmacro.h index 4db6e6d4ab9..82b84f92a1b 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h index 4db6e6d4ab9..82b84f92a1b 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacro.h b/portable/GCC/ARM_CM55/non_secure/portmacro.h index c6a179c524d..369d6825f32 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h index c6a179c524d..369d6825f32 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacro.h b/portable/GCC/ARM_CM85/non_secure/portmacro.h index 7e14f269603..5067aa5737a 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h index 7e14f269603..5067aa5737a 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 1 #define portDONT_DISCARD __attribute__( ( used ) ) /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portmacro.h b/portable/IAR/ARM_CM23/non_secure/portmacro.h index 9dfcc91325f..4940e345e67 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h index 9dfcc91325f..4940e345e67 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M23" #define portHAS_ARMV8M_MAIN_EXTENSION 0 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacro.h b/portable/IAR/ARM_CM33/non_secure/portmacro.h index a2a301f0041..3eaa90c96aa 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h index f0d5f2b9c9c..c662361326a 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M33" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacro.h b/portable/IAR/ARM_CM35P/non_secure/portmacro.h index 633da3a6d0b..56062358401 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h index 633da3a6d0b..56062358401 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -51,6 +53,7 @@ #define portARCH_NAME "Cortex-M35P" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 0 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/portmacro.h b/portable/IAR/ARM_CM55/non_secure/portmacro.h index 95b17941313..bc6c69f1d25 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h index 95b17941313..bc6c69f1d25 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M55" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 0 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/portmacro.h b/portable/IAR/ARM_CM85/non_secure/portmacro.h index efde68dc2c2..999e7666b6e 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index 75e9ea9dd75..5b399358ed8 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void ); #define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) ) #define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL ) +#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL ) /*-----------------------------------------------------------*/ /** @@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void ); * any secure calls. */ #define portNO_SECURE_CONTEXT 0 + +/** + * @brief Constants required to check and configure PACBTI security feature implementation. + */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /** @@ -410,6 +427,26 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + +/** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); + +#endif /* portHAS_PACBTI_FEATURE */ + /** * @brief Setup the timer to generate the tick interrupts. * @@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */ { uint32_t ulIndex = 0; + uint32_t ulControl = 0x0; xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */ ulIndex++; @@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Check PACBTI security feature configuration before pushing the + * CONTROL register's value on task's TCB. */ + ulControl = prvConfigurePACBTI( pdFALSE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + if( xRunPrivileged == pdTRUE ) { xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */ ulIndex++; } else { xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG ); - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */ + xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */ ulIndex++; } @@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; + #if ( portHAS_PACBTI_FEATURE == 1 ) + { + /* Set the CONTROL register value based on PACBTI security feature + * configuration before starting the first task. */ + ( void) prvConfigurePACBTI( pdTRUE ); + } + #endif /* portHAS_PACBTI_FEATURE */ + #if ( configENABLE_MPU == 1 ) { /* Setup the Memory Protection Unit (MPU). */ @@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ + +#if ( portHAS_PACBTI_FEATURE == 1 ) + + static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) + { + uint32_t ulControl = 0x0; + + /* Ensure that PACBTI is implemented. */ + configASSERT( portID_ISAR5_REG != 0x0 ); + + /* Enable UsageFault exception if PAC or BTI is enabled. */ + #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + { + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; + } + #endif + + #if( configENABLE_PAC == 1 ) + { + ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); + } + #endif + + #if( configENABLE_BTI == 1 ) + { + ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); + } + #endif + + if( xWriteControlRegister == pdTRUE ) + { + __asm volatile ( "msr control, %0" : : "r" ( ulControl ) ); + } + + return ulControl; + } + +#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h index efde68dc2c2..999e7666b6e 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -56,6 +58,7 @@ #define portARCH_NAME "Cortex-M85" #define portHAS_ARMV8M_MAIN_EXTENSION 1 #define portARMV8M_MINOR_VERSION 1 +#define portHAS_PACBTI_FEATURE 1 #define portDONT_DISCARD __root /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 3cf65761f96..a2d22b769b9 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -57,6 +59,17 @@ #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 */ +#if ( portHAS_PACBTI_FEATURE == 1 ) + + #ifndef configENABLE_PAC + #error configENABLE_PAC must be defined in FreeRTOSConfig.h. Set configENABLE_PAC to 1 to enable the PAC or 0 to disable the PAC. + #endif + + #ifndef configENABLE_BTI + #error configENABLE_BTI must be defined in FreeRTOSConfig.h. Set configENABLE_BTI to 1 to enable the BTI or 0 to disable the BTI. + #endif + +#endif /* portHAS_PACBTI_FEATURE */ /*-----------------------------------------------------------*/ /**