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>
This commit is contained in:
Paul Bartell 2022-06-29 22:05:26 -07:00 committed by GitHub
parent 8e89acfc98
commit 2dfdfc4ba4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 122 additions and 24 deletions

View File

@ -70,6 +70,12 @@
#define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
#define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) #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. */ /* Constants required to access and manipulate the MPU. */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) ) #define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) )
@ -410,6 +416,18 @@ BaseType_t xPortStartScheduler( void )
* https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ * https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); 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 ) #if ( configASSERT_DEFINED == 1 )
{ {
volatile uint32_t ulOriginalPriority; volatile uint32_t ulOriginalPriority;
@ -587,9 +605,15 @@ void xPortPendSVHandler( void )
" \n" " \n"
" stmdb sp!, {r0, r3} \n" " stmdb sp!, {r0, r3} \n"
" mov r0, %0 \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" " msr basepri, r0 \n"
" dsb \n" " dsb \n"
" isb \n" " isb \n"
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
" cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
#endif
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" mov r0, #0 \n" " mov r0, #0 \n"
" msr basepri, r0 \n" " msr basepri, r0 \n"

View File

@ -71,6 +71,7 @@ typedef unsigned long UBaseType_t;
* not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* MPU specific constants. */ /* MPU specific constants. */
@ -346,10 +347,16 @@ portFORCE_INLINE static void vPortRaiseBASEPRI( void )
__asm volatile __asm volatile
( (
" mov %0, %1 \n"\ " mov %0, %1 \n"
" msr basepri, %0 \n"\ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
" isb \n"\ " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" dsb \n"\ #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" : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );
} }
@ -362,11 +369,17 @@ portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
__asm volatile __asm volatile
( (
" mrs %0, basepri \n"\ " mrs %0, basepri \n"
" mov %1, %2 \n"\ " mov %1, %2 \n"
" msr basepri, %1 \n"\ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
" isb \n"\ " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" dsb \n"\ #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" : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
); );

View File

@ -445,11 +445,11 @@ void xPortPendSVHandler( void )
" \n" " \n"
" stmdb sp!, {r0, r3} \n" " stmdb sp!, {r0, r3} \n"
" mov r0, %0 \n" " mov r0, %0 \n"
" cpsid i \n"/* Errata workaround. */ " cpsid i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" msr basepri, r0 \n" " msr basepri, r0 \n"
" dsb \n" " dsb \n"
" isb \n" " isb \n"
" cpsie i \n"/* Errata workaround. */ " cpsie i \n"/* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
" bl vTaskSwitchContext \n" " bl vTaskSwitchContext \n"
" mov r0, #0 \n" " mov r0, #0 \n"
" msr basepri, r0 \n" " msr basepri, r0 \n"

View File

@ -98,8 +98,8 @@
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) #define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) #define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 /* Constants used to detect Cortex-M7 r0p0 and r0p1 cores, and ensure
* r0p1 port. */ * that a work around is active for errata 837070. */
#define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) ) #define portCPUID ( *( ( volatile uint32_t * ) 0xE000ed00 ) )
#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) #define portCORTEX_M7_r0p1_ID ( 0x410FC271UL )
#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) #define portCORTEX_M7_r0p0_ID ( 0x410FC270UL )
@ -350,11 +350,17 @@ BaseType_t xPortStartScheduler( void )
* See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
/* This port can be used on all revisions of the Cortex-M7 core other than /* Errata 837070 workaround must only be enabled on Cortex-M7 r0p0
* the r0p1 parts. r0p1 parts should use the port from the * and r0p1 cores. */
* /source/portable/GCC/ARM_CM7/r0p1 directory. */ #if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); configASSERT( ( portCPUID == portCORTEX_M7_r0p1_ID ) || ( portCPUID == portCORTEX_M7_r0p0_ID ) );
configASSERT( 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 ) #if ( configASSERT_DEFINED == 1 )
{ {

View File

@ -70,9 +70,15 @@ xPortPendSVHandler:
stmdb sp!, {r0, r3} stmdb sp!, {r0, r3}
mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY 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 msr basepri, r0
dsb dsb
isb isb
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
#endif
bl vTaskSwitchContext bl vTaskSwitchContext
mov r0, #0 mov r0, #0
msr basepri, r0 msr basepri, r0

View File

@ -73,6 +73,7 @@ typedef unsigned long UBaseType_t;
* not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* MPU specific constants. */ /* MPU specific constants. */
@ -253,12 +254,23 @@ typedef struct MPU_SETTINGS
extern void vPortEnterCritical( void ); extern void vPortEnterCritical( void );
extern void vPortExitCritical( void ); extern void vPortExitCritical( void );
#define portDISABLE_INTERRUPTS() \ #if( configENABLE_ERRATA_837070_WORKAROUND == 1 )
{ \ #define portDISABLE_INTERRUPTS() \
__set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ); \ { \
__DSB(); \ __disable_interrupt(); \
__ISB(); \ __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 portENABLE_INTERRUPTS() __set_BASEPRI( 0 )
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()

View File

@ -59,6 +59,12 @@
#define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) ) #define portNVIC_SYS_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
#define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) #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. */ /* Constants required to access and manipulate the MPU. */
#define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) ) #define portMPU_TYPE_REG ( *( ( volatile uint32_t * ) 0xe000ed90 ) )
#define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) ) #define portMPU_REGION_BASE_ADDRESS_REG ( *( ( volatile uint32_t * ) 0xe000ed9C ) )
@ -400,6 +406,18 @@ BaseType_t xPortStartScheduler( void )
* See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); 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 ) #if ( configASSERT_DEFINED == 1 )
{ {
volatile uint32_t ulOriginalPriority; volatile uint32_t ulOriginalPriority;
@ -591,9 +609,15 @@ __asm void xPortPendSVHandler( void )
stmdb sp !, { r0, r3 } stmdb sp !, { r0, r3 }
mov r0, # configMAX_SYSCALL_INTERRUPT_PRIORITY 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 msr basepri, r0
dsb dsb
isb isb
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
cpsie i /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */
#endif
bl vTaskSwitchContext bl vTaskSwitchContext
mov r0, #0 mov r0, #0
msr basepri, r0 msr basepri, r0

View File

@ -70,6 +70,7 @@ typedef unsigned long UBaseType_t;
* not need to be guarded with a critical section. */ * not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1 #define portTICK_TYPE_IS_ATOMIC 1
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* MPU specific constants. */ /* MPU specific constants. */
@ -334,9 +335,15 @@ static portFORCE_INLINE void vPortRaiseBASEPRI( void )
/* Set BASEPRI to the max syscall priority to effect a critical /* Set BASEPRI to the max syscall priority to effect a critical
* section. */ * section. */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
cpsid i
#endif
msr basepri, ulNewBASEPRI msr basepri, ulNewBASEPRI
dsb dsb
isb isb
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
cpsie i
#endif
/* *INDENT-ON* */ /* *INDENT-ON* */
} }
} }
@ -366,9 +373,15 @@ static portFORCE_INLINE uint32_t ulPortRaiseBASEPRI( void )
* section. */ * section. */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
mrs ulReturn, basepri mrs ulReturn, basepri
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
cpsid i
#endif
msr basepri, ulNewBASEPRI msr basepri, ulNewBASEPRI
dsb dsb
isb isb
#if ( configENABLE_ERRATA_837070_WORKAROUND == 1 )
cpsie i
#endif
/* *INDENT-ON* */ /* *INDENT-ON* */
} }