From 3ac93107b90683e17c92fc798f080062e6c7d7e8 Mon Sep 17 00:00:00 2001 From: Jeff Tenney Date: Tue, 25 Aug 2026 18:15:01 -0700 Subject: [PATCH 1/4] Restrict configMAX_SYSCALL_INTERRUPT_PRI... for TZ After this commit, configMAX_SYSCALL_INTERRUPT_PRIORITY must have a zero in the least-significant implemented preemption-priority bit in Trustzone applications. This change ensures that interrupts of higher priority are not masked as a result of non-secure interrupt de-prioritization. For example, consider a PE with 4 preemption-priority bits implemented. If configMAX_SYSCALL_INTERRUPT_PRIORITY is 0x50, then non-secure interrupts that use priority 0x40 would also be masked by FreeRTOS critical sections. This is unexpected because 0x40 is a higher priority than 0x50. De-prioritization changes both 0x50 and 0x40 into 0xA0. --- portable/ARMv8M/non_secure/port.c | 86 ++++++++++++++++++------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index 9c3794c6b3..c0cb540086 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -2194,7 +2194,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2202,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2238,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ From 53057f65e47101a7fa8072e03c49217401148969 Mon Sep 17 00:00:00 2001 From: Jeff Tenney Date: Tue, 25 Aug 2026 18:15:48 -0700 Subject: [PATCH 2/4] Optimize SVCall priority on ARMv8-M --- portable/ARMv8M/non_secure/port.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index c0cb540086..e5837f98d8 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2286,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ From 2ec56be2cc603cbf841c33acf88e3612cee493cd Mon Sep 17 00:00:00 2001 From: Jeff Tenney Date: Tue, 25 Aug 2026 18:48:19 -0700 Subject: [PATCH 3/4] Run copy_files.py --- portable/GCC/ARM_CM23/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM23_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM33/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM33_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM35P/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM35P_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM52/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM52_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM55/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM55_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM85/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_CM85_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/GCC/ARM_STAR_MC3/non_secure/port.c | 89 +++++++++++-------- .../GCC/ARM_STAR_MC3_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM23/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM23_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM33/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM33_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM35P/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM35P_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM52/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM52_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM55/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM55_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM85/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_CM85_NTZ/non_secure/port.c | 89 +++++++++++-------- portable/IAR/ARM_STAR_MC3/non_secure/port.c | 89 +++++++++++-------- .../IAR/ARM_STAR_MC3_NTZ/non_secure/port.c | 89 +++++++++++-------- 28 files changed, 1484 insertions(+), 1008 deletions(-) diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM52/non_secure/port.c b/portable/GCC/ARM_CM52/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM52/non_secure/port.c +++ b/portable/GCC/ARM_CM52/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM52_NTZ/non_secure/port.c b/portable/GCC/ARM_CM52_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM52_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM52_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_STAR_MC3/non_secure/port.c b/portable/GCC/ARM_STAR_MC3/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_STAR_MC3/non_secure/port.c +++ b/portable/GCC/ARM_STAR_MC3/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c b/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM52/non_secure/port.c b/portable/IAR/ARM_CM52/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM52/non_secure/port.c +++ b/portable/IAR/ARM_CM52/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM52_NTZ/non_secure/port.c b/portable/IAR/ARM_CM52_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM52_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM52_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_STAR_MC3/non_secure/port.c b/portable/IAR/ARM_STAR_MC3/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_STAR_MC3/non_secure/port.c +++ b/portable/IAR/ARM_STAR_MC3/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c b/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c index 9c3794c6b3..e5837f98d8 100644 --- a/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c @@ -103,6 +103,7 @@ typedef void ( * portISR_t )( void ); #define portMIN_INTERRUPT_PRIORITY ( 255UL ) #define portNVIC_PENDSV_PRI ( portMIN_INTERRUPT_PRIORITY << 16UL ) #define portNVIC_SYSTICK_PRI ( portMIN_INTERRUPT_PRIORITY << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) /*-----------------------------------------------------------*/ /** @@ -2194,7 +2195,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ { #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) { - volatile uint32_t ulImplementedPrioBits = 0; + volatile uint32_t ulNumPreemptPrioBits = 0; volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API @@ -2202,12 +2203,30 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * "FromISR". FreeRTOS maintains separate thread and ISR API functions to * ensure interrupt entry is as fast and simple as possible. * - * First, determine the number of priority bits available. Write to all - * possible bits in the priority setting for SVCall. */ - portNVIC_SHPR2_REG = 0xFF000000; + * First, determine the number of preemption priority bits available. + * Write to all 7 possible bits in the priority setting for SVCall. If + * the hardware implements 8 bits, the least-significant bit is used for + * sub-priority, not preemption priority, so we don't need check that + * bit. */ + portNVIC_SHPR2_REG = 0xFE000000; /* Read the value back to see how many bits stuck. */ - ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFF000000 ) >> 24 ); + ucMaxPriorityValue = ( uint8_t ) ( ( portNVIC_SHPR2_REG & 0xFE000000 ) >> 24 ); + + #if ( configENABLE_TRUSTZONE == 1 ) + { + /* In TrustZone applications, the maximum value must not use the + * least-significant bit of preemption priority. That bit must be + * zero because the hardware ignores it during de-prioritization of + * non-secure exceptions. */ + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + + /* Initialize the counter of preemption-priority bits to 1 instead + * of 0. The work of counting the implemented preemption-priority + * bits continues further below. */ + ulNumPreemptPrioBits = 1; + } + #endif /* #if ( configENABLE_TRUSTZONE == 1 ) */ /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; @@ -2220,44 +2239,42 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ configASSERT( ucMaxSysCallPriority ); - /* Check that the bits not implemented in hardware are zero in - * configMAX_SYSCALL_INTERRUPT_PRIORITY. */ + /* Check that the bits not implemented in hardware as preemption- + * priority bits are zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. + * + * In TrustZone applications, this check also ensures that the least- + * significant preemption-priority bit is zero in + * configMAX_SYSCALL_INTERRUPT_PRIORITY. The hardware ignores that bit + * when de-prioritizing non-secure exceptions, so it must be zero to + * ensure that the maximum system call priority is not higher than the + * application writer expects. + * + * This check also ensures that the sub-priority bit (if present) is + * zero in configMAX_SYSCALL_INTERRUPT_PRIORITY. When the hardware + * implements 8 priority bits, there is no way for the software to + * configure PRIGROUP to not have sub-priorities. As a result, the + * least significant bit is always used for sub-priority, and there are + * 128 preemption priorities and 2 sub-priorities. + * + * This may cause some confusion in some cases - for example, if + * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 + * priority interrupts will be masked in Critical Sections as those + * are at the same preemption priority. This may appear confusing as + * 4 is higher (numerically lower) priority than + * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not + * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY + * to 4, this confusion does not happen and the behaviour remains the same. */ configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & ( uint8_t ) ( ~( uint32_t ) ucMaxPriorityValue ) ) == 0U ); /* Calculate the maximum acceptable priority group value for the number - * of bits read back. */ + * of preemption-priority bits implemented in the hardware. */ while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { - ulImplementedPrioBits++; + ulNumPreemptPrioBits++; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } - if( ulImplementedPrioBits == 8 ) - { - /* When the hardware implements 8 priority bits, there is no way for - * the software to configure PRIGROUP to not have sub-priorities. As - * a result, the least significant bit is always used for sub-priority - * and there are 128 preemption priorities and 2 sub-priorities. - * - * This may cause some confusion in some cases - for example, if - * configMAX_SYSCALL_INTERRUPT_PRIORITY is set to 5, both 5 and 4 - * priority interrupts will be masked in Critical Sections as those - * are at the same preemption priority. This may appear confusing as - * 4 is higher (numerically lower) priority than - * configMAX_SYSCALL_INTERRUPT_PRIORITY and therefore, should not - * have been masked. Instead, if we set configMAX_SYSCALL_INTERRUPT_PRIORITY - * to 4, this confusion does not happen and the behaviour remains the same. - * - * The following assert ensures that the sub-priority bit in the - * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned - * confusion. */ - configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY & 0x1U ) == 0U ); - ulMaxPRIGROUPValue = 0; - } - else - { - ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulImplementedPrioBits; - } + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS - ulNumPreemptPrioBits; /* Shift the priority group value back to its position within the AIRCR * register. */ @@ -2270,7 +2287,7 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ * the highest priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; - portNVIC_SHPR2_REG = 0; + portNVIC_SHPR2_REG = portNVIC_SVC_PRI; } /*-----------------------------------------------------------*/ From 3bcd72ce1aa5be3143b82642bae08967b27ce6b8 Mon Sep 17 00:00:00 2001 From: Jeff Tenney Date: Tue, 25 Aug 2026 22:30:51 -0700 Subject: [PATCH 4/4] Update old comment about SVCall priority --- portable/ARMv8M/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM23/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM23_NTZ/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM33/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM33_NTZ/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM35P/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM35P_NTZ/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM52/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM52_NTZ/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM55/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM55_NTZ/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM85/non_secure/port.c | 4 ++-- portable/GCC/ARM_CM85_NTZ/non_secure/port.c | 4 ++-- portable/GCC/ARM_STAR_MC3/non_secure/port.c | 4 ++-- portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM23/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM23_NTZ/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM33/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM33_NTZ/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM35P/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM35P_NTZ/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM52/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM52_NTZ/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM55/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM55_NTZ/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM85/non_secure/port.c | 4 ++-- portable/IAR/ARM_CM85_NTZ/non_secure/port.c | 4 ++-- portable/IAR/ARM_STAR_MC3/non_secure/port.c | 4 ++-- portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c | 4 ++-- 29 files changed, 58 insertions(+), 58 deletions(-) diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM52/non_secure/port.c b/portable/GCC/ARM_CM52/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM52/non_secure/port.c +++ b/portable/GCC/ARM_CM52/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM52_NTZ/non_secure/port.c b/portable/GCC/ARM_CM52_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM52_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM52_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_STAR_MC3/non_secure/port.c b/portable/GCC/ARM_STAR_MC3/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_STAR_MC3/non_secure/port.c +++ b/portable/GCC/ARM_STAR_MC3/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c b/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_STAR_MC3_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM52/non_secure/port.c b/portable/IAR/ARM_CM52/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM52/non_secure/port.c +++ b/portable/IAR/ARM_CM52/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM52_NTZ/non_secure/port.c b/portable/IAR/ARM_CM52_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM52_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM52_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_STAR_MC3/non_secure/port.c b/portable/IAR/ARM_STAR_MC3/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_STAR_MC3/non_secure/port.c +++ b/portable/IAR/ARM_STAR_MC3/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI; diff --git a/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c b/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c index e5837f98d8..463149be41 100644 --- a/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_STAR_MC3_NTZ/non_secure/port.c @@ -2283,8 +2283,8 @@ void vPortConfigureInterruptPriorities( void ) /* PRIVILEGED_FUNCTION */ } #endif /* #if ( ( configASSERT_DEFINED == 1 ) && ( portHAS_ARMV8M_MAIN_EXTENSION == 1 ) ) */ - /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall - * the highest priority. */ + /* Make PendSV and SysTick the lowest priority interrupts, and configure + * SVCall for sufficient preemption priority. */ portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI; portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI; portNVIC_SHPR2_REG = portNVIC_SVC_PRI;