Pre-allocate secure-side context structures

This commit improves ARMv8-M security by pre-allocating secure-side task
context structures and changing how tasks reference a secure-side
context structure when calling a secure function. The new configuration
constant secureconfigMAX_SECURE_CONTEXTS sets the number of secure
context structures to pre-allocate. secureconfigMAX_SECURE_CONTEXTS
defaults to 8 if left undefined.

Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
This commit is contained in:
Gaurav Aggarwal 2021-08-04 14:52:22 -07:00 committed by Gaurav-Aggarwal-AWS
parent f8ada39d85
commit ccaa0f4d6e
27 changed files with 1012 additions and 657 deletions

View File

@ -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"
);
}

View File

@ -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"
);
}

View File

@ -1,49 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/* Secure context includes. */
#include "secure_context.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/* Functions implemented in assembler file. */
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_LoadContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_SaveContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/

View File

@ -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

View File

@ -1,49 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/* Secure context includes. */
#include "secure_context.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/* Functions implemented in assembler file. */
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_LoadContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_SaveContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/

View File

@ -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

View File

@ -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 ] ) );
}
}
/*-----------------------------------------------------------*/

View File

@ -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;
/*-----------------------------------------------------------*/
/**

View File

@ -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

View File

@ -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 ] ) );
}
}
/*-----------------------------------------------------------*/

View File

@ -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;
/*-----------------------------------------------------------*/
/**

View File

@ -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"
);
}

View File

@ -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

View File

@ -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 ] ) );
}
}
/*-----------------------------------------------------------*/

View File

@ -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;
/*-----------------------------------------------------------*/
/**

View File

@ -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"
);
}

View File

@ -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

View File

@ -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 ] ) );
}
}
/*-----------------------------------------------------------*/

View File

@ -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;
/*-----------------------------------------------------------*/
/**

View File

@ -1,49 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/* Secure context includes. */
#include "secure_context.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/* Functions implemented in assembler file. */
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_LoadContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_SaveContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/

View File

@ -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

View File

@ -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

View File

@ -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 ] ) );
}
}
/*-----------------------------------------------------------*/

View File

@ -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;
/*-----------------------------------------------------------*/
/**

View File

@ -1,49 +0,0 @@
/*
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
/* Secure context includes. */
#include "secure_context.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/* Functions implemented in assembler file. */
extern void SecureContext_LoadContextAsm( SecureContextHandle_t xSecureContextHandle );
extern void SecureContext_SaveContextAsm( SecureContextHandle_t xSecureContextHandle );
secureportNON_SECURE_CALLABLE void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_LoadContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle )
{
SecureContext_SaveContextAsm( xSecureContextHandle );
}
/*-----------------------------------------------------------*/

View File

@ -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

View File

@ -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