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 <Ahmed.Ismail@arm.com>
This commit is contained in:
Ahmed Ismail 2025-01-14 05:20:52 +00:00 committed by GitHub
parent c38427eea4
commit 78e0cc778a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
87 changed files with 6662 additions and 3530 deletions

View file

@ -106,6 +106,7 @@ CLKSOURCE
CLKSTA CLKSTA
CLRB CLRB
CLRF CLRF
clrm
CLRPSW CLRPSW
CMCNT CMCNT
CMCON CMCON
@ -678,6 +679,7 @@ pylint
pytest pytest
pyyaml pyyaml
RAMPZ RAMPZ
randomisation
RASR RASR
Rationalised Rationalised
Raynald Raynald

View file

@ -93,6 +93,10 @@
#define portBASE_TYPE_EXIT_CRITICAL() taskEXIT_CRITICAL() #define portBASE_TYPE_EXIT_CRITICAL() taskEXIT_CRITICAL()
#endif #endif
#ifndef portGET_CURRENT_TOP_OF_STACK
#define portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ) { pxCurrentTopOfStack = ( StackType_t * ) pxCurrentTCB->pxTopOfStack; }
#endif
#ifndef configSTACK_DEPTH_TYPE #ifndef configSTACK_DEPTH_TYPE
#define configSTACK_DEPTH_TYPE StackType_t #define configSTACK_DEPTH_TYPE StackType_t
#endif #endif

View file

@ -57,9 +57,13 @@
/* Only the current stack state is to be checked. */ /* Only the current stack state is to be checked. */
#define taskCHECK_FOR_STACK_OVERFLOW() \ #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? */ \ /* 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; \ char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
@ -72,15 +76,18 @@
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) #if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
/* Only the current stack state is to be checked. */ /* Only the current stack state is to be checked. */
#define taskCHECK_FOR_STACK_OVERFLOW() \ #define taskCHECK_FOR_STACK_OVERFLOW() \
do { \ do \
\ { \
/* Is the currently saved stack pointer within the stack limit? */ \ StackType_t * pxCurrentTopOfStack; \
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \ portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
{ \ \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ /* Is the currently saved stack pointer within the stack limit? */ \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ if( pxCurrentTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
} \ { \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
} \
} while( 0 ) } while( 0 )
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ #endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
@ -88,20 +95,23 @@
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \ #define taskCHECK_FOR_STACK_OVERFLOW() \
do { \ do \
const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ { \
const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \ const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \
\ const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U; \
if( ( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \ StackType_t * pxCurrentTopOfStack; \
( pulStack[ 0 ] != ulCheckValue ) || \ portGET_CURRENT_TOP_OF_STACK( pxCurrentTopOfStack ); \
( pulStack[ 1 ] != ulCheckValue ) || \ \
( pulStack[ 2 ] != ulCheckValue ) || \ if( ( pxCurrentTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING ) || \
( pulStack[ 3 ] != ulCheckValue ) ) \ ( pulStack[ 0 ] != ulCheckValue ) || \
{ \ ( pulStack[ 1 ] != ulCheckValue ) || \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ ( pulStack[ 2 ] != ulCheckValue ) || \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \ ( pulStack[ 3 ] != ulCheckValue ) ) \
} \ { \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
} \
} while( 0 ) } while( 0 )
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ #endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
@ -110,18 +120,20 @@
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) #if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
#define taskCHECK_FOR_STACK_OVERFLOW() \ #define taskCHECK_FOR_STACK_OVERFLOW() \
do { \ do \
{ \
int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ 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, \
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 ); \ 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 ) ) \ ( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) ) \
{ \ { \
char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \ char * pcOverflowTaskName = pxCurrentTCB->pcTaskName; \

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \n" " msr psplim, r4 \n"
@ -132,6 +140,15 @@
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
" ldr r4, =xSecureContext \n" " ldr r4, =xSecureContext \n"
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " 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" " \n"
" save_general_regs: \n" " save_general_regs: \n"
" mrs r3, psp \n" " mrs r3, psp \n"
" \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ " tst lr, #0x10 \n"
" tst lr, #0x10 \n" " ittt eq \n"
" ittt eq \n" " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
" 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. */
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */
#endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r4, psplim \n" /* r4 = PSPLIM. */
" mrs r5, control \n" /* r5 = CONTROL. */ " 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. */ " 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" " \n"
" select_next_task: \n" " select_next_task: \n"
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " 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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \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. */ " 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. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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 __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" .extern SecureContext_SaveContext \n" " .extern SecureContext_SaveContext \n"
" .extern SecureContext_LoadContext \n" " .extern SecureContext_LoadContext \n"
" \n" " \n"
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " 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 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 r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr 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. */ " mrs r2, psp \n" /* Read PSP in r2. */
" \n" " \n"
" cbz r0, save_ns_context \n" /* No secure context to save. */ " cbz r0, save_ns_context \n" /* No secure context to save. */
" push {r0-r2, r14} \n" " save_s_context: \n"
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " push {r0-r2, lr} \n"
" pop {r0-r3} \n" /* LR is now in r3. */ " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" mov lr, r3 \n" /* LR = r3. */ " pop {r0-r2, lr} \n"
" 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. */ " \n"
" 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. */ " save_ns_context: \n"
" \n" " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " 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. */
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " save_general_regs: \n"
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " it eq \n"
" b select_next_task \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
" \n" #endif /* configENABLE_FPU || configENABLE_MVE */
" save_ns_context: \n" " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " save_special_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " mrs r3, psplim \n" /* r3 = PSPLIM. */
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" it eq \n" #if ( configENABLE_PAC == 1 )
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " mrs r4, PAC_KEY_P_2 \n"
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " mrs r5, PAC_KEY_P_1 \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r6, PAC_KEY_P_0 \n"
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */ " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #endif /* configENABLE_PAC */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " \n"
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " \n"
" \n" " select_next_task: \n"
" select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n"
" dsb \n" " isb \n"
" isb \n" " bl vTaskSwitchContext \n"
" bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */
" mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */
" msr basepri, r0 \n" /* Enable interrupts. */ " \n"
" \n" " restore_context: \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read 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. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
" \n" " \n"
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " restore_special_regs: \n"
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
" mov lr, r4 \n" /* LR = r4. */ " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
" str r0, [r3] \n" /* Restore the task's xSecureContext. */ " msr PAC_KEY_P_2, r4 \n"
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " msr PAC_KEY_P_1, r5 \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " msr PAC_KEY_P_0, r6 \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" push {r2, r4} \n" #endif /* configENABLE_PAC */
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */
" pop {r2, r4} \n" " msr psplim, r3 \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 ). */
" 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. */ " str r0, [r3] \n" /* Restore the task's xSecureContext. */
" 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. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \n" " restore_s_context: \n"
" \n" " push {r1-r3, lr} \n"
" restore_ns_context: \n" " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ " pop {r1-r3, lr} \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " \n"
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " restore_ns_context: \n"
" it eq \n" " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " 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. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \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 ) ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \n" " msr psplim, r3 \n"
@ -130,6 +138,15 @@
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */
" mrs r1, control \n" /* Obtain current control register 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. */ " mrs r2, psp \n" /* r2 = PSP. */
" \n" " \n"
" save_general_regs: \n" " save_general_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ " 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. */ " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r3, psplim \n" /* r3 = PSPLIM. */
" mrs r4, control \n" /* r4 = CONTROL. */ " mrs r4, control \n" /* r4 = CONTROL. */
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ " 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. */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
" \n" " \n"
" select_next_task: \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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \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. */ " 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. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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" " \n"
" mrs r0, psp \n" /* Read PSP in r0. */ " mrs r0, psp \n" /* Read PSP in r0. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " 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. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
" \n" " \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 r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " 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 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. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" \n" " \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. */ " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " 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. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -152,6 +152,14 @@ vRestoreContextOfFirstTask:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -177,6 +185,15 @@ vRestoreContextOfFirstTask:
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
ldr r4, =xSecureContext ldr r4, =xSecureContext
str r1, [r4] /* Set xSecureContext to this task's value for the same. */ 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 r4, psplim /* r4 = PSPLIM. */
mrs r5, control /* r5 = CONTROL. */ mrs r5, control /* r5 = CONTROL. */
stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -329,6 +355,14 @@ PendSV_Handler:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -374,38 +408,37 @@ PendSV_Handler:
mrs r2, psp /* Read PSP in r2. */ mrs r2, psp /* Read PSP in r2. */
cbz r0, save_ns_context /* No secure context to save. */ cbz r0, save_ns_context /* No secure context to save. */
push {r0-r2, r14} save_s_context:
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ push {r0-r2, lr}
pop {r0-r3} /* LR is now in r3. */ bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
mov lr, r3 /* LR = r3. */ pop {r0-r2, lr}
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_ns_context: save_ns_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ mov r3, lr /* r3 = LR. */
ldr r1, [r3] /* Read pxCurrentTCB. */ 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 ) ) #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. */ 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 it eq
vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */
str r2, [r1] /* Save the new top of stack in TCB. */
adds r2, r2, #12 /* r2 = r2 + 12. */ save_special_regs:
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r1, psplim /* r1 = PSPLIM. */ stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ #if ( configENABLE_PAC == 1 )
subs r2, r2, #12 /* r2 = r2 - 12. */ mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -416,34 +449,45 @@ PendSV_Handler:
mov r0, #0 /* r0 = 0. */ mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */ msr basepri, r0 /* Enable interrupts. */
restore_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read 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. */ 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. */ restore_special_regs:
msr psplim, r1 /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
mov lr, r4 /* LR = r4. */ 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 ). */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r3] /* Restore the task's 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. */ 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. */ restore_s_context:
push {r2, r4} push {r1-r3, lr}
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r2, r4} pop {r1-r3, lr}
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
restore_ns_context: 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. */ ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ 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 it eq
vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
restore_context_done:
msr psp, r2 /* Remember the new top of stack for the task. */ msr psp, r2 /* Remember the new top of stack for the task. */
bx lr bx lr

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -142,6 +142,14 @@ vRestoreContextOfFirstTask:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -165,6 +173,15 @@ vRestoreContextOfFirstTask:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
msr psplim, r1 /* Set this task's PSPLIM value. */ msr psplim, r1 /* Set this task's PSPLIM value. */
mrs r1, control /* Obtain current control register value. */ mrs r1, control /* Obtain current control register value. */
@ -233,7 +250,6 @@ PendSV_Handler:
vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */
sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
stmia r1!, {r4-r11} /* Store r4-r11. */ stmia r1!, {r4-r11} /* Store r4-r11. */
ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */
stmia r1!, {r4-r11} /* Store the hardware saved context. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */
@ -242,6 +258,15 @@ PendSV_Handler:
mrs r3, psplim /* r3 = PSPLIM. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r4, control /* r4 = CONTROL. */ mrs r4, control /* r4 = CONTROL. */
stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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. */ str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */
select_next_task: select_next_task:
@ -300,6 +325,14 @@ PendSV_Handler:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -335,6 +368,15 @@ PendSV_Handler:
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ 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 r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
@ -351,6 +393,15 @@ PendSV_Handler:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ 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. */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \n" " msr psplim, r4 \n"
@ -132,6 +140,15 @@
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
" ldr r4, =xSecureContext \n" " ldr r4, =xSecureContext \n"
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " 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" " \n"
" save_general_regs: \n" " save_general_regs: \n"
" mrs r3, psp \n" " mrs r3, psp \n"
" \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ " tst lr, #0x10 \n"
" tst lr, #0x10 \n" " ittt eq \n"
" ittt eq \n" " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
" 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. */
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */
#endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r4, psplim \n" /* r4 = PSPLIM. */
" mrs r5, control \n" /* r5 = CONTROL. */ " 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. */ " 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" " \n"
" select_next_task: \n" " select_next_task: \n"
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " 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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \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. */ " 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. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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 __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" .extern SecureContext_SaveContext \n" " .extern SecureContext_SaveContext \n"
" .extern SecureContext_LoadContext \n" " .extern SecureContext_LoadContext \n"
" \n" " \n"
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " 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 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 r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr 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. */ " mrs r2, psp \n" /* Read PSP in r2. */
" \n" " \n"
" cbz r0, save_ns_context \n" /* No secure context to save. */ " cbz r0, save_ns_context \n" /* No secure context to save. */
" push {r0-r2, r14} \n" " save_s_context: \n"
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " push {r0-r2, lr} \n"
" pop {r0-r3} \n" /* LR is now in r3. */ " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" mov lr, r3 \n" /* LR = r3. */ " pop {r0-r2, lr} \n"
" 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. */ " \n"
" 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. */ " save_ns_context: \n"
" \n" " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " 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. */
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " save_general_regs: \n"
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " it eq \n"
" b select_next_task \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
" \n" #endif /* configENABLE_FPU || configENABLE_MVE */
" save_ns_context: \n" " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " save_special_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " mrs r3, psplim \n" /* r3 = PSPLIM. */
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" it eq \n" #if ( configENABLE_PAC == 1 )
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " mrs r4, PAC_KEY_P_2 \n"
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " mrs r5, PAC_KEY_P_1 \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r6, PAC_KEY_P_0 \n"
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */ " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #endif /* configENABLE_PAC */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " \n"
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " \n"
" \n" " select_next_task: \n"
" select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n"
" dsb \n" " isb \n"
" isb \n" " bl vTaskSwitchContext \n"
" bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */
" mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */
" msr basepri, r0 \n" /* Enable interrupts. */ " \n"
" \n" " restore_context: \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read 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. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
" \n" " \n"
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " restore_special_regs: \n"
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
" mov lr, r4 \n" /* LR = r4. */ " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
" str r0, [r3] \n" /* Restore the task's xSecureContext. */ " msr PAC_KEY_P_2, r4 \n"
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " msr PAC_KEY_P_1, r5 \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " msr PAC_KEY_P_0, r6 \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" push {r2, r4} \n" #endif /* configENABLE_PAC */
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */
" pop {r2, r4} \n" " msr psplim, r3 \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 ). */
" 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. */ " str r0, [r3] \n" /* Restore the task's xSecureContext. */
" 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. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \n" " restore_s_context: \n"
" \n" " push {r1-r3, lr} \n"
" restore_ns_context: \n" " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ " pop {r1-r3, lr} \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " \n"
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " restore_ns_context: \n"
" it eq \n" " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " 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. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \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 ) ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \n" " msr psplim, r3 \n"
@ -130,6 +138,15 @@
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */
" mrs r1, control \n" /* Obtain current control register 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. */ " mrs r2, psp \n" /* r2 = PSP. */
" \n" " \n"
" save_general_regs: \n" " save_general_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ " 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. */ " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r3, psplim \n" /* r3 = PSPLIM. */
" mrs r4, control \n" /* r4 = CONTROL. */ " mrs r4, control \n" /* r4 = CONTROL. */
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ " 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. */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
" \n" " \n"
" select_next_task: \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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \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. */ " 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. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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" " \n"
" mrs r0, psp \n" /* Read PSP in r0. */ " mrs r0, psp \n" /* Read PSP in r0. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " 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. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
" \n" " \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 r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " 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 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. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" \n" " \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. */ " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " 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. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \n" " msr psplim, r4 \n"
@ -132,6 +140,15 @@
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
" ldr r4, =xSecureContext \n" " ldr r4, =xSecureContext \n"
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " 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" " \n"
" save_general_regs: \n" " save_general_regs: \n"
" mrs r3, psp \n" " mrs r3, psp \n"
" \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ " tst lr, #0x10 \n"
" tst lr, #0x10 \n" " ittt eq \n"
" ittt eq \n" " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
" 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. */
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */
#endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r4, psplim \n" /* r4 = PSPLIM. */
" mrs r5, control \n" /* r5 = CONTROL. */ " 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. */ " 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" " \n"
" select_next_task: \n" " select_next_task: \n"
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " 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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \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. */ " 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. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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 __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" .extern SecureContext_SaveContext \n" " .extern SecureContext_SaveContext \n"
" .extern SecureContext_LoadContext \n" " .extern SecureContext_LoadContext \n"
" \n" " \n"
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " 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 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 r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr 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. */ " mrs r2, psp \n" /* Read PSP in r2. */
" \n" " \n"
" cbz r0, save_ns_context \n" /* No secure context to save. */ " cbz r0, save_ns_context \n" /* No secure context to save. */
" push {r0-r2, r14} \n" " save_s_context: \n"
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " push {r0-r2, lr} \n"
" pop {r0-r3} \n" /* LR is now in r3. */ " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" mov lr, r3 \n" /* LR = r3. */ " pop {r0-r2, lr} \n"
" 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. */ " \n"
" 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. */ " save_ns_context: \n"
" \n" " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " 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. */
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " save_general_regs: \n"
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " it eq \n"
" b select_next_task \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
" \n" #endif /* configENABLE_FPU || configENABLE_MVE */
" save_ns_context: \n" " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " save_special_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " mrs r3, psplim \n" /* r3 = PSPLIM. */
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" it eq \n" #if ( configENABLE_PAC == 1 )
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " mrs r4, PAC_KEY_P_2 \n"
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " mrs r5, PAC_KEY_P_1 \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r6, PAC_KEY_P_0 \n"
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */ " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #endif /* configENABLE_PAC */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " \n"
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " \n"
" \n" " select_next_task: \n"
" select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n"
" dsb \n" " isb \n"
" isb \n" " bl vTaskSwitchContext \n"
" bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */
" mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */
" msr basepri, r0 \n" /* Enable interrupts. */ " \n"
" \n" " restore_context: \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read 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. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
" \n" " \n"
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " restore_special_regs: \n"
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
" mov lr, r4 \n" /* LR = r4. */ " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
" str r0, [r3] \n" /* Restore the task's xSecureContext. */ " msr PAC_KEY_P_2, r4 \n"
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " msr PAC_KEY_P_1, r5 \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " msr PAC_KEY_P_0, r6 \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" push {r2, r4} \n" #endif /* configENABLE_PAC */
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */
" pop {r2, r4} \n" " msr psplim, r3 \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 ). */
" 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. */ " str r0, [r3] \n" /* Restore the task's xSecureContext. */
" 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. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \n" " restore_s_context: \n"
" \n" " push {r1-r3, lr} \n"
" restore_ns_context: \n" " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ " pop {r1-r3, lr} \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " \n"
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " restore_ns_context: \n"
" it eq \n" " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " 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. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \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 ) ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \n" " msr psplim, r3 \n"
@ -130,6 +138,15 @@
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */
" mrs r1, control \n" /* Obtain current control register 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. */ " mrs r2, psp \n" /* r2 = PSP. */
" \n" " \n"
" save_general_regs: \n" " save_general_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ " 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. */ " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r3, psplim \n" /* r3 = PSPLIM. */
" mrs r4, control \n" /* r4 = CONTROL. */ " mrs r4, control \n" /* r4 = CONTROL. */
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ " 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. */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
" \n" " \n"
" select_next_task: \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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \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. */ " 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. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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" " \n"
" mrs r0, psp \n" /* Read PSP in r0. */ " mrs r0, psp \n" /* Read PSP in r0. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " 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. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
" \n" " \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 r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " 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 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. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" \n" " \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. */ " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " 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. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \n" " msr psplim, r4 \n"
@ -132,6 +140,15 @@
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
" ldr r4, =xSecureContext \n" " ldr r4, =xSecureContext \n"
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " 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" " \n"
" save_general_regs: \n" " save_general_regs: \n"
" mrs r3, psp \n" " mrs r3, psp \n"
" \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ " tst lr, #0x10 \n"
" tst lr, #0x10 \n" " ittt eq \n"
" ittt eq \n" " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
" 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. */
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */
#endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r4, psplim \n" /* r4 = PSPLIM. */
" mrs r5, control \n" /* r5 = CONTROL. */ " 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. */ " 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" " \n"
" select_next_task: \n" " select_next_task: \n"
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " 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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \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. */ " 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. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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 __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" .extern SecureContext_SaveContext \n" " .extern SecureContext_SaveContext \n"
" .extern SecureContext_LoadContext \n" " .extern SecureContext_LoadContext \n"
" \n" " \n"
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " 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 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 r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr 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. */ " mrs r2, psp \n" /* Read PSP in r2. */
" \n" " \n"
" cbz r0, save_ns_context \n" /* No secure context to save. */ " cbz r0, save_ns_context \n" /* No secure context to save. */
" push {r0-r2, r14} \n" " save_s_context: \n"
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " push {r0-r2, lr} \n"
" pop {r0-r3} \n" /* LR is now in r3. */ " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" mov lr, r3 \n" /* LR = r3. */ " pop {r0-r2, lr} \n"
" 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. */ " \n"
" 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. */ " save_ns_context: \n"
" \n" " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " 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. */
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " save_general_regs: \n"
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " it eq \n"
" b select_next_task \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
" \n" #endif /* configENABLE_FPU || configENABLE_MVE */
" save_ns_context: \n" " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " save_special_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " mrs r3, psplim \n" /* r3 = PSPLIM. */
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" it eq \n" #if ( configENABLE_PAC == 1 )
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " mrs r4, PAC_KEY_P_2 \n"
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " mrs r5, PAC_KEY_P_1 \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r6, PAC_KEY_P_0 \n"
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */ " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #endif /* configENABLE_PAC */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " \n"
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " \n"
" \n" " select_next_task: \n"
" select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n"
" dsb \n" " isb \n"
" isb \n" " bl vTaskSwitchContext \n"
" bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */
" mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */
" msr basepri, r0 \n" /* Enable interrupts. */ " \n"
" \n" " restore_context: \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read 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. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
" \n" " \n"
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " restore_special_regs: \n"
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
" mov lr, r4 \n" /* LR = r4. */ " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
" str r0, [r3] \n" /* Restore the task's xSecureContext. */ " msr PAC_KEY_P_2, r4 \n"
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " msr PAC_KEY_P_1, r5 \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " msr PAC_KEY_P_0, r6 \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" push {r2, r4} \n" #endif /* configENABLE_PAC */
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */
" pop {r2, r4} \n" " msr psplim, r3 \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 ). */
" 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. */ " str r0, [r3] \n" /* Restore the task's xSecureContext. */
" 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. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \n" " restore_s_context: \n"
" \n" " push {r1-r3, lr} \n"
" restore_ns_context: \n" " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ " pop {r1-r3, lr} \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " \n"
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " restore_ns_context: \n"
" it eq \n" " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " 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. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \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 ) ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \n" " msr psplim, r3 \n"
@ -130,6 +138,15 @@
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */
" mrs r1, control \n" /* Obtain current control register 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. */ " mrs r2, psp \n" /* r2 = PSP. */
" \n" " \n"
" save_general_regs: \n" " save_general_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ " 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. */ " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r3, psplim \n" /* r3 = PSPLIM. */
" mrs r4, control \n" /* r4 = CONTROL. */ " mrs r4, control \n" /* r4 = CONTROL. */
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ " 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. */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
" \n" " \n"
" select_next_task: \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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \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. */ " 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. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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" " \n"
" mrs r0, psp \n" /* Read PSP in r0. */ " mrs r0, psp \n" /* Read PSP in r0. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " 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. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
" \n" " \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 r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " 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 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. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" \n" " \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. */ " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " 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. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 set of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \n" " msr psplim, r4 \n"
@ -132,6 +140,15 @@
" ldr r3, [r2] \n" /* Read pxCurrentTCB. */ " ldr r3, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r3] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
" ldr r4, =xSecureContext \n" " ldr r4, =xSecureContext \n"
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */ " 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" " \n"
" save_general_regs: \n" " save_general_regs: \n"
" mrs r3, psp \n" " mrs r3, psp \n"
" \n" #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */
" add r3, r3, #0x20 \n" /* Move r3 to location where s0 is saved. */ " tst lr, #0x10 \n"
" tst lr, #0x10 \n" " ittt eq \n"
" ittt eq \n" " vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */
" vstmiaeq r2!, {s16-s31} \n" /* Store s16-s31. */ " vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vldmiaeq r3, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vstmiaeq r2!, {s0-s16} \n" /* Store hardware saved FP context. */
" 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. */
" sub r3, r3, #0x20 \n" /* Set r3 back to the location of hardware saved context. */ #endif /* configENABLE_FPU || configENABLE_MVE */
#endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r2!, {r4-r11} \n" /* Store r4-r11. */ " stmia r2!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r3, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r4, psplim \n" /* r4 = PSPLIM. */
" mrs r5, control \n" /* r5 = CONTROL. */ " 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. */ " 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" " \n"
" select_next_task: \n" " select_next_task: \n"
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " 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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r2, [r1] \n" /* r2 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r2!, {r0, r3-r5, lr} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
" msr psp, r3 \n" " msr psp, r3 \n"
" msr psplim, r4 \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. */ " 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. */ " stmia r3!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r2!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r2!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r3!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r2!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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 __asm volatile
( (
" .syntax unified \n" " .syntax unified \n"
" .extern SecureContext_SaveContext \n" " .extern SecureContext_SaveContext \n"
" .extern SecureContext_LoadContext \n" " .extern SecureContext_LoadContext \n"
" \n" " \n"
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " 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 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 r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read pxCurrentTCB - Value of pxCurrentTCB must be in r1 as it is used as a parameter later. */ " ldr 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. */ " mrs r2, psp \n" /* Read PSP in r2. */
" \n" " \n"
" cbz r0, save_ns_context \n" /* No secure context to save. */ " cbz r0, save_ns_context \n" /* No secure context to save. */
" push {r0-r2, r14} \n" " save_s_context: \n"
" bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " push {r0-r2, lr} \n"
" pop {r0-r3} \n" /* LR is now in r3. */ " bl SecureContext_SaveContext \n" /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" mov lr, r3 \n" /* LR = r3. */ " pop {r0-r2, lr} \n"
" 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. */ " \n"
" 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. */ " save_ns_context: \n"
" \n" " mov r3, lr \n" /* r3 = LR (EXC_RETURN). */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " 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. */
" ldr r1, [r3] \n" /* Read pxCurrentTCB.*/ " bmi save_special_regs \n" /* If r3 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used. */
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */ " \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " save_general_regs: \n"
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " it eq \n"
" b select_next_task \n" " vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
" \n" #endif /* configENABLE_FPU || configENABLE_MVE */
" save_ns_context: \n" " stmdb r2!, {r4-r11} \n" /* Store the registers that are not saved automatically. */
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " save_special_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " mrs r3, psplim \n" /* r3 = PSPLIM. */
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " stmdb r2!, {r0, r3, lr} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
" it eq \n" #if ( configENABLE_PAC == 1 )
" vstmdbeq r2!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " mrs r3, PAC_KEY_P_3 \n" /* Read task's dedicated PAC key from the PAC key registers. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " mrs r4, PAC_KEY_P_2 \n"
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ " mrs r5, PAC_KEY_P_1 \n"
" str r2, [r1] \n" /* Save the new top of stack in TCB. */ " mrs r6, PAC_KEY_P_0 \n"
" adds r2, r2, #12 \n" /* r2 = r2 + 12. */ " stmdb r2!, {r3-r6} \n" /* Store the task's dedicated PAC key on the stack. */
" stm r2, {r4-r11} \n" /* Store the registers that are not saved automatically. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" mrs r1, psplim \n" /* r1 = PSPLIM. */ #endif /* configENABLE_PAC */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " \n"
" subs r2, r2, #12 \n" /* r2 = r2 - 12. */ " str r2, [r1] \n" /* Save the new top of stack in TCB. */
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */ " \n"
" \n" " select_next_task: \n"
" select_next_task: \n" " mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */
" mov r0, %0 \n" /* r0 = configMAX_SYSCALL_INTERRUPT_PRIORITY */ " msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */
" msr basepri, r0 \n" /* Disable interrupts up to configMAX_SYSCALL_INTERRUPT_PRIORITY. */ " dsb \n"
" dsb \n" " isb \n"
" isb \n" " bl vTaskSwitchContext \n"
" bl vTaskSwitchContext \n" " mov r0, #0 \n" /* r0 = 0. */
" mov r0, #0 \n" /* r0 = 0. */ " msr basepri, r0 \n" /* Enable interrupts. */
" msr basepri, r0 \n" /* Enable interrupts. */ " \n"
" \n" " restore_context: \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r3] \n" /* Read 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. */ " ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
" \n" " \n"
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */ " restore_special_regs: \n"
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
" mov lr, r4 \n" /* LR = r4. */ " ldmia r2!, {r3-r6} \n" /* Read task's dedicated PAC key from stack. */
" ldr r3, =xSecureContext \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */ " msr PAC_KEY_P_3, r3 \n" /* Write the task's dedicated PAC key to the PAC key registers. */
" str r0, [r3] \n" /* Restore the task's xSecureContext. */ " msr PAC_KEY_P_2, r4 \n"
" cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */ " msr PAC_KEY_P_1, r5 \n"
" ldr r3, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ " msr PAC_KEY_P_0, r6 \n"
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */ " clrm {r3-r6} \n" /* Clear r3-r6. */
" push {r2, r4} \n" #endif /* configENABLE_PAC */
" bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ " ldmia r2!, {r0, r3, lr} \n" /* Read from stack - r0 = xSecureContext, r3 = PSPLIM and LR restored. */
" pop {r2, r4} \n" " msr psplim, r3 \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 ). */
" 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. */ " str r0, [r3] \n" /* Restore the task's xSecureContext. */
" 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. */ " cbz r0, restore_ns_context \n" /* If there is no secure context for the task, restore the non-secure context. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \n" " restore_s_context: \n"
" \n" " push {r1-r3, lr} \n"
" restore_ns_context: \n" " bl SecureContext_LoadContext \n" /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
" ldmia r2!, {r4-r11} \n" /* Restore the registers that are not automatically restored. */ " pop {r1-r3, lr} \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) " \n"
" tst lr, #0x10 \n" /* Test Bit[4] in LR. Bit[4] of EXC_RETURN is 0 if the Extended Stack Frame is in use. */ " restore_ns_context: \n"
" it eq \n" " mov r0, lr \n" /* r0 = LR (EXC_RETURN). */
" vldmiaeq r2!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " 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. */
#endif /* configENABLE_FPU || configENABLE_MVE */ " bmi restore_context_done \n" /* r0 < 0 ==> Bit[6] in EXC_RETURN is 1 ==> secure stack was used to store the stack frame. */
" msr psp, r2 \n" /* Remember the new top of stack for the task. */ " \n"
" bx lr \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 ) ::"i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
); );
} }

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -77,16 +77,16 @@
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs_first_task: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \n" " msr psplim, r3 \n"
@ -130,6 +138,15 @@
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ " ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
" \n" " \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. */ " ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */ " msr psplim, r1 \n" /* Set this task's PSPLIM value. */
" mrs r1, control \n" /* Obtain current control register 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. */ " mrs r2, psp \n" /* r2 = PSP. */
" \n" " \n"
" save_general_regs: \n" " save_general_regs: \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */ " add r2, r2, #0x20 \n" /* Move r2 to location where s0 is saved. */
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */ " vstmiaeq r1!, {s16-s31} \n" /* Store s16-s31. */
" vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */ " vldmiaeq r2, {s0-s16} \n" /* Copy hardware saved FP context into s0-s16. */
" vstmiaeq r1!, {s0-s16} \n" /* Store hardware saved FP context. */ " 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. */ " sub r2, r2, #0x20 \n" /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n"
" stmia r1!, {r4-r11} \n" /* Store r4-r11. */ " stmia r1!, {r4-r11} \n" /* Store r4-r11. */
" ldmia r2, {r4-r11} \n" /* Copy the hardware saved context into 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. */ " 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 r3, psplim \n" /* r3 = PSPLIM. */
" mrs r4, control \n" /* r4 = CONTROL. */ " mrs r4, control \n" /* r4 = CONTROL. */
" stmia r1!, {r2-r4, lr} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ " 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. */ " str r1, [r0] \n" /* Save the location from where the context should be restored as the first member of TCB. */
" \n" " \n"
" select_next_task: \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. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" \n" " \n"
#if ( configTOTAL_MPU_REGIONS == 16 ) #if ( configTOTAL_MPU_REGIONS == 16 )
" movs r3, #8 \n" /* r3 = 8. */ " movs r3, #8 \n" /* r3 = 8. */
" str r3, [r1] \n" /* Program RNR = 8. */ " str r3, [r1] \n" /* Program RNR = 8. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
" movs r3, #12 \n" /* r3 = 12. */ " movs r3, #12 \n" /* r3 = 12. */
" str r3, [r1] \n" /* Program RNR = 12. */ " str r3, [r1] \n" /* Program RNR = 12. */
" ldmia r0!, {r4-r11} \n" /* Read 4 sets of RBAR/RLAR registers from TCB. */ " 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. */ " stmia r2, {r4-r11} \n" /* Write 4 set of RBAR/RLAR registers using alias registers. */
#endif /* configTOTAL_MPU_REGIONS == 16 */ #endif /* configTOTAL_MPU_REGIONS == 16 */
" \n" " \n"
" ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */ " ldr r1, =0xe000ed94 \n" /* r1 = 0xe000ed94 [Location of MPU_CTRL]. */
" ldr r2, [r1] \n" /* Read the value 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. */ " ldr r1, [r0] \n" /* r1 = Location of saved context in TCB. */
" \n" " \n"
" restore_special_regs: \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. */ " ldmdb r1!, {r2-r4, lr} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
" msr psp, r2 \n" " msr psp, r2 \n"
" msr psplim, r3 \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. */ " 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. */ " stmia r2!, {r4-r11} \n" /* Copy the hardware saved context on the task stack. */
" ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */ " ldmdb r1!, {r4-r11} \n" /* r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
" tst lr, #0x10 \n" " tst lr, #0x10 \n"
" ittt eq \n" " ittt eq \n"
" vldmdbeq r1!, {s0-s16} \n" /* s0-s16 contain hardware saved FP context. */ " 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. */ " vstmiaeq r2!, {s0-s16} \n" /* Copy hardware saved FP context on the task stack. */
" vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */ " vldmdbeq r1!, {s16-s31} \n" /* Restore s16-s31. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" restore_context_done: \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. */ " 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" " \n"
" mrs r0, psp \n" /* Read PSP in r0. */ " mrs r0, psp \n" /* Read PSP in r0. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */ " vstmdbeq r0!, {s16-s31} \n" /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" mrs r2, psplim \n" /* r2 = PSPLIM. */ " mrs r2, psplim \n" /* r2 = PSPLIM. */
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */ " 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. */ " stmdb r0!, {r2-r11} \n" /* Store on the stack - PSPLIM, LR and registers that are not automatically saved. */
" \n" " \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 r2, =pxCurrentTCB \n" /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */ " ldr r1, [r2] \n" /* Read pxCurrentTCB. */
" str r0, [r1] \n" /* Save the new top of stack in TCB. */ " 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 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. */ " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */
" \n" " \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. */ " ldmia r0!, {r2-r11} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
" \n" " \n"
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ " 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" " it eq \n"
" vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */ " vldmiaeq r0!, {s16-s31} \n" /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
" \n" " \n"
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */ " 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. */ " msr psp, r0 \n" /* Remember the new top of stack for the task. */

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -64,7 +64,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M23.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -152,6 +152,14 @@ vRestoreContextOfFirstTask:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -177,6 +185,15 @@ vRestoreContextOfFirstTask:
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
ldr r4, =xSecureContext ldr r4, =xSecureContext
str r1, [r4] /* Set xSecureContext to this task's value for the same. */ 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 r4, psplim /* r4 = PSPLIM. */
mrs r5, control /* r5 = CONTROL. */ mrs r5, control /* r5 = CONTROL. */
stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -329,6 +355,14 @@ PendSV_Handler:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -374,38 +408,37 @@ PendSV_Handler:
mrs r2, psp /* Read PSP in r2. */ mrs r2, psp /* Read PSP in r2. */
cbz r0, save_ns_context /* No secure context to save. */ cbz r0, save_ns_context /* No secure context to save. */
push {r0-r2, r14} save_s_context:
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ push {r0-r2, lr}
pop {r0-r3} /* LR is now in r3. */ bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
mov lr, r3 /* LR = r3. */ pop {r0-r2, lr}
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_ns_context: save_ns_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ mov r3, lr /* r3 = LR. */
ldr r1, [r3] /* Read pxCurrentTCB. */ 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 ) ) #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. */ 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 it eq
vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */
str r2, [r1] /* Save the new top of stack in TCB. */
adds r2, r2, #12 /* r2 = r2 + 12. */ save_special_regs:
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r1, psplim /* r1 = PSPLIM. */ stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ #if ( configENABLE_PAC == 1 )
subs r2, r2, #12 /* r2 = r2 - 12. */ mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -416,34 +449,45 @@ PendSV_Handler:
mov r0, #0 /* r0 = 0. */ mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */ msr basepri, r0 /* Enable interrupts. */
restore_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read 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. */ 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. */ restore_special_regs:
msr psplim, r1 /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
mov lr, r4 /* LR = r4. */ 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 ). */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r3] /* Restore the task's 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. */ 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. */ restore_s_context:
push {r2, r4} push {r1-r3, lr}
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r2, r4} pop {r1-r3, lr}
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
restore_ns_context: 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. */ ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ 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 it eq
vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
restore_context_done:
msr psp, r2 /* Remember the new top of stack for the task. */ msr psp, r2 /* Remember the new top of stack for the task. */
bx lr bx lr

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -890,7 +891,7 @@ static void prvTaskExitError( void )
return ulAccessPermissions; return ulAccessPermissions;
} }
#endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 ) #if ( configENABLE_MPU == 1 )
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -142,6 +142,14 @@ vRestoreContextOfFirstTask:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -165,6 +173,15 @@ vRestoreContextOfFirstTask:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
msr psplim, r1 /* Set this task's PSPLIM value. */ msr psplim, r1 /* Set this task's PSPLIM value. */
mrs r1, control /* Obtain current control register value. */ mrs r1, control /* Obtain current control register value. */
@ -233,7 +250,6 @@ PendSV_Handler:
vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */
sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
stmia r1!, {r4-r11} /* Store r4-r11. */ stmia r1!, {r4-r11} /* Store r4-r11. */
ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */
stmia r1!, {r4-r11} /* Store the hardware saved context. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */
@ -242,6 +258,15 @@ PendSV_Handler:
mrs r3, psplim /* r3 = PSPLIM. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r4, control /* r4 = CONTROL. */ mrs r4, control /* r4 = CONTROL. */
stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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. */ str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */
select_next_task: select_next_task:
@ -300,6 +325,14 @@ PendSV_Handler:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -335,6 +368,15 @@ PendSV_Handler:
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ 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 r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
@ -351,6 +393,15 @@ PendSV_Handler:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ 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. */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M33.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -409,7 +410,7 @@ static void prvTaskExitError( void );
* @return uint32_t Access permissions. * @return uint32_t Access permissions.
*/ */
static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; 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 ) #if ( configENABLE_MPU == 1 )
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -152,6 +152,14 @@ vRestoreContextOfFirstTask:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -177,6 +185,15 @@ vRestoreContextOfFirstTask:
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
ldr r4, =xSecureContext ldr r4, =xSecureContext
str r1, [r4] /* Set xSecureContext to this task's value for the same. */ 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 r4, psplim /* r4 = PSPLIM. */
mrs r5, control /* r5 = CONTROL. */ mrs r5, control /* r5 = CONTROL. */
stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -329,6 +355,14 @@ PendSV_Handler:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -374,38 +408,37 @@ PendSV_Handler:
mrs r2, psp /* Read PSP in r2. */ mrs r2, psp /* Read PSP in r2. */
cbz r0, save_ns_context /* No secure context to save. */ cbz r0, save_ns_context /* No secure context to save. */
push {r0-r2, r14} save_s_context:
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ push {r0-r2, lr}
pop {r0-r3} /* LR is now in r3. */ bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
mov lr, r3 /* LR = r3. */ pop {r0-r2, lr}
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_ns_context: save_ns_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ mov r3, lr /* r3 = LR. */
ldr r1, [r3] /* Read pxCurrentTCB. */ 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 ) ) #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. */ 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 it eq
vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */
str r2, [r1] /* Save the new top of stack in TCB. */
adds r2, r2, #12 /* r2 = r2 + 12. */ save_special_regs:
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r1, psplim /* r1 = PSPLIM. */ stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ #if ( configENABLE_PAC == 1 )
subs r2, r2, #12 /* r2 = r2 - 12. */ mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -416,34 +449,45 @@ PendSV_Handler:
mov r0, #0 /* r0 = 0. */ mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */ msr basepri, r0 /* Enable interrupts. */
restore_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read 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. */ 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. */ restore_special_regs:
msr psplim, r1 /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
mov lr, r4 /* LR = r4. */ 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 ). */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r3] /* Restore the task's 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. */ 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. */ restore_s_context:
push {r2, r4} push {r1-r3, lr}
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r2, r4} pop {r1-r3, lr}
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
restore_ns_context: 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. */ ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ 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 it eq
vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
restore_context_done:
msr psp, r2 /* Remember the new top of stack for the task. */ msr psp, r2 /* Remember the new top of stack for the task. */
bx lr bx lr

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -142,6 +142,14 @@ vRestoreContextOfFirstTask:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -165,6 +173,15 @@ vRestoreContextOfFirstTask:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
msr psplim, r1 /* Set this task's PSPLIM value. */ msr psplim, r1 /* Set this task's PSPLIM value. */
mrs r1, control /* Obtain current control register value. */ mrs r1, control /* Obtain current control register value. */
@ -233,7 +250,6 @@ PendSV_Handler:
vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */
sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
stmia r1!, {r4-r11} /* Store r4-r11. */ stmia r1!, {r4-r11} /* Store r4-r11. */
ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */
stmia r1!, {r4-r11} /* Store the hardware saved context. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */
@ -242,6 +258,15 @@ PendSV_Handler:
mrs r3, psplim /* r3 = PSPLIM. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r4, control /* r4 = CONTROL. */ mrs r4, control /* r4 = CONTROL. */
stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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. */ str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */
select_next_task: select_next_task:
@ -300,6 +325,14 @@ PendSV_Handler:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -335,6 +368,15 @@ PendSV_Handler:
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ 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 r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
@ -351,6 +393,15 @@ PendSV_Handler:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ 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. */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )

View file

@ -60,7 +60,7 @@
#ifndef configENABLE_MVE #ifndef configENABLE_MVE
#define configENABLE_MVE 0 #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. #error configENABLE_MVE must be left undefined, or defined to 0 for the Cortex-M35.
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -152,6 +152,14 @@ vRestoreContextOfFirstTask:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -177,6 +185,15 @@ vRestoreContextOfFirstTask:
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
ldr r4, =xSecureContext ldr r4, =xSecureContext
str r1, [r4] /* Set xSecureContext to this task's value for the same. */ 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 r4, psplim /* r4 = PSPLIM. */
mrs r5, control /* r5 = CONTROL. */ mrs r5, control /* r5 = CONTROL. */
stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -329,6 +355,14 @@ PendSV_Handler:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -374,38 +408,37 @@ PendSV_Handler:
mrs r2, psp /* Read PSP in r2. */ mrs r2, psp /* Read PSP in r2. */
cbz r0, save_ns_context /* No secure context to save. */ cbz r0, save_ns_context /* No secure context to save. */
push {r0-r2, r14} save_s_context:
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ push {r0-r2, lr}
pop {r0-r3} /* LR is now in r3. */ bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
mov lr, r3 /* LR = r3. */ pop {r0-r2, lr}
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_ns_context: save_ns_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ mov r3, lr /* r3 = LR. */
ldr r1, [r3] /* Read pxCurrentTCB. */ 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 ) ) #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. */ 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 it eq
vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */
str r2, [r1] /* Save the new top of stack in TCB. */
adds r2, r2, #12 /* r2 = r2 + 12. */ save_special_regs:
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r1, psplim /* r1 = PSPLIM. */ stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ #if ( configENABLE_PAC == 1 )
subs r2, r2, #12 /* r2 = r2 - 12. */ mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -416,34 +449,45 @@ PendSV_Handler:
mov r0, #0 /* r0 = 0. */ mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */ msr basepri, r0 /* Enable interrupts. */
restore_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read 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. */ 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. */ restore_special_regs:
msr psplim, r1 /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
mov lr, r4 /* LR = r4. */ 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 ). */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r3] /* Restore the task's 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. */ 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. */ restore_s_context:
push {r2, r4} push {r1-r3, lr}
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r2, r4} pop {r1-r3, lr}
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
restore_ns_context: 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. */ ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ 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 it eq
vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
restore_context_done:
msr psp, r2 /* Remember the new top of stack for the task. */ msr psp, r2 /* Remember the new top of stack for the task. */
bx lr bx lr

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -142,6 +142,14 @@ vRestoreContextOfFirstTask:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -165,6 +173,15 @@ vRestoreContextOfFirstTask:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
msr psplim, r1 /* Set this task's PSPLIM value. */ msr psplim, r1 /* Set this task's PSPLIM value. */
mrs r1, control /* Obtain current control register value. */ mrs r1, control /* Obtain current control register value. */
@ -233,7 +250,6 @@ PendSV_Handler:
vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */
sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
stmia r1!, {r4-r11} /* Store r4-r11. */ stmia r1!, {r4-r11} /* Store r4-r11. */
ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */
stmia r1!, {r4-r11} /* Store the hardware saved context. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */
@ -242,6 +258,15 @@ PendSV_Handler:
mrs r3, psplim /* r3 = PSPLIM. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r4, control /* r4 = CONTROL. */ mrs r4, control /* r4 = CONTROL. */
stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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. */ str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */
select_next_task: select_next_task:
@ -300,6 +325,14 @@ PendSV_Handler:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -335,6 +368,15 @@ PendSV_Handler:
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ 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 r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
@ -351,6 +393,15 @@ PendSV_Handler:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ 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. */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -152,6 +152,14 @@ vRestoreContextOfFirstTask:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -177,6 +185,15 @@ vRestoreContextOfFirstTask:
ldr r3, [r2] /* Read pxCurrentTCB. */ ldr r3, [r2] /* Read pxCurrentTCB. */
ldr r0, [r3] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
ldr r4, =xSecureContext ldr r4, =xSecureContext
str r1, [r4] /* Set xSecureContext to this task's value for the same. */ 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 r4, psplim /* r4 = PSPLIM. */
mrs r5, control /* r5 = CONTROL. */ mrs r5, control /* r5 = CONTROL. */
stmia r2!, {r0, r3-r5, lr} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -329,6 +355,14 @@ PendSV_Handler:
ldr r2, [r1] /* r2 = Location of saved context in TCB. */ ldr r2, [r1] /* r2 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r2!, {r0, r3-r5, lr} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, LR restored. */
msr psp, r3 msr psp, r3
msr psplim, r4 msr psplim, r4
@ -374,38 +408,37 @@ PendSV_Handler:
mrs r2, psp /* Read PSP in r2. */ mrs r2, psp /* Read PSP in r2. */
cbz r0, save_ns_context /* No secure context to save. */ cbz r0, save_ns_context /* No secure context to save. */
push {r0-r2, r14} save_s_context:
bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ push {r0-r2, lr}
pop {r0-r3} /* LR is now in r3. */ bl SecureContext_SaveContext /* Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
mov lr, r3 /* LR = r3. */ pop {r0-r2, lr}
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_ns_context: save_ns_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ mov r3, lr /* r3 = LR. */
ldr r1, [r3] /* Read pxCurrentTCB. */ 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 ) ) #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. */ 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 it eq
vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */ vstmdbeq r2!, {s16-s31} /* Store the additional FP context registers which are not saved automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */ stmdb r2!, {r4-r11} /* Store the registers that are not saved automatically. */
str r2, [r1] /* Save the new top of stack in TCB. */
adds r2, r2, #12 /* r2 = r2 + 12. */ save_special_regs:
stm r2, {r4-r11} /* Store the registers that are not saved automatically. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r1, psplim /* r1 = PSPLIM. */ stmdb r2!, {r0, r3, lr} /* Store xSecureContext, PSPLIM and LR on the stack. */
mov r3, lr /* r3 = LR/EXC_RETURN. */ #if ( configENABLE_PAC == 1 )
subs r2, r2, #12 /* r2 = r2 - 12. */ mrs r3, PAC_KEY_P_3 /* Read task's dedicated PAC key from the PAC key registers. */
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */ 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: select_next_task:
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
@ -416,34 +449,45 @@ PendSV_Handler:
mov r0, #0 /* r0 = 0. */ mov r0, #0 /* r0 = 0. */
msr basepri, r0 /* Enable interrupts. */ msr basepri, r0 /* Enable interrupts. */
restore_context:
ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */ ldr r3, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r3] /* Read 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. */ 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. */ restore_special_regs:
msr psplim, r1 /* Restore the PSPLIM register value for the task. */ #if ( configENABLE_PAC == 1 )
mov lr, r4 /* LR = r4. */ 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 ). */ ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
str r0, [r3] /* Restore the task's 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. */ 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. */ restore_s_context:
push {r2, r4} push {r1-r3, lr}
bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */ bl SecureContext_LoadContext /* Restore the secure context. Params are in r0 and r1. r0 = xSecureContext and r1 = pxCurrentTCB. */
pop {r2, r4} pop {r1-r3, lr}
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
restore_ns_context: 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. */ ldmia r2!, {r4-r11} /* Restore the registers that are not automatically restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #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. */ 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 it eq
vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */ vldmiaeq r2!, {s16-s31} /* Restore the additional FP context registers which are not restored automatically. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
restore_context_done:
msr psp, r2 /* Remember the new top of stack for the task. */ msr psp, r2 /* Remember the new top of stack for the task. */
bx lr bx lr

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS

View file

@ -169,79 +169,80 @@ typedef void ( * portISR_t )( void );
/** /**
* @brief Constants required to manipulate the MPU. * @brief Constants required to manipulate the MPU.
*/ */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) ) #define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) ) #define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) ) #define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) ) #define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) ) #define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) ) #define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) ) #define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) ) #define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) ) #define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) ) #define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
#define portMPU_RBAR_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_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_POS ( 0UL )
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR1_POS ( 8UL ) #define portMPU_MAIR_ATTR1_POS ( 8UL )
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR2_POS ( 16UL ) #define portMPU_MAIR_ATTR2_POS ( 16UL )
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR3_POS ( 24UL ) #define portMPU_MAIR_ATTR3_POS ( 24UL )
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
#define portMPU_MAIR_ATTR4_POS ( 0UL ) #define portMPU_MAIR_ATTR4_POS ( 0UL )
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff ) #define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
#define portMPU_MAIR_ATTR5_POS ( 8UL ) #define portMPU_MAIR_ATTR5_POS ( 8UL )
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 ) #define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
#define portMPU_MAIR_ATTR6_POS ( 16UL ) #define portMPU_MAIR_ATTR6_POS ( 16UL )
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 ) #define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
#define portMPU_MAIR_ATTR7_POS ( 24UL ) #define portMPU_MAIR_ATTR7_POS ( 24UL )
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 ) #define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL ) #define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 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 ) #if ( portARMV8M_MINOR_VERSION >= 1 )
/* Enable Privileged eXecute Never MPU attribute for the selected memory
* region. */ /* Enable Privileged eXecute Never MPU attribute for the selected memory
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) * region. */
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
#endif /* portARMV8M_MINOR_VERSION >= 1 */ #endif /* portARMV8M_MINOR_VERSION >= 1 */
/* Enable privileged access to unmapped region. */ /* Enable privileged access to unmapped region. */
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL ) #define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
/* Enable MPU. */ /* Enable MPU. */
#define portMPU_ENABLE_BIT ( 1UL << 0UL ) #define portMPU_ENABLE_BIT ( 1UL << 0UL )
/* Expected value of the portMPU_TYPE register. */ /* 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 /* Extract first address of the MPU region as encoded in the
* RBAR (Region Base Address Register) value. */ * 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. * @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_UPAC_EN ( 1UL << 7UL )
#define portCONTROL_PAC_EN ( 1UL << 6UL ) #define portCONTROL_PAC_EN ( 1UL << 6UL )
#define portCONTROL_UBTI_EN ( 1UL << 5UL ) #define portCONTROL_UBTI_EN ( 1UL << 5UL )
#define portCONTROL_BTI_EN ( 1UL << 4UL ) #define portCONTROL_BTI_EN ( 1UL << 4UL )
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -427,7 +428,7 @@ static void prvTaskExitError( void );
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
#endif /* configENABLE_FPU */ #endif /* configENABLE_FPU */
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
/** /**
* @brief Configures PACBTI features. * @brief Configures PACBTI features.
@ -1212,6 +1213,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __syscalls_flash_start__; 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_<API>). We need to restore it * point (i.e. the caller of the MPU_<API>). We need to restore it
* when we exit from the system call. */ * when we exit from the system call. */
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ]; pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
/* Store the value of the PSPLIM register before the SVC was raised. /* Store the value of the PSPLIM register before the SVC was raised.
* We need to restore it when we exit from the system call. */ * We need to restore it when we exit from the system call. */
#if ( portUSE_PSPLIM_REGISTER == 1 ) #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. */ /* Start executing the system call upon returning from this handler. */
pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ]; pulSystemCallStack[ portOFFSET_TO_PC ] = uxSystemCallImplementations[ ucSystemCallNumber ];
/* Raise a request to exit from the system call upon finishing the /* Raise a request to exit from the system call upon finishing the
* system call. */ * system call. */
pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit; pulSystemCallStack[ portOFFSET_TO_LR ] = ( uint32_t ) vRequestSystemCallExit;
@ -1359,6 +1363,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
uint32_t ulStackFrameSize, ulSystemCallLocation, i; uint32_t ulStackFrameSize, ulSystemCallLocation, i;
#if defined( __ARMCC_VERSION ) #if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being /* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */ * exported from linker scripts. */
extern uint32_t * __privileged_functions_start__; 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. */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
ulIndex++; ulIndex++;
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
{ {
/* Check PACBTI security feature configuration before pushing the /* Check PACBTI security feature configuration before pushing the
* CONTROL register's value on task's TCB. */ * 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 */ #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 ] ); return &( xMPUSettings->ulContext[ ulIndex ] );
} }
@ -1664,6 +1683,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
} }
#endif /* portPRELOAD_REGISTERS */ #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; return pxTopOfStack;
} }
@ -1786,11 +1819,11 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
portNVIC_SHPR2_REG = 0; 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 /* Set the CONTROL register value based on PACBTI security feature
* configuration before starting the first task. */ * configuration before starting the first task. */
( void) prvConfigurePACBTI( pdTRUE ); ( void ) prvConfigurePACBTI( pdTRUE );
} }
#endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */
@ -1990,9 +2023,9 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
if( xSchedulerRunning == pdFALSE ) if( xSchedulerRunning == pdFALSE )
{ {
/* Grant access to all the kernel objects before the scheduler /* Grant access to all the kernel objects before the scheduler
* is started. It is necessary because there is no task running * is started. It is necessary because there is no task running
* yet and therefore, we cannot use the permissions of any * yet and therefore, we cannot use the permissions of any
* task. */ * task. */
xAccessGranted = pdTRUE; xAccessGranted = pdTRUE;
} }
else if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) 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 ) ) */ #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 ) static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
{ {
@ -2225,13 +2258,13 @@ BaseType_t xPortIsInsideInterrupt( void )
/* Enable UsageFault exception. */ /* Enable UsageFault exception. */
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT; 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 ); ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
} }
#endif #endif
#if( configENABLE_BTI == 1 ) #if ( configENABLE_BTI == 1 )
{ {
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN ); ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
} }

View file

@ -142,6 +142,14 @@ vRestoreContextOfFirstTask:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs_first_task: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -165,6 +173,15 @@ vRestoreContextOfFirstTask:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */ 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. */ ldm r0!, {r1-r2} /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
msr psplim, r1 /* Set this task's PSPLIM value. */ msr psplim, r1 /* Set this task's PSPLIM value. */
mrs r1, control /* Obtain current control register value. */ mrs r1, control /* Obtain current control register value. */
@ -233,7 +250,6 @@ PendSV_Handler:
vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */ vstmiaeq r1!, {s0-s16} /* Store hardware saved FP context. */
sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */ sub r2, r2, #0x20 /* Set r2 back to the location of hardware saved context. */
#endif /* configENABLE_FPU || configENABLE_MVE */ #endif /* configENABLE_FPU || configENABLE_MVE */
stmia r1!, {r4-r11} /* Store r4-r11. */ stmia r1!, {r4-r11} /* Store r4-r11. */
ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */ ldmia r2, {r4-r11} /* Copy the hardware saved context into r4-r11. */
stmia r1!, {r4-r11} /* Store the hardware saved context. */ stmia r1!, {r4-r11} /* Store the hardware saved context. */
@ -242,6 +258,15 @@ PendSV_Handler:
mrs r3, psplim /* r3 = PSPLIM. */ mrs r3, psplim /* r3 = PSPLIM. */
mrs r4, control /* r4 = CONTROL. */ mrs r4, control /* r4 = CONTROL. */
stmia r1!, {r2-r4, lr} /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */ 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. */ str r1, [r0] /* Save the location from where the context should be restored as the first member of TCB. */
select_next_task: select_next_task:
@ -300,6 +325,14 @@ PendSV_Handler:
ldr r1, [r0] /* r1 = Location of saved context in TCB. */ ldr r1, [r0] /* r1 = Location of saved context in TCB. */
restore_special_regs: 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. */ ldmdb r1!, {r2-r4, lr} /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, LR restored. */
msr psp, r2 msr psp, r2
msr psplim, r3 msr psplim, r3
@ -335,6 +368,15 @@ PendSV_Handler:
mov r3, lr /* r3 = LR/EXC_RETURN. */ mov r3, lr /* r3 = LR/EXC_RETURN. */
stmdb r0!, {r2-r11} /* Store on the stack - PSPLIM, LR and registers that are not automatically. */ 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 r2, =pxCurrentTCB /* Read the location of pxCurrentTCB i.e. &( pxCurrentTCB ). */
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
str r0, [r1] /* Save the new top of stack in TCB. */ str r0, [r1] /* Save the new top of stack in TCB. */
@ -351,6 +393,15 @@ PendSV_Handler:
ldr r1, [r2] /* Read pxCurrentTCB. */ ldr r1, [r2] /* Read pxCurrentTCB. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. r0 now points to the top of stack. */ 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. */ ldmia r0!, {r2-r11} /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r11 restored. */
#if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) )

View file

@ -1,6 +1,8 @@
/* /*
* FreeRTOS Kernel <DEVELOPMENT BRANCH> * FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com>
* *
* SPDX-License-Identifier: MIT * 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 BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */;
extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */;
#endif /* configENABLE_MPU */ #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 ) #if ( configENABLE_MPU == 1 )
/** /**
* @brief Settings to define an MPU region. * @brief Settings to define an MPU region.
*/ */
typedef struct MPURegionSettings typedef struct MPURegionSettings
{ {
uint32_t ulRBAR; /**< RBAR for the region. */ 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. #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 #endif
/** /* When MPU wrapper v2 is used, the task's context is stored in TCB and
* @brief System call stack. * 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 typedef struct SYSTEM_CALL_STACK_INFO
{ {
uint32_t ulSystemCallStackBuffer[ configSYSTEM_CALL_STACK_SIZE ]; 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 */ #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_FPU == 1 ) || ( configENABLE_MVE == 1 ) )
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | | | PC, xPSR | CONTROL, EXC_RETURN | | * | | | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+------------------------------+-----+ * +-----------+---------------+----------+-----------------+------------------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><-----------------------------><----> * <-----------><--------------><---------><----------------><-----------------------------><-----------><---->
* 16 16 8 8 5 1 * 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 #define MAX_CONTEXT_SIZE 54
#else /* #if( configENABLE_TRUSTZONE == 1 ) */ #elif ( ( configENABLE_TRUSTZONE == 0 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | s16-s31 | s0-s15, FPSCR | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | TaskPacKey | |
* | | | | PC, xPSR | EXC_RETURN | | * | | | | PC, xPSR | EXC_RETURN | | |
* +-----------+---------------+----------+-----------------+----------------------+-----+ * +-----------+---------------+----------+-----------------+----------------------+------------+-----+
* *
* <-----------><--------------><---------><----------------><---------------------><----> * <-----------><--------------><---------><----------------><---------------------><-----------><---->
* 16 16 8 8 4 1 * 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 #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 ) ) */ #else /* #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */
#if ( configENABLE_TRUSTZONE == 1 ) #if ( ( configENABLE_TRUSTZONE == 1 ) && ( configENABLE_PAC == 1 ) )
/* /*
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | | * | r4-r11 | r0-r3, r12, LR, | xSecureContext, PSP, PSPLIM, | TaskPacKey | |
* | | PC, xPSR | CONTROL, EXC_RETURN | | * | | PC, xPSR | CONTROL, EXC_RETURN | | |
* +----------+-----------------+------------------------------+-----+ * +----------+-----------------+------------------------------+------------+-----+
* *
* <---------><----------------><------------------------------><----> * <---------><----------------><------------------------------><-----------><---->
* 8 8 5 1 * 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 #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 ) */ #else /* #if( configENABLE_TRUSTZONE == 1 ) */
/* /*
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | | * | r4-r11 | r0-r3, r12, LR, | PSP, PSPLIM, CONTROL | |
* | | PC, xPSR | EXC_RETURN | | * | | PC, xPSR | EXC_RETURN | |
* +----------+-----------------+----------------------+-----+ * +----------+-----------------+----------------------+-----+
* *
* <---------><----------------><----------------------><----> * <---------><----------------><----------------------><---->
* 8 8 4 1 * 8 8 4 1
*/ */
#define MAX_CONTEXT_SIZE 21 #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 ) ) */ #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 portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL )
#define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) #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 ) #define portACL_ENTRY_SIZE_BITS ( 32U )
typedef struct MPU_SETTINGS typedef struct MPU_SETTINGS