Skip to content

Commit 31419bf

Browse files
FreeRTOS MPU: Add Privileged eXecute Never MPU attribute support (#1092)
FreeRTOS MPU: Add privileged execute never MPU attribute A new MPU region attribute Privileged eXecute Never (PXN) is introduced in Armv8.1-M architecture, where if an MPU region has PXN attribute set and the processor attempts to execute the code inside with privileged level, the Memory Management Fault exception would be triggered, with IACCVIOL bit in MemManage Fault State Register set to 1. The PXN feature allows privileged software to ensure specific application tasks (threads) to execute in unprivileged level only. Signed-off-by: Ahmed Ismail <[email protected]>
1 parent 0c79e74 commit 31419bf

File tree

56 files changed

+1309
-936
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1309
-936
lines changed

include/task.h

+15-12
Original file line numberDiff line numberDiff line change
@@ -53,30 +53,33 @@
5353
* The tskKERNEL_VERSION_MAJOR, tskKERNEL_VERSION_MINOR, tskKERNEL_VERSION_BUILD
5454
* values will reflect the last released version number.
5555
*/
56-
#define tskKERNEL_VERSION_NUMBER "V11.1.0+"
57-
#define tskKERNEL_VERSION_MAJOR 11
58-
#define tskKERNEL_VERSION_MINOR 1
59-
#define tskKERNEL_VERSION_BUILD 0
56+
#define tskKERNEL_VERSION_NUMBER "V11.1.0+"
57+
#define tskKERNEL_VERSION_MAJOR 11
58+
#define tskKERNEL_VERSION_MINOR 1
59+
#define tskKERNEL_VERSION_BUILD 0
6060

6161
/* MPU region parameters passed in ulParameters
6262
* of MemoryRegion_t struct. */
63-
#define tskMPU_REGION_READ_ONLY ( 1U << 0U )
64-
#define tskMPU_REGION_READ_WRITE ( 1U << 1U )
65-
#define tskMPU_REGION_EXECUTE_NEVER ( 1U << 2U )
66-
#define tskMPU_REGION_NORMAL_MEMORY ( 1U << 3U )
67-
#define tskMPU_REGION_DEVICE_MEMORY ( 1U << 4U )
63+
#define tskMPU_REGION_READ_ONLY ( 1U << 0U )
64+
#define tskMPU_REGION_READ_WRITE ( 1U << 1U )
65+
#define tskMPU_REGION_EXECUTE_NEVER ( 1U << 2U )
66+
#define tskMPU_REGION_NORMAL_MEMORY ( 1U << 3U )
67+
#define tskMPU_REGION_DEVICE_MEMORY ( 1U << 4U )
68+
#if ( portARMV8M_MINOR_VERSION >= 1 )
69+
#define tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ( 1U << 5U )
70+
#endif /* portARMV8M_MINOR_VERSION >= 1 */
6871

6972
/* MPU region permissions stored in MPU settings to
7073
* authorize access requests. */
71-
#define tskMPU_READ_PERMISSION ( 1U << 0U )
72-
#define tskMPU_WRITE_PERMISSION ( 1U << 1U )
74+
#define tskMPU_READ_PERMISSION ( 1U << 0U )
75+
#define tskMPU_WRITE_PERMISSION ( 1U << 1U )
7376

7477
/* The direct to task notification feature used to have only a single notification
7578
* per task. Now there is an array of notifications per task that is dimensioned by
7679
* configTASK_NOTIFICATION_ARRAY_ENTRIES. For backward compatibility, any use of the
7780
* original direct to task notification defaults to using the first index in the
7881
* array. */
79-
#define tskDEFAULT_INDEX_TO_NOTIFY ( 0 )
82+
#define tskDEFAULT_INDEX_TO_NOTIFY ( 0 )
8083

8184
/**
8285
* task. h

portable/ARMv8M/non_secure/port.c

+60-44
Original file line numberDiff line numberDiff line change
@@ -166,73 +166,79 @@ typedef void ( * portISR_t )( void );
166166
/**
167167
* @brief Constants required to manipulate the MPU.
168168
*/
169-
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
170-
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
171-
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
169+
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
170+
#define portMPU_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed94 ) )
171+
#define portMPU_RNR_REG ( *( ( volatile uint32_t * ) 0xe000ed98 ) )
172172

173-
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
174-
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
173+
#define portMPU_RBAR_REG ( *( ( volatile uint32_t * ) 0xe000ed9c ) )
174+
#define portMPU_RLAR_REG ( *( ( volatile uint32_t * ) 0xe000eda0 ) )
175175

176-
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
177-
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
176+
#define portMPU_RBAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda4 ) )
177+
#define portMPU_RLAR_A1_REG ( *( ( volatile uint32_t * ) 0xe000eda8 ) )
178178

179-
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
180-
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
179+
#define portMPU_RBAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edac ) )
180+
#define portMPU_RLAR_A2_REG ( *( ( volatile uint32_t * ) 0xe000edb0 ) )
181181

182-
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
183-
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
182+
#define portMPU_RBAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb4 ) )
183+
#define portMPU_RLAR_A3_REG ( *( ( volatile uint32_t * ) 0xe000edb8 ) )
184184

185-
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
186-
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
185+
#define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) )
186+
#define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) )
187187

188-
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
189-
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
188+
#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
189+
#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */
190190

191-
#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL )
191+
#define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL )
192192

193-
#define portMPU_MAIR_ATTR0_POS ( 0UL )
194-
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
193+
#define portMPU_MAIR_ATTR0_POS ( 0UL )
194+
#define portMPU_MAIR_ATTR0_MASK ( 0x000000ff )
195195

196-
#define portMPU_MAIR_ATTR1_POS ( 8UL )
197-
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
196+
#define portMPU_MAIR_ATTR1_POS ( 8UL )
197+
#define portMPU_MAIR_ATTR1_MASK ( 0x0000ff00 )
198198

199-
#define portMPU_MAIR_ATTR2_POS ( 16UL )
200-
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
199+
#define portMPU_MAIR_ATTR2_POS ( 16UL )
200+
#define portMPU_MAIR_ATTR2_MASK ( 0x00ff0000 )
201201

202-
#define portMPU_MAIR_ATTR3_POS ( 24UL )
203-
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
202+
#define portMPU_MAIR_ATTR3_POS ( 24UL )
203+
#define portMPU_MAIR_ATTR3_MASK ( 0xff000000 )
204204

205-
#define portMPU_MAIR_ATTR4_POS ( 0UL )
206-
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
205+
#define portMPU_MAIR_ATTR4_POS ( 0UL )
206+
#define portMPU_MAIR_ATTR4_MASK ( 0x000000ff )
207207

208-
#define portMPU_MAIR_ATTR5_POS ( 8UL )
209-
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
208+
#define portMPU_MAIR_ATTR5_POS ( 8UL )
209+
#define portMPU_MAIR_ATTR5_MASK ( 0x0000ff00 )
210210

211-
#define portMPU_MAIR_ATTR6_POS ( 16UL )
212-
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
211+
#define portMPU_MAIR_ATTR6_POS ( 16UL )
212+
#define portMPU_MAIR_ATTR6_MASK ( 0x00ff0000 )
213213

214-
#define portMPU_MAIR_ATTR7_POS ( 24UL )
215-
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
214+
#define portMPU_MAIR_ATTR7_POS ( 24UL )
215+
#define portMPU_MAIR_ATTR7_MASK ( 0xff000000 )
216216

217-
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
218-
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
219-
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
220-
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
221-
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
222-
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
223-
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
224-
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL )
217+
#define portMPU_RLAR_ATTR_INDEX0 ( 0UL << 1UL )
218+
#define portMPU_RLAR_ATTR_INDEX1 ( 1UL << 1UL )
219+
#define portMPU_RLAR_ATTR_INDEX2 ( 2UL << 1UL )
220+
#define portMPU_RLAR_ATTR_INDEX3 ( 3UL << 1UL )
221+
#define portMPU_RLAR_ATTR_INDEX4 ( 4UL << 1UL )
222+
#define portMPU_RLAR_ATTR_INDEX5 ( 5UL << 1UL )
223+
#define portMPU_RLAR_ATTR_INDEX6 ( 6UL << 1UL )
224+
#define portMPU_RLAR_ATTR_INDEX7 ( 7UL << 1UL )
225225

226-
#define portMPU_RLAR_REGION_ENABLE ( 1UL )
226+
#define portMPU_RLAR_REGION_ENABLE ( 1UL )
227+
228+
#if ( portARMV8M_MINOR_VERSION >= 1 )
229+
/* Enable Privileged eXecute Never MPU attribute for the selected memory
230+
* region. */
231+
#define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL )
232+
#endif /* portARMV8M_MINOR_VERSION >= 1 */
227233

228234
/* Enable privileged access to unmapped region. */
229-
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
235+
#define portMPU_PRIV_BACKGROUND_ENABLE_BIT ( 1UL << 2UL )
230236

231237
/* Enable MPU. */
232-
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
238+
#define portMPU_ENABLE_BIT ( 1UL << 0UL )
233239

234240
/* Expected value of the portMPU_TYPE register. */
235-
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
241+
#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL )
236242

237243
/* Extract first address of the MPU region as encoded in the
238244
* RBAR (Region Base Address Register) value. */
@@ -1880,6 +1886,16 @@ void vPortEndScheduler( void ) /* PRIVILEGED_FUNCTION */
18801886
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR = ( ulRegionEndAddress ) |
18811887
( portMPU_RLAR_REGION_ENABLE );
18821888

1889+
/* PXN. */
1890+
#if ( portARMV8M_MINOR_VERSION >= 1 )
1891+
{
1892+
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_PRIVILEGED_EXECUTE_NEVER ) != 0 )
1893+
{
1894+
xMPUSettings->xRegionsSettings[ ulRegionNumber ].ulRLAR |= ( portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER );
1895+
}
1896+
}
1897+
#endif /* portARMV8M_MINOR_VERSION >= 1 */
1898+
18831899
/* Normal memory/ Device memory. */
18841900
if( ( xRegions[ lIndex ].ulParameters & tskMPU_REGION_DEVICE_MEMORY ) != 0 )
18851901
{

portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M23"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 0
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __attribute__( ( used ) )
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M23"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 0
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __attribute__( ( used ) )
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M33"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 1
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __attribute__( ( used ) )
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M33"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 1
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __attribute__( ( used ) )
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/GCC/ARM_CM35P/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M35P"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 1
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __attribute__( ( used ) )
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/GCC/ARM_CM55/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
*/
5656
#define portARCH_NAME "Cortex-M55"
5757
#define portHAS_ARMV8M_MAIN_EXTENSION 1
58+
#define portARMV8M_MINOR_VERSION 1
5859
#define portDONT_DISCARD __attribute__( ( used ) )
5960
/*-----------------------------------------------------------*/
6061

portable/ARMv8M/non_secure/portable/GCC/ARM_CM85/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
*/
5656
#define portARCH_NAME "Cortex-M85"
5757
#define portHAS_ARMV8M_MAIN_EXTENSION 1
58+
#define portARMV8M_MINOR_VERSION 1
5859
#define portDONT_DISCARD __attribute__( ( used ) )
5960
/*-----------------------------------------------------------*/
6061

portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M23"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 0
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __root
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/IAR/ARM_CM23_NTZ/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M23"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 0
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __root
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M33"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 1
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __root
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/IAR/ARM_CM33_NTZ/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M33"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 1
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __root
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/IAR/ARM_CM35P/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*/
5151
#define portARCH_NAME "Cortex-M35P"
5252
#define portHAS_ARMV8M_MAIN_EXTENSION 1
53+
#define portARMV8M_MINOR_VERSION 0
5354
#define portDONT_DISCARD __root
5455
/*-----------------------------------------------------------*/
5556

portable/ARMv8M/non_secure/portable/IAR/ARM_CM55/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
*/
5656
#define portARCH_NAME "Cortex-M55"
5757
#define portHAS_ARMV8M_MAIN_EXTENSION 1
58+
#define portARMV8M_MINOR_VERSION 1
5859
#define portDONT_DISCARD __root
5960
/*-----------------------------------------------------------*/
6061

portable/ARMv8M/non_secure/portable/IAR/ARM_CM85/portmacro.h

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
*/
5656
#define portARCH_NAME "Cortex-M85"
5757
#define portHAS_ARMV8M_MAIN_EXTENSION 1
58+
#define portARMV8M_MINOR_VERSION 1
5859
#define portDONT_DISCARD __root
5960
/*-----------------------------------------------------------*/
6061

0 commit comments

Comments
 (0)