Feature: SMP (#278)

* Add XMOS XCore ports

Some minor modifications are also made to the kernel to support the
XCore compiler's automatic stack size calculation.

* Update kernel to support SMP

The XMOS XCore ports are also updated to support SMP.

* Fix compiler warnings in xcore ports

The port set and clear interrupt mask from ISR macros were removed from
the ports so that the default macros found in FreeRTOS.h are used
instead. The default macros do not result in warnings when they are
used.

* Remove inline function from timers.h

Inline function converted to macro. This should now build when
optimizations are off and inlining is disabled.

* Fix compiler warnings in xcore ports and tasks.c

* fixed documentation for ulTaskNotifyTake() and ulTaskNotifyTakeIndexed()

* spelling fixes for tasks.c

Co-authored-by: Michael Bruno <mikeb@xmos.com>
This commit is contained in:
Joseph Julicher 2021-03-15 17:29:08 -07:00 committed by GitHub
parent cafae476e4
commit 989bc332b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
509 changed files with 176869 additions and 174380 deletions

View file

@ -1,206 +1,206 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* Secure context includes. */
#include "secure_context.h"
/* Secure heap includes. */
#include "secure_heap.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/**
* @brief CONTROL value for privileged tasks.
*
* Bit[0] - 0 --> Thread mode is privileged.
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02
/**
* @brief CONTROL value for un-privileged tasks.
*
* Bit[0] - 1 --> Thread mode is un-privileged.
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
/*-----------------------------------------------------------*/
/**
* @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.
*/
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;
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* No stack for thread mode until a task's context is loaded. */
secureportSET_PSPLIM( securecontextNO_STACK );
secureportSET_PSP( securecontextNO_STACK );
#if ( configENABLE_MPU == 1 )
{
/* Configure thread mode to use PSP and to be unprivileged. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
}
#else /* configENABLE_MPU */
{
/* Configure thread mode to use PSP and to be privileged.. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
}
#endif /* configENABLE_MPU */
}
}
/*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 )
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged )
#else /* configENABLE_MPU */
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
#endif /* configENABLE_MPU */
{
uint8_t * pucStackMemory = NULL;
uint32_t ulIPSR;
SecureContextHandle_t xSecureContextHandle = NULL;
#if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL;
#endif /* configENABLE_MPU */
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* Allocate the context structure. */
xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
if( xSecureContextHandle != NULL )
{
/* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize );
if( pucStackMemory != NULL )
{
/* Since stack grows down, the starting point will be the last
* location. Note that this location is next to the last
* allocated byte because the hardware decrements the stack
* 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;
/* The stack cannot go beyond this location. This value is
* programmed in the PSPLIM register on context switch.*/
xSecureContextHandle->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--;
if( ulIsTaskPrivileged )
{
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
}
else
{
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
}
/* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */
xSecureContextHandle->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;
}
#endif /* configENABLE_MPU */
}
else
{
/* Free the context to avoid memory leak and make sure to return
* NULL to indicate failure. */
vPortFree( xSecureContextHandle );
xSecureContextHandle = NULL;
}
}
}
return xSecureContextHandle;
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* Ensure that valid parameters are passed. */
secureportASSERT( xSecureContextHandle != NULL );
/* Free the stack space. */
vPortFree( xSecureContextHandle->pucStackLimit );
/* Free the context itself. */
vPortFree( xSecureContextHandle );
}
}
/*-----------------------------------------------------------*/
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* Secure context includes. */
#include "secure_context.h"
/* Secure heap includes. */
#include "secure_heap.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/**
* @brief CONTROL value for privileged tasks.
*
* Bit[0] - 0 --> Thread mode is privileged.
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_PRIVILEGED 0x02
/**
* @brief CONTROL value for un-privileged tasks.
*
* Bit[0] - 1 --> Thread mode is un-privileged.
* Bit[1] - 1 --> Thread mode uses PSP.
*/
#define securecontextCONTROL_VALUE_UNPRIVILEGED 0x03
/*-----------------------------------------------------------*/
/**
* @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.
*/
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;
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_Init( void )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* No stack for thread mode until a task's context is loaded. */
secureportSET_PSPLIM( securecontextNO_STACK );
secureportSET_PSP( securecontextNO_STACK );
#if ( configENABLE_MPU == 1 )
{
/* Configure thread mode to use PSP and to be unprivileged. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );
}
#else /* configENABLE_MPU */
{
/* Configure thread mode to use PSP and to be privileged.. */
secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );
}
#endif /* configENABLE_MPU */
}
}
/*-----------------------------------------------------------*/
#if ( configENABLE_MPU == 1 )
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged )
#else /* configENABLE_MPU */
secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )
#endif /* configENABLE_MPU */
{
uint8_t * pucStackMemory = NULL;
uint32_t ulIPSR;
SecureContextHandle_t xSecureContextHandle = NULL;
#if ( configENABLE_MPU == 1 )
uint32_t * pulCurrentStackPointer = NULL;
#endif /* configENABLE_MPU */
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* Allocate the context structure. */
xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );
if( xSecureContextHandle != NULL )
{
/* Allocate the stack space. */
pucStackMemory = pvPortMalloc( ulSecureStackSize );
if( pucStackMemory != NULL )
{
/* Since stack grows down, the starting point will be the last
* location. Note that this location is next to the last
* allocated byte because the hardware decrements the stack
* 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;
/* The stack cannot go beyond this location. This value is
* programmed in the PSPLIM register on context switch.*/
xSecureContextHandle->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--;
if( ulIsTaskPrivileged )
{
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;
}
else
{
*( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;
}
/* Store the current stack pointer. This value is programmed in
* the PSP register on context switch. */
xSecureContextHandle->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;
}
#endif /* configENABLE_MPU */
}
else
{
/* Free the context to avoid memory leak and make sure to return
* NULL to indicate failure. */
vPortFree( xSecureContextHandle );
xSecureContextHandle = NULL;
}
}
}
return xSecureContextHandle;
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* Ensure that valid parameters are passed. */
secureportASSERT( xSecureContextHandle != NULL );
/* Free the stack space. */
vPortFree( xSecureContextHandle->pucStackLimit );
/* Free the context itself. */
vPortFree( xSecureContextHandle );
}
}
/*-----------------------------------------------------------*/

View file

@ -1,112 +1,112 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_CONTEXT_H__
#define __SECURE_CONTEXT_H__
/* Standard includes. */
#include <stdint.h>
/* FreeRTOS includes. */
#include "FreeRTOSConfig.h"
/**
* @brief PSP value when no task's context is loaded.
*/
#define securecontextNO_STACK 0x0
/**
* @brief Opaque handle.
*/
struct SecureContext;
typedef struct SecureContext * SecureContextHandle_t;
/*-----------------------------------------------------------*/
/**
* @brief Initializes the secure context management system.
*
* PSP is set to NULL and therefore a task must allocate and load a context
* before calling any secure side function in the thread mode.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*/
void SecureContext_Init( void );
/**
* @brief Allocates a context on the secure side.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
*
* @return Opaque context handle if context is successfully allocated, NULL
* otherwise.
*/
#if ( configENABLE_MPU == 1 )
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged );
#else /* configENABLE_MPU */
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
#endif /* configENABLE_MPU */
/**
* @brief Frees the given context.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] xSecureContextHandle Context handle corresponding to the
* context to be freed.
*/
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle );
/**
* @brief Loads the given context.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] xSecureContextHandle Context handle corresponding to the context
* to be loaded.
*/
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle );
/**
* @brief Saves the given context.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] xSecureContextHandle Context handle corresponding to the context
* to be saved.
*/
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle );
#endif /* __SECURE_CONTEXT_H__ */
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_CONTEXT_H__
#define __SECURE_CONTEXT_H__
/* Standard includes. */
#include <stdint.h>
/* FreeRTOS includes. */
#include "FreeRTOSConfig.h"
/**
* @brief PSP value when no task's context is loaded.
*/
#define securecontextNO_STACK 0x0
/**
* @brief Opaque handle.
*/
struct SecureContext;
typedef struct SecureContext * SecureContextHandle_t;
/*-----------------------------------------------------------*/
/**
* @brief Initializes the secure context management system.
*
* PSP is set to NULL and therefore a task must allocate and load a context
* before calling any secure side function in the thread mode.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*/
void SecureContext_Init( void );
/**
* @brief Allocates a context on the secure side.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] ulSecureStackSize Size of the stack to allocate on secure side.
* @param[in] ulIsTaskPrivileged 1 if the calling task is privileged, 0 otherwise.
*
* @return Opaque context handle if context is successfully allocated, NULL
* otherwise.
*/
#if ( configENABLE_MPU == 1 )
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize,
uint32_t ulIsTaskPrivileged );
#else /* configENABLE_MPU */
SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize );
#endif /* configENABLE_MPU */
/**
* @brief Frees the given context.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] xSecureContextHandle Context handle corresponding to the
* context to be freed.
*/
void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle );
/**
* @brief Loads the given context.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] xSecureContextHandle Context handle corresponding to the context
* to be loaded.
*/
void SecureContext_LoadContext( SecureContextHandle_t xSecureContextHandle );
/**
* @brief Saves the given context.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*
* @param[in] xSecureContextHandle Context handle corresponding to the context
* to be saved.
*/
void SecureContext_SaveContext( SecureContextHandle_t xSecureContextHandle );
#endif /* __SECURE_CONTEXT_H__ */

View file

@ -1,48 +1,48 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* 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 );
}
/*-----------------------------------------------------------*/
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* 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

@ -1,76 +1,76 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
SECTION .text:CODE:NOROOT(2)
THUMB
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.
#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. */
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. */
save_ctx_therad_mode:
bx lr
/*-----------------------------------------------------------*/
END
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
SECTION .text:CODE:NOROOT(2)
THUMB
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.
#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. */
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. */
save_ctx_therad_mode:
bx lr
/*-----------------------------------------------------------*/
END

View file

@ -1,454 +1,454 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* Standard includes. */
#include <stdint.h>
/* Secure context heap includes. */
#include "secure_heap.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/**
* @brief Total heap size.
*/
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
/* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER
#define mtCOVERAGE_TEST_MARKER()
#endif
/* No tracing by default. */
#ifndef traceMALLOC
#define traceMALLOC( pvReturn, xWantedSize )
#endif
/* No tracing by default. */
#ifndef traceFREE
#define traceFREE( pv, xBlockSize )
#endif
/* Block sizes must not get too small. */
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
/* Assumes 8bit bytes! */
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
/*-----------------------------------------------------------*/
/* Allocate the memory for the heap. */
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
* heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
#else /* configAPPLICATION_ALLOCATED_HEAP */
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */
/**
* @brief The linked list structure.
*
* This is used to link free blocks in order of their memory address.
*/
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
size_t xBlockSize; /**< The size of the free block. */
} BlockLink_t;
/*-----------------------------------------------------------*/
/**
* @brief Called automatically to setup the required heap structures the first
* time pvPortMalloc() is called.
*/
static void prvHeapInit( void );
/**
* @brief Inserts a block of memory that is being freed into the correct
* position in the list of free memory blocks.
*
* The block being freed will be merged with the block in front it and/or the
* block behind it if the memory blocks are adjacent to each other.
*
* @param[in] pxBlockToInsert The block being freed.
*/
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
/*-----------------------------------------------------------*/
/**
* @brief The size of the structure placed at the beginning of each allocated
* memory block must by correctly byte aligned.
*/
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
/**
* @brief Create a couple of list links to mark the start and end of the list.
*/
static BlockLink_t xStart, * pxEnd = NULL;
/**
* @brief Keeps track of the number of free bytes remaining, but says nothing
* about fragmentation.
*/
static size_t xFreeBytesRemaining = 0U;
static size_t xMinimumEverFreeBytesRemaining = 0U;
/**
* @brief Gets set to the top bit of an size_t type.
*
* When this bit in the xBlockSize member of an BlockLink_t structure is set
* then the block belongs to the application. When the bit is free the block is
* still part of the free heap space.
*/
static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/
static void prvHeapInit( void )
{
BlockLink_t * pxFirstFreeBlock;
uint8_t * pucAlignedHeap;
size_t uxAddress;
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
/* Ensure the heap starts on a correctly aligned boundary. */
uxAddress = ( size_t ) ucHeap;
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
{
uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
}
pucAlignedHeap = ( uint8_t * ) uxAddress;
/* xStart is used to hold a pointer to the first item in the list of free
* blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
/* pxEnd is used to mark the end of the list of free blocks and is inserted
* at the end of the heap space. */
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
uxAddress -= xHeapStructSize;
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
pxEnd = ( void * ) uxAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the
* entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
/* Only one block exists - and it covers the entire usable heap space. */
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 );
}
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
{
BlockLink_t * pxIterator;
uint8_t * puc;
/* Iterate through the list until a block is found that has a higher address
* than the block being inserted. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
}
/* Do the block being inserted, and the block it is being inserted after
* make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
pxBlockToInsert = pxIterator;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Do the block being inserted, and the block it is being inserted before
* make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{
if( pxIterator->pxNextFreeBlock != pxEnd )
{
/* Form one big block from the two blocks. */
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxEnd;
}
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
}
/* If the block being inserted plugged a gab, so was merged with the block
* before and the block after, then it's pxNextFreeBlock pointer will have
* already been set, and should not be set here as that would make it point
* to itself. */
if( pxIterator != pxBlockToInsert )
{
pxIterator->pxNextFreeBlock = pxBlockToInsert;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/*-----------------------------------------------------------*/
void * pvPortMalloc( size_t xWantedSize )
{
BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
void * pvReturn = NULL;
/* If this is the first call to malloc then the heap will require
* initialisation to setup the list of free blocks. */
if( pxEnd == NULL )
{
prvHeapInit();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Check the requested block size is not so large that the top bit is set.
* The top bit of the block size member of the BlockLink_t structure is used
* to determine who owns the block - the application or the kernel, so it
* must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{
/* The wanted size is increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number of
* bytes. */
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
{
/* Byte alignment required. */
xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) );
secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{
/* Traverse the list from the start (lowest address) block until
* one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If the end marker was reached then a block of adequate size was
* not found. */
if( pxBlock != pxEnd )
{
/* Return the memory space pointed to - jumping over the
* BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out
* of the list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into
* two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
{
/* This block is to be split into two. Create a new
* block following the number of bytes requested. The void
* cast is used to prevent byte alignment warnings from the
* compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
/* Calculate the sizes of two blocks split from the single
* block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( pxNewBlockLink );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
{
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* The block is being returned - it is allocated and owned by
* the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
traceMALLOC( pvReturn, xWantedSize );
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void * pv )
{
uint8_t * puc = ( uint8_t * ) pv;
BlockLink_t * pxLink;
if( pv != NULL )
{
/* The memory being freed will have an BlockLink_t structure immediately
* before it. */
puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;
/* Check the block is actually allocated. */
secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
secureportASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{
if( pxLink->pxNextFreeBlock == NULL )
{
/* The block is being returned to the heap - it is no longer
* allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;
secureportDISABLE_NON_SECURE_INTERRUPTS();
{
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize );
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
}
secureportENABLE_NON_SECURE_INTERRUPTS();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
size_t xPortGetMinimumEverFreeHeapSize( void )
{
return xMinimumEverFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* This just exists to keep the linker quiet. */
}
/*-----------------------------------------------------------*/
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* Standard includes. */
#include <stdint.h>
/* Secure context heap includes. */
#include "secure_heap.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/**
* @brief Total heap size.
*/
#define secureconfigTOTAL_HEAP_SIZE ( ( ( size_t ) ( 10 * 1024 ) ) )
/* No test marker by default. */
#ifndef mtCOVERAGE_TEST_MARKER
#define mtCOVERAGE_TEST_MARKER()
#endif
/* No tracing by default. */
#ifndef traceMALLOC
#define traceMALLOC( pvReturn, xWantedSize )
#endif
/* No tracing by default. */
#ifndef traceFREE
#define traceFREE( pv, xBlockSize )
#endif
/* Block sizes must not get too small. */
#define secureheapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
/* Assumes 8bit bytes! */
#define secureheapBITS_PER_BYTE ( ( size_t ) 8 )
/*-----------------------------------------------------------*/
/* Allocate the memory for the heap. */
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
* heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
#else /* configAPPLICATION_ALLOCATED_HEAP */
static uint8_t ucHeap[ secureconfigTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */
/**
* @brief The linked list structure.
*
* This is used to link free blocks in order of their memory address.
*/
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
size_t xBlockSize; /**< The size of the free block. */
} BlockLink_t;
/*-----------------------------------------------------------*/
/**
* @brief Called automatically to setup the required heap structures the first
* time pvPortMalloc() is called.
*/
static void prvHeapInit( void );
/**
* @brief Inserts a block of memory that is being freed into the correct
* position in the list of free memory blocks.
*
* The block being freed will be merged with the block in front it and/or the
* block behind it if the memory blocks are adjacent to each other.
*
* @param[in] pxBlockToInsert The block being freed.
*/
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert );
/*-----------------------------------------------------------*/
/**
* @brief The size of the structure placed at the beginning of each allocated
* memory block must by correctly byte aligned.
*/
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( secureportBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
/**
* @brief Create a couple of list links to mark the start and end of the list.
*/
static BlockLink_t xStart, * pxEnd = NULL;
/**
* @brief Keeps track of the number of free bytes remaining, but says nothing
* about fragmentation.
*/
static size_t xFreeBytesRemaining = 0U;
static size_t xMinimumEverFreeBytesRemaining = 0U;
/**
* @brief Gets set to the top bit of an size_t type.
*
* When this bit in the xBlockSize member of an BlockLink_t structure is set
* then the block belongs to the application. When the bit is free the block is
* still part of the free heap space.
*/
static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/
static void prvHeapInit( void )
{
BlockLink_t * pxFirstFreeBlock;
uint8_t * pucAlignedHeap;
size_t uxAddress;
size_t xTotalHeapSize = secureconfigTOTAL_HEAP_SIZE;
/* Ensure the heap starts on a correctly aligned boundary. */
uxAddress = ( size_t ) ucHeap;
if( ( uxAddress & secureportBYTE_ALIGNMENT_MASK ) != 0 )
{
uxAddress += ( secureportBYTE_ALIGNMENT - 1 );
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
xTotalHeapSize -= uxAddress - ( size_t ) ucHeap;
}
pucAlignedHeap = ( uint8_t * ) uxAddress;
/* xStart is used to hold a pointer to the first item in the list of free
* blocks. The void cast is used to prevent compiler warnings. */
xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
/* pxEnd is used to mark the end of the list of free blocks and is inserted
* at the end of the heap space. */
uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize;
uxAddress -= xHeapStructSize;
uxAddress &= ~( ( size_t ) secureportBYTE_ALIGNMENT_MASK );
pxEnd = ( void * ) uxAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
/* To start with there is a single free block that is sized to take up the
* entire heap space, minus the space taken by pxEnd. */
pxFirstFreeBlock = ( void * ) pucAlignedHeap;
pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock;
pxFirstFreeBlock->pxNextFreeBlock = pxEnd;
/* Only one block exists - and it covers the entire usable heap space. */
xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
/* Work out the position of the top bit in a size_t variable. */
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * secureheapBITS_PER_BYTE ) - 1 );
}
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert )
{
BlockLink_t * pxIterator;
uint8_t * puc;
/* Iterate through the list until a block is found that has a higher address
* than the block being inserted. */
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
}
/* Do the block being inserted, and the block it is being inserted after
* make a contiguous block of memory? */
puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
pxBlockToInsert = pxIterator;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Do the block being inserted, and the block it is being inserted before
* make a contiguous block of memory? */
puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{
if( pxIterator->pxNextFreeBlock != pxEnd )
{
/* Form one big block from the two blocks. */
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxEnd;
}
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
}
/* If the block being inserted plugged a gab, so was merged with the block
* before and the block after, then it's pxNextFreeBlock pointer will have
* already been set, and should not be set here as that would make it point
* to itself. */
if( pxIterator != pxBlockToInsert )
{
pxIterator->pxNextFreeBlock = pxBlockToInsert;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
/*-----------------------------------------------------------*/
void * pvPortMalloc( size_t xWantedSize )
{
BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink;
void * pvReturn = NULL;
/* If this is the first call to malloc then the heap will require
* initialisation to setup the list of free blocks. */
if( pxEnd == NULL )
{
prvHeapInit();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* Check the requested block size is not so large that the top bit is set.
* The top bit of the block size member of the BlockLink_t structure is used
* to determine who owns the block - the application or the kernel, so it
* must be free. */
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{
/* The wanted size is increased so it can contain a BlockLink_t
* structure in addition to the requested amount of bytes. */
if( xWantedSize > 0 )
{
xWantedSize += xHeapStructSize;
/* Ensure that blocks are always aligned to the required number of
* bytes. */
if( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) != 0x00 )
{
/* Byte alignment required. */
xWantedSize += ( secureportBYTE_ALIGNMENT - ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) );
secureportASSERT( ( xWantedSize & secureportBYTE_ALIGNMENT_MASK ) == 0 );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{
/* Traverse the list from the start (lowest address) block until
* one of adequate size is found. */
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
/* If the end marker was reached then a block of adequate size was
* not found. */
if( pxBlock != pxEnd )
{
/* Return the memory space pointed to - jumping over the
* BlockLink_t structure at its start. */
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
/* This block is being returned for use so must be taken out
* of the list of free blocks. */
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
/* If the block is larger than required it can be split into
* two. */
if( ( pxBlock->xBlockSize - xWantedSize ) > secureheapMINIMUM_BLOCK_SIZE )
{
/* This block is to be split into two. Create a new
* block following the number of bytes requested. The void
* cast is used to prevent byte alignment warnings from the
* compiler. */
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
secureportASSERT( ( ( ( size_t ) pxNewBlockLink ) & secureportBYTE_ALIGNMENT_MASK ) == 0 );
/* Calculate the sizes of two blocks split from the single
* block. */
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
/* Insert the new block into the list of free blocks. */
prvInsertBlockIntoFreeList( pxNewBlockLink );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
{
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* The block is being returned - it is allocated and owned by
* the application and has no "next" block. */
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
traceMALLOC( pvReturn, xWantedSize );
#if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
#endif /* if ( secureconfigUSE_MALLOC_FAILED_HOOK == 1 ) */
secureportASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) secureportBYTE_ALIGNMENT_MASK ) == 0 );
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void * pv )
{
uint8_t * puc = ( uint8_t * ) pv;
BlockLink_t * pxLink;
if( pv != NULL )
{
/* The memory being freed will have an BlockLink_t structure immediately
* before it. */
puc -= xHeapStructSize;
/* This casting is to keep the compiler from issuing warnings. */
pxLink = ( void * ) puc;
/* Check the block is actually allocated. */
secureportASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
secureportASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{
if( pxLink->pxNextFreeBlock == NULL )
{
/* The block is being returned to the heap - it is no longer
* allocated. */
pxLink->xBlockSize &= ~xBlockAllocatedBit;
secureportDISABLE_NON_SECURE_INTERRUPTS();
{
/* Add this block to the list of free blocks. */
xFreeBytesRemaining += pxLink->xBlockSize;
traceFREE( pv, pxLink->xBlockSize );
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
}
secureportENABLE_NON_SECURE_INTERRUPTS();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
size_t xPortGetMinimumEverFreeHeapSize( void )
{
return xMinimumEverFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* This just exists to keep the linker quiet. */
}
/*-----------------------------------------------------------*/

View file

@ -1,51 +1,51 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_HEAP_H__
#define __SECURE_HEAP_H__
/* Standard includes. */
#include <stdlib.h>
/**
* @brief Allocates memory from heap.
*
* @param[in] xWantedSize The size of the memory to be allocated.
*
* @return Pointer to the memory region if the allocation is successful, NULL
* otherwise.
*/
void * pvPortMalloc( size_t xWantedSize );
/**
* @brief Frees the previously allocated memory.
*
* @param[in] pv Pointer to the memory to be freed.
*/
void vPortFree( void * pv );
#endif /* __SECURE_HEAP_H__ */
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_HEAP_H__
#define __SECURE_HEAP_H__
/* Standard includes. */
#include <stdlib.h>
/**
* @brief Allocates memory from heap.
*
* @param[in] xWantedSize The size of the memory to be allocated.
*
* @return Pointer to the memory region if the allocation is successful, NULL
* otherwise.
*/
void * pvPortMalloc( size_t xWantedSize );
/**
* @brief Frees the previously allocated memory.
*
* @param[in] pv Pointer to the memory to be freed.
*/
void vPortFree( void * pv );
#endif /* __SECURE_HEAP_H__ */

View file

@ -1,105 +1,105 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* Standard includes. */
#include <stdint.h>
/* Secure init includes. */
#include "secure_init.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/**
* @brief Constants required to manipulate the SCB.
*/
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
/**
* @brief Constants required to manipulate the FPU.
*/
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
#define secureinitFPCCR_LSPENS_POS ( 29UL )
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
#define secureinitFPCCR_TS_POS ( 26UL )
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
#define secureinitNSACR_CP10_POS ( 10UL )
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
#define secureinitNSACR_CP11_POS ( 11UL )
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
}
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
* permitted. CP11 should be programmed to the same value as CP10. */
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
* that we can enable/disable lazy stacking in port.c file. */
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
* registers (S16-S31) are also pushed to stack on exception entry and
* restored on exception return. */
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
}
}
/*-----------------------------------------------------------*/
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
/* Standard includes. */
#include <stdint.h>
/* Secure init includes. */
#include "secure_init.h"
/* Secure port macros. */
#include "secure_port_macros.h"
/**
* @brief Constants required to manipulate the SCB.
*/
#define secureinitSCB_AIRCR ( ( volatile uint32_t * ) 0xe000ed0c ) /* Application Interrupt and Reset Control Register. */
#define secureinitSCB_AIRCR_VECTKEY_POS ( 16UL )
#define secureinitSCB_AIRCR_VECTKEY_MASK ( 0xFFFFUL << secureinitSCB_AIRCR_VECTKEY_POS )
#define secureinitSCB_AIRCR_PRIS_POS ( 14UL )
#define secureinitSCB_AIRCR_PRIS_MASK ( 1UL << secureinitSCB_AIRCR_PRIS_POS )
/**
* @brief Constants required to manipulate the FPU.
*/
#define secureinitFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */
#define secureinitFPCCR_LSPENS_POS ( 29UL )
#define secureinitFPCCR_LSPENS_MASK ( 1UL << secureinitFPCCR_LSPENS_POS )
#define secureinitFPCCR_TS_POS ( 26UL )
#define secureinitFPCCR_TS_MASK ( 1UL << secureinitFPCCR_TS_POS )
#define secureinitNSACR ( ( volatile uint32_t * ) 0xe000ed8c ) /* Non-secure Access Control Register. */
#define secureinitNSACR_CP10_POS ( 10UL )
#define secureinitNSACR_CP10_MASK ( 1UL << secureinitNSACR_CP10_POS )
#define secureinitNSACR_CP11_POS ( 11UL )
#define secureinitNSACR_CP11_MASK ( 1UL << secureinitNSACR_CP11_POS )
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureInit_DePrioritizeNSExceptions( void )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
*( secureinitSCB_AIRCR ) = ( *( secureinitSCB_AIRCR ) & ~( secureinitSCB_AIRCR_VECTKEY_MASK | secureinitSCB_AIRCR_PRIS_MASK ) ) |
( ( 0x05FAUL << secureinitSCB_AIRCR_VECTKEY_POS ) & secureinitSCB_AIRCR_VECTKEY_MASK ) |
( ( 0x1UL << secureinitSCB_AIRCR_PRIS_POS ) & secureinitSCB_AIRCR_PRIS_MASK );
}
}
/*-----------------------------------------------------------*/
secureportNON_SECURE_CALLABLE void SecureInit_EnableNSFPUAccess( void )
{
uint32_t ulIPSR;
/* Read the Interrupt Program Status Register (IPSR) value. */
secureportREAD_IPSR( ulIPSR );
/* Do nothing if the processor is running in the Thread Mode. IPSR is zero
* when the processor is running in the Thread Mode. */
if( ulIPSR != 0 )
{
/* CP10 = 1 ==> Non-secure access to the Floating Point Unit is
* permitted. CP11 should be programmed to the same value as CP10. */
*( secureinitNSACR ) |= ( secureinitNSACR_CP10_MASK | secureinitNSACR_CP11_MASK );
/* LSPENS = 0 ==> LSPEN is writable fron non-secure state. This ensures
* that we can enable/disable lazy stacking in port.c file. */
*( secureinitFPCCR ) &= ~( secureinitFPCCR_LSPENS_MASK );
/* TS = 1 ==> Treat FP registers as secure i.e. callee saved FP
* registers (S16-S31) are also pushed to stack on exception entry and
* restored on exception return. */
*( secureinitFPCCR ) |= ( secureinitFPCCR_TS_MASK );
}
}
/*-----------------------------------------------------------*/

View file

@ -1,53 +1,53 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_INIT_H__
#define __SECURE_INIT_H__
/**
* @brief De-prioritizes the non-secure exceptions.
*
* This is needed to ensure that the non-secure PendSV runs at the lowest
* priority. Context switch is done in the non-secure PendSV handler.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*/
void SecureInit_DePrioritizeNSExceptions( void );
/**
* @brief Sets up the Floating Point Unit (FPU) for Non-Secure access.
*
* Also sets FPCCR.TS=1 to ensure that the content of the Floating Point
* Registers are not leaked to the non-secure side.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*/
void SecureInit_EnableNSFPUAccess( void );
#endif /* __SECURE_INIT_H__ */
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_INIT_H__
#define __SECURE_INIT_H__
/**
* @brief De-prioritizes the non-secure exceptions.
*
* This is needed to ensure that the non-secure PendSV runs at the lowest
* priority. Context switch is done in the non-secure PendSV handler.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*/
void SecureInit_DePrioritizeNSExceptions( void );
/**
* @brief Sets up the Floating Point Unit (FPU) for Non-Secure access.
*
* Also sets FPCCR.TS=1 to ensure that the content of the Floating Point
* Registers are not leaked to the non-secure side.
*
* @note This function must be called in the handler mode. It is no-op if called
* in the thread mode.
*/
void SecureInit_EnableNSFPUAccess( void );
#endif /* __SECURE_INIT_H__ */

View file

@ -1,133 +1,133 @@
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_PORT_MACROS_H__
#define __SECURE_PORT_MACROS_H__
/**
* @brief Byte alignment requirements.
*/
#define secureportBYTE_ALIGNMENT 8
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
/**
* @brief Macro to declare a function as non-secure callable.
*/
#if defined( __IAR_SYSTEMS_ICC__ )
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
#else
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
#endif
/**
* @brief Set the secure PRIMASK value.
*/
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
/**
* @brief Set the non-secure PRIMASK value.
*/
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
/**
* @brief Read the PSP value in the given variable.
*/
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
/**
* @brief Set the PSP to the given value.
*/
#define secureportSET_PSP( pucCurrentStackPointer ) \
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
/**
* @brief Set the PSPLIM to the given value.
*/
#define secureportSET_PSPLIM( pucStackLimit ) \
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
/**
* @brief Set the NonSecure MSP to the given value.
*/
#define secureportSET_MSP_NS( pucMainStackPointer ) \
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
/**
* @brief Set the CONTROL register to the given value.
*/
#define secureportSET_CONTROL( ulControl ) \
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
/**
* @brief Read the Interrupt Program Status Register (IPSR) value in the given
* variable.
*/
#define secureportREAD_IPSR( ulIPSR ) \
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
/**
* @brief PRIMASK value to enable interrupts.
*/
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
/**
* @brief PRIMASK value to disable interrupts.
*/
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
/**
* @brief Disable secure interrupts.
*/
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
/**
* @brief Disable non-secure interrupts.
*
* This effectively disables context switches.
*/
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
/**
* @brief Enable non-secure interrupts.
*/
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
/**
* @brief Assert definition.
*/
#define secureportASSERT( x ) \
if( ( x ) == 0 ) \
{ \
secureportDISABLE_SECURE_INTERRUPTS(); \
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
for( ; ; ) {; } \
}
#endif /* __SECURE_PORT_MACROS_H__ */
/*
* FreeRTOS Kernel V10.4.3
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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
*
* 1 tab == 4 spaces!
*/
#ifndef __SECURE_PORT_MACROS_H__
#define __SECURE_PORT_MACROS_H__
/**
* @brief Byte alignment requirements.
*/
#define secureportBYTE_ALIGNMENT 8
#define secureportBYTE_ALIGNMENT_MASK ( 0x0007 )
/**
* @brief Macro to declare a function as non-secure callable.
*/
#if defined( __IAR_SYSTEMS_ICC__ )
#define secureportNON_SECURE_CALLABLE __cmse_nonsecure_entry __root
#else
#define secureportNON_SECURE_CALLABLE __attribute__( ( cmse_nonsecure_entry ) ) __attribute__( ( used ) )
#endif
/**
* @brief Set the secure PRIMASK value.
*/
#define secureportSET_SECURE_PRIMASK( ulPrimaskValue ) \
__asm volatile ( "msr primask, %0" : : "r" ( ulPrimaskValue ) : "memory" )
/**
* @brief Set the non-secure PRIMASK value.
*/
#define secureportSET_NON_SECURE_PRIMASK( ulPrimaskValue ) \
__asm volatile ( "msr primask_ns, %0" : : "r" ( ulPrimaskValue ) : "memory" )
/**
* @brief Read the PSP value in the given variable.
*/
#define secureportREAD_PSP( pucOutCurrentStackPointer ) \
__asm volatile ( "mrs %0, psp" : "=r" ( pucOutCurrentStackPointer ) )
/**
* @brief Set the PSP to the given value.
*/
#define secureportSET_PSP( pucCurrentStackPointer ) \
__asm volatile ( "msr psp, %0" : : "r" ( pucCurrentStackPointer ) )
/**
* @brief Set the PSPLIM to the given value.
*/
#define secureportSET_PSPLIM( pucStackLimit ) \
__asm volatile ( "msr psplim, %0" : : "r" ( pucStackLimit ) )
/**
* @brief Set the NonSecure MSP to the given value.
*/
#define secureportSET_MSP_NS( pucMainStackPointer ) \
__asm volatile ( "msr msp_ns, %0" : : "r" ( pucMainStackPointer ) )
/**
* @brief Set the CONTROL register to the given value.
*/
#define secureportSET_CONTROL( ulControl ) \
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) : "memory" )
/**
* @brief Read the Interrupt Program Status Register (IPSR) value in the given
* variable.
*/
#define secureportREAD_IPSR( ulIPSR ) \
__asm volatile ( "mrs %0, ipsr" : "=r" ( ulIPSR ) )
/**
* @brief PRIMASK value to enable interrupts.
*/
#define secureportPRIMASK_ENABLE_INTERRUPTS_VAL 0
/**
* @brief PRIMASK value to disable interrupts.
*/
#define secureportPRIMASK_DISABLE_INTERRUPTS_VAL 1
/**
* @brief Disable secure interrupts.
*/
#define secureportDISABLE_SECURE_INTERRUPTS() secureportSET_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
/**
* @brief Disable non-secure interrupts.
*
* This effectively disables context switches.
*/
#define secureportDISABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_DISABLE_INTERRUPTS_VAL )
/**
* @brief Enable non-secure interrupts.
*/
#define secureportENABLE_NON_SECURE_INTERRUPTS() secureportSET_NON_SECURE_PRIMASK( secureportPRIMASK_ENABLE_INTERRUPTS_VAL )
/**
* @brief Assert definition.
*/
#define secureportASSERT( x ) \
if( ( x ) == 0 ) \
{ \
secureportDISABLE_SECURE_INTERRUPTS(); \
secureportDISABLE_NON_SECURE_INTERRUPTS(); \
for( ; ; ) {; } \
}
#endif /* __SECURE_PORT_MACROS_H__ */