From ae46383c90d5eacb3dfa0cb9d2086e1ce7506c59 Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Wed, 1 Jul 2026 23:28:41 +0530 Subject: [PATCH 1/5] Fix vPortFreeSecureContext to read xSecureContext at correct offset (#1441) When MPU is enabled, the first item in the TCB is not the top of the stack but the stored context location. As a result, xSecureContext is located at a negative offset from that position rather than at offset 0. The current implementation unconditionally reads xSecureContext at offset 0, which returns an incorrect value when MPU is enabled. This commit updates vPortFreeSecureContext to read xSecureContext at the correcct offset based on the port configuration: - CM33/CM35P/CM52/CM55/CM85/STAR_MC3: -20 (or -36 with PAC enabled) - CM23: -20 (no PAC support) - Without MPU: 0 (xSecureContext remains at the top of stack) Signed-off-by: Gaurav Aggarwal --- .../non_secure/portable/GCC/ARM_CM23/portasm.c | 15 +++++++++++---- .../non_secure/portable/GCC/ARM_CM33/portasm.c | 18 ++++++++++++++---- .../non_secure/portable/IAR/ARM_CM23/portasm.s | 11 +++++++++-- .../non_secure/portable/IAR/ARM_CM33/portasm.s | 14 ++++++++++++-- portable/GCC/ARM_CM23/non_secure/portasm.c | 15 +++++++++++---- portable/GCC/ARM_CM33/non_secure/portasm.c | 18 ++++++++++++++---- portable/GCC/ARM_CM35P/non_secure/portasm.c | 18 ++++++++++++++---- portable/GCC/ARM_CM52/non_secure/portasm.c | 18 ++++++++++++++---- portable/GCC/ARM_CM55/non_secure/portasm.c | 18 ++++++++++++++---- portable/GCC/ARM_CM85/non_secure/portasm.c | 18 ++++++++++++++---- portable/GCC/ARM_STAR_MC3/non_secure/portasm.c | 18 ++++++++++++++---- portable/IAR/ARM_CM23/non_secure/portasm.s | 11 +++++++++-- portable/IAR/ARM_CM33/non_secure/portasm.s | 14 ++++++++++++-- portable/IAR/ARM_CM35P/non_secure/portasm.s | 14 ++++++++++++-- portable/IAR/ARM_CM52/non_secure/portasm.s | 14 ++++++++++++-- portable/IAR/ARM_CM55/non_secure/portasm.s | 14 ++++++++++++-- portable/IAR/ARM_CM85/non_secure/portasm.s | 14 ++++++++++++-- portable/IAR/ARM_STAR_MC3/non_secure/portasm.s | 14 ++++++++++++-- 18 files changed, 222 insertions(+), 54 deletions(-) diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c index 978d35259..b584c63e7 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c @@ -47,6 +47,12 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +#if ( configENABLE_MPU == 1 ) + #define SECURE_CONTEXT_OFFSET -20 +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -590,15 +596,16 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " adds r2, r2, %0 \n" /* r2 = r2 + SECURE_CONTEXT_OFFSET. */ + " ldr r1, [r2] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " bne free_secure_context \n" /* Branch if r1 != 0. */ " bx lr \n" /* There is no secure context (xSecureContext is NULL). */ " free_secure_context: \n" - " svc %0 \n" /* Secure context is freed in the supervisor call. */ + " svc %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c index 0ebbe48a4..d6c0348d9 100644 --- a/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c +++ b/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33/portasm.c @@ -45,6 +45,16 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -609,13 +619,13 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " ldr r1, [r2, %0] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" - " svcne %0 \n" /* Secure context is freed in the supervisor call. */ + " svcne %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s index 6817abd7a..d8e0abf79 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s @@ -40,6 +40,12 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #define SECURE_CONTEXT_OFFSET -20 +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext @@ -512,8 +518,9 @@ SVC_Handler: /*-----------------------------------------------------------*/ vPortFreeSecureContext: - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + adds r2, r2, #SECURE_CONTEXT_OFFSET /* r2 = r2 + SECURE_CONTEXT_OFFSET. */ + ldr r1, [r2] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ bne free_secure_context /* Branch if r1 != 0. */ bx lr /* There is no secure context (xSecureContext is NULL). */ diff --git a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s index 8d5988819..47fcfa15b 100644 --- a/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s +++ b/portable/ARMv8M/non_secure/portable/IAR/ARM_CM33/portasm.s @@ -41,6 +41,16 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -532,8 +542,8 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + ldr r1, [r2, #SECURE_CONTEXT_OFFSET] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */ diff --git a/portable/GCC/ARM_CM23/non_secure/portasm.c b/portable/GCC/ARM_CM23/non_secure/portasm.c index 978d35259..b584c63e7 100644 --- a/portable/GCC/ARM_CM23/non_secure/portasm.c +++ b/portable/GCC/ARM_CM23/non_secure/portasm.c @@ -47,6 +47,12 @@ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0. #endif +#if ( configENABLE_MPU == 1 ) + #define SECURE_CONTEXT_OFFSET -20 +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -590,15 +596,16 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " adds r2, r2, %0 \n" /* r2 = r2 + SECURE_CONTEXT_OFFSET. */ + " ldr r1, [r2] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " bne free_secure_context \n" /* Branch if r1 != 0. */ " bx lr \n" /* There is no secure context (xSecureContext is NULL). */ " free_secure_context: \n" - " svc %0 \n" /* Secure context is freed in the supervisor call. */ + " svc %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM33/non_secure/portasm.c b/portable/GCC/ARM_CM33/non_secure/portasm.c index 0ebbe48a4..d6c0348d9 100644 --- a/portable/GCC/ARM_CM33/non_secure/portasm.c +++ b/portable/GCC/ARM_CM33/non_secure/portasm.c @@ -45,6 +45,16 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -609,13 +619,13 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " ldr r1, [r2, %0] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" - " svcne %0 \n" /* Secure context is freed in the supervisor call. */ + " svcne %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM35P/non_secure/portasm.c b/portable/GCC/ARM_CM35P/non_secure/portasm.c index 0ebbe48a4..d6c0348d9 100644 --- a/portable/GCC/ARM_CM35P/non_secure/portasm.c +++ b/portable/GCC/ARM_CM35P/non_secure/portasm.c @@ -45,6 +45,16 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -609,13 +619,13 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " ldr r1, [r2, %0] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" - " svcne %0 \n" /* Secure context is freed in the supervisor call. */ + " svcne %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM52/non_secure/portasm.c b/portable/GCC/ARM_CM52/non_secure/portasm.c index 0ebbe48a4..d6c0348d9 100644 --- a/portable/GCC/ARM_CM52/non_secure/portasm.c +++ b/portable/GCC/ARM_CM52/non_secure/portasm.c @@ -45,6 +45,16 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -609,13 +619,13 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " ldr r1, [r2, %0] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" - " svcne %0 \n" /* Secure context is freed in the supervisor call. */ + " svcne %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM55/non_secure/portasm.c b/portable/GCC/ARM_CM55/non_secure/portasm.c index 0ebbe48a4..d6c0348d9 100644 --- a/portable/GCC/ARM_CM55/non_secure/portasm.c +++ b/portable/GCC/ARM_CM55/non_secure/portasm.c @@ -45,6 +45,16 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -609,13 +619,13 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " ldr r1, [r2, %0] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" - " svcne %0 \n" /* Secure context is freed in the supervisor call. */ + " svcne %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_CM85/non_secure/portasm.c b/portable/GCC/ARM_CM85/non_secure/portasm.c index 0ebbe48a4..d6c0348d9 100644 --- a/portable/GCC/ARM_CM85/non_secure/portasm.c +++ b/portable/GCC/ARM_CM85/non_secure/portasm.c @@ -45,6 +45,16 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -609,13 +619,13 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " ldr r1, [r2, %0] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" - " svcne %0 \n" /* Secure context is freed in the supervisor call. */ + " svcne %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/GCC/ARM_STAR_MC3/non_secure/portasm.c b/portable/GCC/ARM_STAR_MC3/non_secure/portasm.c index 0ebbe48a4..d6c0348d9 100644 --- a/portable/GCC/ARM_STAR_MC3/non_secure/portasm.c +++ b/portable/GCC/ARM_STAR_MC3/non_secure/portasm.c @@ -45,6 +45,16 @@ * header files. */ #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + #if ( configENABLE_MPU == 1 ) void vRestoreContextOfFirstTask( void ) /* __attribute__ (( naked )) PRIVILEGED_FUNCTION */ @@ -609,13 +619,13 @@ void vPortFreeSecureContext( uint32_t * pulTCB ) /* __attribute__ (( naked )) PR ( " .syntax unified \n" " \n" - " ldr r2, [r0] \n" /* The first item in the TCB is the top of the stack. */ - " ldr r1, [r2] \n" /* The first item on the stack is the task's xSecureContext. */ + " ldr r2, [r0] \n" /* The first item in the TCB is the stored context location. */ + " ldr r1, [r2, %0] \n" /* Read xSecureContext from the task's context. */ " cmp r1, #0 \n" /* Raise svc if task's xSecureContext is not NULL. */ " it ne \n" - " svcne %0 \n" /* Secure context is freed in the supervisor call. */ + " svcne %1 \n" /* Secure context is freed in the supervisor call. */ " bx lr \n" /* Return. */ - ::"i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" + ::"i" ( SECURE_CONTEXT_OFFSET ), "i" ( portSVC_FREE_SECURE_CONTEXT ) : "memory" ); } /*-----------------------------------------------------------*/ diff --git a/portable/IAR/ARM_CM23/non_secure/portasm.s b/portable/IAR/ARM_CM23/non_secure/portasm.s index 6817abd7a..d8e0abf79 100644 --- a/portable/IAR/ARM_CM23/non_secure/portasm.s +++ b/portable/IAR/ARM_CM23/non_secure/portasm.s @@ -40,6 +40,12 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #define SECURE_CONTEXT_OFFSET -20 +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext @@ -512,8 +518,9 @@ SVC_Handler: /*-----------------------------------------------------------*/ vPortFreeSecureContext: - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + adds r2, r2, #SECURE_CONTEXT_OFFSET /* r2 = r2 + SECURE_CONTEXT_OFFSET. */ + ldr r1, [r2] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ bne free_secure_context /* Branch if r1 != 0. */ bx lr /* There is no secure context (xSecureContext is NULL). */ diff --git a/portable/IAR/ARM_CM33/non_secure/portasm.s b/portable/IAR/ARM_CM33/non_secure/portasm.s index 8d5988819..47fcfa15b 100644 --- a/portable/IAR/ARM_CM33/non_secure/portasm.s +++ b/portable/IAR/ARM_CM33/non_secure/portasm.s @@ -41,6 +41,16 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -532,8 +542,8 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + ldr r1, [r2, #SECURE_CONTEXT_OFFSET] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */ diff --git a/portable/IAR/ARM_CM35P/non_secure/portasm.s b/portable/IAR/ARM_CM35P/non_secure/portasm.s index 8d5988819..47fcfa15b 100644 --- a/portable/IAR/ARM_CM35P/non_secure/portasm.s +++ b/portable/IAR/ARM_CM35P/non_secure/portasm.s @@ -41,6 +41,16 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -532,8 +542,8 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + ldr r1, [r2, #SECURE_CONTEXT_OFFSET] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */ diff --git a/portable/IAR/ARM_CM52/non_secure/portasm.s b/portable/IAR/ARM_CM52/non_secure/portasm.s index 8d5988819..47fcfa15b 100644 --- a/portable/IAR/ARM_CM52/non_secure/portasm.s +++ b/portable/IAR/ARM_CM52/non_secure/portasm.s @@ -41,6 +41,16 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -532,8 +542,8 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + ldr r1, [r2, #SECURE_CONTEXT_OFFSET] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */ diff --git a/portable/IAR/ARM_CM55/non_secure/portasm.s b/portable/IAR/ARM_CM55/non_secure/portasm.s index 8d5988819..47fcfa15b 100644 --- a/portable/IAR/ARM_CM55/non_secure/portasm.s +++ b/portable/IAR/ARM_CM55/non_secure/portasm.s @@ -41,6 +41,16 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -532,8 +542,8 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + ldr r1, [r2, #SECURE_CONTEXT_OFFSET] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */ diff --git a/portable/IAR/ARM_CM85/non_secure/portasm.s b/portable/IAR/ARM_CM85/non_secure/portasm.s index 8d5988819..47fcfa15b 100644 --- a/portable/IAR/ARM_CM85/non_secure/portasm.s +++ b/portable/IAR/ARM_CM85/non_secure/portasm.s @@ -41,6 +41,16 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -532,8 +542,8 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + ldr r1, [r2, #SECURE_CONTEXT_OFFSET] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */ diff --git a/portable/IAR/ARM_STAR_MC3/non_secure/portasm.s b/portable/IAR/ARM_STAR_MC3/non_secure/portasm.s index 8d5988819..47fcfa15b 100644 --- a/portable/IAR/ARM_STAR_MC3/non_secure/portasm.s +++ b/portable/IAR/ARM_STAR_MC3/non_secure/portasm.s @@ -41,6 +41,16 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler. #define configUSE_MPU_WRAPPERS_V1 0 #endif +#if ( configENABLE_MPU == 1 ) + #if ( configENABLE_PAC == 1 ) + #define SECURE_CONTEXT_OFFSET -36 + #else + #define SECURE_CONTEXT_OFFSET -20 + #endif +#else + #define SECURE_CONTEXT_OFFSET 0 +#endif + EXTERN pxCurrentTCB EXTERN xSecureContext EXTERN vTaskSwitchContext @@ -532,8 +542,8 @@ SVC_Handler: vPortFreeSecureContext: /* r0 = uint32_t *pulTCB. */ - ldr r2, [r0] /* The first item in the TCB is the top of the stack. */ - ldr r1, [r2] /* The first item on the stack is the task's xSecureContext. */ + ldr r2, [r0] /* The first item in the TCB is the stored context location. */ + ldr r1, [r2, #SECURE_CONTEXT_OFFSET] /* Read xSecureContext from the task's context. */ cmp r1, #0 /* Raise svc if task's xSecureContext is not NULL. */ it ne svcne 101 /* Secure context is freed in the supervisor call. portSVC_FREE_SECURE_CONTEXT = 101. */ From a50edad08b29052631aa469d4df6e6ec7ff68878 Mon Sep 17 00:00:00 2001 From: Anubhav Rawal Date: Wed, 8 Jul 2026 17:38:51 -0700 Subject: [PATCH 2/5] fix: Add MPU wrapper for xTimerDelete API (#1412) When using MPU wrappers v2, xTimerDelete needs to be a real function rather than a macro so that the kernel object pool index can be freed after the timer is successfully deleted. Without this, deleting a timer leaks the kernel object pool entry. Signed-off-by: Gaurav Aggarwal Co-authored-by: Gaurav Aggarwal --- include/mpu_prototypes.h | 3 +++ include/mpu_wrappers.h | 1 + include/timers.h | 7 ++++++- portable/Common/mpu_wrappers_v2.c | 34 +++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/mpu_prototypes.h b/include/mpu_prototypes.h index b4c0f4745..d8dc56a48 100644 --- a/include/mpu_prototypes.h +++ b/include/mpu_prototypes.h @@ -369,6 +369,9 @@ BaseType_t MPU_xTimerGenericCommandFromISR( TimerHandle_t xTimer, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t MPU_xTimerDelete( TimerHandle_t xTimer, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + /* MPU versions of event_group.h API functions. */ EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, diff --git a/include/mpu_wrappers.h b/include/mpu_wrappers.h index 3b4738e96..3de2013ce 100644 --- a/include/mpu_wrappers.h +++ b/include/mpu_wrappers.h @@ -190,6 +190,7 @@ #define xTimerCreateStatic MPU_xTimerCreateStatic #define xTimerGetStaticBuffer MPU_xTimerGetStaticBuffer #define xTimerGenericCommandFromISR MPU_xTimerGenericCommandFromISR + #define xTimerDelete MPU_xTimerDelete #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ /* Map standard event_group.h API functions to the MPU equivalents. */ diff --git a/include/timers.h b/include/timers.h index 7d99d3536..191703928 100644 --- a/include/timers.h +++ b/include/timers.h @@ -667,8 +667,13 @@ TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; * * See the xTimerChangePeriod() API function example usage scenario. */ -#define xTimerDelete( xTimer, xTicksToWait ) \ +#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) + BaseType_t xTimerDelete( TimerHandle_t xTimer, + TickType_t xTicksToWait ); +#else + #define xTimerDelete( xTimer, xTicksToWait ) \ xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) +#endif /** * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); diff --git a/portable/Common/mpu_wrappers_v2.c b/portable/Common/mpu_wrappers_v2.c index 70082b829..612cbae18 100644 --- a/portable/Common/mpu_wrappers_v2.c +++ b/portable/Common/mpu_wrappers_v2.c @@ -3890,6 +3890,40 @@ #endif /* if ( configUSE_TIMERS == 1 ) */ /*-----------------------------------------------------------*/ + #if ( configUSE_TIMERS == 1 ) + + BaseType_t MPU_xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ) /* PRIVILEGED_FUNCTION */ + { + BaseType_t xReturn = pdFALSE; + TimerHandle_t xInternalTimerHandle = NULL; + int32_t lIndex; + + lIndex = ( int32_t ) xTimer; + + if( IS_EXTERNAL_INDEX_VALID( lIndex ) != pdFALSE ) + { + xInternalTimerHandle = MPU_GetTimerHandleAtIndex( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + + if( xInternalTimerHandle != NULL ) + { + xReturn = xTimerGenericCommandFromTask( xInternalTimerHandle, + tmrCOMMAND_DELETE, + 0U, /* xOptionalValue */ + NULL, /* pxHigherPriorityTaskWoken */ + xTicksToWait ); + if( xReturn != pdFALSE ) + { + MPU_SetIndexFreeInKernelObjectPool( CONVERT_TO_INTERNAL_INDEX( lIndex ) ); + } + } + } + + return xReturn; + } + + #endif /* if ( configUSE_TIMERS == 1 ) */ +/*-----------------------------------------------------------*/ + /*-----------------------------------------------------------*/ /* MPU wrappers for event group APIs. */ /*-----------------------------------------------------------*/ From d72263b404d925d313c7cd5400513ef1f8822d31 Mon Sep 17 00:00:00 2001 From: wanghengZzz <150767771+wanghengZzz@users.noreply.github.com> Date: Fri, 10 Jul 2026 02:55:17 +0800 Subject: [PATCH 3/5] fix copy-paste comment typos in xTaskGetApplicationTaskTagFromISR and xTaskGetApplicationTaskTag (#1446) --- tasks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks.c b/tasks.c index 461271fcf..3c97d3c2f 100644 --- a/tasks.c +++ b/tasks.c @@ -5035,11 +5035,11 @@ BaseType_t xTaskIncrementTick( void ) traceENTER_xTaskGetApplicationTaskTag( xTask ); - /* If xTask is NULL then set the calling task's hook. */ + /* If xTask is NULL then get the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); configASSERT( pxTCB != NULL ); - /* Save the hook function in the TCB. A critical section is required as + /* Access the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ taskENTER_CRITICAL(); { @@ -5065,11 +5065,11 @@ BaseType_t xTaskIncrementTick( void ) traceENTER_xTaskGetApplicationTaskTagFromISR( xTask ); - /* If xTask is NULL then set the calling task's hook. */ + /* If xTask is NULL then get the calling task's hook. */ pxTCB = prvGetTCBFromHandle( xTask ); configASSERT( pxTCB != NULL ); - /* Save the hook function in the TCB. A critical section is required as + /* Access the hook function in the TCB. A critical section is required as * the value can be accessed from an interrupt. */ /* MISRA Ref 4.7.1 [Return value shall be checked] */ /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */ From 9db704cd3bbe4963f9bd3de1f1161ea2cf90768b Mon Sep 17 00:00:00 2001 From: Old-Ding <35417409+Old-Ding@users.noreply.github.com> Date: Fri, 10 Jul 2026 08:31:36 +0800 Subject: [PATCH 4/5] docs: clarify MPU region parameter macros (#1445) Document that MemoryRegion_t.ulParameters macros are port specific so users select the tskMPU_REGION_* or portMPU_REGION_* values that match their MPU port. Signed-off-by: Old-Ding Co-authored-by: Old-Ding --- include/task.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/task.h b/include/task.h index 2add58b94..5353dc694 100644 --- a/include/task.h +++ b/include/task.h @@ -548,6 +548,14 @@ typedef enum * The function parameters define the memory regions and associated access * permissions allocated to the task. * + * The parameter macros used in MemoryRegion_t.ulParameters are port specific. + * Some ports, including the Cortex-M3/4 MPU ports, use the portMPU_REGION_* + * values shown below. + * ARMv8-M MPU ports, such as CM23, CM33, CM52, CM55, CM85 and STAR_MC3, use + * the tskMPU_REGION_* values defined in this header; the port translates them + * into MPU register settings. Check the selected port's headers before selecting + * the region parameter macros. + * * See xTaskCreateRestrictedStatic() for a version that does not use any * dynamic memory allocation. * @@ -639,6 +647,14 @@ typedef enum * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be * created without using any dynamic memory allocation. * + * The parameter macros used in MemoryRegion_t.ulParameters are port specific. + * Some ports, including the Cortex-M3/4 MPU ports, use the portMPU_REGION_* + * values shown below. + * ARMv8-M MPU ports, such as CM23, CM33, CM52, CM55, CM85 and STAR_MC3, use + * the tskMPU_REGION_* values defined in this header; the port translates them + * into MPU register settings. Check the selected port's headers before selecting + * the region parameter macros. + * * @param pxTaskDefinition Pointer to a structure that contains a member * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API * documentation) plus an optional stack buffer and the memory region @@ -728,6 +744,14 @@ typedef enum * @param[in] pxRegions A pointer to a MemoryRegion_t structure that contains the * new memory region definitions. * + * The parameter macros used in MemoryRegion_t.ulParameters are port specific. + * Some ports, including the Cortex-M3/4 MPU ports, use the portMPU_REGION_* + * values shown below. + * ARMv8-M MPU ports, such as CM23, CM33, CM52, CM55, CM85 and STAR_MC3, use + * the tskMPU_REGION_* values defined in this header; the port translates them + * into MPU register settings. Check the selected port's headers before selecting + * the region parameter macros. + * * Example usage: * @code{c} * // Define an array of MemoryRegion_t structures that configures an MPU region From 78069a79ea8f9d17c0eae88c417fd41e2c54a2cd Mon Sep 17 00:00:00 2001 From: Kody Stribrny <89810515+kstribrnAmzn@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:15:53 -0700 Subject: [PATCH 5/5] Add usage assertions when deleting a queue (#1449) Adds an assertion which helps to verify a queue is not in use before deletion. --- queue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/queue.c b/queue.c index 37d953ac9..83c7ac730 100644 --- a/queue.c +++ b/queue.c @@ -2261,6 +2261,8 @@ void vQueueDelete( QueueHandle_t xQueue ) traceENTER_vQueueDelete( xQueue ); configASSERT( pxQueue ); + configASSERT( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) ); + configASSERT( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) ); traceQUEUE_DELETE( pxQueue ); #if ( configQUEUE_REGISTRY_SIZE > 0 )