portable: aarch64_sre: add configUSE_TASK_FPU_SUPPORT support

This is a direct backport of upstream commit [1] for aarch64 (legacy operation port)
done under [2]
The same code can be applied on the aarch SRE port to be able to enable FPU context
saving on all tasks context switch to mitigate GCC optimization to use SIMD registers
for copy.

[1] "55eceb22: Add configUSE_TASK_FPU_SUPPORT to AARCH64 port (#1048)"
[2] https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/1048

Signed-off-by: Marouen Ghodhbane <marouen.ghodhbane@nxp.com>
This commit is contained in:
Marouen Ghodhbane 2024-10-09 17:31:45 +02:00 committed by Aziz Sellami
parent 1b8f5965d3
commit a9e6fd8ef0
2 changed files with 55 additions and 14 deletions

View file

@ -121,6 +121,10 @@
::"r" ( portUNMASK_VALUE ) ); \ ::"r" ( portUNMASK_VALUE ) ); \
} }
/* The space on the stack required to hold the FPU registers.
* There are 32 128-bit registers.*/
#define portFPU_REGISTER_WORDS ( 32 * 2 )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* /*
@ -229,23 +233,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 = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
pxTopOfStack--; pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */ *pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
pxTopOfStack--;
pxTopOfStack--;
*pxTopOfStack = portINITIAL_PSTATE; *pxTopOfStack = portINITIAL_PSTATE;
pxTopOfStack--;
pxTopOfStack--;
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */ *pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
pxTopOfStack--;
/* The task will start with a critical nesting count of 0 as interrupts are #if ( configUSE_TASK_FPU_SUPPORT == 1 )
* enabled. */ {
*pxTopOfStack = portNO_CRITICAL_NESTING; /* The task will start with a critical nesting count of 0 as interrupts are
pxTopOfStack--; * enabled. */
pxTopOfStack--;
*pxTopOfStack = portNO_CRITICAL_NESTING;
/* The task will start without a floating point context. A task that uses /* The task will start without a floating point context. A task that
* the floating point hardware must call vPortTaskUsesFPU() before executing * uses the floating point hardware must call vPortTaskUsesFPU() before
* any floating point instructions. */ * executing any floating point instructions. */
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT; 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; return pxTopOfStack;
} }
@ -384,6 +412,8 @@ void FreeRTOS_Tick_Handler( void )
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
void vPortTaskUsesFPU( void ) void vPortTaskUsesFPU( void )
{ {
/* A task is registering the fact that it needs an FPU context. Set the /* A task is registering the fact that it needs an FPU context. Set the
@ -393,6 +423,8 @@ void vPortTaskUsesFPU( void )
/* Consider initialising the FPSR here - but probably not necessary in /* Consider initialising the FPSR here - but probably not necessary in
* AArch64. */ * AArch64. */
} }
#endif /* configUSE_TASK_FPU_SUPPORT */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vPortClearInterruptMask( UBaseType_t uxNewMaskValue ) void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )

View file

@ -135,9 +135,18 @@ extern void vPortInstallFreeRTOSVectorTable( void );
* handler for whichever peripheral is used to generate the RTOS tick. */ * handler for whichever peripheral is used to generate the RTOS tick. */
void FreeRTOS_Tick_Handler( void ); void FreeRTOS_Tick_Handler( void );
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU() /* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
* before any floating point instructions are executed. */ * created without an FPU context and must call vPortTaskUsesFPU() to give
void vPortTaskUsesFPU( void ); * themselves an FPU context before using any FPU instructions. If
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
* by default. */
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
void vPortTaskUsesFPU( void );
#else
/* Each task has an FPU context already, so define this function away to
* nothing to prevent it from being called accidentally. */
#define vPortTaskUsesFPU()
#endif
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU() #define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL ) #define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )