diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index d100fcd494b..3582741e3bc 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -106,6 +106,7 @@ CLKSOURCE CLKSTA CLRB CLRF +clrm CLRPSW CMCNT CMCON @@ -678,6 +679,7 @@ pylint pytest pyyaml RAMPZ +randomisation RASR Rationalised Raynald diff --git a/.github/scripts/kernel_checker.py b/.github/scripts/kernel_checker.py index 228257042d2..24f21ef0794 100755 --- a/.github/scripts/kernel_checker.py +++ b/.github/scripts/kernel_checker.py @@ -114,6 +114,7 @@ r'.*portable/.*/ARM_CM35*', r'.*portable/.*/ARM_CM55*', r'.*portable/.*/ARM_CM85*', + r'include/FreeRTOS.h', ] KERNEL_HEADER = [ diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 3fecbdd734e..c6c10bc019a 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.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 * @@ -29,10 +31,13 @@ #ifndef INC_FREERTOS_H #define INC_FREERTOS_H +/* Ensure that standard library header files are included only in case of compilers, and not assemblers. */ +#if defined( __ICCARM__ ) || defined( __CC_ARM ) || defined( __GNUC__ ) || defined( _WIN32 ) + /* * Include the generic headers required for the FreeRTOS port being used. */ -#include + #include /* * If stdint.h cannot be located then: @@ -47,7 +52,8 @@ * contains the typedefs required to build FreeRTOS. Read the instructions * in FreeRTOS/source/stdint.readme for more information. */ -#include /* READ COMMENT ABOVE. */ + #include /* READ COMMENT ABOVE. */ +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(_WIN32) */ /* Acceptable values for configTICK_TYPE_WIDTH_IN_BITS. */ #define TICK_TYPE_WIDTH_16_BITS 0 @@ -101,11 +107,14 @@ #define configASSERT_DEFINED 1 #endif -/* Basic FreeRTOS definitions. */ -#include "projdefs.h" +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined( __ICCARM__ ) || defined( __CC_ARM ) || defined( __GNUC__ ) || defined( _WIN32 ) + /* Basic FreeRTOS definitions. */ + #include "projdefs.h" /* Definitions specific to the port being used. */ -#include "portable.h" + #include "portable.h" +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(_WIN32) */ /* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ #ifndef configUSE_NEWLIB_REENTRANT @@ -3088,6 +3097,9 @@ ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined( __ICCARM__ ) || defined( __CC_ARM ) || defined( __GNUC__ ) || defined( _WIN32 ) + /* * In line with software engineering best practice, FreeRTOS implements a strict * data hiding policy, so the real structures used by FreeRTOS to maintain the @@ -3098,47 +3110,47 @@ * real objects are used for this purpose. The dummy list and list item * structures below are used for inclusion in such a dummy structure. */ -struct xSTATIC_LIST_ITEM -{ - #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) - TickType_t xDummy1; - #endif - TickType_t xDummy2; - void * pvDummy3[ 4 ]; - #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) - TickType_t xDummy4; - #endif -}; -typedef struct xSTATIC_LIST_ITEM StaticListItem_t; - -#if ( configUSE_MINI_LIST_ITEM == 1 ) - /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ - struct xSTATIC_MINI_LIST_ITEM + struct xSTATIC_LIST_ITEM { #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) TickType_t xDummy1; #endif TickType_t xDummy2; - void * pvDummy3[ 2 ]; + void * pvDummy3[ 4 ]; + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy4; + #endif }; - typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; -#else /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ - typedef struct xSTATIC_LIST_ITEM StaticMiniListItem_t; -#endif /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ + typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + + #if ( configUSE_MINI_LIST_ITEM == 1 ) + /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ + struct xSTATIC_MINI_LIST_ITEM + { + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void * pvDummy3[ 2 ]; + }; + typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + #else /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ + typedef struct xSTATIC_LIST_ITEM StaticMiniListItem_t; + #endif /* if ( configUSE_MINI_LIST_ITEM == 1 ) */ /* See the comments above the struct xSTATIC_LIST_ITEM definition. */ -typedef struct xSTATIC_LIST -{ - #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) - TickType_t xDummy1; - #endif - UBaseType_t uxDummy2; - void * pvDummy3; - StaticMiniListItem_t xDummy4; - #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) - TickType_t xDummy5; - #endif -} StaticList_t; + typedef struct xSTATIC_LIST + { + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + UBaseType_t uxDummy2; + void * pvDummy3; + StaticMiniListItem_t xDummy4; + #if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy5; + #endif + } StaticList_t; /* * In line with software engineering best practice, especially when supplying a @@ -3153,65 +3165,65 @@ typedef struct xSTATIC_LIST * are set. Its contents are somewhat obfuscated in the hope users will * recognise that it would be unwise to make direct use of the structure members. */ -typedef struct xSTATIC_TCB -{ - void * pxDummy1; - #if ( portUSING_MPU_WRAPPERS == 1 ) - xMPU_SETTINGS xDummy2; - #endif - #if ( configUSE_CORE_AFFINITY == 1 ) && ( configNUMBER_OF_CORES > 1 ) - UBaseType_t uxDummy26; - #endif - StaticListItem_t xDummy3[ 2 ]; - UBaseType_t uxDummy5; - void * pxDummy6; - #if ( configNUMBER_OF_CORES > 1 ) - BaseType_t xDummy23; - UBaseType_t uxDummy24; - #endif - uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; - #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) - BaseType_t xDummy25; - #endif - #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) - void * pxDummy8; - #endif - #if ( portCRITICAL_NESTING_IN_TCB == 1 ) - UBaseType_t uxDummy9; - #endif - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxDummy10[ 2 ]; - #endif - #if ( configUSE_MUTEXES == 1 ) - UBaseType_t uxDummy12[ 2 ]; - #endif - #if ( configUSE_APPLICATION_TASK_TAG == 1 ) - void * pxDummy14; - #endif - #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) - void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; - #endif - #if ( configGENERATE_RUN_TIME_STATS == 1 ) - configRUN_TIME_COUNTER_TYPE ulDummy16; - #endif - #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) - configTLS_BLOCK_TYPE xDummy17; - #endif - #if ( configUSE_TASK_NOTIFICATIONS == 1 ) - uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; - uint8_t ucDummy19[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; - #endif - #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) - uint8_t uxDummy20; - #endif + typedef struct xSTATIC_TCB + { + void * pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + #if ( configUSE_CORE_AFFINITY == 1 ) && ( configNUMBER_OF_CORES > 1 ) + UBaseType_t uxDummy26; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void * pxDummy6; + #if ( configNUMBER_OF_CORES > 1 ) + BaseType_t xDummy23; + UBaseType_t uxDummy24; + #endif + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) + BaseType_t xDummy25; + #endif + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + void * pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void * pxDummy14; + #endif + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void * pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + configRUN_TIME_COUNTER_TYPE ulDummy16; + #endif + #if ( configUSE_C_RUNTIME_TLS_SUPPORT == 1 ) + configTLS_BLOCK_TYPE xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + uint8_t ucDummy19[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + #endif + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t uxDummy20; + #endif - #if ( INCLUDE_xTaskAbortDelay == 1 ) - uint8_t ucDummy21; - #endif - #if ( configUSE_POSIX_ERRNO == 1 ) - int iDummy22; - #endif -} StaticTask_t; + #if ( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDummy21; + #endif + #if ( configUSE_POSIX_ERRNO == 1 ) + int iDummy22; + #endif + } StaticTask_t; /* * In line with software engineering best practice, especially when supplying a @@ -3227,34 +3239,34 @@ typedef struct xSTATIC_TCB * users will recognise that it would be unwise to make direct use of the * structure members. */ -typedef struct xSTATIC_QUEUE -{ - void * pvDummy1[ 3 ]; - - union + typedef struct xSTATIC_QUEUE { - void * pvDummy2; - UBaseType_t uxDummy2; - } u; + void * pvDummy1[ 3 ]; - StaticList_t xDummy3[ 2 ]; - UBaseType_t uxDummy4[ 3 ]; - uint8_t ucDummy5[ 2 ]; + union + { + void * pvDummy2; + UBaseType_t uxDummy2; + } u; - #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucDummy6; - #endif + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; - #if ( configUSE_QUEUE_SETS == 1 ) - void * pvDummy7; - #endif + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxDummy8; - uint8_t ucDummy9; - #endif -} StaticQueue_t; -typedef StaticQueue_t StaticSemaphore_t; + #if ( configUSE_QUEUE_SETS == 1 ) + void * pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif + } StaticQueue_t; + typedef StaticQueue_t StaticSemaphore_t; /* * In line with software engineering best practice, especially when supplying a @@ -3270,19 +3282,19 @@ typedef StaticQueue_t StaticSemaphore_t; * obfuscated in the hope users will recognise that it would be unwise to make * direct use of the structure members. */ -typedef struct xSTATIC_EVENT_GROUP -{ - TickType_t xDummy1; - StaticList_t xDummy2; + typedef struct xSTATIC_EVENT_GROUP + { + TickType_t xDummy1; + StaticList_t xDummy2; - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxDummy3; - #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; + #endif - #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) - uint8_t ucDummy4; - #endif -} StaticEventGroup_t; + #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; + #endif + } StaticEventGroup_t; /* * In line with software engineering best practice, especially when supplying a @@ -3298,18 +3310,18 @@ typedef struct xSTATIC_EVENT_GROUP * the hope users will recognise that it would be unwise to make direct use of * the structure members. */ -typedef struct xSTATIC_TIMER -{ - void * pvDummy1; - StaticListItem_t xDummy2; - TickType_t xDummy3; - void * pvDummy5; - TaskFunction_t pvDummy6; - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxDummy7; - #endif - uint8_t ucDummy8; -} StaticTimer_t; + typedef struct xSTATIC_TIMER + { + void * pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + void * pvDummy5; + TaskFunction_t pvDummy6; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy7; + #endif + uint8_t ucDummy8; + } StaticTimer_t; /* * In line with software engineering best practice, especially when supplying a @@ -3325,22 +3337,23 @@ typedef struct xSTATIC_TIMER * somewhat obfuscated in the hope users will recognise that it would be unwise * to make direct use of the structure members. */ -typedef struct xSTATIC_STREAM_BUFFER -{ - size_t uxDummy1[ 4 ]; - void * pvDummy2[ 3 ]; - uint8_t ucDummy3; - #if ( configUSE_TRACE_FACILITY == 1 ) - UBaseType_t uxDummy4; - #endif - #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) - void * pvDummy5[ 2 ]; - #endif - UBaseType_t uxDummy6; -} StaticStreamBuffer_t; + typedef struct xSTATIC_STREAM_BUFFER + { + size_t uxDummy1[ 4 ]; + void * pvDummy2[ 3 ]; + uint8_t ucDummy3; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy4; + #endif + #if ( configUSE_SB_COMPLETED_CALLBACK == 1 ) + void * pvDummy5[ 2 ]; + #endif + UBaseType_t uxDummy6; + } StaticStreamBuffer_t; /* Message buffers are built on stream buffers. */ -typedef StaticStreamBuffer_t StaticMessageBuffer_t; + typedef StaticStreamBuffer_t StaticMessageBuffer_t; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) || defined(_WIN32) */ /* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ 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 aaeccaa3511..a0075a79835 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -419,31 +453,33 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -458,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ 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 7cdff70050d..e0b49ddd64d 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 @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \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. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) 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 212688d6177..508694f5d00 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -381,31 +414,33 @@ PendSV_Handler: lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ b select_next_task save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -419,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ 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 9d6c6a7ef9a..ebe7f2b9dea 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 @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/ARMv8M/non_secure/portasm.h b/portable/ARMv8M/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/ARMv8M/non_secure/portasm.h +++ b/portable/ARMv8M/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.h b/portable/GCC/ARM_CM23/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.h +++ b/portable/GCC/ARM_CM23/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index aa9c238167b..eb3a326b7ee 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index aaeccaa3511..a0075a79835 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -419,31 +453,33 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -458,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.h b/portable/GCC/ARM_CM33/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.h +++ b/portable/GCC/ARM_CM33/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index aa9c238167b..eb3a326b7ee 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \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. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index aa9c238167b..eb3a326b7ee 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c index aaeccaa3511..a0075a79835 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -419,31 +453,33 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -458,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.h b/portable/GCC/ARM_CM35P/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.h +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index aa9c238167b..eb3a326b7ee 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \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. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index aa9c238167b..eb3a326b7ee 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.c b/portable/GCC/ARM_CM55/non_secure/portasm.c index aaeccaa3511..a0075a79835 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -419,31 +453,33 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -458,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.h b/portable/GCC/ARM_CM55/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.h +++ b/portable/GCC/ARM_CM55/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index aa9c238167b..eb3a326b7ee 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \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. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index aa9c238167b..eb3a326b7ee 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.c b/portable/GCC/ARM_CM85/non_secure/portasm.c index aaeccaa3511..a0075a79835 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -131,6 +140,14 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" @@ -300,6 +317,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r4, psplim \n" /* r4 = PSPLIM. */ " mrs r5, control \n" /* r5 = CONTROL. */ " stmia r2!, {r0, r3-r5, lr} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -357,6 +382,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* r1 = pxCurrentTCB.*/ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" @@ -419,31 +453,33 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " lsls r1, r3, #25 \n" /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ " bpl save_ns_context \n" /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ - " subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " b select_next_task \n" " \n" " save_ns_context: \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " it eq \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - " subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - " str r2, [r1] \n" /* Save the new top of stack in TCB. */ - " adds r2, r2, #12 \n" /* r2 = r2 + 12. */ - " stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " mrs r1, psplim \n" /* r1 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ - " subs r2, r2, #12 \n" /* r2 = r2 - 12. */ - " stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " stmdb r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -458,6 +494,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ " mov lr, r4 \n" /* LR = r4. */ diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.h b/portable/GCC/ARM_CM85/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.h +++ b/portable/GCC/ARM_CM85/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 80225b5cbca..2f48644ba7c 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c index 7cdff70050d..e0b49ddd64d 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c @@ -99,6 +99,15 @@ " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs_first_task: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -129,6 +138,15 @@ " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " \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. */ @@ -279,6 +297,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r3, psplim \n" /* r3 = PSPLIM. */ " mrs r4, control \n" /* r4 = CONTROL. */ " stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + " mrs r2, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_3 \n" + " stmia r1!, {r2-r5} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -336,6 +362,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r0, [r2] \n" /* r0 = pxCurrentTCB.*/ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " restore_special_regs: \n" " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" @@ -381,6 +416,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,6 +441,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r2-r5} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r3 \n" + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_0, r5 \n" + " clrm {r2-r5} \n" + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 5c963ea29f5..25894458944 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portasm.h b/portable/IAR/ARM_CM23/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM23/non_secure/portasm.h +++ b/portable/IAR/ARM_CM23/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 5c963ea29f5..25894458944 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 5c963ea29f5..25894458944 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.h b/portable/IAR/ARM_CM33/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.h +++ b/portable/IAR/ARM_CM33/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index 212688d6177..508694f5d00 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -381,31 +414,33 @@ PendSV_Handler: lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ b select_next_task save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -419,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 5c963ea29f5..25894458944 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 9fdbe6d5037..7d681cfed9f 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.h b/portable/IAR/ARM_CM35P/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.h +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s index 212688d6177..508694f5d00 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -381,31 +414,33 @@ PendSV_Handler: lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ b select_next_task save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -419,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.h b/portable/IAR/ARM_CM55/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.h +++ b/portable/IAR/ARM_CM55/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.s b/portable/IAR/ARM_CM55/non_secure/portasm.s index 212688d6177..508694f5d00 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -381,31 +414,33 @@ PendSV_Handler: lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ b select_next_task save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -419,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.h b/portable/IAR/ARM_CM85/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.h +++ b/portable/IAR/ARM_CM85/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.s b/portable/IAR/ARM_CM85/non_secure/portasm.s index 212688d6177..508694f5d00 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -150,6 +151,14 @@ vRestoreContextOfFirstTask: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -176,6 +185,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext @@ -271,6 +288,14 @@ PendSV_Handler: mrs r4, psplim /* r4 = PSPLIM. */ mrs r5, control /* r5 = CONTROL. */ stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -327,6 +352,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* r1 = pxCurrentTCB.*/ ldr r2, [r1] /* r2 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ restore_special_regs: ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ @@ -381,31 +414,33 @@ PendSV_Handler: lsls r1, r3, #25 /* r1 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ bpl save_ns_context /* bpl - branch if positive or zero. If r1 >= 0 ==> Bit[6] in EXC_RETURN is 0 i.e. non-secure stack was used. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ b select_next_task save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ - str r2, [r1] /* Save the new top of stack in TCB. */ - adds r2, r2, #12 /* r2 = r2 + 12. */ - stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ + stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r1, psplim /* r1 = PSPLIM. */ mov r3, lr /* r3 = LR/EXC_RETURN. */ - subs r2, r2, #12 /* r2 = r2 - 12. */ - stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + stmdb r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ + + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} + #endif /* configENABLE_PAC */ + ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + ldr r1, [r3] /* Read pxCurrentTCB. */ + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -419,7 +454,14 @@ PendSV_Handler: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} + #endif /* configENABLE_PAC */ ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ msr psplim, r1 /* Restore the PSPLIM register value for the task. */ mov lr, r4 /* LR = r4. */ diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index f3f5d3eddf0..3cdd5161b42 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -41,6 +41,11 @@ #include "mpu_wrappers.h" #include "mpu_syscall_numbers.h" +#if ( configENABLE_PAC == 1 ) + #include + #include +#endif /* configENABLE_PAC */ + /* Portasm includes. */ #include "portasm.h" @@ -1582,6 +1587,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = pulTaskPacKey[i]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1681,18 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + static uint32_t pulTaskPacKey[4]; + vPortGenerateTaskRandomPacKey( pulTaskPacKey ); + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pxTopOfStack--; + *pxTopOfStack = pulTaskPacKey[i]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -2245,5 +2274,22 @@ BaseType_t xPortIsInsideInterrupt( void ) return ulControl; } + #if ( configENABLE_PAC == 1 ) + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ) + { + static BaseType_t isSeeded = pdFALSE; + if ( isSeeded == pdFALSE ) + { + srand(time(NULL)); + isSeeded = pdTRUE; + } + + for ( uint8_t i = 0; i < ( portPAC_KEY_SIZE_BYTES / sizeof( uint32_t ) ); i++ ) + { + pulTaskPacKey[i] = rand(); + } + } + #endif /* configENABLE_PAC */ + #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h index b7021b0242f..b89128ca6cb 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.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 * @@ -35,80 +37,83 @@ /* MPU wrappers includes. */ #include "mpu_wrappers.h" -/** - * @brief Restore the context of the first task so that the first task starts - * executing. - */ -void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +/* Ensure that typedefs are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + /** + * @brief Restore the context of the first task so that the first task starts + * executing. + */ + void vRestoreContextOfFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Checks whether or not the processor is privileged. - * - * @return 1 if the processor is already privileged, 0 otherwise. - */ -BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + BaseType_t xIsPrivileged( void ) __attribute__( ( naked ) ); -/** - * @brief Raises the privilege level by clearing the bit 0 of the CONTROL - * register. - * - * @note This is a privileged function and should only be called from the kernel - * code. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Raises the privilege level by clearing the bit 0 of the CONTROL + * register. + * + * @note This is a privileged function and should only be called from the kernel + * code. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vRaisePrivilege( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Lowers the privilege level by setting the bit 0 of the CONTROL - * register. - * - * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. - * Bit[0] = 0 --> The processor is running privileged - * Bit[0] = 1 --> The processor is running unprivileged. - */ -void vResetPrivilege( void ) __attribute__( ( naked ) ); + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + * + * Bit 0 of the CONTROL register defines the privilege level of Thread Mode. + * Bit[0] = 0 --> The processor is running privileged + * Bit[0] = 1 --> The processor is running unprivileged. + */ + void vResetPrivilege( void ) __attribute__( ( naked ) ); -/** - * @brief Starts the first task. - */ -void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Starts the first task. + */ + void vStartFirstTask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Disables interrupts. - */ -uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Disables interrupts. + */ + uint32_t ulSetInterruptMask( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Enables interrupts. - */ -void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Enables interrupts. + */ + void vClearInterruptMask( uint32_t ulMask ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief PendSV Exception handler. - */ -void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief PendSV Exception handler. + */ + void PendSV_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief SVC Handler. - */ -void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief SVC Handler. + */ + void SVC_Handler( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; -/** - * @brief Allocate a Secure context for the calling task. - * - * @param[in] ulSecureStackSize The size of the stack to be allocated on the - * secure side for the calling task. - */ -void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); + /** + * @brief Allocate a Secure context for the calling task. + * + * @param[in] ulSecureStackSize The size of the stack to be allocated on the + * secure side for the calling task. + */ + void vPortAllocateSecureContext( uint32_t ulSecureStackSize ) __attribute__( ( naked ) ); -/** - * @brief Free the task's secure context. - * - * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. - */ -void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; + /** + * @brief Free the task's secure context. + * + * @param[in] pulTCB Pointer to the Task Control Block (TCB) of the task. + */ + void vPortFreeSecureContext( uint32_t * pulTCB ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; +#endif /* defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) */ #endif /* __PORT_ASM_H__ */ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ebe7f2b9dea 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s @@ -27,12 +27,13 @@ * https://github.com/FreeRTOS * */ -/* Including FreeRTOSConfig.h here will cause build errors if the header file -contains code not understood by the assembler - for example the 'extern' keyword. -To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so +/* Including FreeRTOSConfig.h and portasm.h here will cause build errors if the +header file contains code not understood by the assembler - for example the 'extern' +keyword. To avoid errors place any such code inside a #ifdef __ICCARM__/#endif block so the code is included in C files but excluded by the preprocessor in assembly files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. */ #include "FreeRTOSConfig.h" +#include "portasm.h" /* System call numbers includes. */ #include "mpu_syscall_numbers.h" @@ -140,6 +141,14 @@ vRestoreContextOfFirstTask: ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ restore_special_regs_first_task: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ @@ -165,6 +174,15 @@ vRestoreContextOfFirstTask: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -242,6 +260,16 @@ PendSV_Handler: mrs r3, psplim /* r3 = PSPLIM. */ mrs r4, control /* r4 = CONTROL. */ stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ + + #if ( configENABLE_PAC == 1 ) + mrs r2, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_3 + stmia r1!, {r2-r5} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r2-r5} + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -299,6 +327,15 @@ PendSV_Handler: ldr r0, [r2] /* r0 = pxCurrentTCB.*/ ldr r1, [r0] /* r1 = Location of saved context in TCB. */ + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + restore_special_regs: ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 @@ -335,6 +372,15 @@ PendSV_Handler: mov r3, lr /* r3 = LR/EXC_RETURN. */ stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ + #if ( configENABLE_PAC == 1 ) + mrs r1, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r2, PAC_KEY_P_2 + mrs r3, PAC_KEY_P_1 + mrs r4, PAC_KEY_P_0 + stmdb r0!, {r1-r4} /* Store the task's dedicated PAC key on the stack. */ + clrm {r1-r4} + #endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +397,15 @@ PendSV_Handler: ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ + #if ( configENABLE_PAC == 1 ) + ldmia r0!, {r2-r5} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r3 + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_0, r5 + clrm {r2-r5} + #endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..d8ef5b17925 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2024 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -125,6 +127,20 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; #endif /* configENABLE_MPU */ + +#if ( configENABLE_PAC == 1 ) + /** + * @brief Generates 128-bit task's random PAC key. + * + * The implementation in this file is weak to allow application writers to + * provide their own Random Number Generator implementation for PAC keys randomisation. + * + * @param pulTaskPacKey Pointer to task's PAC key array to be assigned an 128-bit random number. + */ + __attribute__( ( weak ) ) void vPortGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + + #define portPAC_KEY_SIZE_BYTES 16 +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -223,63 +239,114 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) +/* +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+------------------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><-----------><----> +* 16 16 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 70 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) /* - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | | | PC, xPSR | CONTROL, EXC_RETURN | | - * +-----------+---------------+----------+-----------------+------------------------------+-----+ - * - * <-----------><--------------><---------><----------------><-----------------------------><----> - * 16 16 8 8 5 1 - */ +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | | | PC, xPSR | CONTROL, EXC_RETURN | | +* +-----------+---------------+----------+-----------------+------------------------------+-----+ +* +* <-----------><--------------><---------><----------------><-----------------------------><----> +* 16 16 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 1 ) */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) /* - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | | | PC, xPSR | EXC_RETURN | | - * +-----------+---------------+----------+-----------------+----------------------+-----+ - * - * <-----------><--------------><---------><----------------><---------------------><----> - * 16 16 8 8 4 1 - */ +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | | | PC, xPSR | EXC_RETURN | | | +* +-----------+---------------+----------+-----------------+----------------------+------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><-----------><----> +* 16 16 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 69 + + #else + +/* +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | | | PC, xPSR | EXC_RETURN | | +* +-----------+---------------+----------+-----------------+----------------------+-----+ +* +* <-----------><--------------><---------><----------------><---------------------><----> +* 16 16 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 53 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ - #if ( configENABLE_TRUSTZONE == 1 ) + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) /* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ +* +----------+-----------------+------------------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | | +* +----------+-----------------+------------------------------+------------+-----+ +* +* <---------><----------------><------------------------------><-----------><----> +* 8 8 5 16 1 +*/ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + +/* +* +----------+-----------------+------------------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | +* | | PC, xPSR | CONTROL, EXC_RETURN | | +* +----------+-----------------+------------------------------+-----+ +* +* <---------><----------------><------------------------------><----> +* 8 8 5 1 +*/ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + +/* +* +----------+-----------------+----------------------+------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | +* | | PC, xPSR | EXC_RETURN | | | +* +----------+-----------------+----------------------+------------+-----+ +* +* <---------><----------------><----------------------><-----------><----> +* 8 8 4 16 1 +*/ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ /* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ +* +----------+-----------------+----------------------+-----+ +* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | +* | | PC, xPSR | EXC_RETURN | | +* +----------+-----------------+----------------------+-----+ +* +* <---------><----------------><----------------------><----> +* 8 8 4 1 +*/ #define MAX_CONTEXT_SIZE 21 - #endif /* #if( configENABLE_TRUSTZONE == 1 ) */ + #endif /* #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ #endif /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */