in portable/IAR/ARM_CM33_NTZ/non_secure/port.c [1052:1172]
void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
const struct xMEMORY_REGION * const xRegions,
StackType_t * pxBottomOfStack,
uint32_t ulStackDepth )
{
uint32_t ulRegionStartAddress, ulRegionEndAddress, ulRegionNumber;
int32_t lIndex = 0;
#if defined( __ARMCC_VERSION )
/* Declaration when these variable are defined in code instead of being
* exported from linker scripts. */
extern uint32_t * __privileged_sram_start__;
extern uint32_t * __privileged_sram_end__;
#else
/* Declaration when these variable are exported from linker scripts. */
extern uint32_t __privileged_sram_start__[];
extern uint32_t __privileged_sram_end__[];
#endif /* defined( __ARMCC_VERSION ) */
/* Setup MAIR0. */
xMPUSettings->ulMAIR0 = ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK );
xMPUSettings->ulMAIR0 |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK );
/* This function is called automatically when the task is created - in
* which case the stack region parameters will be valid. At all other
* times the stack parameters will not be valid and it is assumed that
* the stack region has already been configured. */
if( ulStackDepth > 0 )
{
ulRegionStartAddress = ( uint32_t ) pxBottomOfStack;
ulRegionEndAddress = ( uint32_t ) pxBottomOfStack + ( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) - 1;
/* If the stack is within the privileged SRAM, do not protect it
* using a separate MPU region. This is needed because privileged
* SRAM is already protected using an MPU region and ARMv8-M does
* not allow overlapping MPU regions. */
if( ( ulRegionStartAddress >= ( uint32_t ) __privileged_sram_start__ ) &&
( ulRegionEndAddress <= ( uint32_t ) __privileged_sram_end__ ) )
{
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = 0;
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = 0;
}
else
{
/* Define the region that allows access to the stack. */
ulRegionStartAddress &= portMPU_RBAR_ADDRESS_MASK;
ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;
xMPUSettings->xRegionsSettings[ 0 ].ulRBAR = ( ulRegionStartAddress ) |
( portMPU_REGION_NON_SHAREABLE ) |
( portMPU_REGION_READ_WRITE ) |
( portMPU_REGION_EXECUTE_NEVER );
xMPUSettings->xRegionsSettings[ 0 ].ulRLAR = ( ulRegionEndAddress ) |
( portMPU_RLAR_ATTR_INDEX0 ) |
( portMPU_RLAR_REGION_ENABLE );
}
}
/* User supplied configurable regions. */
for( ulRegionNumber = 1; ulRegionNumber <= portNUM_CONFIGURABLE_REGIONS; ulRegionNumber++ )
{
/* If xRegions is NULL i.e. the task has not specified any MPU
* region, the else part ensures that all the configurable MPU
* regions are invalidated. */
if( ( xRegions != NULL ) && ( xRegions[ lIndex ].ulLengthInBytes > 0UL ) )
{
/* Translate the generic region definition contained in xRegions
* into the ARMv8 specific MPU settings that are then stored in
* xMPUSettings. */
ulRegionStartAddress = ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) & portMPU_RBAR_ADDRESS_MASK;
ulRegionEndAddress = ( uint32_t ) xRegions[ lIndex ].pvBaseAddress + xRegions[ lIndex ].ulLengthInBytes - 1;
ulRegionEndAddress &= portMPU_RLAR_ADDRESS_MASK;
/* Start address. */
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = ( ulRegionStartAddress ) |
( portMPU_REGION_NON_SHAREABLE );
/* RO/RW. */
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_READ_ONLY ) != 0 )
{
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_ONLY );
}
else
{
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_READ_WRITE );
}
/* XN. */
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_EXECUTE_NEVER ) != 0 )
{
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR |= ( portMPU_REGION_EXECUTE_NEVER );
}
/* End Address. */
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) |
( portMPU_RLAR_REGION_ENABLE );
/* Normal memory/ Device memory. */
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 )
{
/* Attr1 in MAIR0 is configured as device memory. */
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX1;
}
else
{
/* Attr1 in MAIR0 is configured as normal memory. */
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= portMPU_RLAR_ATTR_INDEX0;
}
}
else
{
/* Invalidate the region. */
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRBAR = 0UL;
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = 0UL;
}
lIndex++;
}
}