diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index 42f9196d7d..d100fcd494 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/.github/scripts/kernel_checker.py b/.github/scripts/kernel_checker.py index b57b7f5278..228257042d 100755 --- a/.github/scripts/kernel_checker.py +++ b/.github/scripts/kernel_checker.py @@ -28,6 +28,7 @@ # */ import os +import re from common.header_checker import HeaderChecker #-------------------------------------------------------------------------------------------------- @@ -106,6 +107,15 @@ r'.*portable/GCC/AVR32_UC3/.*', ] +KERNEL_ARM_COLLAB_FILES_PATTERNS = [ + r'.*portable/ARMv8M/*', + r'.*portable/.*/ARM_CM23*', + r'.*portable/.*/ARM_CM33*', + r'.*portable/.*/ARM_CM35*', + r'.*portable/.*/ARM_CM55*', + r'.*portable/.*/ARM_CM85*', +] + KERNEL_HEADER = [ '/*\n', ' * FreeRTOS Kernel \n', @@ -139,19 +149,92 @@ FREERTOS_COPYRIGHT_REGEX = r"^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$" +FREERTOS_ARM_COLLAB_COPYRIGHT_REGEX = r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$)|" + \ + r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright 20\d\d Arm Limited and/or its affiliates( \*\/)?$)|" + \ + r"(^(;|#)?( *(\/\*|\*|#|\/\/))? ( \*\/)?$)" + + +class KernelHeaderChecker(HeaderChecker): + def __init__( + self, + header, + padding=1000, + ignored_files=None, + ignored_ext=None, + ignored_patterns=None, + py_ext=None, + asm_ext=None, + third_party_patterns=None, + copyright_regex = None + ): + super().__init__(header, padding, ignored_files, ignored_ext, ignored_patterns, + py_ext, asm_ext, third_party_patterns, copyright_regex) + + self.armCollabRegex = re.compile(FREERTOS_ARM_COLLAB_COPYRIGHT_REGEX) + + self.armCollabFilesPatternList = [] + for pattern in KERNEL_ARM_COLLAB_FILES_PATTERNS: + self.armCollabFilesPatternList.append(re.compile(pattern)) + + def isArmCollabFile(self, path): + for pattern in self.armCollabFilesPatternList: + if pattern.match(path): + return True + return False + + def checkArmCollabFile(self, path): + isValid = False + file_ext = os.path.splitext(path)[-1] + + with open(path, encoding="utf-8", errors="ignore") as file: + chunk = file.read(len("".join(self.header)) + self.padding) + lines = [("%s\n" % line) for line in chunk.strip().splitlines()][ + : len(self.header) + 2 + ] + if (len(lines) > 0) and (lines[0].find("#!") == 0): + lines.remove(lines[0]) + + # Split lines in sections. + headers = dict() + headers["text"] = [] + headers["copyright"] = [] + headers["spdx"] = [] + for line in lines: + if self.armCollabRegex.match(line): + headers["copyright"].append(line) + elif "SPDX-License-Identifier:" in line: + headers["spdx"].append(line) + else: + headers["text"].append(line) + + text_equal = self.isValidHeaderSection(file_ext, "text", headers["text"]) + spdx_equal = self.isValidHeaderSection(file_ext, "spdx", headers["spdx"]) + + if text_equal and spdx_equal and len(headers["copyright"]) == 3: + isValid = True + + return isValid + + def customCheck(self, path): + isValid = False + if self.isArmCollabFile(path): + isValid = self.checkArmCollabFile(path) + return isValid + + def main(): parser = HeaderChecker.configArgParser() args = parser.parse_args() # Configure the checks then run - checker = HeaderChecker(KERNEL_HEADER, - copyright_regex=FREERTOS_COPYRIGHT_REGEX, - ignored_files=KERNEL_IGNORED_FILES, - ignored_ext=KERNEL_IGNORED_EXTENSIONS, - ignored_patterns=KERNEL_IGNORED_PATTERNS, - third_party_patterns=KERNEL_THIRD_PARTY_PATTERNS, - py_ext=KERNEL_PY_EXTENSIONS, - asm_ext=KERNEL_ASM_EXTENSIONS) + checker = KernelHeaderChecker(KERNEL_HEADER, + copyright_regex=FREERTOS_COPYRIGHT_REGEX, + ignored_files=KERNEL_IGNORED_FILES, + ignored_ext=KERNEL_IGNORED_EXTENSIONS, + ignored_patterns=KERNEL_IGNORED_PATTERNS, + third_party_patterns=KERNEL_THIRD_PARTY_PATTERNS, + py_ext=KERNEL_PY_EXTENSIONS, + asm_ext=KERNEL_ASM_EXTENSIONS) checker.ignoreFile(os.path.split(__file__)[-1]) rc = checker.processArgs(args) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fd1ff56bd..f0a87bfe31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,15 +138,18 @@ if(NOT FREERTOS_PORT) " IAR_ARM_CM33_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-secure\n" " IAR_ARM_CM33_SECURE - Compiler: IAR Target: ARM Cortex-M33 secure\n" " IAR_ARM_CM33_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-trustzone non-secure\n" + " IAR_ARM_CM33_TFM - Compiler: IAR Target: ARM Cortex-M33 non-secure for TF-M\n" " IAR_ARM_CM35P_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-secure\n" " IAR_ARM_CM35P_SECURE - Compiler: IAR Target: ARM Cortex-M35P secure\n" " IAR_ARM_CM35P_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-trustzone non-secure\n" " IAR_ARM_CM55_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-secure\n" " IAR_ARM_CM55_SECURE - Compiler: IAR Target: ARM Cortex-M55 secure\n" " IAR_ARM_CM55_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n" + " IAR_ARM_CM55_TFM - Compiler: IAR Target: ARM Cortex-M55 non-secure for TF-M\n" " IAR_ARM_CM85_NONSECURE - Compiler: IAR Target: ARM Cortex-M85 non-secure\n" " IAR_ARM_CM85_SECURE - Compiler: IAR Target: ARM Cortex-M85 secure\n" " IAR_ARM_CM85_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M85 non-trustzone non-secure\n" + " IAR_ARM_CM85_TFM - Compiler: IAR Target: ARM Cortex-M85 non-secure for TF-M\n" " IAR_ARM_CRX_NOGIC - Compiler: IAR Target: ARM Cortex-Rx no GIC\n" " IAR_ATMEGA323 - Compiler: IAR Target: ATMega323\n" " IAR_ATMEL_SAM7S64 - Compiler: IAR Target: Atmel SAM7S64\n" diff --git a/History.txt b/History.txt index d5293b90bb..ae29ae9c9b 100644 --- a/History.txt +++ b/History.txt @@ -528,7 +528,7 @@ Changes between FreeRTOS V10.4.3 and FreeRTOS V10.4.4 released May 28 2021 in more files. + Other minor updates include adding additional configASSERT() checks and correcting and improving code comments. - + Go look at the smp branch to see the progress towards the Symetric + + Go look at the smp branch to see the progress towards the Symmetric Multiprocessing Kernel. https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp Changes between FreeRTOS V10.4.2 and FreeRTOS V10.4.3 released December 14 2020 @@ -2015,7 +2015,7 @@ Changes between V6.1.0 and V6.1.1 released January 14 2011 Embedded Workbench. + Added a new port for the MSP430X core using the IAR Embedded Workbench. + Updated all the RX62N demo projects that target the Renesas Demonstration - Kit (RDK) to take into account the revered LED wiring on later hardware + Kit (RDK) to take into account the reversed LED wiring on later hardware revisions, and the new J-Link debug interface DLL. + Updated all the RX62N demo projects so the IO page served by the example embedded web server works with all web browsers. @@ -3174,7 +3174,7 @@ Changes between V1.2.3 and V1.2.4 xSerialPortInitMinimal() and the function xPortInit() has been renamed to xSerialPortInit(). + The function sSerialPutChar() has been renamed cSerialPutChar() and - the function return type chaned to portCHAR. + the function return type changed to portCHAR. + The integer and flop tasks now include calls to tskYIELD(), allowing them to be used with the cooperative scheduler. + All the demo applications now use the integer and comtest tasks when the @@ -3308,7 +3308,7 @@ Changes between V1.01 and V1.2.0 ports to allocate a different maximum number of priorities. + By default the trace facility is off, previously USE_TRACE_FACILITY was defined. - + comtest.c now uses a psuedo random delay between sends. This allows for + + comtest.c now uses a pseudo random delay between sends. This allows for better testing as the interrupts do not arrive at regular intervals. + Minor change to the Flashlite serial port driver. The driver is written to demonstrate the scheduler and is not written to be efficient. diff --git a/examples/coverity/README.md b/examples/coverity/README.md index 367c1d6e8e..60df693436 100644 --- a/examples/coverity/README.md +++ b/examples/coverity/README.md @@ -17,7 +17,7 @@ files. ## Getting Started ### Prerequisites -Coverity can be run on any platform mentioned [here](https://sig-docs.synopsys.com/polaris/topics/c_coverity-compatible-platforms.html). +Coverity can be run on any platform mentioned [here](https://documentation.blackduck.com/bundle/coverity-docs/page/deploy-install-guide/topics/supported_platforms_for_coverity_analysis.html). The following are the prerequisites to generate coverity report: 1. CMake version > 3.13.0 (You can check whether you have this by typing `cmake --version`). @@ -35,7 +35,7 @@ commands in a terminal: ~~~ 2. Create the build files using CMake in a `build` directory: -Singe core FreeRTOS: +Single core FreeRTOS: ~~~ cmake -B build -S examples/coverity ~~~ diff --git a/examples/template_configuration/FreeRTOSConfig.h b/examples/template_configuration/FreeRTOSConfig.h index fe21f11083..8c5e530664 100644 --- a/examples/template_configuration/FreeRTOSConfig.h +++ b/examples/template_configuration/FreeRTOSConfig.h @@ -643,7 +643,7 @@ * contain the most recent error for that task. */ #define configUSE_POSIX_ERRNO 0 -/* Set the following INCLUDE_* constants to 1 to incldue the named API function, +/* Set the following INCLUDE_* constants to 1 to include the named API function, * or 0 to exclude the named API function. Most linkers will remove unused * functions even when the constant is 1. */ #define INCLUDE_vTaskPrioritySet 1 diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 2e3a4c2260..5c321d9596 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -3185,6 +3185,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/include/mpu_prototypes.h b/include/mpu_prototypes.h index cacadc6c66..1efd13440b 100644 --- a/include/mpu_prototypes.h +++ b/include/mpu_prototypes.h @@ -335,7 +335,7 @@ BaseType_t MPU_xTimerGenericCommandFromTask( TimerHandle_t xTimer, BaseType_t MPU_xTimerGenericCommandFromTaskEntry( const xTimerGenericCommandFromTaskParams_t * pxParams ) FREERTOS_SYSTEM_CALL; const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) FREERTOS_SYSTEM_CALL; BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; @@ -346,12 +346,12 @@ TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; * with all the APIs. */ TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION; diff --git a/include/task.h b/include/task.h index b923fefc69..bf3a5f856f 100644 --- a/include/task.h +++ b/include/task.h @@ -2386,7 +2386,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; * * WARN: This function assumes that the pcWriteBuffer is of length * configSTATS_BUFFER_MAX_LENGTH. This function is there only for - * backward compatiblity. New applications are recommended to use + * backward compatibility. New applications are recommended to use * vTaskGetRunTimeStatistics and supply the length of the pcWriteBuffer * explicitly. * diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c index 1fb67891de..7a62caff02 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/mpu_wrappers_v2_asm.c @@ -1546,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( 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 a7f9db7675..5acf8160f9 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/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c index 1fb67891de..7a62caff02 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/mpu_wrappers_v2_asm.c @@ -1546,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( 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 a7f9db7675..5acf8160f9 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/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c index 02229d9644..33410a0c3f 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c index aa9379fdff..aaeccaa351 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.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 * @@ -134,8 +136,9 @@ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -224,7 +227,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -301,7 +304,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -444,7 +447,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" 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 0fc61f23c2..452a436556 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/mpu_wrappers_v2_asm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c index 6642c9e202..4b984932da 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c index cdb2632c52..7cdff70050 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.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 * @@ -130,8 +132,9 @@ " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -220,7 +223,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -280,7 +283,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -383,7 +386,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" 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 0fc61f23c2..452a436556 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 4db6e6d4ab..82b84f92a1 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 c6a179c524..369d6825f3 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 7e14f26960..5067aa5737 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 9dfcc91325..4940e345e6 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 9dfcc91325..4940e345e6 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/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s index 418c5f887f..212688d617 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -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 * @@ -179,8 +181,9 @@ vRestoreContextOfFirstTask: ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +216,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -272,7 +275,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -406,7 +409,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext 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 0f7d100df7..5e126dbf9f 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/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s index 44f6626466..9d6c6a7ef9 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portasm.s @@ -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 * @@ -165,8 +167,9 @@ vRestoreContextOfFirstTask: ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +202,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -243,7 +246,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -337,7 +340,7 @@ PendSV_Handler: str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext 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 0f7d100df7..5e126dbf9f 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 0ad1009b68..d617ac0c25 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 597af66fad..6a52722675 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 ff5c9895d4..c88adc77c2 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/portasm.h b/portable/ARMv8M/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/ARMv8M/non_secure/portasm.h +++ b/portable/ARMv8M/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 3cf65761f9..cd83bee576 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/ARMv8M/secure/context/secure_context.c +++ b/portable/ARMv8M/secure/context/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt index 553397589e..f761ebc47e 100644 --- a/portable/CMakeLists.txt +++ b/portable/CMakeLists.txt @@ -453,6 +453,12 @@ add_library(freertos_kernel_port OBJECT IAR/ARM_CM33_NTZ/non_secure/portasm.s IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S> + $<$: + IAR/ARM_CM33_NTZ/non_secure/port.c + IAR/ARM_CM33_NTZ/non_secure/portasm.s + IAR/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.S + ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> + $<$: IAR/ARM_CM35P/non_secure/port.c IAR/ARM_CM35P/non_secure/portasm.s @@ -486,6 +492,12 @@ add_library(freertos_kernel_port OBJECT IAR/ARM_CM55_NTZ/non_secure/portasm.s IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S> + $<$: + IAR/ARM_CM55_NTZ/non_secure/port.c + IAR/ARM_CM55_NTZ/non_secure/portasm.s + IAR/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.S + ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> + $<$: IAR/ARM_CM85/non_secure/port.c IAR/ARM_CM85/non_secure/portasm.s @@ -502,6 +514,12 @@ add_library(freertos_kernel_port OBJECT IAR/ARM_CM85_NTZ/non_secure/portasm.s IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S> + $<$: + IAR/ARM_CM85_NTZ/non_secure/port.c + IAR/ARM_CM85_NTZ/non_secure/portasm.s + IAR/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.S + ThirdParty/GCC/ARM_TFM/os_wrapper_freertos.c> + # ARMv7-R Ports for IAR EWARM $<$: IAR/ARM_CRx_No_GIC/port.c @@ -755,13 +773,112 @@ if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NONSECURE" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(33|55|85)_TFM" OR FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR - FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE" + FREERTOS_PORT MATCHES "IAR_ARM_CM(23|33|55|85)_NONSECURE" OR + FREERTOS_PORT MATCHES "IAR_ARM_CM(33|55|85)_TFM" ) target_sources(freertos_kernel_port PRIVATE Common/mpu_wrappers.c 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 + INTERFACE + 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 + INTERFACE + 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 + INTERFACE + 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 + INTERFACE + 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 + INTERFACE + 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 @@ -956,6 +1073,7 @@ target_include_directories(freertos_kernel_port_headers INTERFACE $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM33_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM35P/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM35P/secure> @@ -965,10 +1083,12 @@ target_include_directories(freertos_kernel_port_headers INTERFACE $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM55_NTZ/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/non_secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85/secure> $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure> + $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CM85_NTZ/non_secure> # ARMv7-R Ports for IAR EWARM $<$:${CMAKE_CURRENT_LIST_DIR}/IAR/ARM_CRx_No_GIC> diff --git a/portable/Common/mpu_wrappers.c b/portable/Common/mpu_wrappers.c index e9a890585a..4c57316657 100644 --- a/portable/Common/mpu_wrappers.c +++ b/portable/Common/mpu_wrappers.c @@ -1799,14 +1799,14 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* FREERTOS_SYSTEM_CALL */ { if( portIS_PRIVILEGED() == pdFALSE ) { portRAISE_PRIVILEGE(); portMEMORY_BARRIER(); - vTimerSetReloadMode( xTimer, uxAutoReload ); + vTimerSetReloadMode( xTimer, xAutoReload ); portMEMORY_BARRIER(); portRESET_PRIVILEGE(); @@ -1814,7 +1814,7 @@ } else { - vTimerSetReloadMode( xTimer, uxAutoReload ); + vTimerSetReloadMode( xTimer, xAutoReload ); } } #endif /* if ( configUSE_TIMERS == 1 ) */ diff --git a/portable/Common/mpu_wrappers_v2.c b/portable/Common/mpu_wrappers_v2.c index c5bbdc3185..eb9e6f056d 100644 --- a/portable/Common/mpu_wrappers_v2.c +++ b/portable/Common/mpu_wrappers_v2.c @@ -3558,10 +3558,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, - const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; + const BaseType_t xAutoReload ) PRIVILEGED_FUNCTION; void MPU_vTimerSetReloadModeImpl( TimerHandle_t xTimer, - const UBaseType_t uxAutoReload ) /* PRIVILEGED_FUNCTION */ + const BaseType_t xAutoReload ) /* PRIVILEGED_FUNCTION */ { TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; @@ -3579,7 +3579,7 @@ if( xInternalTimerHandle != NULL ) { - vTimerSetReloadMode( xInternalTimerHandle, uxAutoReload ); + vTimerSetReloadMode( xInternalTimerHandle, xAutoReload ); } } } @@ -3733,7 +3733,7 @@ TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /* PRIVILEGED_FUNCTION */ { @@ -3745,7 +3745,7 @@ if( lIndex != -1 ) { - xInternalTimerHandle = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback ); + xInternalTimerHandle = xTimerCreate( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, MPU_TimerCallback ); if( xInternalTimerHandle != NULL ) { @@ -3768,7 +3768,7 @@ TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, - const UBaseType_t uxAutoReload, + const BaseType_t xAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ) /* PRIVILEGED_FUNCTION */ @@ -3781,7 +3781,7 @@ if( lIndex != -1 ) { - xInternalTimerHandle = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, MPU_TimerCallback, pxTimerBuffer ); + xInternalTimerHandle = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, MPU_TimerCallback, pxTimerBuffer ); if( xInternalTimerHandle != NULL ) { diff --git a/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h b/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h index a335e4ad2f..e5aa862e08 100644 --- a/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h +++ b/portable/GCC/ARM7_AT91SAM7S/AT91SAM7X256.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h b/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h index a680c48619..a148b18a60 100644 --- a/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h +++ b/portable/GCC/ARM7_AT91SAM7S/ioat91sam7x256.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ @@ -3125,9 +3125,9 @@ AT91C_MC_RCB EQU( 0x1 << 0 ); -( MC ) Remap Command Bit /* - -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ AT91C_MC_UNDADD EQU( 0x1 << 0 ); --( MC ) Undefined Addess Abort Status +-( MC ) Undefined Address Abort Status AT91C_MC_MISADD EQU( 0x1 << 1 ); --( MC ) Misaligned Addess Abort Status +-( MC ) Misaligned Address Abort Status AT91C_MC_ABTSZ EQU( 0x3 << 8 ); -( MC ) Abort Size Status AT91C_MC_ABTSZ_BYTE EQU( 0x0 << 8 ); @@ -5698,7 +5698,7 @@ AT91C_US_CLKS EQU( 0x3 << 4 ); AT91C_EMAC_SA3H EQU( 0xFFFDC0AC ); -( EMAC ) Specific Address 3 Top, Last 2 bytes AT91C_EMAC_RRE EQU( 0xFFFDC06C ); - -( EMAC ) Receive Ressource Error Register + -( EMAC ) Receive Resource Error Register AT91C_EMAC_STE EQU( 0xFFFDC084 ); -( EMAC ) SQE Test Error Register /* - ========== Register definition for PDC_ADC peripheral ========== */ diff --git a/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h b/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h index 0d9a708843..5de1aee3b8 100644 --- a/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h +++ b/portable/GCC/ARM7_AT91SAM7S/lib_AT91SAM7X256.h @@ -210,7 +210,7 @@ /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -222,7 +222,7 @@ /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -234,7 +234,7 @@ /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -246,7 +246,7 @@ /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; diff --git a/portable/GCC/ARM_AARCH64/port.c b/portable/GCC/ARM_AARCH64/port.c index 238874edc8..7f080db743 100644 --- a/portable/GCC/ARM_AARCH64/port.c +++ b/portable/GCC/ARM_AARCH64/port.c @@ -547,7 +547,7 @@ UBaseType_t uxPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/GCC/ARM_CA9/port.c b/portable/GCC/ARM_CA9/port.c index 79b60a9330..0fd9dd4719 100644 --- a/portable/GCC/ARM_CA9/port.c +++ b/portable/GCC/ARM_CA9/port.c @@ -562,7 +562,7 @@ uint32_t ulPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/GCC/ARM_CM0/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM0/mpu_wrappers_v2_asm.c index cd7be632b0..4f14482e25 100644 --- a/portable/GCC/ARM_CM0/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM0/mpu_wrappers_v2_asm.c @@ -1648,10 +1648,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM0/portasm.h b/portable/GCC/ARM_CM0/portasm.h index 77e87b1324..3465075313 100644 --- a/portable/GCC/ARM_CM0/portasm.h +++ b/portable/GCC/ARM_CM0/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c index 1fb67891de..7a62caff02 100644 --- a/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM23/non_secure/mpu_wrappers_v2_asm.c @@ -1546,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/GCC/ARM_CM23/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.h +++ b/portable/GCC/ARM_CM23/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM23/non_secure/portmacro.h b/portable/GCC/ARM_CM23/non_secure/portmacro.h index a7f9db7675..5acf8160f9 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/GCC/ARM_CM23/secure/secure_context.c +++ b/portable/GCC/ARM_CM23/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c index 1fb67891de..7a62caff02 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1546,10 +1546,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h index a7f9db7675..5acf8160f9 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c index 02229d9644..33410a0c3f 100644 --- a/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM33/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index aa9379fdff..aaeccaa351 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.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 * @@ -134,8 +136,9 @@ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -224,7 +227,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -301,7 +304,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -444,7 +447,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.h b/portable/GCC/ARM_CM33/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.h +++ b/portable/GCC/ARM_CM33/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM33/non_secure/portmacro.h b/portable/GCC/ARM_CM33/non_secure/portmacro.h index 0fc61f23c2..452a436556 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/GCC/ARM_CM33/secure/secure_context.c +++ b/portable/GCC/ARM_CM33/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c index 6642c9e202..4b984932da 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c index cdb2632c52..7cdff70050 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.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 * @@ -130,8 +132,9 @@ " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -220,7 +223,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -280,7 +283,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -383,7 +386,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h index 0fc61f23c2..452a436556 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c index 02229d9644..33410a0c3f 100644 --- a/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM35P/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c index aa9379fdff..aaeccaa351 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.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 * @@ -134,8 +136,9 @@ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -224,7 +227,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -301,7 +304,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -444,7 +447,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.h b/portable/GCC/ARM_CM35P/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.h +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacro.h b/portable/GCC/ARM_CM35P/non_secure/portmacro.h index 4db6e6d4ab..82b84f92a1 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM35P/secure/secure_context.c b/portable/GCC/ARM_CM35P/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/GCC/ARM_CM35P/secure/secure_context.c +++ b/portable/GCC/ARM_CM35P/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c index 6642c9e202..4b984932da 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c index cdb2632c52..7cdff70050 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.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 * @@ -130,8 +132,9 @@ " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -220,7 +223,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -280,7 +283,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -383,7 +386,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h index 4db6e6d4ab..82b84f92a1 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c index 71bb6602e6..428e6e84a9 100644 --- a/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM3_MPU/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c index 71bb6602e6..428e6e84a9 100644 --- a/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM4_MPU/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM4_MPU/portmacro.h b/portable/GCC/ARM_CM4_MPU/portmacro.h index d9677a72b5..264887e8e3 100644 --- a/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -98,7 +98,7 @@ typedef unsigned long UBaseType_t; #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c index 02229d9644..33410a0c3f 100644 --- a/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM55/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM55/non_secure/portasm.c index aa9379fdff..aaeccaa351 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55/non_secure/portasm.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 * @@ -134,8 +136,9 @@ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -224,7 +227,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -301,7 +304,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -444,7 +447,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.h b/portable/GCC/ARM_CM55/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.h +++ b/portable/GCC/ARM_CM55/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM55/non_secure/portmacro.h b/portable/GCC/ARM_CM55/non_secure/portmacro.h index c6a179c524..369d6825f3 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM55/secure/secure_context.c b/portable/GCC/ARM_CM55/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/GCC/ARM_CM55/secure/secure_context.c +++ b/portable/GCC/ARM_CM55/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c index 6642c9e202..4b984932da 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c index cdb2632c52..7cdff70050 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.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 * @@ -130,8 +132,9 @@ " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -220,7 +223,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -280,7 +283,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -383,7 +386,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacro.h index c6a179c524..369d6825f3 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c index 02229d9644..33410a0c3f 100644 --- a/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM85/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM85/non_secure/portasm.c index aa9379fdff..aaeccaa351 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85/non_secure/portasm.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 * @@ -134,8 +136,9 @@ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " msr psplim, r2 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -224,7 +227,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -301,7 +304,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -444,7 +447,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.h b/portable/GCC/ARM_CM85/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.h +++ b/portable/GCC/ARM_CM85/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM85/non_secure/portmacro.h b/portable/GCC/ARM_CM85/non_secure/portmacro.h index 7e14f26960..5067aa5737 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CM85/secure/secure_context.c b/portable/GCC/ARM_CM85/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/GCC/ARM_CM85/secure/secure_context.c +++ b/portable/GCC/ARM_CM85/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c index 6642c9e202..4b984932da 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/mpu_wrappers_v2_asm.c @@ -1495,10 +1495,10 @@ #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) __attribute__( ( naked ) ) FREERTOS_SYSTEM_CALL; void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* __attribute__ (( naked )) FREERTOS_SYSTEM_CALL */ { __asm volatile ( diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c index cdb2632c52..7cdff70050 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.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 * @@ -130,8 +132,9 @@ " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ - " movs r1, #2 \n" /* r1 = 2. */ - " msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */ + " mrs r1, control \n" /* Obtain current control register value. */ + " orrs r1, r1, #2 \n" /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointer (PSP). */ + " msr control, r1 \n" /* Write back the new control register value. */ " adds r0, #32 \n" /* Discard everything up to r0. */ " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ " isb \n" @@ -220,7 +223,7 @@ uint32_t ulSetInterruptMask( void ) /* __attribute__(( naked )) PRIVILEGED_FUNCT " \n" " mrs r0, basepri \n" /* r0 = basepri. Return original basepri value. */ " mov r1, %0 \n" /* r1 = configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " msr basepri, r1 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r1 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bx lr \n" /* Return. */ @@ -280,7 +283,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" @@ -383,7 +386,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " str r0, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n" " isb \n" " bl vTaskSwitchContext \n" diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacro.h index 7e14f26960..5067aa5737 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 3cf65761f9..cd83bee576 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/GCC/ARM_CRx_MPU/port.c b/portable/GCC/ARM_CRx_MPU/port.c index e4904e58d5..6b8d77cd67 100644 --- a/portable/GCC/ARM_CRx_MPU/port.c +++ b/portable/GCC/ARM_CRx_MPU/port.c @@ -100,7 +100,7 @@ PRIVILEGED_DATA static BaseType_t prvPortSchedulerRunning = pdFALSE; * @param ulBufferLength Length of the given buffer. * @param ulAccessRequested Access requested. * - * @return pdTRUE if MPU region settins authorizes the requested access to the + * @return pdTRUE if MPU region settings authorizes the requested access to the * given buffer, pdFALSE otherwise. */ PRIVILEGED_FUNCTION static BaseType_t prvMPURegionAuthorizesBuffer( const xMPU_REGION_REGISTERS * xTaskMPURegion, diff --git a/portable/GCC/ARM_CRx_MPU/portmacro.h b/portable/GCC/ARM_CRx_MPU/portmacro.h index 7e80f093e5..1eb8f0162f 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro.h @@ -236,7 +236,7 @@ typedef uint32_t TickType_t; #define portTICK_TYPE_IS_ATOMIC 1 /** - * @brief The number of miliseconds between system ticks. + * @brief The number of milliseconds between system ticks. * * @ingroup System Clock */ @@ -380,7 +380,7 @@ void vPortExitCritical( void ); * @note The processor privilege level is determined by checking the * mode bits [4:0] of the Current Program Status Register (CPSR). * - * @return pdTRUE, if the processer is privileged, pdFALSE otherwise. + * @return pdTRUE, if the processor is privileged, pdFALSE otherwise. */ BaseType_t xPortIsPrivileged( void ); diff --git a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h index a113ac02d4..c9573e419c 100644 --- a/portable/GCC/ARM_CRx_MPU/portmacro_asm.h +++ b/portable/GCC/ARM_CRx_MPU/portmacro_asm.h @@ -36,7 +36,7 @@ extern "C" { #include "FreeRTOSConfig.h" #ifndef configTOTAL_MPU_REGIONS - #error "Set configTOTAL_MPU_REGIONS to the humber of MPU regions in FreeRTOSConfig.h" + #error "Set configTOTAL_MPU_REGIONS to the number of MPU regions in FreeRTOSConfig.h" #elif( configTOTAL_MPU_REGIONS == 12 ) #define portMPU_TOTAL_REGIONS ( 12UL ) #elif( configTOTAL_MPU_REGIONS == 16 ) diff --git a/portable/GCC/AVR32_UC3/port.c b/portable/GCC/AVR32_UC3/port.c index bd8b0bd2b6..984ef56a00 100644 --- a/portable/GCC/AVR32_UC3/port.c +++ b/portable/GCC/AVR32_UC3/port.c @@ -401,7 +401,7 @@ static void prvSetupTimerInterrupt( void ) #if ( configTICK_USE_TC == 1 ) volatile avr32_tc_t * tc = &AVR32_TC; - /* Options for waveform genration. */ + /* Options for waveform generation. */ tc_waveform_opt_t waveform_opt = { .channel = configTICK_TC_CHANNEL, /* Channel selection. */ diff --git a/portable/IAR/ARM_CA9/port.c b/portable/IAR/ARM_CA9/port.c index f26ae37902..66852f9a71 100644 --- a/portable/IAR/ARM_CA9/port.c +++ b/portable/IAR/ARM_CA9/port.c @@ -438,7 +438,7 @@ uint32_t ulPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( ( portICCBPR_BINARY_POINT_REGISTER & portBINARY_POINT_BITS ) <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM23/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM23/non_secure/portasm.h +++ b/portable/IAR/ARM_CM23/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM23/non_secure/portmacro.h b/portable/IAR/ARM_CM23/non_secure/portmacro.h index 9dfcc91325..4940e345e6 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/IAR/ARM_CM23/secure/secure_context.c +++ b/portable/IAR/ARM_CM23/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h index 9dfcc91325..4940e345e6 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM33/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.h +++ b/portable/IAR/ARM_CM33/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index 418c5f887f..212688d617 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -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 * @@ -179,8 +181,9 @@ vRestoreContextOfFirstTask: ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +216,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -272,7 +275,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -406,7 +409,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM33/non_secure/portmacro.h b/portable/IAR/ARM_CM33/non_secure/portmacro.h index 0f7d100df7..5e126dbf9f 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/IAR/ARM_CM33/secure/secure_context.c +++ b/portable/IAR/ARM_CM33/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s index 44f6626466..9d6c6a7ef9 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s @@ -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 * @@ -165,8 +167,9 @@ vRestoreContextOfFirstTask: ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +202,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -243,7 +246,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -337,7 +340,7 @@ PendSV_Handler: str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h index 0f7d100df7..5e126dbf9f 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM35P/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.h +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s index 418c5f887f..212688d617 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -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 * @@ -179,8 +181,9 @@ vRestoreContextOfFirstTask: ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +216,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -272,7 +275,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -406,7 +409,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacro.h b/portable/IAR/ARM_CM35P/non_secure/portmacro.h index 0ad1009b68..d617ac0c25 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM35P/secure/secure_context.c b/portable/IAR/ARM_CM35P/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/IAR/ARM_CM35P/secure/secure_context.c +++ b/portable/IAR/ARM_CM35P/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s index 44f6626466..9d6c6a7ef9 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s @@ -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 * @@ -165,8 +167,9 @@ vRestoreContextOfFirstTask: ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +202,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -243,7 +246,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -337,7 +340,7 @@ PendSV_Handler: str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h index 0ad1009b68..d617ac0c25 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM4F_MPU/portmacro.h b/portable/IAR/ARM_CM4F_MPU/portmacro.h index f7f8b51f14..246b82ddee 100644 --- a/portable/IAR/ARM_CM4F_MPU/portmacro.h +++ b/portable/IAR/ARM_CM4F_MPU/portmacro.h @@ -100,7 +100,7 @@ typedef unsigned long UBaseType_t; #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM55/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.h +++ b/portable/IAR/ARM_CM55/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.s b/portable/IAR/ARM_CM55/non_secure/portasm.s index 418c5f887f..212688d617 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55/non_secure/portasm.s @@ -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 * @@ -179,8 +181,9 @@ vRestoreContextOfFirstTask: ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +216,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -272,7 +275,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -406,7 +409,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM55/non_secure/portmacro.h b/portable/IAR/ARM_CM55/non_secure/portmacro.h index 597af66fad..6a52722675 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM55/secure/secure_context.c b/portable/IAR/ARM_CM55/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/IAR/ARM_CM55/secure/secure_context.c +++ b/portable/IAR/ARM_CM55/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s index 44f6626466..9d6c6a7ef9 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s @@ -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 * @@ -165,8 +167,9 @@ vRestoreContextOfFirstTask: ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +202,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -243,7 +246,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -337,7 +340,7 @@ PendSV_Handler: str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacro.h index 597af66fad..6a52722675 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM85/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.h +++ b/portable/IAR/ARM_CM85/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.s b/portable/IAR/ARM_CM85/non_secure/portasm.s index 418c5f887f..212688d617 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85/non_secure/portasm.s @@ -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 * @@ -179,8 +181,9 @@ vRestoreContextOfFirstTask: ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ msr psplim, r2 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -213,7 +216,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -272,7 +275,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -406,7 +409,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM85/non_secure/portmacro.h b/portable/IAR/ARM_CM85/non_secure/portmacro.h index ff5c9895d4..c88adc77c2 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/ARM_CM85/secure/secure_context.c b/portable/IAR/ARM_CM85/secure/secure_context.c index 72fb3862c9..3aa335e637 100644 --- a/portable/IAR/ARM_CM85/secure/secure_context.c +++ b/portable/IAR/ARM_CM85/secure/secure_context.c @@ -207,7 +207,7 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * securecontextNO_STACK when no secure context is loaded. */ if( ( ulIPSR != 0 ) && ( pucStackLimit == securecontextNO_STACK ) ) { - /* Ontain a free secure context. */ + /* Obtain a free secure context. */ ulSecureContextIndex = ulGetSecureContext( pvTaskHandle ); /* Were we able to get a free context? */ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index 75e9ea9dd7..a33dfa43c3 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 * @@ -54,7 +56,7 @@ * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only * i.e. the processor boots as secure and never jumps to the non-secure side. * The Trust Zone support in the port must be disabled in order to run FreeRTOS - * on the secure side. The following are the valid configuration seetings: + * on the secure side. The following are the valid configuration settings: * * 1. Run FreeRTOS on the Secure Side: * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 @@ -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/portasm.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h index bd5a2bfca9..b7021b0242 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h @@ -52,7 +52,7 @@ BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); * @brief Raises the privilege level by clearing the bit 0 of the CONTROL * register. * - * @note This is a privileged function and should only be called from the kenrel + * @note This is a privileged function and should only be called from the kernel * code. * * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s index 44f6626466..9d6c6a7ef9 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s @@ -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 * @@ -165,8 +167,9 @@ vRestoreContextOfFirstTask: ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ - movs r1, #2 /* r1 = 2. */ - msr CONTROL, r1 /* Switch to use PSP in the thread mode. */ + mrs r1, control /* Obtain current control register value. */ + orrs r1, r1, #2 /* r1 = r1 | 0x2 - Set the second bit to use the program stack pointe (PSP). */ + msr control, r1 /* Write back the new control register value. */ adds r0, #32 /* Discard everything up to r0. */ msr psp, r0 /* This is now the new top of stack to use in the task. */ isb @@ -199,7 +202,7 @@ vStartFirstTask: ulSetInterruptMask: mrs r0, basepri /* r0 = basepri. Return original basepri value. */ mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r1 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r1 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bx lr /* Return. */ @@ -243,7 +246,7 @@ PendSV_Handler: select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext @@ -337,7 +340,7 @@ PendSV_Handler: str r0, [r1] /* Save the new top of stack in TCB. */ mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY - msr basepri, r0 /* Disable interrupts upto configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + msr basepri, r0 /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ dsb isb bl vTaskSwitchContext diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacro.h index ff5c9895d4..c88adc77c2 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 3cf65761f9..cd83bee576 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -137,7 +137,7 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portPRIVILEGE_BIT ( 0x0UL ) #endif /* configENABLE_MPU */ -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/IAR/AVR32_UC3/port.c b/portable/IAR/AVR32_UC3/port.c index 7a1cc640bb..dbe121cca7 100644 --- a/portable/IAR/AVR32_UC3/port.c +++ b/portable/IAR/AVR32_UC3/port.c @@ -374,7 +374,7 @@ static void prvSetupTimerInterrupt( void ) #if ( configTICK_USE_TC == 1 ) volatile avr32_tc_t * tc = &AVR32_TC; - /* Options for waveform genration. */ + /* Options for waveform generation. */ tc_waveform_opt_t waveform_opt = { .channel = configTICK_TC_CHANNEL, /* Channel selection. */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h b/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h index 2dbceba436..6df7678842 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h @@ -562,8 +562,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h b/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h index 9d95f3eb79..a39150071b 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h @@ -487,8 +487,8 @@ /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( 0x1 << 8 ) /* (MC) Half-word */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h index b8a7652f42..a143430dbc 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h index fe701970e8..78ea375951 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h @@ -411,8 +411,8 @@ /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( 0x1 << 8 ) /* (MC) Half-word */ @@ -1234,7 +1234,7 @@ #define EMAC_ECOL ( 96 ) /* Excessive Collision Register */ #define EMAC_TUND ( 100 ) /* Transmit Underrun Error Register */ #define EMAC_CSE ( 104 ) /* Carrier Sense Error Register */ -#define EMAC_RRE ( 108 ) /* Receive Ressource Error Register */ +#define EMAC_RRE ( 108 ) /* Receive Resource Error Register */ #define EMAC_ROV ( 112 ) /* Receive Overrun Errors Register */ #define EMAC_RSE ( 116 ) /* Receive Symbol Errors Register */ #define EMAC_ELE ( 120 ) /* Excessive Length Errors Register */ @@ -2096,7 +2096,7 @@ #define AT91C_EMAC_SA1H ( 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h index 98e1babc23..f512099740 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h @@ -627,8 +627,8 @@ typedef struct _AT91S_MC /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( ( unsigned int ) 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( ( unsigned int ) 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( ( unsigned int ) 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( ( unsigned int ) 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( ( unsigned int ) 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( ( unsigned int ) 0x1 << 8 ) /* (MC) Half-word */ @@ -1509,7 +1509,7 @@ typedef struct _AT91S_EMAC AT91_REG EMAC_ECOL; /* Excessive Collision Register */ AT91_REG EMAC_TUND; /* Transmit Underrun Error Register */ AT91_REG EMAC_CSE; /* Carrier Sense Error Register */ - AT91_REG EMAC_RRE; /* Receive Ressource Error Register */ + AT91_REG EMAC_RRE; /* Receive Resource Error Register */ AT91_REG EMAC_ROV; /* Receive Overrun Errors Register */ AT91_REG EMAC_RSE; /* Receive Symbol Errors Register */ AT91_REG EMAC_ELE; /* Excessive Length Errors Register */ @@ -2393,7 +2393,7 @@ typedef struct _AT91S_TDES #define AT91C_EMAC_SA1H ( ( AT91_REG * ) 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( ( AT91_REG * ) 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( ( AT91_REG * ) 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( ( AT91_REG * ) 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( ( AT91_REG * ) 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( ( AT91_REG * ) 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h b/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h index 5c0be5efc4..8471ca44dc 100644 --- a/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h +++ b/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h @@ -411,8 +411,8 @@ /* -------- MC_RCR : (MC Offset: 0x0) MC Remap Control Register -------- */ #define AT91C_MC_RCB ( 0x1 << 0 ) /* (MC) Remap Command Bit */ /* -------- MC_ASR : (MC Offset: 0x4) MC Abort Status Register -------- */ -#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Addess Abort Status */ -#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Addess Abort Status */ +#define AT91C_MC_UNDADD ( 0x1 << 0 ) /* (MC) Undefined Address Abort Status */ +#define AT91C_MC_MISADD ( 0x1 << 1 ) /* (MC) Misaligned Address Abort Status */ #define AT91C_MC_ABTSZ ( 0x3 << 8 ) /* (MC) Abort Size Status */ #define AT91C_MC_ABTSZ_BYTE ( 0x0 << 8 ) /* (MC) Byte */ #define AT91C_MC_ABTSZ_HWORD ( 0x1 << 8 ) /* (MC) Half-word */ @@ -1234,7 +1234,7 @@ #define EMAC_ECOL ( 96 ) /* Excessive Collision Register */ #define EMAC_TUND ( 100 ) /* Transmit Underrun Error Register */ #define EMAC_CSE ( 104 ) /* Carrier Sense Error Register */ -#define EMAC_RRE ( 108 ) /* Receive Ressource Error Register */ +#define EMAC_RRE ( 108 ) /* Receive Resource Error Register */ #define EMAC_ROV ( 112 ) /* Receive Overrun Errors Register */ #define EMAC_RSE ( 116 ) /* Receive Symbol Errors Register */ #define EMAC_ELE ( 120 ) /* Excessive Length Errors Register */ @@ -2096,7 +2096,7 @@ #define AT91C_EMAC_SA1H ( 0xFFFDC09C ) /* (EMAC) Specific Address 1 Top, Last 2 bytes */ #define AT91C_EMAC_CSE ( 0xFFFDC068 ) /* (EMAC) Carrier Sense Error Register */ #define AT91C_EMAC_SA3H ( 0xFFFDC0AC ) /* (EMAC) Specific Address 3 Top, Last 2 bytes */ -#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Ressource Error Register */ +#define AT91C_EMAC_RRE ( 0xFFFDC06C ) /* (EMAC) Receive Resource Error Register */ #define AT91C_EMAC_STE ( 0xFFFDC084 ) /* (EMAC) SQE Test Error Register */ /* ========== Register definition for PDC_ADC peripheral ========== */ #define AT91C_ADC_PTSR ( 0xFFFD8124 ) /* (PDC_ADC) PDC Transfer Status Register */ diff --git a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h index a392be1a7a..c53e6c8af2 100644 --- a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h +++ b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h @@ -60,7 +60,7 @@ __inline void AT91F_MC_EFC_CfgModeReg( AT91PS_MC pMC, /* pointer to a MC co /**---------------------------------------------------------------------------- */ /** \fn AT91F_MC_EFC_GetModeReg */ -/** \brief Return MC EFC Mode Regsiter */ +/** \brief Return MC EFC Mode Register */ /**---------------------------------------------------------------------------- */ __inline unsigned int AT91F_MC_EFC_GetModeReg( AT91PS_MC pMC ) /* pointer to a MC controller */ { @@ -69,7 +69,7 @@ __inline unsigned int AT91F_MC_EFC_GetModeReg( AT91PS_MC pMC ) /* pointer to a M /**---------------------------------------------------------------------------- */ /** \fn AT91F_MC_EFC_ComputeFMCN */ -/** \brief Return MC EFC Mode Regsiter */ +/** \brief Return MC EFC Mode Register */ /**---------------------------------------------------------------------------- */ __inline unsigned int AT91F_MC_EFC_ComputeFMCN( int master_clock ) /* master clock in Hz */ { @@ -123,7 +123,7 @@ __inline unsigned int AT91F_MC_EFC_IsInterruptSet( AT91PS_MC pMC, /* \arg /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -135,7 +135,7 @@ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -147,7 +147,7 @@ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -159,7 +159,7 @@ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC con /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; @@ -742,7 +742,7 @@ __inline unsigned int AT91F_SPI_SendFrame( AT91PS_SPI pSPI, /**---------------------------------------------------------------------------- */ /** \fn AT91F_SPI_Close */ -/** \brief Close SPI: disable IT disable transfert, close PDC */ +/** \brief Close SPI: disable IT disable transfer, close PDC */ /**---------------------------------------------------------------------------- */ __inline void AT91F_SPI_Close( AT91PS_SPI pSPI ) /* \arg pointer to a SPI controller */ { @@ -1063,7 +1063,7 @@ __inline void AT91F_CKGR_DisableMainOscillator( AT91PS_CKGR pCKGR ) /* \arg poin /**---------------------------------------------------------------------------- */ /** \fn AT91F_CKGR_CfgMainOscStartUpTime */ -/** \brief Cfg MOR Register according to the main osc startup time */ +/** \brief Cfg MORE Register according to the main osc startup time */ /**---------------------------------------------------------------------------- */ __inline void AT91F_CKGR_CfgMainOscStartUpTime( AT91PS_CKGR pCKGR, /* \arg pointer to CKGR controller */ unsigned int startup_time, /* \arg main osc startup time in microsecond (us) */ diff --git a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h index 61fbb1f79f..4fc9758949 100644 --- a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h +++ b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h @@ -210,7 +210,7 @@ /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -222,7 +222,7 @@ /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -234,7 +234,7 @@ /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -246,7 +246,7 @@ /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; @@ -1054,7 +1054,7 @@ /**---------------------------------------------------------------------------- */ /** \fn AT91F_CKGR_CfgMainOscStartUpTime */ -/** \brief Cfg MOR Register according to the main osc startup time */ +/** \brief Cfg MORE Register according to the main osc startup time */ /**---------------------------------------------------------------------------- */ __inline void AT91F_CKGR_CfgMainOscStartUpTime( AT91PS_CKGR pCKGR, /* \arg pointer to CKGR controller */ unsigned int startup_time, /* \arg main osc startup time in microsecond (us) */ diff --git a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h index 0d9a708843..4ac85fb969 100644 --- a/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h +++ b/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h @@ -210,7 +210,7 @@ /** \brief Set the next receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RNPR = ( unsigned int ) address; @@ -222,7 +222,7 @@ /** \brief Set the next transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetNextTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TNPR = ( unsigned int ) address; @@ -234,7 +234,7 @@ /** \brief Set the receive transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetRx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be received */ + char * address, /* \arg address to the next block to be received */ unsigned int bytes ) /* \arg number of bytes to be received */ { pPDC->PDC_RPR = ( unsigned int ) address; @@ -246,7 +246,7 @@ /** \brief Set the transmit transfer descriptor */ /**---------------------------------------------------------------------------- */ __inline void AT91F_PDC_SetTx( AT91PS_PDC pPDC, /* \arg pointer to a PDC controller */ - char * address, /* \arg address to the next bloc to be transmitted */ + char * address, /* \arg address to the next block to be transmitted */ unsigned int bytes ) /* \arg number of bytes to be transmitted */ { pPDC->PDC_TPR = ( unsigned int ) address; @@ -1054,7 +1054,7 @@ /**---------------------------------------------------------------------------- */ /** \fn AT91F_CKGR_CfgMainOscStartUpTime */ -/** \brief Cfg MOR Register according to the main osc startup time */ +/** \brief Cfg MORE Register according to the main osc startup time */ /**---------------------------------------------------------------------------- */ __inline void AT91F_CKGR_CfgMainOscStartUpTime( AT91PS_CKGR pCKGR, /* \arg pointer to CKGR controller */ unsigned int startup_time, /* \arg main osc startup time in microsecond (us) */ diff --git a/portable/MPLAB/PIC24_dsPIC/port.c b/portable/MPLAB/PIC24_dsPIC/port.c index 0299ec0ee3..f309128e50 100644 --- a/portable/MPLAB/PIC24_dsPIC/port.c +++ b/portable/MPLAB/PIC24_dsPIC/port.c @@ -45,7 +45,7 @@ #define portTIMER_PRESCALE 8 #define portINITIAL_SR 0 -/* Defined for backward compatability with project created prior to +/* Defined for backward compatibility with project created prior to FreeRTOS.org V4.3.0. */ #ifndef configKERNEL_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY 1 diff --git a/portable/RVDS/ARM_CA9/port.c b/portable/RVDS/ARM_CA9/port.c index c892326449..7ef38f399a 100644 --- a/portable/RVDS/ARM_CA9/port.c +++ b/portable/RVDS/ARM_CA9/port.c @@ -476,7 +476,7 @@ uint32_t ulPortSetInterruptMask( void ) * this is not the case (if some bits represent a sub-priority). * * The priority grouping is configured by the GIC's binary point register - * (ICCBPR). Writting 0 to ICCBPR will ensure it is set to its lowest + * (ICCBPR). Writing 0 to ICCBPR will ensure it is set to its lowest * possible value (which may be above 0). */ configASSERT( portICCBPR_BINARY_POINT_REGISTER <= portMAX_BINARY_POINT_VALUE ); } diff --git a/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c b/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c index 82dd5f40d5..950788e09d 100644 --- a/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c +++ b/portable/RVDS/ARM_CM4_MPU/mpu_wrappers_v2_asm.c @@ -1240,10 +1240,10 @@ MPU_pcTimerGetName_Unpriv #if ( configUSE_TIMERS == 1 ) void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; + const BaseType_t xAutoReload ) FREERTOS_SYSTEM_CALL; __asm void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, - const BaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + const BaseType_t xAutoReload ) /* FREERTOS_SYSTEM_CALL */ { PRESERVE8 extern MPU_vTimerSetReloadModeImpl diff --git a/portable/RVDS/ARM_CM4_MPU/portmacro.h b/portable/RVDS/ARM_CM4_MPU/portmacro.h index 1faeffd272..005e005033 100644 --- a/portable/RVDS/ARM_CM4_MPU/portmacro.h +++ b/portable/RVDS/ARM_CM4_MPU/portmacro.h @@ -97,7 +97,7 @@ typedef unsigned long UBaseType_t; #define portMPU_RASR_TEX_S_C_B_LOCATION ( 16UL ) #define portMPU_RASR_TEX_S_C_B_MASK ( 0x3FUL ) -/* MPU settings that can be overriden in FreeRTOSConfig.h. */ +/* MPU settings that can be overridden in FreeRTOSConfig.h. */ #ifndef configTOTAL_MPU_REGIONS /* Define to 8 for backward compatibility. */ #define configTOTAL_MPU_REGIONS ( 8UL ) diff --git a/portable/ThirdParty/GCC/ARC_EM_HS/port.c b/portable/ThirdParty/GCC/ARC_EM_HS/port.c index 0e023088ef..7837f8f738 100644 --- a/portable/ThirdParty/GCC/ARC_EM_HS/port.c +++ b/portable/ThirdParty/GCC/ARC_EM_HS/port.c @@ -204,7 +204,7 @@ void vPortEndTask( void ) /* * !!! Note !!! * This a trick!!! - * It's a copy from task.c. We need to konw the definition of TCB for the purpose of hardware + * It's a copy from task.c. We need to know the definition of TCB for the purpose of hardware * stack check. Pls don't forget to update it when FreeRTOS is updated. */ typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ diff --git a/portable/ThirdParty/GCC/ARC_v1/port.c b/portable/ThirdParty/GCC/ARC_v1/port.c index 728cd6fac8..39e8b771b1 100644 --- a/portable/ThirdParty/GCC/ARC_v1/port.c +++ b/portable/ThirdParty/GCC/ARC_v1/port.c @@ -204,7 +204,7 @@ void vPortEndTask( void ) /* * !!! Note !!! * This a trick!!! - * It's a copy from task.c. We need to konw the definition of TCB for the purpose of hardware + * It's a copy from task.c. We need to know the definition of TCB for the purpose of hardware * stack check. Pls don't forget to update it when FreeRTOS is updated. */ typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 94e80cc4d6..1bec7afd88 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -165,30 +165,15 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, thread = ( Thread_t * ) ( pxTopOfStack + 1 ) - 1; pxTopOfStack = ( StackType_t * ) thread - 1; - #ifdef __APPLE__ - pxEndOfStack = ( StackType_t * ) mach_vm_round_page( pxEndOfStack ); - #endif - + /* Ensure that there is enough space to store Thread_t on the stack. */ ulStackSize = ( size_t ) ( pxTopOfStack + 1 - pxEndOfStack ) * sizeof( *pxTopOfStack ); - - #ifdef __APPLE__ - ulStackSize = mach_vm_trunc_page( ulStackSize ); - #endif + configASSERT( ulStackSize > sizeof( Thread_t ) ); thread->pxCode = pxCode; thread->pvParams = pvParameters; thread->xDying = pdFALSE; - /* Ensure ulStackSize is at least PTHREAD_STACK_MIN */ - ulStackSize = (ulStackSize < ( size_t ) ( PTHREAD_STACK_MIN ) ) ? ( size_t ) ( PTHREAD_STACK_MIN ) : ulStackSize; - pthread_attr_init( &xThreadAttributes ); - iRet = pthread_attr_setstacksize( &xThreadAttributes, ulStackSize ); - - if( iRet != 0 ) - { - fprintf( stderr, "[WARN] pthread_attr_setstacksize failed with return value: %d. Default stack size will be used.\n", iRet ); - } thread->ev = event_create(); @@ -257,7 +242,7 @@ BaseType_t xPortStartScheduler( void ) xSchedulerEnd = pdFALSE; /* Reset pthread_once_t, needed to restart the scheduler again. - * memset the internal struct members for MacOS/Linux Compatability */ + * memset the internal struct members for MacOS/Linux Compatibility */ #if __APPLE__ hSigSetupThread.__sig = _PTHREAD_ONCE_SIG_init; memset( ( void * ) &hSigSetupThread.__opaque, 0, sizeof(hSigSetupThread.__opaque)); diff --git a/portable/ThirdParty/GCC/Posix/portmacro.h b/portable/ThirdParty/GCC/Posix/portmacro.h index d1e35d1255..e117749fea 100644 --- a/portable/ThirdParty/GCC/Posix/portmacro.h +++ b/portable/ThirdParty/GCC/Posix/portmacro.h @@ -135,7 +135,7 @@ extern void vPortCancelThread( void * pxTaskToDelete ); * are always a full memory barrier. ISRs are emulated as signals * which also imply a full memory barrier. * - * Thus, only a compilier barrier is needed to prevent the compiler + * Thus, only a compiler barrier is needed to prevent the compiler * reordering. */ #define portMEMORY_BARRIER() __asm volatile ( "" ::: "memory" ) diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h index bf91eda36f..0232508840 100644 --- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h +++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h @@ -83,7 +83,7 @@ typedef uint32_t UBaseType_t; #define portBYTE_ALIGNMENT 8 #define portDONT_DISCARD __attribute__( ( used ) ) -/* We have to use PICO_DIVIDER_DISABLE_INTERRUPTS as the source of truth rathern than our config, +/* We have to use PICO_DIVIDER_DISABLE_INTERRUPTS as the source of truth rather than our config, * as our FreeRTOSConfig.h header cannot be included by ASM code - which is what this affects in the SDK */ #define portUSE_DIVIDER_SAVE_RESTORE !PICO_DIVIDER_DISABLE_INTERRUPTS #if portUSE_DIVIDER_SAVE_RESTORE diff --git a/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h b/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h index fa942add3c..b7e42aa944 100644 --- a/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h +++ b/portable/ThirdParty/GCC/Xtensa_ESP32/include/FreeRTOSConfig_arch.h @@ -114,7 +114,7 @@ * interrupts. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY XCHAL_EXCM_LEVEL -/* Stack alignment, architecture specifc. Must be a power of two. */ +/* Stack alignment, architecture specific. Must be a power of two. */ #define configSTACK_ALIGNMENT 16 diff --git a/portable/WizC/PIC18/portmacro.h b/portable/WizC/PIC18/portmacro.h index a976bbd99f..abeb955d02 100644 --- a/portable/WizC/PIC18/portmacro.h +++ b/portable/WizC/PIC18/portmacro.h @@ -154,7 +154,7 @@ extern uint8_t ucCriticalNesting; /* * The minimal stacksize is calculated on the first reference of * portMINIMAL_STACK_SIZE. Some input to this calculation is - * compiletime determined, other input is port-defined (see port.c) + * compile time determined, other input is port-defined (see port.c) */ extern uint16_t usPortCALCULATE_MINIMAL_STACK_SIZE( void ); extern uint16_t usCalcMinStackSize; diff --git a/portable/oWatcom/16BitDOS/common/portasm.h b/portable/oWatcom/16BitDOS/common/portasm.h index dac4dc864d..b9cb0e697f 100644 --- a/portable/oWatcom/16BitDOS/common/portasm.h +++ b/portable/oWatcom/16BitDOS/common/portasm.h @@ -63,7 +63,7 @@ debugger). The true stack pointer is then stored in the bp register. We add "les bx, dword ptr pxCurrentTCB" \ "mov ss, es:[ bx + 2 ]" \ "mov sp, es:[ bx ]" \ - "mov bp, sp" /* Prepair the bp register for the restoration of the SP in the compiler generated portion of the ISR */ \ + "mov bp, sp" /* Prepare the bp register for the restoration of the SP in the compiler generated portion of the ISR */ \ "add bp, 0x0002" diff --git a/tasks.c b/tasks.c index 285e52d947..098e948ee8 100644 --- a/tasks.c +++ b/tasks.c @@ -2278,6 +2278,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the calling task that is * being deleted. */ pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + configASSERT( pxTCB != NULL ); /* Remove task from the ready/delayed list. */ if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) @@ -2574,7 +2575,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, traceENTER_eTaskGetState( xTask ); - configASSERT( pxTCB ); + configASSERT( pxTCB != NULL ); #if ( configNUMBER_OF_CORES == 1 ) if( pxTCB == pxCurrentTCB ) @@ -2719,6 +2720,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the priority of the task * that called uxTaskPriorityGet() that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxPriority; } #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) @@ -2771,6 +2774,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the priority of the calling * task that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxPriority; } taskUNLOCK_DATA_GROUP_FROM_ISR( uxSavedInterruptStatus, &xISRSpinlock ); @@ -2801,6 +2806,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the base priority of the task * that called uxTaskBasePriorityGet() that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxBasePriority; } #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) @@ -2853,6 +2860,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the base priority of the calling * task that is being queried. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxReturn = pxTCB->uxBasePriority; } taskUNLOCK_DATA_GROUP_FROM_ISR( uxSavedInterruptStatus, &xISRSpinlock ); @@ -2901,6 +2910,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the priority of the calling * task that is being changed. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); @@ -3103,6 +3113,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); pxTCB->uxCoreAffinityMask = uxCoreAffinityMask; @@ -3166,6 +3177,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + uxCoreAffinityMask = pxTCB->uxCoreAffinityMask; } #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) @@ -3197,6 +3210,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); pxTCB->xPreemptionDisable++; } @@ -3228,6 +3242,8 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, #endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */ { pxTCB = prvGetTCBFromHandle( xTask ); + + configASSERT( pxTCB != NULL ); configASSERT( pxTCB->xPreemptionDisable > 0U ); pxTCB->xPreemptionDisable--; @@ -3270,6 +3286,7 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, /* If null is passed in here then it is the running task that is * being suspended. */ pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + configASSERT( pxTCB != NULL ); traceTASK_SUSPEND( pxTCB ); @@ -4419,7 +4436,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /* If null is passed in here then the name of the calling task is being * queried. */ pxTCB = prvGetTCBFromHandle( xTaskToQuery ); - configASSERT( pxTCB ); + configASSERT( pxTCB != NULL ); traceRETURN_pcTaskGetName( &( pxTCB->pcTaskName[ 0 ] ) ); @@ -4582,6 +4599,7 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) configASSERT( ppxTaskBuffer != NULL ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 ) { @@ -4829,7 +4847,7 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) traceENTER_xTaskAbortDelay( xTask ); - configASSERT( pxTCB ); + configASSERT( pxTCB != NULL ); vTaskSuspendAll(); { @@ -5254,6 +5272,7 @@ BaseType_t xTaskIncrementTick( void ) /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ @@ -5291,6 +5310,7 @@ BaseType_t xTaskIncrementTick( void ) /* If xTask is NULL then set the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); /* Save the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ @@ -6415,6 +6435,8 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) ( xIndex < ( BaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS ) ) { pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB != NULL ); + pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; } else @@ -6442,6 +6464,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) /* If null is passed in here then we are modifying the MPU settings of * the calling task. */ pxTCB = prvGetTCBFromHandle( xTaskToModify ); + configASSERT( pxTCB != NULL ); vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), pxRegions, NULL, 0 ); @@ -6580,6 +6603,7 @@ static void prvCheckTasksWaitingTermination( void ) /* xTask is NULL then get the state of the calling task. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); pxTaskStatus->xHandle = pxTCB; pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName[ 0 ] ); @@ -6804,6 +6828,7 @@ static void prvCheckTasksWaitingTermination( void ) * type. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if portSTACK_GROWTH < 0 { @@ -6836,6 +6861,7 @@ static void prvCheckTasksWaitingTermination( void ) traceENTER_uxTaskGetStackHighWaterMark( xTask ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if portSTACK_GROWTH < 0 { @@ -8832,6 +8858,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* If null is passed in here then it is the calling task that is having * its notification state cleared. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) taskLOCK_KERNEL_DATA_GROUP(); @@ -8879,6 +8906,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* If null is passed in here then it is the calling task that is having * its notification state cleared. */ pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) taskLOCK_KERNEL_DATA_GROUP(); @@ -8914,6 +8942,7 @@ TickType_t uxTaskResetEventItemValue( void ) traceENTER_ulTaskGetRunTimeCounter( xTask ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); traceRETURN_ulTaskGetRunTimeCounter( pxTCB->ulRunTimeCounter ); @@ -8941,6 +8970,8 @@ TickType_t uxTaskResetEventItemValue( void ) if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); + ulReturn = pxTCB->ulRunTimeCounter / ulTotalTime; } else @@ -9144,6 +9175,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, traceENTER_xTaskGetMPUSettings( xTask ); pxTCB = prvGetTCBFromHandle( xTask ); + configASSERT( pxTCB != NULL ); traceRETURN_xTaskGetMPUSettings( &( pxTCB->xMPUSettings ) );