Skip to content

Commit ff0989e

Browse files
GhMarwenarchigup
authored andcommitted
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] #1048 Signed-off-by: Marouen Ghodhbane <[email protected]>
1 parent 1b8f596 commit ff0989e

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

portable/GCC/ARM_AARCH64_SRE/port.c

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@
121121
::"r" ( portUNMASK_VALUE ) ); \
122122
}
123123

124+
/* The space on the stack required to hold the FPU registers.
125+
* There are 32 128-bit registers.*/
126+
#define portFPU_REGISTER_WORDS ( 32 * 2 )
127+
124128
/*-----------------------------------------------------------*/
125129

126130
/*
@@ -229,23 +233,47 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
229233
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
230234
pxTopOfStack--;
231235
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
232-
pxTopOfStack--;
233-
234-
*pxTopOfStack = portINITIAL_PSTATE;
235-
pxTopOfStack--;
236236

237-
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
238237
pxTopOfStack--;
238+
*pxTopOfStack = portINITIAL_PSTATE;
239239

240-
/* The task will start with a critical nesting count of 0 as interrupts are
241-
* enabled. */
242-
*pxTopOfStack = portNO_CRITICAL_NESTING;
243240
pxTopOfStack--;
241+
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
244242

245-
/* The task will start without a floating point context. A task that uses
246-
* the floating point hardware must call vPortTaskUsesFPU() before executing
247-
* any floating point instructions. */
248-
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
243+
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
244+
{
245+
/* The task will start with a critical nesting count of 0 as interrupts are
246+
* enabled. */
247+
pxTopOfStack--;
248+
*pxTopOfStack = portNO_CRITICAL_NESTING;
249+
250+
/* The task will start without a floating point context. A task that
251+
* uses the floating point hardware must call vPortTaskUsesFPU() before
252+
* executing any floating point instructions. */
253+
pxTopOfStack--;
254+
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
255+
}
256+
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
257+
{
258+
/* The task will start with a floating point context. Leave enough
259+
* space for the registers - and ensure they are initialised to 0. */
260+
pxTopOfStack -= portFPU_REGISTER_WORDS;
261+
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
262+
263+
/* The task will start with a critical nesting count of 0 as interrupts are
264+
* enabled. */
265+
pxTopOfStack--;
266+
*pxTopOfStack = portNO_CRITICAL_NESTING;
267+
268+
pxTopOfStack--;
269+
*pxTopOfStack = pdTRUE;
270+
ullPortTaskHasFPUContext = pdTRUE;
271+
}
272+
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
273+
{
274+
#error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
275+
}
276+
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
249277

250278
return pxTopOfStack;
251279
}
@@ -384,6 +412,8 @@ void FreeRTOS_Tick_Handler( void )
384412
}
385413
/*-----------------------------------------------------------*/
386414

415+
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
416+
387417
void vPortTaskUsesFPU( void )
388418
{
389419
/* A task is registering the fact that it needs an FPU context. Set the
@@ -393,6 +423,8 @@ void vPortTaskUsesFPU( void )
393423
/* Consider initialising the FPSR here - but probably not necessary in
394424
* AArch64. */
395425
}
426+
427+
#endif /* configUSE_TASK_FPU_SUPPORT */
396428
/*-----------------------------------------------------------*/
397429

398430
void vPortClearInterruptMask( UBaseType_t uxNewMaskValue )

portable/GCC/ARM_AARCH64_SRE/portmacro.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,18 @@ extern void vPortInstallFreeRTOSVectorTable( void );
135135
* handler for whichever peripheral is used to generate the RTOS tick. */
136136
void FreeRTOS_Tick_Handler( void );
137137

138-
/* Any task that uses the floating point unit MUST call vPortTaskUsesFPU()
139-
* before any floating point instructions are executed. */
140-
void vPortTaskUsesFPU( void );
138+
/* If configUSE_TASK_FPU_SUPPORT is set to 1 (or left undefined) then tasks are
139+
* created without an FPU context and must call vPortTaskUsesFPU() to give
140+
* themselves an FPU context before using any FPU instructions. If
141+
* configUSE_TASK_FPU_SUPPORT is set to 2 then all tasks will have an FPU context
142+
* by default. */
143+
#if ( configUSE_TASK_FPU_SUPPORT != 2 )
144+
void vPortTaskUsesFPU( void );
145+
#else
146+
/* Each task has an FPU context already, so define this function away to
147+
* nothing to prevent it from being called accidentally. */
148+
#define vPortTaskUsesFPU()
149+
#endif
141150
#define portTASK_USES_FLOATING_POINT() vPortTaskUsesFPU()
142151

143152
#define portLOWEST_INTERRUPT_PRIORITY ( ( ( uint32_t ) configUNIQUE_INTERRUPT_PRIORITIES ) - 1UL )

0 commit comments

Comments
 (0)