Add Cortex M7 r0p1 Errata 837070 workaround to CM4_MPU ports (#513)
* Clarify Cortex M7 r0p1 errata number in r0p1 specific port.
* Add ARM Cortex M7 r0p0 / r0p1 Errata 837070 workaround to CM4 MPU ports.
Optionally, enable the errata workaround by defining configTARGET_ARM_CM7_r0p0 or configTARGET_ARM_CM7_r0p1 in FreeRTOSConfig.h.
* Add r0p1 errata support to IAR port as well
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
* Change macro name to configENABLE_ERRATA_837070_WORKAROUND
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
Co-authored-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c
index a10d9b9..ecffbfe 100644
--- a/portable/GCC/ARM_CM4_MPU/port.c
+++ b/portable/GCC/ARM_CM4_MPU/port.c
@@ -70,6 +70,12 @@
#define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
#define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL )
+/* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure
+ * that a work around is active for errata 837070. */
+#define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
+#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
+#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
+
/* Constants required to access and manipulate the MPU. */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) )
@@ -410,6 +416,18 @@
* https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) );
+ /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0
+ * and r0p1 cores. */
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) );
+ #else
+ /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define
+ * configENABLE_ERRATA_837070_WORKAROUND to 1 in your
+ * FreeRTOSConfig.h. */
+ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
+ configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
+ #endif
+
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
@@ -587,9 +605,15 @@
" \n"
" stmdb sp!, {r0, r3} \n"
" mov r0, %0 \n"
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
" msr basepri, r0 \n"
" dsb \n"
" isb \n"
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
" msr basepri, r0 \n"
diff --git a/portable/GCC/ARM_CM4_MPU/portmacro.h b/portable/GCC/ARM_CM4_MPU/portmacro.h
index d77522b..cef1b04 100644
--- a/portable/GCC/ARM_CM4_MPU/portmacro.h
+++ b/portable/GCC/ARM_CM4_MPU/portmacro.h
@@ -71,6 +71,7 @@
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
+
/*-----------------------------------------------------------*/
/* MPU specific constants. */
@@ -346,10 +347,16 @@
__asm volatile
(
- " mov %0, %1 \n"\
- " msr basepri, %0 \n"\
- " isb \n"\
- " dsb \n"\
+ " mov %0, %1 \n"
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
+ " msr basepri, %0 \n"
+ " isb \n"
+ " dsb \n"
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
: "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
);
}
@@ -362,11 +369,17 @@
__asm volatile
(
- " mrs %0, basepri \n"\
- " mov %1, %2 \n"\
- " msr basepri, %1 \n"\
- " isb \n"\
- " dsb \n"\
+ " mrs %0, basepri \n"
+ " mov %1, %2 \n"
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
+ " msr basepri, %1 \n"
+ " isb \n"
+ " dsb \n"
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
: "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
);
diff --git a/portable/GCC/ARM_CM7/r0p1/port.c b/portable/GCC/ARM_CM7/r0p1/port.c
index df36423..130e187 100644
--- a/portable/GCC/ARM_CM7/r0p1/port.c
+++ b/portable/GCC/ARM_CM7/r0p1/port.c
@@ -445,11 +445,11 @@
" \n"
" stmdb sp!, {r0, r3} \n"
" mov r0, %0 \n"
- " cpsid i \n"/* Errata workaround. */
+ " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" msr basepri, r0 \n"
" dsb \n"
" isb \n"
- " cpsie i \n"/* Errata workaround. */
+ " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
" msr basepri, r0 \n"
diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c
index 5e8c723..c9a2541 100644
--- a/portable/IAR/ARM_CM4F_MPU/port.c
+++ b/portable/IAR/ARM_CM4F_MPU/port.c
@@ -98,8 +98,8 @@
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
-/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7
- * r0p1 port. */
+/* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure
+ * that a work around is active for errata 837070. */
#define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
@@ -350,11 +350,17 @@
* See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
- /* This port can be used on all revisions of the Cortex-M7 core other than
- * the r0p1 parts. r0p1 parts should use the port from the
- * /source/portable/GCC/ARM_CM7/r0p1 directory. */
- configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
- configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
+ /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0
+ * and r0p1 cores. */
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) );
+ #else
+ /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define
+ * configENABLE_ERRATA_837070_WORKAROUND to 1 in your
+ * FreeRTOSConfig.h. */
+ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
+ configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
+ #endif
#if ( configASSERT_DEFINED == 1 )
{
diff --git a/portable/IAR/ARM_CM4F_MPU/portasm.s b/portable/IAR/ARM_CM4F_MPU/portasm.s
index 1ea6fda..f37912b 100644
--- a/portable/IAR/ARM_CM4F_MPU/portasm.s
+++ b/portable/IAR/ARM_CM4F_MPU/portasm.s
@@ -70,9 +70,15 @@
stmdb sp!, {r0, r3}
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
msr basepri, r0
dsb
isb
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
bl vTaskSwitchContext
mov r0, #0
msr basepri, r0
diff --git a/portable/IAR/ARM_CM4F_MPU/portmacro.h b/portable/IAR/ARM_CM4F_MPU/portmacro.h
index ea7ecdd..659fb13 100644
--- a/portable/IAR/ARM_CM4F_MPU/portmacro.h
+++ b/portable/IAR/ARM_CM4F_MPU/portmacro.h
@@ -73,6 +73,7 @@
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
+
/*-----------------------------------------------------------*/
/* MPU specific constants. */
@@ -253,12 +254,23 @@
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
-#define portDISABLE_INTERRUPTS() \
- { \
- __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
- __DSB(); \
- __ISB(); \
- }
+#if( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ #define portDISABLE_INTERRUPTS() \
+ { \
+ __disable_interrupt(); \
+ __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
+ __DSB(); \
+ __ISB(); \
+ __enable_interrupt(); \
+ }
+#else
+ #define portDISABLE_INTERRUPTS() \
+ { \
+ __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \
+ __DSB(); \
+ __ISB(); \
+ }
+#endif
#define portENABLE_INTERRUPTS() __set_BASEPRI( 0 )
#define portENTER_CRITICAL() vPortEnterCritical()
diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c
index 4d3c4a4..46fe89d 100644
--- a/portable/RVDS/ARM_CM4_MPU/port.c
+++ b/portable/RVDS/ARM_CM4_MPU/port.c
@@ -59,6 +59,12 @@
#define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
#define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL )
+/* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure
+ * that a work around is active for errata 837070. */
+#define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
+#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
+#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
+
/* Constants required to access and manipulate the MPU. */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) )
@@ -400,6 +406,18 @@
* See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
+ /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0
+ * and r0p1 cores. */
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) );
+ #else
+ /* When using this port on a Cortex-M7 r0p0 or r0p1 core, define
+ * configENABLE_ERRATA_837070_WORKAROUND to 1 in your
+ * FreeRTOSConfig.h. */
+ configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
+ configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
+ #endif
+
#if ( configASSERT_DEFINED == 1 )
{
volatile uint32_t ulOriginalPriority;
@@ -591,9 +609,15 @@
stmdb sp !, { r0, r3 }
mov r0, # configMAX_SYSCALL_INTERRUPT_PRIORITY
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsid i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
msr basepri, r0
dsb
isb
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
+ #endif
bl vTaskSwitchContext
mov r0, #0
msr basepri, r0
diff --git a/portable/RVDS/ARM_CM4_MPU/portmacro.h b/portable/RVDS/ARM_CM4_MPU/portmacro.h
index 4e0ad0a..7c3d7b5 100644
--- a/portable/RVDS/ARM_CM4_MPU/portmacro.h
+++ b/portable/RVDS/ARM_CM4_MPU/portmacro.h
@@ -70,6 +70,7 @@
* not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
+
/*-----------------------------------------------------------*/
/* MPU specific constants. */
@@ -334,9 +335,15 @@
/* Set BASEPRI to the max syscall priority to effect a critical
* section. */
/* *INDENT-OFF* */
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsid i
+ #endif
msr basepri, ulNewBASEPRI
dsb
isb
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsie i
+ #endif
/* *INDENT-ON* */
}
}
@@ -366,9 +373,15 @@
* section. */
/* *INDENT-OFF* */
mrs ulReturn, basepri
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsid i
+ #endif
msr basepri, ulNewBASEPRI
dsb
isb
+ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
+ cpsie i
+ #endif
/* *INDENT-ON* */
}