From 6b7d4cf41be3438177ae7104553f0c69d2f2d286 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Thu, 23 Nov 2023 10:45:58 +0530 Subject: [PATCH] Add Access Control List to MPU ports (#897) This PR adds Access Control to kernel objects on a per task basis to MPU ports. The following needs to be defined in the `FreeRTOSConfig.h` to enable this feature: ```c ``` This PR adds the following new APIs: ```c void vGrantAccessToTask( TaskHandle_t xTask, TaskHandle_t xTaskToGrantAccess ); void vRevokeAccessToTask( TaskHandle_t xTask, TaskHandle_t xTaskToRevokeAccess ); void vGrantAccessToSemaphore( TaskHandle_t xTask, SemaphoreHandle_t xSemaphoreToGrantAccess ); void vRevokeAccessToSemaphore( TaskHandle_t xTask, SemaphoreHandle_t xSemaphoreToRevokeAccess ); void vGrantAccessToQueue( TaskHandle_t xTask, QueueHandle_t xQueueToGrantAccess ); void vRevokeAccessToQueue( TaskHandle_t xTask, QueueHandle_t xQueueToRevokeAccess ); void vGrantAccessToQueueSet( TaskHandle_t xTask, QueueSetHandle_t xQueueSetToGrantAccess ); void vRevokeAccessToQueueSet( TaskHandle_t xTask, QueueSetHandle_t xQueueSetToRevokeAccess ); void vGrantAccessToEventGroup( TaskHandle_t xTask, EventGroupHandle_t xEventGroupToGrantAccess ); void vRevokeAccessToEventGroup( TaskHandle_t xTask, EventGroupHandle_t xEventGroupToRevokeAccess ); void vGrantAccessToStreamBuffer( TaskHandle_t xTask, StreamBufferHandle_t xStreamBufferToGrantAccess ); void vRevokeAccessToStreamBuffer( TaskHandle_t xTask, StreamBufferHandle_t xStreamBufferToRevokeAccess ); void vGrantAccessToMessageBuffer( TaskHandle_t xTask, MessageBufferHandle_t xMessageBufferToGrantAccess ); void vRevokeAccessToMessageBuffer( TaskHandle_t xTask, MessageBufferHandle_t xMessageBufferToRevokeAccess ); void vGrantAccessToTimer( TaskHandle_t xTask, TimerHandle_t xTimerToGrantAccess ); void vRevokeAccessToTimer( TaskHandle_t xTask, TimerHandle_t xTimerToRevokeAccess ); ``` An unprivileged task by default has access to itself only and no other kernel object. The application writer needs to explicitly grant an unprivileged task access to all the kernel objects it needs. The best place to do that is before starting the scheduler when all the kernel objects are created. For example, let's say an unprivileged tasks needs access to a queue and an event group, the application writer needs to do the following: ```c vGrantAccessToQueue( xUnprivilegedTaskHandle, xQueue ); vGrantAccessToEventGroup( xUnprivilegedTaskHandle, xEventGroup ); ``` The application writer MUST revoke all the accesses before deleting a task. Failing to do so will result in undefined behavior. In the above example, the application writer needs to make the following 2 calls before deleting the task: ```c vRevokeAccessToQueue( xUnprivilegedTaskHandle, xQueue ); vRevokeAccessToEventGroup( xUnprivilegedTaskHandle, xEventGroup ); ``` --- include/FreeRTOS.h | 5 + include/mpu_wrappers.h | 29 + include/portable.h | 15 + include/task.h | 21 + portable/ARMv8M/non_secure/port.c | 110 +++ portable/ARMv8M/non_secure/portmacrocommon.h | 6 + portable/Common/mpu_wrappers.c | 4 + portable/Common/mpu_wrappers_v2.c | 891 +++++++++++++----- portable/GCC/ARM_CM23/non_secure/port.c | 110 +++ .../GCC/ARM_CM23/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM23_NTZ/non_secure/port.c | 110 +++ .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM33/non_secure/port.c | 110 +++ .../GCC/ARM_CM33/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM33_NTZ/non_secure/port.c | 110 +++ .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM35P/non_secure/port.c | 110 +++ .../ARM_CM35P/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM35P_NTZ/non_secure/port.c | 110 +++ .../non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM3_MPU/port.c | 110 +++ portable/GCC/ARM_CM3_MPU/portmacro.h | 14 +- portable/GCC/ARM_CM4_MPU/port.c | 110 +++ portable/GCC/ARM_CM4_MPU/portmacro.h | 8 +- portable/GCC/ARM_CM55/non_secure/port.c | 110 +++ .../GCC/ARM_CM55/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM55_NTZ/non_secure/port.c | 110 +++ .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM85/non_secure/port.c | 110 +++ .../GCC/ARM_CM85/non_secure/portmacrocommon.h | 6 + portable/GCC/ARM_CM85_NTZ/non_secure/port.c | 110 +++ .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM23/non_secure/port.c | 110 +++ .../IAR/ARM_CM23/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM23_NTZ/non_secure/port.c | 110 +++ .../ARM_CM23_NTZ/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM33/non_secure/port.c | 110 +++ .../IAR/ARM_CM33/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM33_NTZ/non_secure/port.c | 110 +++ .../ARM_CM33_NTZ/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM35P/non_secure/port.c | 110 +++ .../ARM_CM35P/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM35P_NTZ/non_secure/port.c | 110 +++ .../non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM4F_MPU/port.c | 110 +++ portable/IAR/ARM_CM4F_MPU/portmacro.h | 8 +- portable/IAR/ARM_CM55/non_secure/port.c | 110 +++ .../IAR/ARM_CM55/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM55_NTZ/non_secure/port.c | 110 +++ .../ARM_CM55_NTZ/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM85/non_secure/port.c | 110 +++ .../IAR/ARM_CM85/non_secure/portmacrocommon.h | 6 + portable/IAR/ARM_CM85_NTZ/non_secure/port.c | 110 +++ .../ARM_CM85_NTZ/non_secure/portmacrocommon.h | 6 + portable/RVDS/ARM_CM4_MPU/port.c | 113 ++- portable/RVDS/ARM_CM4_MPU/portmacro.h | 8 +- 56 files changed, 3645 insertions(+), 237 deletions(-) diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 9228e071f..f09828255 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -86,6 +86,11 @@ #define configUSE_MPU_WRAPPERS_V1 0 #endif +/* Set configENABLE_ACCESS_CONTROL_LIST to 1 to enable access control list support. */ +#ifndef configENABLE_ACCESS_CONTROL_LIST + #define configENABLE_ACCESS_CONTROL_LIST 0 +#endif + /* Basic FreeRTOS definitions. */ #include "projdefs.h" diff --git a/include/mpu_wrappers.h b/include/mpu_wrappers.h index db6356344..c7cdaa247 100644 --- a/include/mpu_wrappers.h +++ b/include/mpu_wrappers.h @@ -233,6 +233,35 @@ #define PRIVILEGED_DATA __attribute__( ( section( "privileged_data" ) ) ) #define FREERTOS_SYSTEM_CALL + + #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + #define vGrantAccessToTask( xTask, xTaskToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) ) + #define vRevokeAccessToTask( xTask, xTaskToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToRevokeAccess ) ) + + #define vGrantAccessToSemaphore( xTask, xSemaphoreToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToGrantAccess ) ) + #define vRevokeAccessToSemaphore( xTask, xSemaphoreToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToRevokeAccess ) ) + + #define vGrantAccessToQueue( xTask, xQueueToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToGrantAccess ) ) + #define vRevokeAccessToQueue( xTask, xQueueToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToRevokeAccess ) ) + + #define vGrantAccessToQueueSet( xTask, xQueueSetToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToGrantAccess ) ) + #define vRevokeAccessToQueueSet( xTask, xQueueSetToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToRevokeAccess ) ) + + #define vGrantAccessToEventGroup( xTask, xEventGroupToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToGrantAccess ) ) + #define vRevokeAccessToEventGroup( xTask, xEventGroupToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToRevokeAccess ) ) + + #define vGrantAccessToStreamBuffer( xTask, xStreamBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToGrantAccess ) ) + #define vRevokeAccessToStreamBuffer( xTask, xStreamBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToRevokeAccess ) ) + + #define vGrantAccessToMessageBuffer( xTask, xMessageBufferToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToGrantAccess ) ) + #define vRevokeAccessToMessageBuffer( xTask, xMessageBufferToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToRevokeAccess ) ) + + #define vGrantAccessToTimer( xTask, xTimerToGrantAccess ) vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToGrantAccess ) ) + #define vRevokeAccessToTimer( xTask, xTimerToRevokeAccess ) vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToRevokeAccess ) ) + + #endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ /* Ensure API functions go in the privileged execution section. */ diff --git a/include/portable.h b/include/portable.h index ebce9d6cf..8faeb738a 100644 --- a/include/portable.h +++ b/include/portable.h @@ -247,6 +247,21 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION; #endif +/** + * @brief Checks if the calling task is authorized to access the given kernel object. + * + * @param lInternalIndexOfKernelObject The index of the kernel object in the kernel + * object handle pool. + * + * @return pdTRUE if the calling task is authorized to access the kernel object, + * pdFALSE otherwise. + */ +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION; + +#endif + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/include/task.h b/include/task.h index 9a198f2f4..fc600934d 100644 --- a/include/task.h +++ b/include/task.h @@ -3206,6 +3206,27 @@ void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNC #endif /* portUSING_MPU_WRAPPERS */ + +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/* + * For internal use only. Grant/Revoke a task's access to a kernel object. + */ + void vGrantAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) PRIVILEGED_FUNCTION; + void vRevokeAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Grant/Revoke a task's access to a kernel object. + */ + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION; + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION; + +#endif /* #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portmacrocommon.h b/portable/ARMv8M/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/ARMv8M/non_secure/portmacrocommon.h +++ b/portable/ARMv8M/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/Common/mpu_wrappers.c b/portable/Common/mpu_wrappers.c index e6c8850ed..ac8251436 100644 --- a/portable/Common/mpu_wrappers.c +++ b/portable/Common/mpu_wrappers.c @@ -50,6 +50,10 @@ #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + #error Access control list is not available with this MPU wrapper. Please set configENABLE_ACCESS_CONTROL_LIST to 0. + #endif + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, diff --git a/portable/Common/mpu_wrappers_v2.c b/portable/Common/mpu_wrappers_v2.c index bf3b8c9fc..90c977d6b 100644 --- a/portable/Common/mpu_wrappers_v2.c +++ b/portable/Common/mpu_wrappers_v2.c @@ -338,6 +338,76 @@ } /*-----------------------------------------------------------*/ + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + void vGrantAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) /* PRIVILEGED_FUNCTION */ + { + int32_t lExternalTaskIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( IS_EXTERNAL_INDEX_VALID( lExternalKernelObjectHandle ) != pdFALSE ) + { + if( xExternalTaskHandle == NULL ) + { + vPortGrantAccessToKernelObject( xExternalTaskHandle, CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + else + { + lExternalTaskIndex = ( int32_t ) xExternalTaskHandle; + + if( IS_EXTERNAL_INDEX_VALID( lExternalTaskIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lExternalTaskIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, + CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + } + } + } + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ +/*-----------------------------------------------------------*/ + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + void vRevokeAccessToKernelObject( TaskHandle_t xExternalTaskHandle, + int32_t lExternalKernelObjectHandle ) /* PRIVILEGED_FUNCTION */ + { + int32_t lExternalTaskIndex; + TaskHandle_t xInternalTaskHandle = NULL; + + if( IS_EXTERNAL_INDEX_VALID( lExternalKernelObjectHandle ) != pdFALSE ) + { + if( xExternalTaskHandle == NULL ) + { + vPortRevokeAccessToKernelObject( xExternalTaskHandle, CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + else + { + lExternalTaskIndex = ( int32_t ) xExternalTaskHandle; + + if( IS_EXTERNAL_INDEX_VALID( lExternalTaskIndex ) != pdFALSE ) + { + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lExternalTaskIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vPortRevokeAccessToKernelObject( xInternalTaskHandle, + CONVERT_TO_INTERNAL_INDEX( lExternalKernelObjectHandle ) ); + } + } + } + } + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ +/*-----------------------------------------------------------*/ + #if ( configUSE_TIMERS == 1 ) static void MPU_TimerCallback( TimerHandle_t xInternalHandle ) /* PRIVILEGED_FUNCTION */ @@ -409,6 +479,7 @@ BaseType_t MPU_xTaskAbortDelayImpl( TaskHandle_t xTask ) /* PRIVILEGED_FUNCTION */ { BaseType_t xReturn = pdFAIL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; TaskHandle_t xInternalTaskHandle = NULL; int32_t lIndex; @@ -416,11 +487,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - xReturn = xTaskAbortDelay( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskAbortDelay( xInternalTaskHandle ); + } } } @@ -449,6 +525,7 @@ UBaseType_t MPU_uxTaskPriorityGetImpl( const TaskHandle_t pxTask ) /* PRIVILEGED_FUNCTION */ { UBaseType_t uxReturn = configMAX_PRIORITIES; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; @@ -462,11 +539,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - uxReturn = uxTaskPriorityGet( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskPriorityGet( xInternalTaskHandle ); + } } } } @@ -486,16 +568,22 @@ eTaskState eReturn = eInvalid; TaskHandle_t xInternalTaskHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; lIndex = ( int32_t ) pxTask; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - eReturn = eTaskGetState( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + eReturn = eTaskGetState( xInternalTaskHandle ); + } } } @@ -520,6 +608,7 @@ int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; BaseType_t xIsTaskStatusWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; xIsTaskStatusWriteable = xPortIsAuthorizedToAccessBuffer( pxTaskStatus, sizeof( TaskStatus_t ), @@ -537,11 +626,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - vTaskGetInfo( xInternalTaskHandle, pxTaskStatus, xGetFreeStackSpace, eState ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskGetInfo( xInternalTaskHandle, pxTaskStatus, xGetFreeStackSpace, eState ); + } } } } @@ -575,6 +669,7 @@ { int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( pxTaskToSuspend == NULL ) { @@ -594,11 +689,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - vTaskSuspend( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSuspend( xInternalTaskHandle ); + } } } } @@ -616,16 +716,22 @@ { int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; lIndex = ( int32_t ) pxTaskToResume; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - vTaskResume( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskResume( xInternalTaskHandle ); + } } } } @@ -697,6 +803,7 @@ configRUN_TIME_COUNTER_TYPE xReturn = 0; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTask == NULL ) { @@ -708,11 +815,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - xReturn = ulTaskGetRunTimeCounter( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = ulTaskGetRunTimeCounter( xInternalTaskHandle ); + } } } } @@ -732,6 +844,7 @@ configRUN_TIME_COUNTER_TYPE xReturn = 0; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTask == NULL ) { @@ -743,11 +856,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - xReturn = ulTaskGetRunTimePercent( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = ulTaskGetRunTimePercent( xInternalTaskHandle ); + } } } } @@ -800,6 +918,7 @@ { TaskHandle_t xInternalTaskHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTask == NULL ) { @@ -811,11 +930,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - vTaskSetApplicationTaskTag( xInternalTaskHandle, pxTagValue ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSetApplicationTaskTag( xInternalTaskHandle, pxTagValue ); + } } } } @@ -833,6 +957,7 @@ TaskHookFunction_t xReturn = NULL; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTask == NULL ) { @@ -844,11 +969,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - xReturn = xTaskGetApplicationTaskTag( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGetApplicationTaskTag( xInternalTaskHandle ); + } } } } @@ -871,6 +1001,7 @@ { int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTaskToSet == NULL ) { @@ -882,11 +1013,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - vTaskSetThreadLocalStoragePointer( xInternalTaskHandle, xIndex, pvValue ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + vTaskSetThreadLocalStoragePointer( xInternalTaskHandle, xIndex, pvValue ); + } } } } @@ -906,6 +1042,7 @@ void * pvReturn = NULL; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTaskToQuery == NULL ) { @@ -917,11 +1054,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - pvReturn = pvTaskGetThreadLocalStoragePointer( xInternalTaskHandle, xIndex ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + pvReturn = pvTaskGetThreadLocalStoragePointer( xInternalTaskHandle, xIndex ); + } } } } @@ -983,6 +1125,7 @@ UBaseType_t uxReturn = 0; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTask == NULL ) { @@ -994,11 +1137,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - uxReturn = uxTaskGetStackHighWaterMark( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark( xInternalTaskHandle ); + } } } } @@ -1018,6 +1166,7 @@ configSTACK_DEPTH_TYPE uxReturn = 0; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( xTask == NULL ) { @@ -1029,11 +1178,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - uxReturn = uxTaskGetStackHighWaterMark2( xInternalTaskHandle ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + uxReturn = uxTaskGetStackHighWaterMark2( xInternalTaskHandle ); + } } } } @@ -1167,6 +1321,7 @@ int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; BaseType_t xIsPreviousNotificationValueWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; BaseType_t xAreParamsReadable = pdFALSE; if( pxParams != NULL ) @@ -1199,15 +1354,20 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - xReturn = xTaskGenericNotify( xInternalTaskHandle, - pxParams->uxIndexToNotify, - pxParams->ulValue, - pxParams->eAction, - pxParams->pulPreviousNotificationValue ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotify( xInternalTaskHandle, + pxParams->uxIndexToNotify, + pxParams->ulValue, + pxParams->eAction, + pxParams->pulPreviousNotificationValue ); + } } } } @@ -1320,6 +1480,7 @@ BaseType_t xReturn = pdFAIL; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES ) { @@ -1333,11 +1494,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - xReturn = xTaskGenericNotifyStateClear( xInternalTaskHandle, uxIndexToClear ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + xReturn = xTaskGenericNotifyStateClear( xInternalTaskHandle, uxIndexToClear ); + } } } } @@ -1362,6 +1528,7 @@ uint32_t ulReturn = 0; int32_t lIndex; TaskHandle_t xInternalTaskHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessTask = pdFALSE; if( uxIndexToClear < configTASK_NOTIFICATION_ARRAY_ENTRIES ) { @@ -1375,11 +1542,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTask = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTaskHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTask == pdTRUE ) { - ulReturn = ulTaskGenericNotifyValueClear( xInternalTaskHandle, uxIndexToClear, ulBitsToClear ); + xInternalTaskHandle = MPU_GetTaskHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTaskHandle != NULL ) + { + ulReturn = ulTaskGenericNotifyValueClear( xInternalTaskHandle, uxIndexToClear, ulBitsToClear ); + } } } } @@ -1463,6 +1635,17 @@ if( xInternalTaskHandle != NULL ) { MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + { + /* By default, an unprivileged task has access to itself. */ + if( ( uxPriority & portPRIVILEGE_BIT ) == 0 ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, lIndex ); + } + } + #endif + xExternalTaskHandle = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); } else @@ -1628,6 +1811,16 @@ { MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + { + /* By default, an unprivileged task has access to itself. */ + if( ( pxTaskDefinition->uxPriority & portPRIVILEGE_BIT ) == 0 ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, lIndex ); + } + } + #endif + if( pxCreatedTask != NULL ) { *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); @@ -1664,6 +1857,16 @@ { MPU_StoreTaskHandleAtIndex( lIndex, xInternalTaskHandle ); + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + { + /* By default, an unprivileged task has access to itself. */ + if( ( pxTaskDefinition->uxPriority & portPRIVILEGE_BIT ) == 0 ) + { + vPortGrantAccessToKernelObject( xInternalTaskHandle, lIndex ); + } + } + #endif + if( pxCreatedTask != NULL ) { *pxCreatedTask = ( TaskHandle_t ) CONVERT_TO_EXTERNAL_INDEX( lIndex ); @@ -1909,36 +2112,42 @@ QueueHandle_t xInternalQueueHandle = NULL; BaseType_t xReturn = pdFAIL; BaseType_t xIsItemToQueueReadable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; UBaseType_t uxQueueItemSize, uxQueueLength; lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); - uxQueueLength = uxQueueGetQueueLength( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( ( !( ( pvItemToQueue == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) && - ( !( ( xCopyPosition == queueOVERWRITE ) && ( uxQueueLength != ( UBaseType_t ) 1U ) ) ) - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) - #endif - ) + if( xInternalQueueHandle != NULL ) { - if( pvItemToQueue != NULL ) - { - xIsItemToQueueReadable = xPortIsAuthorizedToAccessBuffer( pvItemToQueue, - uxQueueGetQueueItemSize( xInternalQueueHandle ), - tskMPU_READ_PERMISSION ); - } + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + uxQueueLength = uxQueueGetQueueLength( xInternalQueueHandle ); - if( ( pvItemToQueue == NULL ) || ( xIsItemToQueueReadable == pdTRUE ) ) + if( ( !( ( pvItemToQueue == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) && + ( !( ( xCopyPosition == queueOVERWRITE ) && ( uxQueueLength != ( UBaseType_t ) 1U ) ) ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) { - xReturn = xQueueGenericSend( xInternalQueueHandle, pvItemToQueue, xTicksToWait, xCopyPosition ); + if( pvItemToQueue != NULL ) + { + xIsItemToQueueReadable = xPortIsAuthorizedToAccessBuffer( pvItemToQueue, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_READ_PERMISSION ); + } + + if( ( pvItemToQueue == NULL ) || ( xIsItemToQueueReadable == pdTRUE ) ) + { + xReturn = xQueueGenericSend( xInternalQueueHandle, pvItemToQueue, xTicksToWait, xCopyPosition ); + } } } } @@ -1955,16 +2164,22 @@ int32_t lIndex; QueueHandle_t xInternalQueueHandle = NULL; UBaseType_t uxReturn = 0; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) pxQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - uxReturn = uxQueueMessagesWaiting( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueMessagesWaiting( xInternalQueueHandle ); + } } } @@ -1979,16 +2194,22 @@ int32_t lIndex; QueueHandle_t xInternalQueueHandle = NULL; UBaseType_t uxReturn = 0; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - uxReturn = uxQueueSpacesAvailable( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + uxReturn = uxQueueSpacesAvailable( xInternalQueueHandle ); + } } } @@ -2008,31 +2229,37 @@ QueueHandle_t xInternalQueueHandle = NULL; BaseType_t xReturn = pdFAIL; BaseType_t xIsReceiveBufferWritable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; UBaseType_t uxQueueItemSize; lIndex = ( int32_t ) pxQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) - #endif - ) + if( xInternalQueueHandle != NULL ) { - xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, - uxQueueGetQueueItemSize( xInternalQueueHandle ), - tskMPU_WRITE_PERMISSION ); + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); - if( xIsReceiveBufferWritable == pdTRUE ) + if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) { - xReturn = xQueueReceive( xInternalQueueHandle, pvBuffer, xTicksToWait ); + xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_WRITE_PERMISSION ); + + if( xIsReceiveBufferWritable == pdTRUE ) + { + xReturn = xQueueReceive( xInternalQueueHandle, pvBuffer, xTicksToWait ); + } } } } @@ -2055,30 +2282,36 @@ BaseType_t xReturn = pdFAIL; BaseType_t xIsReceiveBufferWritable = pdFALSE; UBaseType_t uxQueueItemSize; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) - #endif - ) + if( xInternalQueueHandle != NULL ) { - xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, - uxQueueGetQueueItemSize( xInternalQueueHandle ), - tskMPU_WRITE_PERMISSION ); + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); - if( xIsReceiveBufferWritable == pdTRUE ) + if( ( !( ( ( pvBuffer ) == NULL ) && ( uxQueueItemSize != ( UBaseType_t ) 0U ) ) ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) { - xReturn = xQueuePeek( xInternalQueueHandle, pvBuffer, xTicksToWait ); + xIsReceiveBufferWritable = xPortIsAuthorizedToAccessBuffer( pvBuffer, + uxQueueGetQueueItemSize( xInternalQueueHandle ), + tskMPU_WRITE_PERMISSION ); + + if( xIsReceiveBufferWritable == pdTRUE ) + { + xReturn = xQueuePeek( xInternalQueueHandle, pvBuffer, xTicksToWait ); + } } } } @@ -2098,24 +2331,30 @@ QueueHandle_t xInternalQueueHandle = NULL; BaseType_t xReturn = pdFAIL; UBaseType_t uxQueueItemSize; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( ( uxQueueItemSize == 0 ) - #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) - && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) - #endif - ) + if( xInternalQueueHandle != NULL ) { - xReturn = xQueueSemaphoreTake( xInternalQueueHandle, xTicksToWait ); + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + + if( ( uxQueueItemSize == 0 ) + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + && ( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ) + #endif + ) + { + xReturn = xQueueSemaphoreTake( xInternalQueueHandle, xTicksToWait ); + } } } } @@ -2134,25 +2373,31 @@ TaskHandle_t xMutexHolderTaskExternalHandle = NULL; int32_t lIndex, lMutexHolderTaskIndex; QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) xSemaphore; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - xMutexHolderTaskInternalHandle = xQueueGetMutexHolder( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xMutexHolderTaskInternalHandle != NULL ) + if( xInternalQueueHandle != NULL ) { - lMutexHolderTaskIndex = MPU_GetIndexForTaskHandle( xMutexHolderTaskInternalHandle ); + xMutexHolderTaskInternalHandle = xQueueGetMutexHolder( xInternalQueueHandle ); - if( lMutexHolderTaskIndex != -1 ) + if( xMutexHolderTaskInternalHandle != NULL ) { - xMutexHolderTaskExternalHandle = ( TaskHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lMutexHolderTaskIndex ) ); + lMutexHolderTaskIndex = MPU_GetIndexForTaskHandle( xMutexHolderTaskInternalHandle ); + + if( lMutexHolderTaskIndex != -1 ) + { + xMutexHolderTaskExternalHandle = ( TaskHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lMutexHolderTaskIndex ) ); + } } } } @@ -2173,6 +2418,7 @@ TickType_t xBlockTime ) /* PRIVILEGED_FUNCTION */ { BaseType_t xReturn = pdFAIL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; int32_t lIndex; QueueHandle_t xInternalQueueHandle = NULL; UBaseType_t uxQueueItemSize; @@ -2181,15 +2427,20 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( uxQueueItemSize == 0 ) + if( xInternalQueueHandle != NULL ) { - xReturn = xQueueTakeMutexRecursive( xInternalQueueHandle, xBlockTime ); + uxQueueItemSize = uxQueueGetQueueItemSize( xInternalQueueHandle ); + + if( uxQueueItemSize == 0 ) + { + xReturn = xQueueTakeMutexRecursive( xInternalQueueHandle, xBlockTime ); + } } } } @@ -2207,6 +2458,7 @@ BaseType_t MPU_xQueueGiveMutexRecursiveImpl( QueueHandle_t xMutex ) /* PRIVILEGED_FUNCTION */ { BaseType_t xReturn = pdFAIL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; int32_t lIndex; QueueHandle_t xInternalQueueHandle = NULL; @@ -2214,11 +2466,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - xReturn = xQueueGiveMutexRecursive( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + xReturn = xQueueGiveMutexRecursive( xInternalQueueHandle ); + } } } @@ -2240,24 +2497,30 @@ QueueSetMemberHandle_t xSelectedMemberInternal = NULL; QueueSetMemberHandle_t xSelectedMemberExternal = NULL; int32_t lIndexQueueSet, lIndexSelectedMember; + BaseType_t xCallingTaskIsAuthorizedToAccessQueueSet = pdFALSE; lIndexQueueSet = ( int32_t ) xQueueSet; if( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) { - xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xCallingTaskIsAuthorizedToAccessQueueSet = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); - if( xInternalQueueSetHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueueSet == pdTRUE ) { - xSelectedMemberInternal = xQueueSelectFromSet( xInternalQueueSetHandle, xBlockTimeTicks ); + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); - if( xSelectedMemberInternal != NULL ) + if( xInternalQueueSetHandle != NULL ) { - lIndexSelectedMember = MPU_GetIndexForQueueSetMemberHandle( xSelectedMemberInternal ); + xSelectedMemberInternal = xQueueSelectFromSet( xInternalQueueSetHandle, xBlockTimeTicks ); - if( lIndexSelectedMember != -1 ) + if( xSelectedMemberInternal != NULL ) { - xSelectedMemberExternal = ( QueueSetMemberHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lIndexSelectedMember ) ); + lIndexSelectedMember = MPU_GetIndexForQueueSetMemberHandle( xSelectedMemberInternal ); + + if( lIndexSelectedMember != -1 ) + { + xSelectedMemberExternal = ( QueueSetMemberHandle_t ) ( CONVERT_TO_EXTERNAL_INDEX( lIndexSelectedMember ) ); + } } } } @@ -2281,6 +2544,8 @@ QueueSetMemberHandle_t xInternalQueueSetMemberHandle = NULL; QueueSetHandle_t xInternalQueueSetHandle = NULL; int32_t lIndexQueueSet, lIndexQueueSetMember; + BaseType_t xCallingTaskIsAuthorizedToAccessQueueSet = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessQueueSetMember = pdFALSE; lIndexQueueSet = ( int32_t ) xQueueSet; lIndexQueueSetMember = ( int32_t ) xQueueOrSemaphore; @@ -2288,12 +2553,18 @@ if( ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSet ) != pdFALSE ) && ( IS_EXTERNAL_INDEX_VALID( lIndexQueueSetMember ) != pdFALSE ) ) { - xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); - xInternalQueueSetMemberHandle = MPU_GetQueueSetMemberHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); + xCallingTaskIsAuthorizedToAccessQueueSet = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xCallingTaskIsAuthorizedToAccessQueueSetMember = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); - if( ( xInternalQueueSetHandle != NULL ) && ( xInternalQueueSetMemberHandle != NULL ) ) + if( ( xCallingTaskIsAuthorizedToAccessQueueSet == pdTRUE ) && ( xCallingTaskIsAuthorizedToAccessQueueSetMember == pdTRUE ) ) { - xReturn = xQueueAddToSet( xInternalQueueSetMemberHandle, xInternalQueueSetHandle ); + xInternalQueueSetHandle = MPU_GetQueueSetHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSet ) ); + xInternalQueueSetMemberHandle = MPU_GetQueueSetMemberHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndexQueueSetMember ) ); + + if( ( xInternalQueueSetHandle != NULL ) && ( xInternalQueueSetMemberHandle != NULL ) ) + { + xReturn = xQueueAddToSet( xInternalQueueSetMemberHandle, xInternalQueueSetHandle ); + } } } @@ -2313,16 +2584,22 @@ { int32_t lIndex; QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - vQueueAddToRegistry( xInternalQueueHandle, pcName ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueAddToRegistry( xInternalQueueHandle, pcName ); + } } } } @@ -2338,16 +2615,22 @@ { int32_t lIndex; QueueHandle_t xInternalQueueHandle = NULL; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - vQueueUnregisterQueue( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + vQueueUnregisterQueue( xInternalQueueHandle ); + } } } } @@ -2364,16 +2647,22 @@ const char * pcReturn = NULL; QueueHandle_t xInternalQueueHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessQueue = pdFALSE; lIndex = ( int32_t ) xQueue; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessQueue = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalQueueHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessQueue == pdTRUE ) { - pcReturn = pcQueueGetName( xInternalQueueHandle ); + xInternalQueueHandle = MPU_GetQueueHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalQueueHandle != NULL ) + { + pcReturn = pcQueueGetName( xInternalQueueHandle ); + } } } @@ -2971,16 +3260,22 @@ void * pvReturn = NULL; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - pvReturn = pvTimerGetTimerID( xInternalTimerHandle ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + pvReturn = pvTimerGetTimerID( xInternalTimerHandle ); + } } } @@ -3000,16 +3295,22 @@ { TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - vTimerSetTimerID( xInternalTimerHandle, pvNewID ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + vTimerSetTimerID( xInternalTimerHandle, pvNewID ); + } } } } @@ -3026,16 +3327,22 @@ BaseType_t xReturn = pdFALSE; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - xReturn = xTimerIsTimerActive( xInternalTimerHandle ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerIsTimerActive( xInternalTimerHandle ); + } } } @@ -3091,6 +3398,7 @@ TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; BaseType_t xIsHigherPriorityTaskWokenWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; BaseType_t xAreParamsReadable = pdFALSE; if( pxParams != NULL ) @@ -3116,15 +3424,20 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - xReturn = xTimerGenericCommand( xInternalTimerHandle, - pxParams->xCommandID, - pxParams->xOptionalValue, - pxParams->pxHigherPriorityTaskWoken, - pxParams->xTicksToWait ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGenericCommand( xInternalTimerHandle, + pxParams->xCommandID, + pxParams->xOptionalValue, + pxParams->pxHigherPriorityTaskWoken, + pxParams->xTicksToWait ); + } } } } @@ -3175,16 +3488,22 @@ const char * pcReturn = NULL; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - pcReturn = pcTimerGetName( xInternalTimerHandle ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + pcReturn = pcTimerGetName( xInternalTimerHandle ); + } } } @@ -3204,16 +3523,22 @@ { TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - vTimerSetReloadMode( xInternalTimerHandle, uxAutoReload ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + vTimerSetReloadMode( xInternalTimerHandle, uxAutoReload ); + } } } } @@ -3230,16 +3555,22 @@ BaseType_t xReturn = pdFALSE; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - xReturn = xTimerGetReloadMode( xInternalTimerHandle ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetReloadMode( xInternalTimerHandle ); + } } } @@ -3258,16 +3589,22 @@ UBaseType_t uxReturn = 0; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - uxReturn = uxTimerGetReloadMode( xInternalTimerHandle ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + uxReturn = uxTimerGetReloadMode( xInternalTimerHandle ); + } } } @@ -3286,16 +3623,22 @@ TickType_t xReturn = 0; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - xReturn = xTimerGetPeriod( xInternalTimerHandle ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetPeriod( xInternalTimerHandle ); + } } } @@ -3314,16 +3657,22 @@ TickType_t xReturn = 0; TimerHandle_t xInternalTimerHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessTimer = pdFALSE; lIndex = ( int32_t ) xTimer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessTimer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalTimerHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessTimer == pdTRUE ) { - xReturn = xTimerGetExpiryTime( xInternalTimerHandle ); + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGetExpiryTime( xInternalTimerHandle ); + } } } @@ -3467,6 +3816,7 @@ EventBits_t xReturn = 0; EventGroupHandle_t xInternalEventGroupHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; BaseType_t xAreParamsReadable = pdFALSE; if( pxParams != NULL ) @@ -3489,15 +3839,20 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - xReturn = xEventGroupWaitBits( xInternalEventGroupHandle, - pxParams->uxBitsToWaitFor, - pxParams->xClearOnExit, - pxParams->xWaitForAllBits, - pxParams->xTicksToWait ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupWaitBits( xInternalEventGroupHandle, + pxParams->uxBitsToWaitFor, + pxParams->xClearOnExit, + pxParams->xWaitForAllBits, + pxParams->xTicksToWait ); + } } } } @@ -3516,6 +3871,7 @@ EventBits_t xReturn = 0; EventGroupHandle_t xInternalEventGroupHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; if( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) { @@ -3523,11 +3879,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - xReturn = xEventGroupClearBits( xInternalEventGroupHandle, uxBitsToClear ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupClearBits( xInternalEventGroupHandle, uxBitsToClear ); + } } } } @@ -3545,6 +3906,7 @@ EventBits_t xReturn = 0; EventGroupHandle_t xInternalEventGroupHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; if( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) { @@ -3552,11 +3914,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - xReturn = xEventGroupSetBits( xInternalEventGroupHandle, uxBitsToSet ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSetBits( xInternalEventGroupHandle, uxBitsToSet ); + } } } } @@ -3578,6 +3945,7 @@ EventBits_t xReturn = 0; EventGroupHandle_t xInternalEventGroupHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; if( ( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ) && ( uxBitsToWaitFor != 0 ) @@ -3590,11 +3958,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - xReturn = xEventGroupSync( xInternalEventGroupHandle, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = xEventGroupSync( xInternalEventGroupHandle, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + } } } } @@ -3612,16 +3985,22 @@ UBaseType_t xReturn = 0; EventGroupHandle_t xInternalEventGroupHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; lIndex = ( int32_t ) xEventGroup; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - xReturn = uxEventGroupGetNumber( xInternalEventGroupHandle ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + xReturn = uxEventGroupGetNumber( xInternalEventGroupHandle ); + } } } @@ -3641,16 +4020,22 @@ { EventGroupHandle_t xInternalEventGroupHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessEventGroup = pdFALSE; lIndex = ( int32_t ) xEventGroup; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessEventGroup = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalEventGroupHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessEventGroup == pdTRUE ) { - vEventGroupSetNumber( xInternalEventGroupHandle, uxEventGroupNumber ); + xInternalEventGroupHandle = MPU_GetEventGroupHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalEventGroupHandle != NULL ) + { + vEventGroupSetNumber( xInternalEventGroupHandle, uxEventGroupNumber ); + } } } } @@ -3867,6 +4252,7 @@ StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; BaseType_t xIsTxDataBufferReadable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; if( pvTxData != NULL ) { @@ -3880,11 +4266,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferSend( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, xTicksToWait ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSend( xInternalStreamBufferHandle, pvTxData, xDataLengthBytes, xTicksToWait ); + } } } } @@ -3908,6 +4299,7 @@ StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; BaseType_t xIsRxDataBufferWriteable = pdFALSE; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; if( pvRxData != NULL ) { @@ -3921,11 +4313,16 @@ if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferReceive( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, xTicksToWait ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferReceive( xInternalStreamBufferHandle, pvRxData, xBufferLengthBytes, xTicksToWait ); + } } } } @@ -3942,16 +4339,22 @@ BaseType_t xReturn = pdFALSE; StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; lIndex = ( int32_t ) xStreamBuffer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferIsFull( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsFull( xInternalStreamBufferHandle ); + } } } @@ -3966,16 +4369,22 @@ BaseType_t xReturn = pdFALSE; StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; lIndex = ( int32_t ) xStreamBuffer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferIsEmpty( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferIsEmpty( xInternalStreamBufferHandle ); + } } } @@ -3990,16 +4399,22 @@ size_t xReturn = 0; StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; lIndex = ( int32_t ) xStreamBuffer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferSpacesAvailable( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSpacesAvailable( xInternalStreamBufferHandle ); + } } } @@ -4014,16 +4429,22 @@ size_t xReturn = 0; StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; lIndex = ( int32_t ) xStreamBuffer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferBytesAvailable( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferBytesAvailable( xInternalStreamBufferHandle ); + } } } @@ -4040,16 +4461,22 @@ BaseType_t xReturn = pdFALSE; StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; lIndex = ( int32_t ) xStreamBuffer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferSetTriggerLevel( xInternalStreamBufferHandle, xTriggerLevel ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferSetTriggerLevel( xInternalStreamBufferHandle, xTriggerLevel ); + } } } @@ -4064,16 +4491,22 @@ size_t xReturn = 0; StreamBufferHandle_t xInternalStreamBufferHandle = NULL; int32_t lIndex; + BaseType_t xCallingTaskIsAuthorizedToAccessStreamBuffer = pdFALSE; lIndex = ( int32_t ) xStreamBuffer; if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) { - xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + xCallingTaskIsAuthorizedToAccessStreamBuffer = xPortIsAuthorizedToAccessKernelObject( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); - if( xInternalStreamBufferHandle != NULL ) + if( xCallingTaskIsAuthorizedToAccessStreamBuffer == pdTRUE ) { - xReturn = xStreamBufferNextMessageLengthBytes( xInternalStreamBufferHandle ); + xInternalStreamBufferHandle = MPU_GetStreamBufferHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalStreamBufferHandle != NULL ) + { + xReturn = xStreamBufferNextMessageLengthBytes( xInternalStreamBufferHandle ); + } } } diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index fd00078c4..7131be066 100644 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -252,6 +252,15 @@ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; * switches can only occur when uxCriticalNesting is zero. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/* + * This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned @@ -824,6 +833,12 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; + #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ __asm volatile ( @@ -1367,3 +1382,98 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM3_MPU/portmacro.h b/portable/GCC/ARM_CM3_MPU/portmacro.h index cfc72b17e..e20c19ecd 100644 --- a/portable/GCC/ARM_CM3_MPU/portmacro.h +++ b/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -127,7 +127,10 @@ #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ - #define MAX_CONTEXT_SIZE 20 +#define MAX_CONTEXT_SIZE ( 20 ) + +/* Size of an Access Control List (ACL) entry in bits. */ +#define portACL_ENTRY_SIZE_BITS ( 32U ) /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) @@ -140,10 +143,13 @@ uint32_t ulContext[ MAX_CONTEXT_SIZE ]; uint32_t ulTaskFlags; - #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) - xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; #endif - } xMPU_SETTINGS; + #endif +} xMPU_SETTINGS; /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index 2a94f04c5..bc058276d 100644 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -277,6 +277,15 @@ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; * switches can only occur when uxCriticalNesting is zero. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/* + * This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned @@ -911,6 +920,12 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; + #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); @@ -1538,3 +1553,98 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM4_MPU/portmacro.h b/portable/GCC/ARM_CM4_MPU/portmacro.h index c239ff5df..ef7bffebe 100644 --- a/portable/GCC/ARM_CM4_MPU/portmacro.h +++ b/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -216,7 +216,10 @@ typedef struct MPU_REGION_SETTINGS #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -#define MAX_CONTEXT_SIZE 52 +#define MAX_CONTEXT_SIZE ( 52 ) + +/* Size of an Access Control List (ACL) entry in bits. */ +#define portACL_ENTRY_SIZE_BITS ( 32U ) /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) @@ -231,6 +234,9 @@ typedef struct MPU_SETTINGS #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index df3b35b53..990cf220b 100644 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -283,6 +283,15 @@ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; * variable. */ static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/* + * This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /* * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure * FreeRTOS API functions are not called from interrupts that have been assigned @@ -787,6 +796,12 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; + #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); @@ -1262,3 +1277,98 @@ BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer, #endif /* configASSERT_DEFINED */ /*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM4F_MPU/portmacro.h b/portable/IAR/ARM_CM4F_MPU/portmacro.h index 48a08b598..cdb74085f 100644 --- a/portable/IAR/ARM_CM4F_MPU/portmacro.h +++ b/portable/IAR/ARM_CM4F_MPU/portmacro.h @@ -218,7 +218,10 @@ typedef struct MPU_REGION_SETTINGS #endif /* configUSE_MPU_WRAPPERS_V1 == 0 */ -#define MAX_CONTEXT_SIZE 52 +#define MAX_CONTEXT_SIZE ( 52 ) + +/* Size of an Access Control List (ACL) entry in bits. */ +#define portACL_ENTRY_SIZE_BITS ( 32U ) /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) @@ -233,6 +236,9 @@ typedef struct MPU_SETTINGS #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index 4b1564397..f220a6d7e 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -472,6 +472,15 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #endif /* configENABLE_MPU == 1 */ /*-----------------------------------------------------------*/ +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif + /** * @brief Each task maintains its own interrupt status in the critical nesting * variable. @@ -1651,6 +1660,12 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */ /* Initialize the critical nesting count ready for the first task. */ ulCriticalNesting = 0; + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Start the first task. */ vStartFirstTask(); @@ -1931,3 +1946,98 @@ BaseType_t xPortIsInsideInterrupt( void ) #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_BASEPRI == 1 ) ) */ /*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h index 2ef4c90c1..816e34894 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/portmacrocommon.h @@ -287,6 +287,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) #define portTASK_IS_PRIVILEGED_FLAG ( 1UL << 1UL ) +/* Size of an Access Control List (ACL) entry in bits. */ + #define portACL_ENTRY_SIZE_BITS ( 32U ) + typedef struct MPU_SETTINGS { uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ @@ -296,6 +299,9 @@ extern void vClearInterruptMask( uint32_t ulMask ) /* __attribute__(( naked )) P #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS; diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index 6702c4cd9..92c8aad9f 100644 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -140,7 +140,16 @@ /* Each task maintains its own interrupt status in the critical nesting * variable. Note this is not saved as part of the task context as context * switches can only occur when uxCriticalNesting is zero. */ -static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; +PRIVILEGED_DATA static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + +/* + * This variable is set to pdTRUE when the scheduler is started. + */ + PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; + +#endif /* * Setup the timer to generate the tick interrupts. @@ -905,6 +914,12 @@ BaseType_t xPortStartScheduler( void ) /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; + #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + { + xSchedulerRunning = pdTRUE; + } + #endif + /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); @@ -1539,3 +1554,99 @@ __asm uint32_t prvPortGetIPSR( void ) } #endif /* configASSERT_DEFINED */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortGrantAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] |= ( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) + + void vPortRevokeAccessToKernelObject( TaskHandle_t xInternalTaskHandle, + int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + xMPU_SETTINGS * xTaskMpuSettings; + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + xTaskMpuSettings = xTaskGetMPUSettings( xInternalTaskHandle ); + + xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] &= ~( 1U << ulAccessControlListEntryBit ); + } + +#endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + uint32_t ulAccessControlListEntryIndex, ulAccessControlListEntryBit; + BaseType_t xAccessGranted = pdFALSE; + const xMPU_SETTINGS * xTaskMpuSettings; + + if( xSchedulerRunning == pdFALSE ) + { + /* Grant access to all the kernel objects before the scheduler + * is started. It is necessary because there is no task running + * yet and therefore, we cannot use the permissions of any + * task. */ + xAccessGranted = pdTRUE; + } + else + { + xTaskMpuSettings = xTaskGetMPUSettings( NULL ); /* Calling task's MPU settings. */ + + ulAccessControlListEntryIndex = ( ( uint32_t ) lInternalIndexOfKernelObject / portACL_ENTRY_SIZE_BITS ); + ulAccessControlListEntryBit = ( ( uint32_t ) lInternalIndexOfKernelObject % portACL_ENTRY_SIZE_BITS ); + + if( ( xTaskMpuSettings->ulTaskFlags & portTASK_IS_PRIVILEGED_FLAG ) == portTASK_IS_PRIVILEGED_FLAG ) + { + xAccessGranted = pdTRUE; + } + else + { + if( ( xTaskMpuSettings->ulAccessControlList[ ulAccessControlListEntryIndex ] & ( 1U << ulAccessControlListEntryBit ) ) != 0 ) + { + xAccessGranted = pdTRUE; + } + } + } + + return xAccessGranted; + } + + #else /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + + BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) /* PRIVILEGED_FUNCTION */ + { + ( void ) lInternalIndexOfKernelObject; + + /* If Access Control List feature is not used, all the tasks have + * access to all the kernel objects. */ + return pdTRUE; + } + + #endif /* #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) */ + +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ +/*-----------------------------------------------------------*/ diff --git a/portable/RVDS/ARM_CM4_MPU/portmacro.h b/portable/RVDS/ARM_CM4_MPU/portmacro.h index 6a46c3085..b68af5a73 100644 --- a/portable/RVDS/ARM_CM4_MPU/portmacro.h +++ b/portable/RVDS/ARM_CM4_MPU/portmacro.h @@ -216,7 +216,10 @@ typedef struct MPU_REGION_SETTINGS #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ -#define MAX_CONTEXT_SIZE 52 +#define MAX_CONTEXT_SIZE ( 52 ) + +/* Size of an Access Control List (ACL) entry in bits. */ +#define portACL_ENTRY_SIZE_BITS ( 32U ) /* Flags used for xMPU_SETTINGS.ulTaskFlags member. */ #define portSTACK_FRAME_HAS_PADDING_FLAG ( 1UL << 0UL ) @@ -231,6 +234,9 @@ typedef struct MPU_SETTINGS #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) xSYSTEM_CALL_STACK_INFO xSystemCallStackInfo; + #if ( configENABLE_ACCESS_CONTROL_LIST == 1 ) + uint32_t ulAccessControlList[ ( configPROTECTED_KERNEL_OBJECT_POOL_SIZE / portACL_ENTRY_SIZE_BITS ) + 1 ]; + #endif #endif } xMPU_SETTINGS;