Pre-allocate secure-side context structures
This commit improves ARMv8-M security by pre-allocating secure-side task
context structures and changing how tasks reference a secure-side
context structure when calling a secure function. The new configuration
constant secureconfigMAX_SECURE_CONTEXTS sets the number of secure
context structures to pre-allocate. secureconfigMAX_SECURE_CONTEXTS
defaults to 8 if left undefined.
Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
diff --git a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c
index 047ed8e..8677b22 100644
--- a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c
+++ b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM23/secure_context_port.c
@@ -36,56 +36,60 @@
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
#endif
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, load_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " ldmia r0!, {r1, r2} \n"/* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " ldmia r1!, {r3} \n"/* Read CONTROL register value from task's stack. r3 = CONTROL. */
- " msr control, r3 \n"/* CONTROL = r3. */
+ " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ " msr control, r3 \n" /* CONTROL = r3. */
#endif /* configENABLE_MPU */
- " msr psplim, r2 \n"/* PSPLIM = r2. */
- " msr psp, r1 \n"/* PSP = r1. */
- " \n"
- " load_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " msr psplim, r2 \n" /* PSPLIM = r2. */
+ " msr psp, r1 \n" /* PSP = r1. */
+ " \n"
+ " load_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::: "r0", "r1", "r2"
);
}
/*-----------------------------------------------------------*/
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, save_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " mrs r1, psp \n"/* r1 = PSP. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " mrs r1, psp \n" /* r1 = PSP. */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " mrs r2, control \n"/* r2 = CONTROL. */
- " subs r1, r1, #4 \n"/* Make space for the CONTROL value on the stack. */
- " str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- " stmia r1!, {r2} \n"/* Store CONTROL value on the stack. */
+ " mrs r2, control \n" /* r2 = CONTROL. */
+ " subs r1, r1, #4 \n" /* Make space for the CONTROL value on the stack. */
+ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ " stmia r1!, {r2} \n" /* Store CONTROL value on the stack. */
#else /* configENABLE_MPU */
- " str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
+ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
#endif /* configENABLE_MPU */
- " movs r1, %0 \n"/* r1 = securecontextNO_STACK. */
- " msr psplim, r1 \n"/* PSPLIM = securecontextNO_STACK. */
- " msr psp, r1 \n"/* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
- " \n"
- " save_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
+ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
+ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ " \n"
+ " save_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::"i" ( securecontextNO_STACK ) : "r1", "memory"
);
}
diff --git a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c
index 4c6d0be..0731abe 100644
--- a/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c
+++ b/portable/ARMv8M/secure/context/portable/GCC/ARM_CM33/secure_context_port.c
@@ -32,57 +32,62 @@
/* Secure port macros. */
#include "secure_port_macros.h"
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, load_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " ldmia r0!, {r1, r2} \n"/* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " ldmia r1!, {r3} \n"/* Read CONTROL register value from task's stack. r3 = CONTROL. */
- " msr control, r3 \n"/* CONTROL = r3. */
+ " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ " msr control, r3 \n" /* CONTROL = r3. */
#endif /* configENABLE_MPU */
- " msr psplim, r2 \n"/* PSPLIM = r2. */
- " msr psp, r1 \n"/* PSP = r1. */
- " \n"
- " load_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " msr psplim, r2 \n" /* PSPLIM = r2. */
+ " msr psp, r1 \n" /* PSP = r1. */
+ " \n"
+ " load_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::: "r0", "r1", "r2"
);
}
/*-----------------------------------------------------------*/
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, save_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " mrs r1, psp \n"/* r1 = PSP. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " mrs r1, psp \n" /* r1 = PSP. */
+ " \n"
#if ( configENABLE_FPU == 1 )
- " vstmdb r1!, {s0} \n"/* Trigger the defferred stacking of FPU registers. */
- " vldmia r1!, {s0} \n"/* Nullify the effect of the pervious statement. */
+ " vstmdb r1!, {s0} \n" /* Trigger the defferred stacking of FPU registers. */
+ " vldmia r1!, {s0} \n" /* Nullify the effect of the pervious statement. */
#endif /* configENABLE_FPU */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " mrs r2, control \n"/* r2 = CONTROL. */
- " stmdb r1!, {r2} \n"/* Store CONTROL value on the stack. */
+ " mrs r2, control \n" /* r2 = CONTROL. */
+ " stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */
#endif /* configENABLE_MPU */
- " str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- " movs r1, %0 \n"/* r1 = securecontextNO_STACK. */
- " msr psplim, r1 \n"/* PSPLIM = securecontextNO_STACK. */
- " msr psp, r1 \n"/* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
- " \n"
- " save_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
+ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
+ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ " \n"
+ " save_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::"i" ( securecontextNO_STACK ) : "r1", "memory"
);
}
diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port.c b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port.c
deleted file mode 100644
index d8ca0f5..0000000
--- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * FreeRTOS Kernel <DEVELOPMENT BRANCH>
- * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * SPDX-License-Identifier: MIT
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * https://www.FreeRTOS.org
- * https://github.com/FreeRTOS
- *
- */
-
-/* Secure context includes. */
-#include "secure_context.h"
-
-/* Secure port macros. */
-#include "secure_port_macros.h"
-
-/* Functions implemented in assembler file. */
-extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
-extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
-
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_LoadContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
-
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_SaveContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s
index 8fbb49a..cf245b9 100644
--- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s
+++ b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port_asm.s
@@ -26,52 +26,56 @@
*
*/
- SECTION .text:CODE:NOROOT(2)
- THUMB
+ SECTION .text:CODE:NOROOT(2)
+ THUMB
- PUBLIC SecureContext_LoadContextAsm
- PUBLIC SecureContext_SaveContextAsm
+ PUBLIC SecureContext_LoadContextAsm
+ PUBLIC SecureContext_SaveContextAsm
#if ( configENABLE_FPU == 1 )
- #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
+ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
#endif
/*-----------------------------------------------------------*/
SecureContext_LoadContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
-#if ( configENABLE_MPU == 1 )
- ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
- msr control, r3 /* CONTROL = r3. */
-#endif /* configENABLE_MPU */
- msr psplim, r2 /* PSPLIM = r2. */
- msr psp, r1 /* PSP = r1. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
- load_ctx_therad_mode:
- bx lr
+#if ( configENABLE_MPU == 1 )
+ ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ msr control, r3 /* CONTROL = r3. */
+#endif /* configENABLE_MPU */
+
+ msr psplim, r2 /* PSPLIM = r2. */
+ msr psp, r1 /* PSP = r1. */
+
+ load_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
SecureContext_SaveContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- mrs r1, psp /* r1 = PSP. */
-#if ( configENABLE_MPU == 1 )
- mrs r2, control /* r2 = CONTROL. */
- subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */
- str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- stmia r1!, {r2} /* Store CONTROL value on the stack. */
-#else /* configENABLE_MPU */
- str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
-#endif /* configENABLE_MPU */
- movs r1, #0 /* r1 = securecontextNO_STACK. */
- msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
- msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ mrs r1, psp /* r1 = PSP. */
- save_ctx_therad_mode:
- bx lr
+#if ( configENABLE_MPU == 1 )
+ mrs r2, control /* r2 = CONTROL. */
+ subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */
+ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ stmia r1!, {r2} /* Store CONTROL value on the stack. */
+#else /* configENABLE_MPU */
+ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+#endif /* configENABLE_MPU */
+
+ movs r1, #0 /* r1 = securecontextNO_STACK. */
+ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
+ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+
+ save_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
- END
+ END
diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port.c b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port.c
deleted file mode 100644
index d8ca0f5..0000000
--- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * FreeRTOS Kernel <DEVELOPMENT BRANCH>
- * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * SPDX-License-Identifier: MIT
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * https://www.FreeRTOS.org
- * https://github.com/FreeRTOS
- *
- */
-
-/* Secure context includes. */
-#include "secure_context.h"
-
-/* Secure port macros. */
-#include "secure_port_macros.h"
-
-/* Functions implemented in assembler file. */
-extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
-extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
-
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_LoadContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
-
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_SaveContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
diff --git a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s
index 297679b..0df0a1b 100644
--- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s
+++ b/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port_asm.s
@@ -26,49 +26,54 @@
*
*/
- SECTION .text:CODE:NOROOT(2)
- THUMB
+ SECTION .text:CODE:NOROOT(2)
+ THUMB
- PUBLIC SecureContext_LoadContextAsm
- PUBLIC SecureContext_SaveContextAsm
+ PUBLIC SecureContext_LoadContextAsm
+ PUBLIC SecureContext_SaveContextAsm
/*-----------------------------------------------------------*/
SecureContext_LoadContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
-#if ( configENABLE_MPU == 1 )
- ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
- msr control, r3 /* CONTROL = r3. */
-#endif /* configENABLE_MPU */
- msr psplim, r2 /* PSPLIM = r2. */
- msr psp, r1 /* PSP = r1. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
- load_ctx_therad_mode:
- bx lr
+#if ( configENABLE_MPU == 1 )
+ ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ msr control, r3 /* CONTROL = r3. */
+#endif /* configENABLE_MPU */
+
+ msr psplim, r2 /* PSPLIM = r2. */
+ msr psp, r1 /* PSP = r1. */
+
+ load_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
SecureContext_SaveContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- mrs r1, psp /* r1 = PSP. */
-#if ( configENABLE_FPU == 1 )
- vstmdb r1!, {s0} /* Trigger the defferred stacking of FPU registers. */
- vldmia r1!, {s0} /* Nullify the effect of the pervious statement. */
-#endif /* configENABLE_FPU */
-#if ( configENABLE_MPU == 1 )
- mrs r2, control /* r2 = CONTROL. */
- stmdb r1!, {r2} /* Store CONTROL value on the stack. */
-#endif /* configENABLE_MPU */
- str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- movs r1, #0 /* r1 = securecontextNO_STACK. */
- msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
- msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ mrs r1, psp /* r1 = PSP. */
- save_ctx_therad_mode:
- bx lr
+#if ( configENABLE_FPU == 1 )
+ vstmdb r1!, {s0} /* Trigger the defferred stacking of FPU registers. */
+ vldmia r1!, {s0} /* Nullify the effect of the pervious statement. */
+#endif /* configENABLE_FPU */
+
+#if ( configENABLE_MPU == 1 )
+ mrs r2, control /* r2 = CONTROL. */
+ stmdb r1!, {r2} /* Store CONTROL value on the stack. */
+#endif /* configENABLE_MPU */
+
+ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ movs r1, #0 /* r1 = securecontextNO_STACK. */
+ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
+ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+
+ save_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
- END
+ END
diff --git a/portable/ARMv8M/secure/context/secure_context.c b/portable/ARMv8M/secure/context/secure_context.c
index deede89..96a5662 100644
--- a/portable/ARMv8M/secure/context/secure_context.c
+++ b/portable/ARMv8M/secure/context/secure_context.c
@@ -50,25 +50,74 @@
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
+
+/**
+ * @brief Invalid context ID.
+ */
+#define securecontextINVALID_CONTEXT_ID 0UL
+
+/**
+ * @brief Maximum number of secure contexts.
+ */
+#ifndef secureconfigMAX_SECURE_CONTEXTS
+ #define secureconfigMAX_SECURE_CONTEXTS 8UL
+#endif
/*-----------------------------------------------------------*/
/**
- * @brief Structure to represent secure context.
- *
- * @note Since stack grows down, pucStackStart is the highest address while
- * pucStackLimit is the first addess of the allocated memory.
+ * @brief Pre-allocated array of secure contexts.
*/
-typedef struct SecureContext
+SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Get a free context from the secure context pool (xSecureContexts).
+ *
+ * @return Index of a free context in the xSecureContexts array.
+ */
+static uint32_t ulGetSecureContext( void );
+
+/**
+ * @brief Return the secure context to the secure context pool (xSecureContexts).
+ *
+ * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
+ */
+static void vReturnSecureContext( uint32_t ulSecureContextIndex );
+
+/* These are implemented in assembly. */
+extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
+extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
+/*-----------------------------------------------------------*/
+
+static uint32_t ulGetSecureContext( void )
{
- uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
- uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
- uint8_t * pucStackStart; /**< First location of the stack memory. */
-} SecureContext_t;
+ uint32_t ulSecureContextIndex;
+
+ for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ )
+ {
+ if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) )
+ {
+ break;
+ }
+ }
+
+ return ulSecureContextIndex;
+}
+/*-----------------------------------------------------------*/
+
+static void vReturnSecureContext( uint32_t ulSecureContextIndex )
+{
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
+}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, i;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -81,6 +130,14 @@
secureportSET_PSPLIM( securecontextNO_STACK );
secureportSET_PSP( securecontextNO_STACK );
+ /* Initialize all secure contexts. */
+ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
+ {
+ xSecureContexts[ i ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ i ].pucStackLimit = NULL;
+ xSecureContexts[ i ].pucStackStart = NULL;
+ }
+
#if ( configENABLE_MPU == 1 )
{
/* Configure thread mode to use PSP and to be unprivileged. */
@@ -88,7 +145,7 @@
}
#else /* configENABLE_MPU */
{
- /* Configure thread mode to use PSP and to be privileged.. */
+ /* Configure thread mode to use PSP and to be privileged. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
}
#endif /* configENABLE_MPU */
@@ -104,8 +161,8 @@
#endif /* configENABLE_MPU */
{
uint8_t * pucStackMemory = NULL;
- uint32_t ulIPSR;
- SecureContextHandle_t xSecureContextHandle = NULL;
+ uint32_t ulIPSR, ulSecureContextIndex;
+ SecureContextHandle_t xSecureContextHandle;
#if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL;
@@ -118,10 +175,11 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Allocate the context structure. */
- xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
+ /* Ontain a free secure context. */
+ ulSecureContextIndex = ulGetSecureContext();
- if( xSecureContextHandle != NULL )
+ /* Were we able to get a free context? */
+ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
{
/* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize );
@@ -134,18 +192,18 @@
* pointer before writing i.e. if stack pointer is 0x2, a push
* operation will decrement the stack pointer to 0x1 and then
* write at 0x1. */
- xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
/* The stack cannot go beyond this location. This value is
* programmed in the PSPLIM register on context switch.*/
- xSecureContextHandle->pucStackLimit = pucStackMemory;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
#if ( configENABLE_MPU == 1 )
{
/* Store the correct CONTROL value for the task on the stack.
* This value is programmed in the CONTROL register on
* context switch. */
- pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
+ pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
pulCurrentStackPointer--;
if( ulIsTaskPrivileged )
@@ -159,22 +217,22 @@
/* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
}
#else /* configENABLE_MPU */
{
/* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
}
#endif /* configENABLE_MPU */
+
+ /* Ensure to never return 0 as a valid context handle. */
+ xSecureContextHandle = ulSecureContextIndex + 1UL;
}
else
{
- /* Free the context to avoid memory leak and make sure to return
- * NULL to indicate failure. */
- vPortFree( xSecureContextHandle );
- xSecureContextHandle = NULL;
+ xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
}
}
}
@@ -185,7 +243,7 @@
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, ulSecureContextIndex;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -194,14 +252,43 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Ensure that valid parameters are passed. */
- secureportASSERT( xSecureContextHandle != NULL );
+ /* Only free if a valid context handle is passed. */
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
- /* Free the stack space. */
- vPortFree( xSecureContextHandle->pucStackLimit );
+ /* Free the stack space. */
+ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
- /* Free the context itself. */
- vPortFree( xSecureContextHandle );
+ /* Return the context back to the free contexts pool. */
+ vReturnSecureContext( ulSecureContextIndex );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
}
}
/*-----------------------------------------------------------*/
diff --git a/portable/ARMv8M/secure/context/secure_context.h b/portable/ARMv8M/secure/context/secure_context.h
index 77a9332..b7a3ba5 100644
--- a/portable/ARMv8M/secure/context/secure_context.h
+++ b/portable/ARMv8M/secure/context/secure_context.h
@@ -36,15 +36,29 @@
#include "FreeRTOSConfig.h"
/**
- * @brief PSP value when no task's context is loaded.
+ * @brief PSP value when no secure context is loaded.
*/
#define securecontextNO_STACK 0x0
+/*-----------------------------------------------------------*/
/**
- * @brief Opaque handle.
+ * @brief Structure to represent a secure context.
+ *
+ * @note Since stack grows down, pucStackStart is the highest address while
+ * pucStackLimit is the first address of the allocated memory.
*/
-struct SecureContext;
-typedef struct SecureContext * SecureContextHandle_t;
+typedef struct SecureContext
+{
+ uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
+ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
+ uint8_t * pucStackStart; /**< First location of the stack memory. */
+} SecureContext_t;
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Opaque handle for a secure context.
+ */
+typedef uint32_t SecureContextHandle_t;
/*-----------------------------------------------------------*/
/**
diff --git a/portable/ARMv8M/secure/heap/secure_heap.c b/portable/ARMv8M/secure/heap/secure_heap.c
index 0100ad0..099b01f 100644
--- a/portable/ARMv8M/secure/heap/secure_heap.c
+++ b/portable/ARMv8M/secure/heap/secure_heap.c
@@ -38,7 +38,9 @@
/**
* @brief Total heap size.
*/
-#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#ifndef secureconfigTOTAL_HEAP_SIZE
+ #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#endif
/* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER
diff --git a/portable/GCC/ARM_CM23/secure/secure_context.c b/portable/GCC/ARM_CM23/secure/secure_context.c
index deede89..96a5662 100644
--- a/portable/GCC/ARM_CM23/secure/secure_context.c
+++ b/portable/GCC/ARM_CM23/secure/secure_context.c
@@ -50,25 +50,74 @@
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
+
+/**
+ * @brief Invalid context ID.
+ */
+#define securecontextINVALID_CONTEXT_ID 0UL
+
+/**
+ * @brief Maximum number of secure contexts.
+ */
+#ifndef secureconfigMAX_SECURE_CONTEXTS
+ #define secureconfigMAX_SECURE_CONTEXTS 8UL
+#endif
/*-----------------------------------------------------------*/
/**
- * @brief Structure to represent secure context.
- *
- * @note Since stack grows down, pucStackStart is the highest address while
- * pucStackLimit is the first addess of the allocated memory.
+ * @brief Pre-allocated array of secure contexts.
*/
-typedef struct SecureContext
+SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Get a free context from the secure context pool (xSecureContexts).
+ *
+ * @return Index of a free context in the xSecureContexts array.
+ */
+static uint32_t ulGetSecureContext( void );
+
+/**
+ * @brief Return the secure context to the secure context pool (xSecureContexts).
+ *
+ * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
+ */
+static void vReturnSecureContext( uint32_t ulSecureContextIndex );
+
+/* These are implemented in assembly. */
+extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
+extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
+/*-----------------------------------------------------------*/
+
+static uint32_t ulGetSecureContext( void )
{
- uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
- uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
- uint8_t * pucStackStart; /**< First location of the stack memory. */
-} SecureContext_t;
+ uint32_t ulSecureContextIndex;
+
+ for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ )
+ {
+ if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) )
+ {
+ break;
+ }
+ }
+
+ return ulSecureContextIndex;
+}
+/*-----------------------------------------------------------*/
+
+static void vReturnSecureContext( uint32_t ulSecureContextIndex )
+{
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
+}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, i;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -81,6 +130,14 @@
secureportSET_PSPLIM( securecontextNO_STACK );
secureportSET_PSP( securecontextNO_STACK );
+ /* Initialize all secure contexts. */
+ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
+ {
+ xSecureContexts[ i ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ i ].pucStackLimit = NULL;
+ xSecureContexts[ i ].pucStackStart = NULL;
+ }
+
#if ( configENABLE_MPU == 1 )
{
/* Configure thread mode to use PSP and to be unprivileged. */
@@ -88,7 +145,7 @@
}
#else /* configENABLE_MPU */
{
- /* Configure thread mode to use PSP and to be privileged.. */
+ /* Configure thread mode to use PSP and to be privileged. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
}
#endif /* configENABLE_MPU */
@@ -104,8 +161,8 @@
#endif /* configENABLE_MPU */
{
uint8_t * pucStackMemory = NULL;
- uint32_t ulIPSR;
- SecureContextHandle_t xSecureContextHandle = NULL;
+ uint32_t ulIPSR, ulSecureContextIndex;
+ SecureContextHandle_t xSecureContextHandle;
#if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL;
@@ -118,10 +175,11 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Allocate the context structure. */
- xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
+ /* Ontain a free secure context. */
+ ulSecureContextIndex = ulGetSecureContext();
- if( xSecureContextHandle != NULL )
+ /* Were we able to get a free context? */
+ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
{
/* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize );
@@ -134,18 +192,18 @@
* pointer before writing i.e. if stack pointer is 0x2, a push
* operation will decrement the stack pointer to 0x1 and then
* write at 0x1. */
- xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
/* The stack cannot go beyond this location. This value is
* programmed in the PSPLIM register on context switch.*/
- xSecureContextHandle->pucStackLimit = pucStackMemory;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
#if ( configENABLE_MPU == 1 )
{
/* Store the correct CONTROL value for the task on the stack.
* This value is programmed in the CONTROL register on
* context switch. */
- pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
+ pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
pulCurrentStackPointer--;
if( ulIsTaskPrivileged )
@@ -159,22 +217,22 @@
/* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
}
#else /* configENABLE_MPU */
{
/* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
}
#endif /* configENABLE_MPU */
+
+ /* Ensure to never return 0 as a valid context handle. */
+ xSecureContextHandle = ulSecureContextIndex + 1UL;
}
else
{
- /* Free the context to avoid memory leak and make sure to return
- * NULL to indicate failure. */
- vPortFree( xSecureContextHandle );
- xSecureContextHandle = NULL;
+ xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
}
}
}
@@ -185,7 +243,7 @@
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, ulSecureContextIndex;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -194,14 +252,43 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Ensure that valid parameters are passed. */
- secureportASSERT( xSecureContextHandle != NULL );
+ /* Only free if a valid context handle is passed. */
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
- /* Free the stack space. */
- vPortFree( xSecureContextHandle->pucStackLimit );
+ /* Free the stack space. */
+ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
- /* Free the context itself. */
- vPortFree( xSecureContextHandle );
+ /* Return the context back to the free contexts pool. */
+ vReturnSecureContext( ulSecureContextIndex );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
}
}
/*-----------------------------------------------------------*/
diff --git a/portable/GCC/ARM_CM23/secure/secure_context.h b/portable/GCC/ARM_CM23/secure/secure_context.h
index 77a9332..b7a3ba5 100644
--- a/portable/GCC/ARM_CM23/secure/secure_context.h
+++ b/portable/GCC/ARM_CM23/secure/secure_context.h
@@ -36,15 +36,29 @@
#include "FreeRTOSConfig.h"
/**
- * @brief PSP value when no task's context is loaded.
+ * @brief PSP value when no secure context is loaded.
*/
#define securecontextNO_STACK 0x0
+/*-----------------------------------------------------------*/
/**
- * @brief Opaque handle.
+ * @brief Structure to represent a secure context.
+ *
+ * @note Since stack grows down, pucStackStart is the highest address while
+ * pucStackLimit is the first address of the allocated memory.
*/
-struct SecureContext;
-typedef struct SecureContext * SecureContextHandle_t;
+typedef struct SecureContext
+{
+ uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
+ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
+ uint8_t * pucStackStart; /**< First location of the stack memory. */
+} SecureContext_t;
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Opaque handle for a secure context.
+ */
+typedef uint32_t SecureContextHandle_t;
/*-----------------------------------------------------------*/
/**
diff --git a/portable/GCC/ARM_CM23/secure/secure_context_port.c b/portable/GCC/ARM_CM23/secure/secure_context_port.c
index 047ed8e..8677b22 100644
--- a/portable/GCC/ARM_CM23/secure/secure_context_port.c
+++ b/portable/GCC/ARM_CM23/secure/secure_context_port.c
@@ -36,56 +36,60 @@
#error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
#endif
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, load_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " ldmia r0!, {r1, r2} \n"/* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " ldmia r1!, {r3} \n"/* Read CONTROL register value from task's stack. r3 = CONTROL. */
- " msr control, r3 \n"/* CONTROL = r3. */
+ " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ " msr control, r3 \n" /* CONTROL = r3. */
#endif /* configENABLE_MPU */
- " msr psplim, r2 \n"/* PSPLIM = r2. */
- " msr psp, r1 \n"/* PSP = r1. */
- " \n"
- " load_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " msr psplim, r2 \n" /* PSPLIM = r2. */
+ " msr psp, r1 \n" /* PSP = r1. */
+ " \n"
+ " load_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::: "r0", "r1", "r2"
);
}
/*-----------------------------------------------------------*/
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, save_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " mrs r1, psp \n"/* r1 = PSP. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " mrs r1, psp \n" /* r1 = PSP. */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " mrs r2, control \n"/* r2 = CONTROL. */
- " subs r1, r1, #4 \n"/* Make space for the CONTROL value on the stack. */
- " str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- " stmia r1!, {r2} \n"/* Store CONTROL value on the stack. */
+ " mrs r2, control \n" /* r2 = CONTROL. */
+ " subs r1, r1, #4 \n" /* Make space for the CONTROL value on the stack. */
+ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ " stmia r1!, {r2} \n" /* Store CONTROL value on the stack. */
#else /* configENABLE_MPU */
- " str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
+ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
#endif /* configENABLE_MPU */
- " movs r1, %0 \n"/* r1 = securecontextNO_STACK. */
- " msr psplim, r1 \n"/* PSPLIM = securecontextNO_STACK. */
- " msr psp, r1 \n"/* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
- " \n"
- " save_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
+ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
+ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ " \n"
+ " save_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::"i" ( securecontextNO_STACK ) : "r1", "memory"
);
}
diff --git a/portable/GCC/ARM_CM23/secure/secure_heap.c b/portable/GCC/ARM_CM23/secure/secure_heap.c
index 0100ad0..099b01f 100644
--- a/portable/GCC/ARM_CM23/secure/secure_heap.c
+++ b/portable/GCC/ARM_CM23/secure/secure_heap.c
@@ -38,7 +38,9 @@
/**
* @brief Total heap size.
*/
-#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#ifndef secureconfigTOTAL_HEAP_SIZE
+ #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#endif
/* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER
diff --git a/portable/GCC/ARM_CM33/secure/secure_context.c b/portable/GCC/ARM_CM33/secure/secure_context.c
index deede89..96a5662 100644
--- a/portable/GCC/ARM_CM33/secure/secure_context.c
+++ b/portable/GCC/ARM_CM33/secure/secure_context.c
@@ -50,25 +50,74 @@
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
+
+/**
+ * @brief Invalid context ID.
+ */
+#define securecontextINVALID_CONTEXT_ID 0UL
+
+/**
+ * @brief Maximum number of secure contexts.
+ */
+#ifndef secureconfigMAX_SECURE_CONTEXTS
+ #define secureconfigMAX_SECURE_CONTEXTS 8UL
+#endif
/*-----------------------------------------------------------*/
/**
- * @brief Structure to represent secure context.
- *
- * @note Since stack grows down, pucStackStart is the highest address while
- * pucStackLimit is the first addess of the allocated memory.
+ * @brief Pre-allocated array of secure contexts.
*/
-typedef struct SecureContext
+SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Get a free context from the secure context pool (xSecureContexts).
+ *
+ * @return Index of a free context in the xSecureContexts array.
+ */
+static uint32_t ulGetSecureContext( void );
+
+/**
+ * @brief Return the secure context to the secure context pool (xSecureContexts).
+ *
+ * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
+ */
+static void vReturnSecureContext( uint32_t ulSecureContextIndex );
+
+/* These are implemented in assembly. */
+extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
+extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
+/*-----------------------------------------------------------*/
+
+static uint32_t ulGetSecureContext( void )
{
- uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
- uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
- uint8_t * pucStackStart; /**< First location of the stack memory. */
-} SecureContext_t;
+ uint32_t ulSecureContextIndex;
+
+ for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ )
+ {
+ if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) )
+ {
+ break;
+ }
+ }
+
+ return ulSecureContextIndex;
+}
+/*-----------------------------------------------------------*/
+
+static void vReturnSecureContext( uint32_t ulSecureContextIndex )
+{
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
+}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, i;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -81,6 +130,14 @@
secureportSET_PSPLIM( securecontextNO_STACK );
secureportSET_PSP( securecontextNO_STACK );
+ /* Initialize all secure contexts. */
+ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
+ {
+ xSecureContexts[ i ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ i ].pucStackLimit = NULL;
+ xSecureContexts[ i ].pucStackStart = NULL;
+ }
+
#if ( configENABLE_MPU == 1 )
{
/* Configure thread mode to use PSP and to be unprivileged. */
@@ -88,7 +145,7 @@
}
#else /* configENABLE_MPU */
{
- /* Configure thread mode to use PSP and to be privileged.. */
+ /* Configure thread mode to use PSP and to be privileged. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
}
#endif /* configENABLE_MPU */
@@ -104,8 +161,8 @@
#endif /* configENABLE_MPU */
{
uint8_t * pucStackMemory = NULL;
- uint32_t ulIPSR;
- SecureContextHandle_t xSecureContextHandle = NULL;
+ uint32_t ulIPSR, ulSecureContextIndex;
+ SecureContextHandle_t xSecureContextHandle;
#if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL;
@@ -118,10 +175,11 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Allocate the context structure. */
- xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
+ /* Ontain a free secure context. */
+ ulSecureContextIndex = ulGetSecureContext();
- if( xSecureContextHandle != NULL )
+ /* Were we able to get a free context? */
+ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
{
/* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize );
@@ -134,18 +192,18 @@
* pointer before writing i.e. if stack pointer is 0x2, a push
* operation will decrement the stack pointer to 0x1 and then
* write at 0x1. */
- xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
/* The stack cannot go beyond this location. This value is
* programmed in the PSPLIM register on context switch.*/
- xSecureContextHandle->pucStackLimit = pucStackMemory;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
#if ( configENABLE_MPU == 1 )
{
/* Store the correct CONTROL value for the task on the stack.
* This value is programmed in the CONTROL register on
* context switch. */
- pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
+ pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
pulCurrentStackPointer--;
if( ulIsTaskPrivileged )
@@ -159,22 +217,22 @@
/* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
}
#else /* configENABLE_MPU */
{
/* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
}
#endif /* configENABLE_MPU */
+
+ /* Ensure to never return 0 as a valid context handle. */
+ xSecureContextHandle = ulSecureContextIndex + 1UL;
}
else
{
- /* Free the context to avoid memory leak and make sure to return
- * NULL to indicate failure. */
- vPortFree( xSecureContextHandle );
- xSecureContextHandle = NULL;
+ xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
}
}
}
@@ -185,7 +243,7 @@
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, ulSecureContextIndex;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -194,14 +252,43 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Ensure that valid parameters are passed. */
- secureportASSERT( xSecureContextHandle != NULL );
+ /* Only free if a valid context handle is passed. */
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
- /* Free the stack space. */
- vPortFree( xSecureContextHandle->pucStackLimit );
+ /* Free the stack space. */
+ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
- /* Free the context itself. */
- vPortFree( xSecureContextHandle );
+ /* Return the context back to the free contexts pool. */
+ vReturnSecureContext( ulSecureContextIndex );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
}
}
/*-----------------------------------------------------------*/
diff --git a/portable/GCC/ARM_CM33/secure/secure_context.h b/portable/GCC/ARM_CM33/secure/secure_context.h
index 77a9332..b7a3ba5 100644
--- a/portable/GCC/ARM_CM33/secure/secure_context.h
+++ b/portable/GCC/ARM_CM33/secure/secure_context.h
@@ -36,15 +36,29 @@
#include "FreeRTOSConfig.h"
/**
- * @brief PSP value when no task's context is loaded.
+ * @brief PSP value when no secure context is loaded.
*/
#define securecontextNO_STACK 0x0
+/*-----------------------------------------------------------*/
/**
- * @brief Opaque handle.
+ * @brief Structure to represent a secure context.
+ *
+ * @note Since stack grows down, pucStackStart is the highest address while
+ * pucStackLimit is the first address of the allocated memory.
*/
-struct SecureContext;
-typedef struct SecureContext * SecureContextHandle_t;
+typedef struct SecureContext
+{
+ uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
+ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
+ uint8_t * pucStackStart; /**< First location of the stack memory. */
+} SecureContext_t;
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Opaque handle for a secure context.
+ */
+typedef uint32_t SecureContextHandle_t;
/*-----------------------------------------------------------*/
/**
diff --git a/portable/GCC/ARM_CM33/secure/secure_context_port.c b/portable/GCC/ARM_CM33/secure/secure_context_port.c
index 4c6d0be..0731abe 100644
--- a/portable/GCC/ARM_CM33/secure/secure_context_port.c
+++ b/portable/GCC/ARM_CM33/secure/secure_context_port.c
@@ -32,57 +32,62 @@
/* Secure port macros. */
#include "secure_port_macros.h"
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, load_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " ldmia r0!, {r1, r2} \n"/* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, load_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " ldmia r0!, {r1, r2} \n" /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " ldmia r1!, {r3} \n"/* Read CONTROL register value from task's stack. r3 = CONTROL. */
- " msr control, r3 \n"/* CONTROL = r3. */
+ " ldmia r1!, {r3} \n" /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ " msr control, r3 \n" /* CONTROL = r3. */
#endif /* configENABLE_MPU */
- " msr psplim, r2 \n"/* PSPLIM = r2. */
- " msr psp, r1 \n"/* PSP = r1. */
- " \n"
- " load_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " msr psplim, r2 \n" /* PSPLIM = r2. */
+ " msr psp, r1 \n" /* PSP = r1. */
+ " \n"
+ " load_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::: "r0", "r1", "r2"
);
}
/*-----------------------------------------------------------*/
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext )
{
- /* xSecureContextHandle value is in r0. */
+ /* pxSecureContext value is in r0. */
__asm volatile
(
- " .syntax unified \n"
- " \n"
- " mrs r1, ipsr \n"/* r1 = IPSR. */
- " cbz r1, save_ctx_therad_mode \n"/* Do nothing if the processor is running in the Thread Mode. */
- " mrs r1, psp \n"/* r1 = PSP. */
+ " .syntax unified \n"
+ " \n"
+ " mrs r1, ipsr \n" /* r1 = IPSR. */
+ " cbz r1, save_ctx_therad_mode \n" /* Do nothing if the processor is running in the Thread Mode. */
+ " mrs r1, psp \n" /* r1 = PSP. */
+ " \n"
#if ( configENABLE_FPU == 1 )
- " vstmdb r1!, {s0} \n"/* Trigger the defferred stacking of FPU registers. */
- " vldmia r1!, {s0} \n"/* Nullify the effect of the pervious statement. */
+ " vstmdb r1!, {s0} \n" /* Trigger the defferred stacking of FPU registers. */
+ " vldmia r1!, {s0} \n" /* Nullify the effect of the pervious statement. */
#endif /* configENABLE_FPU */
+ " \n"
#if ( configENABLE_MPU == 1 )
- " mrs r2, control \n"/* r2 = CONTROL. */
- " stmdb r1!, {r2} \n"/* Store CONTROL value on the stack. */
+ " mrs r2, control \n" /* r2 = CONTROL. */
+ " stmdb r1!, {r2} \n" /* Store CONTROL value on the stack. */
#endif /* configENABLE_MPU */
- " str r1, [r0] \n"/* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- " movs r1, %0 \n"/* r1 = securecontextNO_STACK. */
- " msr psplim, r1 \n"/* PSPLIM = securecontextNO_STACK. */
- " msr psp, r1 \n"/* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
- " \n"
- " save_ctx_therad_mode: \n"
- " nop \n"
- " \n"
+ " \n"
+ " str r1, [r0] \n" /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ " movs r1, %0 \n" /* r1 = securecontextNO_STACK. */
+ " msr psplim, r1 \n" /* PSPLIM = securecontextNO_STACK. */
+ " msr psp, r1 \n" /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ " \n"
+ " save_ctx_therad_mode: \n"
+ " bx lr \n"
+ " \n"
::"i" ( securecontextNO_STACK ) : "r1", "memory"
);
}
diff --git a/portable/GCC/ARM_CM33/secure/secure_heap.c b/portable/GCC/ARM_CM33/secure/secure_heap.c
index 0100ad0..099b01f 100644
--- a/portable/GCC/ARM_CM33/secure/secure_heap.c
+++ b/portable/GCC/ARM_CM33/secure/secure_heap.c
@@ -38,7 +38,9 @@
/**
* @brief Total heap size.
*/
-#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#ifndef secureconfigTOTAL_HEAP_SIZE
+ #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#endif
/* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER
diff --git a/portable/IAR/ARM_CM23/secure/secure_context.c b/portable/IAR/ARM_CM23/secure/secure_context.c
index deede89..96a5662 100644
--- a/portable/IAR/ARM_CM23/secure/secure_context.c
+++ b/portable/IAR/ARM_CM23/secure/secure_context.c
@@ -50,25 +50,74 @@
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
+
+/**
+ * @brief Invalid context ID.
+ */
+#define securecontextINVALID_CONTEXT_ID 0UL
+
+/**
+ * @brief Maximum number of secure contexts.
+ */
+#ifndef secureconfigMAX_SECURE_CONTEXTS
+ #define secureconfigMAX_SECURE_CONTEXTS 8UL
+#endif
/*-----------------------------------------------------------*/
/**
- * @brief Structure to represent secure context.
- *
- * @note Since stack grows down, pucStackStart is the highest address while
- * pucStackLimit is the first addess of the allocated memory.
+ * @brief Pre-allocated array of secure contexts.
*/
-typedef struct SecureContext
+SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Get a free context from the secure context pool (xSecureContexts).
+ *
+ * @return Index of a free context in the xSecureContexts array.
+ */
+static uint32_t ulGetSecureContext( void );
+
+/**
+ * @brief Return the secure context to the secure context pool (xSecureContexts).
+ *
+ * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
+ */
+static void vReturnSecureContext( uint32_t ulSecureContextIndex );
+
+/* These are implemented in assembly. */
+extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
+extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
+/*-----------------------------------------------------------*/
+
+static uint32_t ulGetSecureContext( void )
{
- uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
- uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
- uint8_t * pucStackStart; /**< First location of the stack memory. */
-} SecureContext_t;
+ uint32_t ulSecureContextIndex;
+
+ for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ )
+ {
+ if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) )
+ {
+ break;
+ }
+ }
+
+ return ulSecureContextIndex;
+}
+/*-----------------------------------------------------------*/
+
+static void vReturnSecureContext( uint32_t ulSecureContextIndex )
+{
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
+}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, i;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -81,6 +130,14 @@
secureportSET_PSPLIM( securecontextNO_STACK );
secureportSET_PSP( securecontextNO_STACK );
+ /* Initialize all secure contexts. */
+ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
+ {
+ xSecureContexts[ i ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ i ].pucStackLimit = NULL;
+ xSecureContexts[ i ].pucStackStart = NULL;
+ }
+
#if ( configENABLE_MPU == 1 )
{
/* Configure thread mode to use PSP and to be unprivileged. */
@@ -88,7 +145,7 @@
}
#else /* configENABLE_MPU */
{
- /* Configure thread mode to use PSP and to be privileged.. */
+ /* Configure thread mode to use PSP and to be privileged. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
}
#endif /* configENABLE_MPU */
@@ -104,8 +161,8 @@
#endif /* configENABLE_MPU */
{
uint8_t * pucStackMemory = NULL;
- uint32_t ulIPSR;
- SecureContextHandle_t xSecureContextHandle = NULL;
+ uint32_t ulIPSR, ulSecureContextIndex;
+ SecureContextHandle_t xSecureContextHandle;
#if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL;
@@ -118,10 +175,11 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Allocate the context structure. */
- xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
+ /* Ontain a free secure context. */
+ ulSecureContextIndex = ulGetSecureContext();
- if( xSecureContextHandle != NULL )
+ /* Were we able to get a free context? */
+ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
{
/* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize );
@@ -134,18 +192,18 @@
* pointer before writing i.e. if stack pointer is 0x2, a push
* operation will decrement the stack pointer to 0x1 and then
* write at 0x1. */
- xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
/* The stack cannot go beyond this location. This value is
* programmed in the PSPLIM register on context switch.*/
- xSecureContextHandle->pucStackLimit = pucStackMemory;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
#if ( configENABLE_MPU == 1 )
{
/* Store the correct CONTROL value for the task on the stack.
* This value is programmed in the CONTROL register on
* context switch. */
- pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
+ pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
pulCurrentStackPointer--;
if( ulIsTaskPrivileged )
@@ -159,22 +217,22 @@
/* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
}
#else /* configENABLE_MPU */
{
/* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
}
#endif /* configENABLE_MPU */
+
+ /* Ensure to never return 0 as a valid context handle. */
+ xSecureContextHandle = ulSecureContextIndex + 1UL;
}
else
{
- /* Free the context to avoid memory leak and make sure to return
- * NULL to indicate failure. */
- vPortFree( xSecureContextHandle );
- xSecureContextHandle = NULL;
+ xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
}
}
}
@@ -185,7 +243,7 @@
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, ulSecureContextIndex;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -194,14 +252,43 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Ensure that valid parameters are passed. */
- secureportASSERT( xSecureContextHandle != NULL );
+ /* Only free if a valid context handle is passed. */
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
- /* Free the stack space. */
- vPortFree( xSecureContextHandle->pucStackLimit );
+ /* Free the stack space. */
+ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
- /* Free the context itself. */
- vPortFree( xSecureContextHandle );
+ /* Return the context back to the free contexts pool. */
+ vReturnSecureContext( ulSecureContextIndex );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
}
}
/*-----------------------------------------------------------*/
diff --git a/portable/IAR/ARM_CM23/secure/secure_context.h b/portable/IAR/ARM_CM23/secure/secure_context.h
index 77a9332..b7a3ba5 100644
--- a/portable/IAR/ARM_CM23/secure/secure_context.h
+++ b/portable/IAR/ARM_CM23/secure/secure_context.h
@@ -36,15 +36,29 @@
#include "FreeRTOSConfig.h"
/**
- * @brief PSP value when no task's context is loaded.
+ * @brief PSP value when no secure context is loaded.
*/
#define securecontextNO_STACK 0x0
+/*-----------------------------------------------------------*/
/**
- * @brief Opaque handle.
+ * @brief Structure to represent a secure context.
+ *
+ * @note Since stack grows down, pucStackStart is the highest address while
+ * pucStackLimit is the first address of the allocated memory.
*/
-struct SecureContext;
-typedef struct SecureContext * SecureContextHandle_t;
+typedef struct SecureContext
+{
+ uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
+ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
+ uint8_t * pucStackStart; /**< First location of the stack memory. */
+} SecureContext_t;
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Opaque handle for a secure context.
+ */
+typedef uint32_t SecureContextHandle_t;
/*-----------------------------------------------------------*/
/**
diff --git a/portable/IAR/ARM_CM23/secure/secure_context_port.c b/portable/IAR/ARM_CM23/secure/secure_context_port.c
deleted file mode 100644
index d8ca0f5..0000000
--- a/portable/IAR/ARM_CM23/secure/secure_context_port.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * FreeRTOS Kernel <DEVELOPMENT BRANCH>
- * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * SPDX-License-Identifier: MIT
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * https://www.FreeRTOS.org
- * https://github.com/FreeRTOS
- *
- */
-
-/* Secure context includes. */
-#include "secure_context.h"
-
-/* Secure port macros. */
-#include "secure_port_macros.h"
-
-/* Functions implemented in assembler file. */
-extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
-extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
-
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_LoadContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
-
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_SaveContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
diff --git a/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s
index 8fbb49a..cf245b9 100644
--- a/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s
+++ b/portable/IAR/ARM_CM23/secure/secure_context_port_asm.s
@@ -26,52 +26,56 @@
*
*/
- SECTION .text:CODE:NOROOT(2)
- THUMB
+ SECTION .text:CODE:NOROOT(2)
+ THUMB
- PUBLIC SecureContext_LoadContextAsm
- PUBLIC SecureContext_SaveContextAsm
+ PUBLIC SecureContext_LoadContextAsm
+ PUBLIC SecureContext_SaveContextAsm
#if ( configENABLE_FPU == 1 )
- #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
+ #error Cortex-M23 does not have a Floating Point Unit (FPU) and therefore configENABLE_FPU must be set to 0.
#endif
/*-----------------------------------------------------------*/
SecureContext_LoadContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
-#if ( configENABLE_MPU == 1 )
- ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
- msr control, r3 /* CONTROL = r3. */
-#endif /* configENABLE_MPU */
- msr psplim, r2 /* PSPLIM = r2. */
- msr psp, r1 /* PSP = r1. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
- load_ctx_therad_mode:
- bx lr
+#if ( configENABLE_MPU == 1 )
+ ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ msr control, r3 /* CONTROL = r3. */
+#endif /* configENABLE_MPU */
+
+ msr psplim, r2 /* PSPLIM = r2. */
+ msr psp, r1 /* PSP = r1. */
+
+ load_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
SecureContext_SaveContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- mrs r1, psp /* r1 = PSP. */
-#if ( configENABLE_MPU == 1 )
- mrs r2, control /* r2 = CONTROL. */
- subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */
- str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- stmia r1!, {r2} /* Store CONTROL value on the stack. */
-#else /* configENABLE_MPU */
- str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
-#endif /* configENABLE_MPU */
- movs r1, #0 /* r1 = securecontextNO_STACK. */
- msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
- msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ mrs r1, psp /* r1 = PSP. */
- save_ctx_therad_mode:
- bx lr
+#if ( configENABLE_MPU == 1 )
+ mrs r2, control /* r2 = CONTROL. */
+ subs r1, r1, #4 /* Make space for the CONTROL value on the stack. */
+ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ stmia r1!, {r2} /* Store CONTROL value on the stack. */
+#else /* configENABLE_MPU */
+ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+#endif /* configENABLE_MPU */
+
+ movs r1, #0 /* r1 = securecontextNO_STACK. */
+ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
+ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+
+ save_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
- END
+ END
diff --git a/portable/IAR/ARM_CM23/secure/secure_heap.c b/portable/IAR/ARM_CM23/secure/secure_heap.c
index 0100ad0..099b01f 100644
--- a/portable/IAR/ARM_CM23/secure/secure_heap.c
+++ b/portable/IAR/ARM_CM23/secure/secure_heap.c
@@ -38,7 +38,9 @@
/**
* @brief Total heap size.
*/
-#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#ifndef secureconfigTOTAL_HEAP_SIZE
+ #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#endif
/* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER
diff --git a/portable/IAR/ARM_CM33/secure/secure_context.c b/portable/IAR/ARM_CM33/secure/secure_context.c
index deede89..96a5662 100644
--- a/portable/IAR/ARM_CM33/secure/secure_context.c
+++ b/portable/IAR/ARM_CM33/secure/secure_context.c
@@ -50,25 +50,74 @@
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
+
+/**
+ * @brief Invalid context ID.
+ */
+#define securecontextINVALID_CONTEXT_ID 0UL
+
+/**
+ * @brief Maximum number of secure contexts.
+ */
+#ifndef secureconfigMAX_SECURE_CONTEXTS
+ #define secureconfigMAX_SECURE_CONTEXTS 8UL
+#endif
/*-----------------------------------------------------------*/
/**
- * @brief Structure to represent secure context.
- *
- * @note Since stack grows down, pucStackStart is the highest address while
- * pucStackLimit is the first addess of the allocated memory.
+ * @brief Pre-allocated array of secure contexts.
*/
-typedef struct SecureContext
+SecureContext_t xSecureContexts[ secureconfigMAX_SECURE_CONTEXTS ];
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Get a free context from the secure context pool (xSecureContexts).
+ *
+ * @return Index of a free context in the xSecureContexts array.
+ */
+static uint32_t ulGetSecureContext( void );
+
+/**
+ * @brief Return the secure context to the secure context pool (xSecureContexts).
+ *
+ * @param[in] ulSecureContextIndex Index of the context in the xSecureContexts array.
+ */
+static void vReturnSecureContext( uint32_t ulSecureContextIndex );
+
+/* These are implemented in assembly. */
+extern void SecureContext_LoadContextAsm( SecureContext_t * pxSecureContext );
+extern void SecureContext_SaveContextAsm( SecureContext_t * pxSecureContext );
+/*-----------------------------------------------------------*/
+
+static uint32_t ulGetSecureContext( void )
{
- uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
- uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
- uint8_t * pucStackStart; /**< First location of the stack memory. */
-} SecureContext_t;
+ uint32_t ulSecureContextIndex;
+
+ for( ulSecureContextIndex = 0; ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS; ulSecureContextIndex++ )
+ {
+ if( ( xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackLimit == NULL ) &&
+ ( xSecureContexts[ ulSecureContextIndex ].pucStackStart == NULL ) )
+ {
+ break;
+ }
+ }
+
+ return ulSecureContextIndex;
+}
+/*-----------------------------------------------------------*/
+
+static void vReturnSecureContext( uint32_t ulSecureContextIndex )
+{
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = NULL;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = NULL;
+}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, i;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -81,6 +130,14 @@
secureportSET_PSPLIM( securecontextNO_STACK );
secureportSET_PSP( securecontextNO_STACK );
+ /* Initialize all secure contexts. */
+ for( i = 0; i < secureconfigMAX_SECURE_CONTEXTS; i++ )
+ {
+ xSecureContexts[ i ].pucCurrentStackPointer = NULL;
+ xSecureContexts[ i ].pucStackLimit = NULL;
+ xSecureContexts[ i ].pucStackStart = NULL;
+ }
+
#if ( configENABLE_MPU == 1 )
{
/* Configure thread mode to use PSP and to be unprivileged. */
@@ -88,7 +145,7 @@
}
#else /* configENABLE_MPU */
{
- /* Configure thread mode to use PSP and to be privileged.. */
+ /* Configure thread mode to use PSP and to be privileged. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
}
#endif /* configENABLE_MPU */
@@ -104,8 +161,8 @@
#endif /* configENABLE_MPU */
{
uint8_t * pucStackMemory = NULL;
- uint32_t ulIPSR;
- SecureContextHandle_t xSecureContextHandle = NULL;
+ uint32_t ulIPSR, ulSecureContextIndex;
+ SecureContextHandle_t xSecureContextHandle;
#if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL;
@@ -118,10 +175,11 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Allocate the context structure. */
- xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
+ /* Ontain a free secure context. */
+ ulSecureContextIndex = ulGetSecureContext();
- if( xSecureContextHandle != NULL )
+ /* Were we able to get a free context? */
+ if( ulSecureContextIndex < secureconfigMAX_SECURE_CONTEXTS )
{
/* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize );
@@ -134,18 +192,18 @@
* pointer before writing i.e. if stack pointer is 0x2, a push
* operation will decrement the stack pointer to 0x1 and then
* write at 0x1. */
- xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;
+ xSecureContexts[ ulSecureContextIndex ].pucStackStart = pucStackMemory + ulSecureStackSize;
/* The stack cannot go beyond this location. This value is
* programmed in the PSPLIM register on context switch.*/
- xSecureContextHandle->pucStackLimit = pucStackMemory;
+ xSecureContexts[ ulSecureContextIndex ].pucStackLimit = pucStackMemory;
#if ( configENABLE_MPU == 1 )
{
/* Store the correct CONTROL value for the task on the stack.
* This value is programmed in the CONTROL register on
* context switch. */
- pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;
+ pulCurrentStackPointer = ( uint32_t * ) xSecureContexts[ ulSecureContextIndex ].pucStackStart;
pulCurrentStackPointer--;
if( ulIsTaskPrivileged )
@@ -159,22 +217,22 @@
/* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;
}
#else /* configENABLE_MPU */
{
/* Current SP is set to the starting of the stack. This
* value programmed in the PSP register on context switch. */
- xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;
+ xSecureContexts[ ulSecureContextIndex ].pucCurrentStackPointer = xSecureContexts[ ulSecureContextIndex ].pucStackStart;
}
#endif /* configENABLE_MPU */
+
+ /* Ensure to never return 0 as a valid context handle. */
+ xSecureContextHandle = ulSecureContextIndex + 1UL;
}
else
{
- /* Free the context to avoid memory leak and make sure to return
- * NULL to indicate failure. */
- vPortFree( xSecureContextHandle );
- xSecureContextHandle = NULL;
+ xSecureContextHandle = securecontextINVALID_CONTEXT_ID;
}
}
}
@@ -185,7 +243,7 @@
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{
- uint32_t ulIPSR;
+ uint32_t ulIPSR, ulSecureContextIndex;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
@@ -194,14 +252,43 @@
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
- /* Ensure that valid parameters are passed. */
- secureportASSERT( xSecureContextHandle != NULL );
+ /* Only free if a valid context handle is passed. */
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
- /* Free the stack space. */
- vPortFree( xSecureContextHandle->pucStackLimit );
+ /* Free the stack space. */
+ vPortFree( xSecureContexts[ ulSecureContextIndex ].pucStackLimit );
- /* Free the context itself. */
- vPortFree( xSecureContextHandle );
+ /* Return the context back to the free contexts pool. */
+ vReturnSecureContext( ulSecureContextIndex );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_LoadContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
+ }
+}
+/*-----------------------------------------------------------*/
+
+secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
+{
+ uint32_t ulSecureContextIndex;
+
+ if( ( xSecureContextHandle > 0UL ) && ( xSecureContextHandle <= secureconfigMAX_SECURE_CONTEXTS ) )
+ {
+ ulSecureContextIndex = xSecureContextHandle - 1UL;
+
+ SecureContext_SaveContextAsm( &( xSecureContexts[ ulSecureContextIndex ] ) );
}
}
/*-----------------------------------------------------------*/
diff --git a/portable/IAR/ARM_CM33/secure/secure_context.h b/portable/IAR/ARM_CM33/secure/secure_context.h
index 77a9332..b7a3ba5 100644
--- a/portable/IAR/ARM_CM33/secure/secure_context.h
+++ b/portable/IAR/ARM_CM33/secure/secure_context.h
@@ -36,15 +36,29 @@
#include "FreeRTOSConfig.h"
/**
- * @brief PSP value when no task's context is loaded.
+ * @brief PSP value when no secure context is loaded.
*/
#define securecontextNO_STACK 0x0
+/*-----------------------------------------------------------*/
/**
- * @brief Opaque handle.
+ * @brief Structure to represent a secure context.
+ *
+ * @note Since stack grows down, pucStackStart is the highest address while
+ * pucStackLimit is the first address of the allocated memory.
*/
-struct SecureContext;
-typedef struct SecureContext * SecureContextHandle_t;
+typedef struct SecureContext
+{
+ uint8_t * pucCurrentStackPointer; /**< Current value of stack pointer (PSP). */
+ uint8_t * pucStackLimit; /**< Last location of the stack memory (PSPLIM). */
+ uint8_t * pucStackStart; /**< First location of the stack memory. */
+} SecureContext_t;
+/*-----------------------------------------------------------*/
+
+/**
+ * @brief Opaque handle for a secure context.
+ */
+typedef uint32_t SecureContextHandle_t;
/*-----------------------------------------------------------*/
/**
diff --git a/portable/IAR/ARM_CM33/secure/secure_context_port.c b/portable/IAR/ARM_CM33/secure/secure_context_port.c
deleted file mode 100644
index d8ca0f5..0000000
--- a/portable/IAR/ARM_CM33/secure/secure_context_port.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * FreeRTOS Kernel <DEVELOPMENT BRANCH>
- * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * SPDX-License-Identifier: MIT
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * https://www.FreeRTOS.org
- * https://github.com/FreeRTOS
- *
- */
-
-/* Secure context includes. */
-#include "secure_context.h"
-
-/* Secure port macros. */
-#include "secure_port_macros.h"
-
-/* Functions implemented in assembler file. */
-extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
-extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
-
-secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_LoadContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
-
-secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
-{
- SecureContext_SaveContextAsm( xSecureContextHandle );
-}
-/*-----------------------------------------------------------*/
diff --git a/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s b/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s
index 297679b..0df0a1b 100644
--- a/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s
+++ b/portable/IAR/ARM_CM33/secure/secure_context_port_asm.s
@@ -26,49 +26,54 @@
*
*/
- SECTION .text:CODE:NOROOT(2)
- THUMB
+ SECTION .text:CODE:NOROOT(2)
+ THUMB
- PUBLIC SecureContext_LoadContextAsm
- PUBLIC SecureContext_SaveContextAsm
+ PUBLIC SecureContext_LoadContextAsm
+ PUBLIC SecureContext_SaveContextAsm
/*-----------------------------------------------------------*/
SecureContext_LoadContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- ldmia r0!, {r1, r2} /* r1 = xSecureContextHandle->pucCurrentStackPointer, r2 = xSecureContextHandle->pucStackLimit. */
-#if ( configENABLE_MPU == 1 )
- ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
- msr control, r3 /* CONTROL = r3. */
-#endif /* configENABLE_MPU */
- msr psplim, r2 /* PSPLIM = r2. */
- msr psp, r1 /* PSP = r1. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, load_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ ldmia r0!, {r1, r2} /* r1 = pxSecureContext->pucCurrentStackPointer, r2 = pxSecureContext->pucStackLimit. */
- load_ctx_therad_mode:
- bx lr
+#if ( configENABLE_MPU == 1 )
+ ldmia r1!, {r3} /* Read CONTROL register value from task's stack. r3 = CONTROL. */
+ msr control, r3 /* CONTROL = r3. */
+#endif /* configENABLE_MPU */
+
+ msr psplim, r2 /* PSPLIM = r2. */
+ msr psp, r1 /* PSP = r1. */
+
+ load_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
SecureContext_SaveContextAsm:
- /* xSecureContextHandle value is in r0. */
- mrs r1, ipsr /* r1 = IPSR. */
- cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
- mrs r1, psp /* r1 = PSP. */
-#if ( configENABLE_FPU == 1 )
- vstmdb r1!, {s0} /* Trigger the defferred stacking of FPU registers. */
- vldmia r1!, {s0} /* Nullify the effect of the pervious statement. */
-#endif /* configENABLE_FPU */
-#if ( configENABLE_MPU == 1 )
- mrs r2, control /* r2 = CONTROL. */
- stmdb r1!, {r2} /* Store CONTROL value on the stack. */
-#endif /* configENABLE_MPU */
- str r1, [r0] /* Save the top of stack in context. xSecureContextHandle->pucCurrentStackPointer = r1. */
- movs r1, #0 /* r1 = securecontextNO_STACK. */
- msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
- msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+ /* pxSecureContext value is in r0. */
+ mrs r1, ipsr /* r1 = IPSR. */
+ cbz r1, save_ctx_therad_mode /* Do nothing if the processor is running in the Thread Mode. */
+ mrs r1, psp /* r1 = PSP. */
- save_ctx_therad_mode:
- bx lr
+#if ( configENABLE_FPU == 1 )
+ vstmdb r1!, {s0} /* Trigger the defferred stacking of FPU registers. */
+ vldmia r1!, {s0} /* Nullify the effect of the pervious statement. */
+#endif /* configENABLE_FPU */
+
+#if ( configENABLE_MPU == 1 )
+ mrs r2, control /* r2 = CONTROL. */
+ stmdb r1!, {r2} /* Store CONTROL value on the stack. */
+#endif /* configENABLE_MPU */
+
+ str r1, [r0] /* Save the top of stack in context. pxSecureContext->pucCurrentStackPointer = r1. */
+ movs r1, #0 /* r1 = securecontextNO_STACK. */
+ msr psplim, r1 /* PSPLIM = securecontextNO_STACK. */
+ msr psp, r1 /* PSP = securecontextNO_STACK i.e. No stack for thread mode until next task's context is loaded. */
+
+ save_ctx_therad_mode:
+ bx lr
/*-----------------------------------------------------------*/
- END
+ END
diff --git a/portable/IAR/ARM_CM33/secure/secure_heap.c b/portable/IAR/ARM_CM33/secure/secure_heap.c
index 0100ad0..099b01f 100644
--- a/portable/IAR/ARM_CM33/secure/secure_heap.c
+++ b/portable/IAR/ARM_CM33/secure/secure_heap.c
@@ -38,7 +38,9 @@
/**
* @brief Total heap size.
*/
-#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#ifndef secureconfigTOTAL_HEAP_SIZE
+ #define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
+#endif
/* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER