From 78e0cc778ae01100ce7ca0eaf838567cd19f9720 Mon Sep 17 00:00:00 2001 From: Ahmed Ismail <64546783+AhmedIsmail02@users.noreply.github.com> Date: Tue, 14 Jan 2025 05:20:52 +0000 Subject: [PATCH] ARMv8.1-M: Add task dedicated PAC key support (#1195) armv8.1-m: Add task dedicated PAC key To harden the security, each task is assigned a dedicated PAC key, so that attackers needs to guess the all the tasks' PAC keys right to exploit the system using Return Oriented Programming. The kernel is now updated to support the following: * A PAC key set with a random number generated and is saved in the task's context when a task is created. * As part of scheduling, the task's PAC key is stored/restored to/from the task's context when a task is unscheduled/scheduled from/to run. stack-overflow-check: Introduce portGET_CURRENT_TOP_OF_STACK macro When MPU wrapper v2 is used, the task's context is stored in TCB and `pxTopOfStack`` member of TCB points to the context location in TCB. We, therefore, need to read PSP to find the task's current top of stack. Signed-off-by: Ahmed Ismail --- .github/.cSpellWords.txt | 2 + include/portable.h | 4 + include/stack_macros.h | 68 +++-- portable/ARMv8M/non_secure/port.c | 159 ++++++---- .../portable/GCC/ARM_CM23/portmacro.h | 2 +- .../portable/GCC/ARM_CM23_NTZ/portmacro.h | 2 +- .../portable/GCC/ARM_CM33/portasm.c | 285 ++++++++++-------- .../portable/GCC/ARM_CM33/portmacro.h | 2 +- .../portable/GCC/ARM_CM33_NTZ/portasm.c | 144 ++++++--- .../portable/GCC/ARM_CM33_NTZ/portmacro.h | 2 +- .../portable/GCC/ARM_CM35P/portmacro.h | 2 +- .../portable/IAR/ARM_CM23/portmacro.h | 2 +- .../portable/IAR/ARM_CM23_NTZ/portmacro.h | 2 +- .../portable/IAR/ARM_CM33/portasm.s | 120 +++++--- .../portable/IAR/ARM_CM33/portmacro.h | 2 +- .../portable/IAR/ARM_CM33_NTZ/portasm.s | 53 +++- .../portable/IAR/ARM_CM33_NTZ/portmacro.h | 2 +- .../portable/IAR/ARM_CM35P/portmacro.h | 2 +- portable/ARMv8M/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM23/non_secure/port.c | 159 ++++++---- portable/GCC/ARM_CM23/non_secure/portmacro.h | 2 +- .../GCC/ARM_CM23/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM23_NTZ/non_secure/port.c | 159 ++++++---- .../GCC/ARM_CM23_NTZ/non_secure/portmacro.h | 2 +- .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM33/non_secure/port.c | 163 ++++++---- portable/GCC/ARM_CM33/non_secure/portasm.c | 285 ++++++++++-------- portable/GCC/ARM_CM33/non_secure/portmacro.h | 2 +- .../GCC/ARM_CM33/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM33_NTZ/non_secure/port.c | 163 ++++++---- .../GCC/ARM_CM33_NTZ/non_secure/portasm.c | 144 ++++++--- .../GCC/ARM_CM33_NTZ/non_secure/portmacro.h | 2 +- .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM35P/non_secure/port.c | 163 ++++++---- portable/GCC/ARM_CM35P/non_secure/portasm.c | 285 ++++++++++-------- portable/GCC/ARM_CM35P/non_secure/portmacro.h | 2 +- .../ARM_CM35P/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM35P_NTZ/non_secure/port.c | 163 ++++++---- .../GCC/ARM_CM35P_NTZ/non_secure/portasm.c | 144 ++++++--- .../GCC/ARM_CM35P_NTZ/non_secure/portmacro.h | 2 +- .../non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM55/non_secure/port.c | 163 ++++++---- portable/GCC/ARM_CM55/non_secure/portasm.c | 285 ++++++++++-------- .../GCC/ARM_CM55/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM55_NTZ/non_secure/port.c | 163 ++++++---- .../GCC/ARM_CM55_NTZ/non_secure/portasm.c | 144 ++++++--- .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM85/non_secure/port.c | 163 ++++++---- portable/GCC/ARM_CM85/non_secure/portasm.c | 285 ++++++++++-------- .../GCC/ARM_CM85/non_secure/portmacrocommon.h | 181 +++++++---- portable/GCC/ARM_CM85_NTZ/non_secure/port.c | 163 ++++++---- .../GCC/ARM_CM85_NTZ/non_secure/portasm.c | 144 ++++++--- .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM23/non_secure/port.c | 163 ++++++---- portable/IAR/ARM_CM23/non_secure/portmacro.h | 2 +- .../IAR/ARM_CM23/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM23_NTZ/non_secure/port.c | 163 ++++++---- .../IAR/ARM_CM23_NTZ/non_secure/portmacro.h | 2 +- .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM33/non_secure/port.c | 163 ++++++---- portable/IAR/ARM_CM33/non_secure/portasm.s | 120 +++++--- portable/IAR/ARM_CM33/non_secure/portmacro.h | 2 +- .../IAR/ARM_CM33/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM33_NTZ/non_secure/port.c | 163 ++++++---- .../IAR/ARM_CM33_NTZ/non_secure/portasm.s | 53 +++- .../IAR/ARM_CM33_NTZ/non_secure/portmacro.h | 2 +- .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM35P/non_secure/port.c | 161 ++++++---- portable/IAR/ARM_CM35P/non_secure/portasm.s | 120 +++++--- portable/IAR/ARM_CM35P/non_secure/portmacro.h | 2 +- .../ARM_CM35P/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM35P_NTZ/non_secure/port.c | 159 ++++++---- .../IAR/ARM_CM35P_NTZ/non_secure/portasm.s | 53 +++- .../IAR/ARM_CM35P_NTZ/non_secure/portmacro.h | 2 +- .../non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM55/non_secure/port.c | 159 ++++++---- portable/IAR/ARM_CM55/non_secure/portasm.s | 120 +++++--- .../IAR/ARM_CM55/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM55_NTZ/non_secure/port.c | 159 ++++++---- .../IAR/ARM_CM55_NTZ/non_secure/portasm.s | 53 +++- .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM85/non_secure/port.c | 159 ++++++---- portable/IAR/ARM_CM85/non_secure/portasm.s | 120 +++++--- .../IAR/ARM_CM85/non_secure/portmacrocommon.h | 181 +++++++---- portable/IAR/ARM_CM85_NTZ/non_secure/port.c | 159 ++++++---- .../IAR/ARM_CM85_NTZ/non_secure/portasm.s | 53 +++- .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 181 +++++++---- 87 files changed, 6725 insertions(+), 3593 deletions(-) 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/include/portable.h b/include/portable.h index 68e11e79311..c9b74453547 100644 --- a/include/portable.h +++ b/include/portable.h @@ -93,6 +93,10 @@ #define portBASE_TYPE_EXIT_CRITICAL() taskEXIT_CRITICAL() #endif +#ifndef portGET_CURRENT_TOP_OF_STACK + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { pxCurrentTopOfStack = ( StackType_t * ) pxCurrentTCB->pxTopOfStack; } +#endif + #ifndef configSTACK_DEPTH_TYPE #define configSTACK_DEPTH_TYPE StackType_t #endif diff --git a/include/stack_macros.h b/include/stack_macros.h index a9c5764bbe0..300be4cb3d2 100644 --- a/include/stack_macros.h +++ b/include/stack_macros.h @@ -57,9 +57,13 @@ /* Only the current stack state is to be checked. */ #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ + do \ + { \ + StackType_t * pxCurrentTopOfStack; \ + portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \ + \ /* Is the currently saved stack pointer within the stack limit? */ \ - if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \ + if( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) \ { \ char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ @@ -72,15 +76,18 @@ #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) /* Only the current stack state is to be checked. */ - #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ - \ - /* Is the currently saved stack pointer within the stack limit? */ \ - if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ - { \ - char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ - vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ - } \ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + do \ + { \ + StackType_t * pxCurrentTopOfStack; \ + portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ + { \ + char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ + } \ } while( 0 ) #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ @@ -88,20 +95,23 @@ #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) - #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ - const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ - const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \ - \ - if( ( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \ - ( pulStack[ 0 ] != ulCheckValue ) || \ - ( pulStack[ 1 ] != ulCheckValue ) || \ - ( pulStack[ 2 ] != ulCheckValue ) || \ - ( pulStack[ 3 ] != ulCheckValue ) ) \ - { \ - char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ - vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ - } \ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + do \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \ + StackType_t * pxCurrentTopOfStack; \ + portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \ + \ + if( ( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \ + ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ + } \ } while( 0 ) #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ @@ -110,18 +120,20 @@ #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) #define taskCHECK_FOR_STACK_OVERFLOW() \ - do { \ + do \ + { \ int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ - \ + StackType_t * pxCurrentTopOfStack; \ + portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \ \ pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ \ - if( ( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \ + if( ( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) || \ ( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) ) \ { \ char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h index a7f9db76750..e81b8922886 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h index a7f9db76750..e81b8922886 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ 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..0ebbe48a45c 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -132,6 +140,15 @@ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ @@ -280,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -300,7 +315,15 @@ 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. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -335,16 +358,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -358,6 +381,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -380,13 +411,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -401,89 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " 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. */ - " 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. */ - " 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. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " 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. */ - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 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 restore_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. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h index 0fc61f23c22..2d435ca0b28 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ 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..bc7bb607107 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 @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -130,6 +138,15 @@ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " mrs r1, control \n" /* Obtain current control register value. */ @@ -261,16 +278,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -279,6 +295,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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -314,16 +338,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -337,6 +361,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -346,13 +378,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -371,16 +403,25 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,13 +438,22 @@ 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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h index 0fc61f23c22..2d435ca0b28 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h index 4db6e6d4ab9..b886287ac30 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h index 9dfcc91325f..9d6c3368e74 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h index 9dfcc91325f..9d6c3368e74 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ 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..8d5988819fc 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -152,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -177,6 +185,15 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -271,7 +288,16 @@ 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. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -329,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -374,38 +408,37 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - 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. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - 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. */ - 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!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -416,34 +449,45 @@ PendSV_Handler: mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - 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. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 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 restore_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. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h index 0f7d100df76..53b668b5b86 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ 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..ba6e8e915ce 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 @@ -142,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -165,6 +173,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -233,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -242,6 +258,15 @@ 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} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -300,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -335,6 +368,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +393,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} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h index 0f7d100df76..53b668b5b86 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h index 0ad1009b683..6e543efb5a3 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM23/non_secure/portmacro.h b/portable/GCC/ARM_CM23/non_secure/portmacro.h index a7f9db76750..e81b8922886 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h index a7f9db76750..e81b8922886 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index aa9c238167b..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index aaeccaa3511..0ebbe48a45c 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -132,6 +140,15 @@ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ @@ -280,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -300,7 +315,15 @@ 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. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -335,16 +358,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -358,6 +381,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -380,13 +411,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -401,89 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " 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. */ - " 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. */ - " 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. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " 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. */ - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 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 restore_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. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } diff --git a/portable/GCC/ARM_CM33/non_secure/portmacro.h b/portable/GCC/ARM_CM33/non_secure/portmacro.h index 0fc61f23c22..2d435ca0b28 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index aa9c238167b..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c index 7cdff70050d..bc7bb607107 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -130,6 +138,15 @@ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " mrs r1, control \n" /* Obtain current control register value. */ @@ -261,16 +278,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -279,6 +295,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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -314,16 +338,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -337,6 +361,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -346,13 +378,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -371,16 +403,25 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,13 +438,22 @@ 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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h index 0fc61f23c22..2d435ca0b28 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index aa9c238167b..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c index aaeccaa3511..0ebbe48a45c 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -132,6 +140,15 @@ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ @@ -280,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -300,7 +315,15 @@ 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. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -335,16 +358,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -358,6 +381,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -380,13 +411,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -401,89 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " 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. */ - " 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. */ - " 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. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " 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. */ - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 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 restore_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. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacro.h b/portable/GCC/ARM_CM35P/non_secure/portmacro.h index 4db6e6d4ab9..b886287ac30 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index aa9c238167b..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c index 7cdff70050d..bc7bb607107 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -130,6 +138,15 @@ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " mrs r1, control \n" /* Obtain current control register value. */ @@ -261,16 +278,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -279,6 +295,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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -314,16 +338,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -337,6 +361,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -346,13 +378,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -371,16 +403,25 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,13 +438,22 @@ 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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h index 4db6e6d4ab9..b886287ac30 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index aa9c238167b..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.c b/portable/GCC/ARM_CM55/non_secure/portasm.c index aaeccaa3511..0ebbe48a45c 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -132,6 +140,15 @@ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ @@ -280,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -300,7 +315,15 @@ 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. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -335,16 +358,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -358,6 +381,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -380,13 +411,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -401,89 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " 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. */ - " 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. */ - " 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. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " 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. */ - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 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 restore_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. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index aa9c238167b..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c index 7cdff70050d..bc7bb607107 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -130,6 +138,15 @@ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " mrs r1, control \n" /* Obtain current control register value. */ @@ -261,16 +278,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -279,6 +295,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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -314,16 +338,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -337,6 +361,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -346,13 +378,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -371,16 +403,25 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,13 +438,22 @@ 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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index aa9c238167b..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.c b/portable/GCC/ARM_CM85/non_secure/portasm.c index aaeccaa3511..0ebbe48a45c 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -132,6 +140,15 @@ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ " ldr r4, =xSecureContext \n" " str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ @@ -280,17 +297,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " save_general_regs: \n" " mrs r3, psp \n" - " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -300,7 +315,15 @@ 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. */ - " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_0 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_1 \n" + " mrs r5, PAC_KEY_P_2 \n" + " mrs r6, PAC_KEY_P_3 \n" + " stmia r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the task's context. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " str r2, [r1] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ @@ -335,16 +358,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -358,6 +381,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r2!, {r3-r6} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r4 \n" + " msr PAC_KEY_P_2, r5 \n" + " msr PAC_KEY_P_3, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ " msr psp, r3 \n" " msr psplim, r4 \n" @@ -380,13 +411,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r2!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r2, [r1] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -401,89 +432,99 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att { __asm volatile ( - " .syntax unified \n" - " .extern SecureContext_SaveContext \n" - " .extern SecureContext_LoadContext \n" - " \n" - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ - " mrs r2, psp \n" /* Read PSP in r2. */ - " \n" - " cbz r0, save_ns_context \n" /* No secure context to save. */ - " push {r0-r2, r14} \n" - " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r0-r3} \n" /* LR is now in r3. */ - " mov lr, r3 \n" /* LR = r3. */ - " 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. */ - " 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. */ - " 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. */ - " \n" - " select_next_task: \n" - " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ - " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ - " dsb \n" - " isb \n" - " bl vTaskSwitchContext \n" - " mov r0, #0 \n" /* r0 = 0. */ - " msr basepri, r0 \n" /* Enable interrupts. */ - " \n" - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - " \n" - " 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. */ - " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ - " str r0, [r3] \n" /* Restore the task's xSecureContext. */ - " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ - " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ - " push {r2, r4} \n" - " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - " pop {r2, r4} \n" - " mov lr, r4 \n" /* LR = r4. */ - " lsls r1, r4, #25 \n" /* r1 = r4 << 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 restore_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. */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" - " \n" - " restore_ns_context: \n" - " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " msr psp, r2 \n" /* Remember the new top of stack for the task. */ - " bx lr \n" + " .syntax unified \n" + " .extern SecureContext_SaveContext \n" + " .extern SecureContext_LoadContext \n" + " \n" + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " ldr r0, [r3] \n" /* Read xSecureContext - Value of xSecureContext must be in r0 as it is used as a parameter later. */ + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ + " mrs r2, psp \n" /* Read PSP in r2. */ + " \n" + " cbz r0, save_ns_context \n" /* No secure context to save. */ + " save_s_context: \n" + " push {r0-r2, lr} \n" + " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r0-r2, lr} \n" + " \n" + " save_ns_context: \n" + " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */ + " lsls r3, r3, #25 \n" /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + " \n" + " save_general_regs: \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */ + " \n" + " save_special_regs: \n" + " mrs r3, psplim \n" /* r3 = PSPLIM. */ + " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r4, PAC_KEY_P_2 \n" + " mrs r5, PAC_KEY_P_1 \n" + " mrs r6, PAC_KEY_P_0 \n" + " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " \n" + " str r2, [r1] \n" /* Save the new top of stack in TCB. */ + " \n" + " select_next_task: \n" + " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ + " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" /* r0 = 0. */ + " msr basepri, r0 \n" /* Enable interrupts. */ + " \n" + " restore_context: \n" + " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ + " ldr r1, [r3] \n" /* Read pxCurrentTCB. */ + " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ + " \n" + " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_1, r5 \n" + " msr PAC_KEY_P_0, r6 \n" + " clrm {r3-r6} \n" /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + " msr psplim, r3 \n" /* Restore the PSPLIM register value for the task. */ + " ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ + " str r0, [r3] \n" /* Restore the task's xSecureContext. */ + " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ + " \n" + " restore_s_context: \n" + " push {r1-r3, lr} \n" + " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + " pop {r1-r3, lr} \n" + " \n" + " restore_ns_context: \n" + " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */ + " lsls r0, r0, #25 \n" /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + " \n" + " restore_general_regs: \n" + " ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ + " \n" + " restore_context_done: \n" + " msr psp, r2 \n" /* Remember the new top of stack for the task. */ + " bx lr \n" ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 80225b5cbca..b2fd7e5183a 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c index 7cdff70050d..bc7bb607107 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portasm.c @@ -77,16 +77,16 @@ " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -100,6 +100,14 @@ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs_first_task: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -130,6 +138,15 @@ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " \n" + #if ( configENABLE_PAC == 1 ) + " ldmia r0!, {r1-r4} \n" /* Read task's dedicated PAC key from stack. */ + " msr PAC_KEY_P_3, r1 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_2, r2 \n" + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_0, r4 \n" + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " mrs r1, control \n" /* Obtain current control register value. */ @@ -261,16 +278,15 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " mrs r2, psp \n" /* r2 = PSP. */ " \n" " save_general_regs: \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ - " tst lr, #0x10 \n" - " ittt eq \n" - " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ - " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ - " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ - " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ - " \n" + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ + " tst lr, #0x10 \n" + " ittt eq \n" + " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ + " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ + " vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ + " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store the hardware saved context. */ @@ -279,6 +295,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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */ " \n" " select_next_task: \n" @@ -314,16 +338,16 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ " \n" - #if ( configTOTAL_MPU_REGIONS == 16 ) - " movs r3, #8 \n" /* r3 = 8. */ - " str r3, [r1] \n" /* Program RNR = 8. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - " movs r3, #12 \n" /* r3 = 12. */ - " str r3, [r1] \n" /* Program RNR = 12. */ - " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ - " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ - #endif /* configTOTAL_MPU_REGIONS == 16 */ + #if ( configTOTAL_MPU_REGIONS == 16 ) + " movs r3, #8 \n" /* r3 = 8. */ + " str r3, [r1] \n" /* Program RNR = 8. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + " movs r3, #12 \n" /* r3 = 12. */ + " str r3, [r1] \n" /* Program RNR = 12. */ + " ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ + " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */ + #endif /* configTOTAL_MPU_REGIONS == 16 */ " \n" " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r2, [r1] \n" /* Read the value of MPU_CTRL. */ @@ -337,6 +361,14 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */ " \n" " restore_special_regs: \n" + #if ( configENABLE_PAC == 1 ) + " ldmdb r1!, {r2-r5} \n" /* Read task's dedicated PAC key from the task's context. */ + " msr PAC_KEY_P_0, r2 \n" /* Write the task's dedicated PAC key to the PAC key registers. */ + " msr PAC_KEY_P_1, r3 \n" + " msr PAC_KEY_P_2, r4 \n" + " msr PAC_KEY_P_3, r5 \n" + " clrm {r2-r5} \n" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ " msr psp, r2 \n" " msr psplim, r3 \n" @@ -346,13 +378,13 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " ldmdb r1!, {r4-r11} \n" /* r4-r11 contain hardware saved context. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" - " ittt eq \n" - " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ - " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ - " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" + " ittt eq \n" + " vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ + " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */ + " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " restore_context_done: \n" " str r1, [r0] \n" /* Save the location where the context should be saved next as the first member of TCB. */ @@ -371,16 +403,25 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att " \n" " mrs r0, psp \n" /* Read PSP in r0. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " mrs r2, psplim \n" /* r2 = PSPLIM. */ " mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */ " \n" + #if ( configENABLE_PAC == 1 ) + " mrs r1, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */ + " mrs r2, PAC_KEY_P_2 \n" + " mrs r3, PAC_KEY_P_1 \n" + " mrs r4, PAC_KEY_P_0 \n" + " stmdb r0!, {r1-r4} \n" /* Store the task's dedicated PAC key on the stack. */ + " clrm {r1-r4} \n" /* Clear r1-r4. */ + #endif /* configENABLE_PAC */ + " \n" " ldr r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " str r0, [r1] \n" /* Save the new top of stack in TCB. */ @@ -397,13 +438,22 @@ 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" /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + " \n" " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ " \n" - #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ - " it eq \n" - " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ - #endif /* configENABLE_FPU || configENABLE_MVE */ + #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) + " tst r3, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ + #endif /* configENABLE_FPU || configENABLE_MVE */ " \n" " msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 5c963ea29f5..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM23/non_secure/portmacro.h b/portable/IAR/ARM_CM23/non_secure/portmacro.h index 9dfcc91325f..9d6c3368e74 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 5c963ea29f5..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h index 9dfcc91325f..9d6c3368e74 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacro.h @@ -64,7 +64,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 5c963ea29f5..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index 212688d6177..8d5988819fc 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -152,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -177,6 +185,15 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -271,7 +288,16 @@ 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. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -329,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -374,38 +408,37 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - 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. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - 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. */ - 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!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -416,34 +449,45 @@ PendSV_Handler: mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - 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. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 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 restore_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. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM33/non_secure/portmacro.h b/portable/IAR/ARM_CM33/non_secure/portmacro.h index 0f7d100df76..53b668b5b86 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 5c963ea29f5..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -890,7 +891,7 @@ static void prvTaskExitError( void ) return ulAccessPermissions; } -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ /*-----------------------------------------------------------*/ #if ( configENABLE_MPU == 1 ) @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ba6e8e915ce 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portasm.s @@ -142,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -165,6 +173,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -233,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -242,6 +258,15 @@ 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} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -300,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -335,6 +368,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +393,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} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h index 0f7d100df76..53b668b5b86 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 9fdbe6d5037..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -409,7 +410,7 @@ static void prvTaskExitError( void ); * @return uint32_t Access permissions. */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; -#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ +#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s index 212688d6177..8d5988819fc 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -152,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -177,6 +185,15 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -271,7 +288,16 @@ 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. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -329,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -374,38 +408,37 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - 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. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - 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. */ - 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!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -416,34 +449,45 @@ PendSV_Handler: mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - 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. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 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 restore_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. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacro.h b/portable/IAR/ARM_CM35P/non_secure/portmacro.h index 0ad1009b683..6e543efb5a3 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ba6e8e915ce 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portasm.s @@ -142,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -165,6 +173,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -233,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -242,6 +258,15 @@ 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} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -300,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -335,6 +368,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +393,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} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h index 0ad1009b683..6e543efb5a3 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacro.h @@ -60,7 +60,7 @@ #ifndef configENABLE_MVE #define configENABLE_MVE 0 -#elif( configENABLE_MVE != 0 ) +#elif ( configENABLE_MVE != 0 ) #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35. #endif /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.s b/portable/IAR/ARM_CM55/non_secure/portasm.s index 212688d6177..8d5988819fc 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55/non_secure/portasm.s @@ -152,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -177,6 +185,15 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -271,7 +288,16 @@ 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. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -329,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -374,38 +408,37 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - 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. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - 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. */ - 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!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -416,34 +449,45 @@ PendSV_Handler: mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - 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. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 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 restore_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. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ba6e8e915ce 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portasm.s @@ -142,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -165,6 +173,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -233,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -242,6 +258,15 @@ 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} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -300,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -335,6 +368,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +393,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} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.s b/portable/IAR/ARM_CM85/non_secure/portasm.s index 212688d6177..8d5988819fc 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85/non_secure/portasm.s @@ -152,6 +152,14 @@ vRestoreContextOfFirstTask: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -177,6 +185,15 @@ vRestoreContextOfFirstTask: ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ +#if ( configENABLE_PAC == 1 ) + ldmia r0!, {r1-r4} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r1 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r2 + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_0, r4 + clrm {r1-r4} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */ ldr r4, =xSecureContext str r1, [r4] /* Set xSecureContext to this task's value for the same. */ @@ -271,7 +288,16 @@ 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. */ - str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_0 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_1 + mrs r5, PAC_KEY_P_2 + mrs r6, PAC_KEY_P_3 + stmia r2!, {r3-r6} /* Store the task's dedicated PAC key on the task's context. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -329,6 +355,14 @@ PendSV_Handler: ldr r2, [r1] /* r2 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r2!, {r3-r6} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r4 + msr PAC_KEY_P_2, r5 + msr PAC_KEY_P_3, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */ msr psp, r3 msr psplim, r4 @@ -374,38 +408,37 @@ PendSV_Handler: mrs r2, psp /* Read PSP in r2. */ cbz r0, save_ns_context /* No secure context to save. */ - push {r0-r2, r14} - bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r0-r3} /* LR is now in r3. */ - mov lr, r3 /* LR = r3. */ - 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. */ - b select_next_task + save_s_context: + push {r0-r2, lr} + bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ + pop {r0-r2, lr} save_ns_context: - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ + mov r3, lr /* r3 = LR. */ + lsls r3, r3, #25 /* r3 = r3 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi save_special_regs /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */ + + save_general_regs: #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - 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. */ - 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!, {r4-r11} /* Store the registers that are not saved automatically. */ + + save_special_regs: + mrs r3, psplim /* r3 = PSPLIM. */ + stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */ + #if ( configENABLE_PAC == 1 ) + mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */ + mrs r4, PAC_KEY_P_2 + mrs r5, PAC_KEY_P_1 + mrs r6, PAC_KEY_P_0 + stmdb r2!, {r3-r6} /* Store the task's dedicated PAC key on the stack. */ + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + + str r2, [r1] /* Save the new top of stack in TCB. */ select_next_task: mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY @@ -416,34 +449,45 @@ PendSV_Handler: mov r0, #0 /* r0 = 0. */ msr basepri, r0 /* Enable interrupts. */ + restore_context: ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r3] /* Read pxCurrentTCB. */ ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */ - 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. */ + restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmia r2!, {r3-r6} /* Read task's dedicated PAC key from stack. */ + msr PAC_KEY_P_3, r3 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_1, r5 + msr PAC_KEY_P_0, r6 + clrm {r3-r6} /* Clear r3-r6. */ + #endif /* configENABLE_PAC */ + ldmia r2!, {r0, r3, lr} http://files.iar.com/ftp/pub/box/bxarm-9.60.3.deb/* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */ + msr psplim, r3 /* Restore the PSPLIM register value for the task. */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */ str r0, [r3] /* Restore the task's xSecureContext. */ cbz r0, restore_ns_context /* If there is no secure context for the task, restore the non-secure context. */ - ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ - ldr r1, [r3] /* Read pxCurrentTCB. */ - push {r2, r4} + + restore_s_context: + push {r1-r3, lr} bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ - pop {r2, r4} - mov lr, r4 /* LR = r4. */ - lsls r1, r4, #25 /* r1 = r4 << 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 restore_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. */ - msr psp, r2 /* Remember the new top of stack for the task. */ - bx lr + pop {r1-r3, lr} restore_ns_context: + mov r0, lr /* r0 = LR (EXC_RETURN). */ + lsls r0, r0, #25 /* r0 = r0 << 25. Bit[6] of EXC_RETURN is 1 if secure stack was used, 0 if non-secure stack was used to store stack frame. */ + bmi restore_context_done /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */ + + restore_general_regs: ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) tst lr, #0x10 /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ it eq vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ #endif /* configENABLE_FPU || configENABLE_MVE */ + + restore_context_done: msr psp, r2 /* Remember the new top of stack for the task. */ bx lr diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index f3f5d3eddf0..b2fd7e5183a 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the MPU. */ -#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) -#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) -#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) +#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) -#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) -#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) +#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) +#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) -#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) -#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) +#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) +#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) -#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) -#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) +#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) +#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) -#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) -#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) +#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) +#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) -#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) -#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) +#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) +#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) +#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) -#define portMPU_MAIR_ATTR0_POS ( 0UL ) -#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR0_POS ( 0UL ) +#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR1_POS ( 8UL ) -#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR1_POS ( 8UL ) +#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR2_POS ( 16UL ) -#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR2_POS ( 16UL ) +#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR3_POS ( 24UL ) -#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR3_POS ( 24UL ) +#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) -#define portMPU_MAIR_ATTR4_POS ( 0UL ) -#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) +#define portMPU_MAIR_ATTR4_POS ( 0UL ) +#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) -#define portMPU_MAIR_ATTR5_POS ( 8UL ) -#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) +#define portMPU_MAIR_ATTR5_POS ( 8UL ) +#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) -#define portMPU_MAIR_ATTR6_POS ( 16UL ) -#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) +#define portMPU_MAIR_ATTR6_POS ( 16UL ) +#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) -#define portMPU_MAIR_ATTR7_POS ( 24UL ) -#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) +#define portMPU_MAIR_ATTR7_POS ( 24UL ) +#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) -#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) -#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) +#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL ) -#define portMPU_RLAR_REGION_ENABLE ( 1UL ) +#define portMPU_RLAR_REGION_ENABLE ( 1UL ) #if ( portARMV8M_MINOR_VERSION >= 1 ) - /* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ - #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) + +/* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ + #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ /* Enable privileged access to unmapped region. */ -#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) +#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) /* Enable MPU. */ -#define portMPU_ENABLE_BIT ( 1UL << 0UL ) +#define portMPU_ENABLE_BIT ( 1UL << 0UL ) /* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) +#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ @@ -380,14 +381,14 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to check and configure PACBTI security feature implementation. */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) - #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) + #define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) ) - #define portCONTROL_UPAC_EN ( 1UL << 7UL ) - #define portCONTROL_PAC_EN ( 1UL << 6UL ) - #define portCONTROL_UBTI_EN ( 1UL << 5UL ) - #define portCONTROL_BTI_EN ( 1UL << 4UL ) + #define portCONTROL_UPAC_EN ( 1UL << 7UL ) + #define portCONTROL_PAC_EN ( 1UL << 6UL ) + #define portCONTROL_UBTI_EN ( 1UL << 5UL ) + #define portCONTROL_BTI_EN ( 1UL << 4UL ) #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ /*-----------------------------------------------------------*/ @@ -427,7 +428,7 @@ static void prvTaskExitError( void ); static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) /** * @brief Configures PACBTI features. @@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __syscalls_flash_start__; @@ -1282,6 +1284,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * point (i.e. the caller of the MPU_). We need to restore it * when we exit from the system call. */ pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; + /* Store the value of the PSPLIM register before the SVC was raised. * We need to restore it when we exit from the system call. */ #if ( portUSE_PSPLIM_REGISTER == 1 ) @@ -1300,6 +1303,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Start executing the system call upon returning from this handler. */ pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; + /* Raise a request to exit from the system call upon finishing the * system call. */ pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; @@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO uint32_t ulStackFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) + /* Declaration when these variable are defined in code instead of being * exported from linker scripts. */ extern uint32_t * __privileged_functions_start__; @@ -1541,7 +1546,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Check PACBTI security feature configuration before pushing the * CONTROL register's value on task's TCB. */ @@ -1582,6 +1587,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + xMPUSettings->ulContext[ ulIndex ] = ulTaskPacKey[ i ]; + ulIndex++; + } + } + #endif /* configENABLE_PAC */ + return &( xMPUSettings->ulContext[ ulIndex ] ); } @@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #endif /* portPRELOAD_REGISTERS */ + #if ( configENABLE_PAC == 1 ) + { + uint32_t ulTaskPacKey[ 4 ], i; + + vApplicationGenerateTaskRandomPacKey( &( ulTaskPacKey[ 0 ] ) ); + + for( i = 0; i < 4; i++ ) + { + pxTopOfStack--; + *pxTopOfStack = ulTaskPacKey[ i ]; + } + } + #endif /* configENABLE_PAC */ + return pxTopOfStack; } @@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = 0; - #if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) + #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) { /* Set the CONTROL register value based on PACBTI security feature * configuration before starting the first task. */ - ( void) prvConfigurePACBTI( pdTRUE ); + ( void ) prvConfigurePACBTI( pdTRUE ); } #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */ if( xSchedulerRunning == pdFALSE ) { /* Grant access to all the kernel objects before the scheduler - * is started. It is necessary because there is no task running - * yet and therefore, we cannot use the permissions of any - * task. */ + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ xAccessGranted = pdTRUE; } else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) @@ -2213,7 +2246,7 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ /*-----------------------------------------------------------*/ -#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) +#if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ) { @@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void ) /* Enable UsageFault exception. */ portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; - #if( configENABLE_PAC == 1 ) + #if ( configENABLE_PAC == 1 ) { ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN ); } #endif - #if( configENABLE_BTI == 1 ) + #if ( configENABLE_BTI == 1 ) { ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); } diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s index 9d6c6a7ef9a..ba6e8e915ce 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portasm.s @@ -142,6 +142,14 @@ vRestoreContextOfFirstTask: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs_first_task: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -165,6 +173,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */ msr psplim, r1 /* Set this task's PSPLIM value. */ mrs r1, control /* Obtain current control register value. */ @@ -233,7 +250,6 @@ PendSV_Handler: vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */ - stmia r1!, {r4-r11} /* Store r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */ @@ -242,6 +258,15 @@ 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} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ + str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */ select_next_task: @@ -300,6 +325,14 @@ PendSV_Handler: ldr r1, [r0] /* r1 = Location of saved context in TCB. */ restore_special_regs: + #if ( configENABLE_PAC == 1 ) + ldmdb r1!, {r2-r5} /* Read task's dedicated PAC key from the task's context. */ + msr PAC_KEY_P_0, r2 /* Write the task's dedicated PAC key to the PAC key registers. */ + msr PAC_KEY_P_1, r3 + msr PAC_KEY_P_2, r4 + msr PAC_KEY_P_3, r5 + clrm {r2-r5} /* Clear r2-r5. */ + #endif /* configENABLE_PAC */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */ msr psp, r2 msr psplim, r3 @@ -335,6 +368,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} /* Clear r1-r4. */ +#endif /* configENABLE_PAC */ + ldr r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r1, [r2] /* Read pxCurrentTCB. */ str r0, [r1] /* Save the new top of stack in TCB. */ @@ -351,6 +393,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} /* Clear r2-r5. */ +#endif /* configENABLE_PAC */ + ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 8a8dc7d6ae3..e74fa825787 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,18 @@ 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. + * + * @param[out] pulTaskPacKey Pointer to a 4-word (128-bits) array to be + * filled with a 128-bit random number. + */ + void vApplicationGenerateTaskRandomPacKey( uint32_t * pulTaskPacKey ); + +#endif /* configENABLE_PAC */ /*-----------------------------------------------------------*/ /** @@ -188,9 +202,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configENABLE_MPU == 1 ) -/** - * @brief Settings to define an MPU region. - */ + /** + * @brief Settings to define an MPU region. + */ typedef struct MPURegionSettings { uint32_t ulRBAR; /**< RBAR for the region. */ @@ -203,9 +217,14 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #error configSYSTEM_CALL_STACK_SIZE must be defined to the desired size of the system call stack in words for using MPU wrappers v2. #endif -/** - * @brief System call stack. - */ + /* When MPU wrapper v2 is used, the task's context is stored in TCB and + * pxTopOfStack member of TCB points to the context location in TCB. We, + * therefore, need to read PSP to find the task's current top of stack. */ + #define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { __asm volatile ( "mrs %0, psp" : "=r" ( pxCurrentTopOfStack ) ); } + + /** + * @brief System call stack. + */ typedef struct SYSTEM_CALL_STACK_INFO { uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; @@ -218,76 +237,128 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -/** - * @brief MPU settings as stored in the TCB. - */ + /** + * @brief MPU settings as stored in the TCB. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) - #if ( configENABLE_TRUSTZONE == 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 - */ + #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 + */ #define MAX_CONTEXT_SIZE 54 - #else /* #if( configENABLE_TRUSTZONE == 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 - */ + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | | | PC, xPSR | EXC_RETURN | | | + * +-----------+---------------+----------+-----------------+----------------------+------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><-----------><----> + * 16 16 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 69 + + #else /* if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) */ + + /* + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | + * | | | | PC, xPSR | EXC_RETURN | | + * +-----------+---------------+----------+-----------------+----------------------+-----+ + * + * <-----------><--------------><---------><----------------><---------------------><----> + * 16 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 ) - -/* - * +----------+-----------------+------------------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | - * | | PC, xPSR | CONTROL, EXC_RETURN | | - * +----------+-----------------+------------------------------+-----+ - * - * <---------><----------------><------------------------------><----> - * 8 8 5 1 - */ + #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+------------------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | | + * +----------+-----------------+------------------------------+------------+-----+ + * + * <---------><----------------><------------------------------><-----------><----> + * 8 8 5 16 1 + */ + #define MAX_CONTEXT_SIZE 38 + + #elif ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 0 ) ) + + /* + * +----------+-----------------+------------------------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | + * | | PC, xPSR | CONTROL, EXC_RETURN | | + * +----------+-----------------+------------------------------+-----+ + * + * <---------><----------------><------------------------------><----> + * 8 8 5 1 + */ #define MAX_CONTEXT_SIZE 22 + #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) ) + + /* + * +----------+-----------------+----------------------+------------+-----+ + * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | | + * | | PC, xPSR | EXC_RETURN | | | + * +----------+-----------------+----------------------+------------+-----+ + * + * <---------><----------------><----------------------><-----------><----> + * 8 8 4 16 1 + */ + #define MAX_CONTEXT_SIZE 37 + #else /* #if( configENABLE_TRUSTZONE == 1 ) */ -/* - * +----------+-----------------+----------------------+-----+ - * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | - * | | PC, xPSR | EXC_RETURN | | - * +----------+-----------------+----------------------+-----+ - * - * <---------><----------------><----------------------><----> - * 8 8 4 1 - */ + /* + * +----------+-----------------+----------------------+-----+ + * | 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 ) ) */ -/* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ + /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) -/* Size of an Access Control List (ACL) entry in bits. */ + /* Size of an Access Control List (ACL) entry in bits. */ #define portACL_ENTRY_SIZE_BITS ( 32U ) typedef struct MPU_SETTINGS