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 047ed8e99..8677b2297 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 4c6d0be11..0731abe1f 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 d8ca0f504..000000000 --- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM23/secure_context_port.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * FreeRTOS Kernel - * 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 8fbb49aca..cf245b915 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 d8ca0f504..000000000 --- a/portable/ARMv8M/secure/context/portable/IAR/ARM_CM33/secure_context_port.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * FreeRTOS Kernel - * 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 297679b96..0df0a1b40 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 deede8924..96a566211 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* 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_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl * 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 77a93323a..b7a3ba50e 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 0100ad011..099b01f1f 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 deede8924..96a566211 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* 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_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl * 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 77a93323a..b7a3ba50e 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 047ed8e99..8677b2297 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 0100ad011..099b01f1f 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 deede8924..96a566211 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* 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_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl * 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 77a93323a..b7a3ba50e 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 4c6d0be11..0731abe1f 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 0100ad011..099b01f1f 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 deede8924..96a566211 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* 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_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl * 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 77a93323a..b7a3ba50e 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 d8ca0f504..000000000 --- a/portable/IAR/ARM_CM23/secure/secure_context_port.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * FreeRTOS Kernel - * 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 8fbb49aca..cf245b915 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 0100ad011..099b01f1f 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 deede8924..96a566211 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) } #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) #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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) * 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_Init( void ) /* 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_Init( void ) 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 @@ secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandl * 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 77a93323a..b7a3ba50e 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 d8ca0f504..000000000 --- a/portable/IAR/ARM_CM33/secure/secure_context_port.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * FreeRTOS Kernel - * 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 297679b96..0df0a1b40 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 0100ad011..099b01f1f 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