mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-10 08:07:46 -04:00
Add configUSE_TASK_FPU_SUPPORT to AARCH64 port
NEON SIMD is required by standard AARCH64 and its registers are frequently utilized by standard functions such as memcpy(). This means that even simple tasks that do not use any floating point arithmetics may still alter the contents of the FPU registers. For this reason it makes sense to add support for configUSE_TASK_FPU_SUPPORT to be able to enforce FPU register saving and restoring globally. The implementation was largely adopted from the ARM_CA9 port. However, the FPU registers must be placed on the stack before the critical nesting count to match the AARCH64 portASM.S.
This commit is contained in:
parent
30afc1a2c0
commit
d57cbc07d0
1 changed files with 39 additions and 11 deletions
|
@ -133,6 +133,10 @@
|
|||
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
|
||||
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
|
||||
|
||||
/* The space on the stack required to hold the FPU registers.
|
||||
* There are 32 128-bit registers.*/
|
||||
#define portFPU_REGISTER_WORDS ( 32 * 2 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -244,23 +248,47 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
|
|||
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
|
||||
pxTopOfStack--;
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portINITIAL_PSTATE;
|
||||
pxTopOfStack--;
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
* enabled. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
pxTopOfStack--;
|
||||
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
|
||||
{
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
* enabled. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
/* The task will start without a floating point context. A task that uses
|
||||
* the floating point hardware must call vPortTaskUsesFPU() before executing
|
||||
* any floating point instructions. */
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
/* The task will start without a floating point context. A task that
|
||||
* uses the floating point hardware must call vPortTaskUsesFPU() before
|
||||
* executing any floating point instructions. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
|
||||
}
|
||||
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
|
||||
{
|
||||
/* The task will start with a floating point context. Leave enough
|
||||
* space for the registers - and ensure they are initialised to 0. */
|
||||
pxTopOfStack -= portFPU_REGISTER_WORDS;
|
||||
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
|
||||
|
||||
/* The task will start with a critical nesting count of 0 as interrupts are
|
||||
* enabled. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = pdTRUE;
|
||||
ullPortTaskHasFPUContext = pdTRUE;
|
||||
}
|
||||
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||
{
|
||||
#error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
|
||||
}
|
||||
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue