Skip to content

Commit d57cbc0

Browse files
committed
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.
1 parent 30afc1a commit d57cbc0

File tree

1 file changed

+40
-12
lines changed
  • portable/GCC/ARM_AARCH64

1 file changed

+40
-12
lines changed

portable/GCC/ARM_AARCH64/port.c

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@
133133
#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff )
134134
#define portBIT_0_SET ( ( uint8_t ) 0x01 )
135135

136+
/* The space on the stack required to hold the FPU registers.
137+
* There are 32 128-bit registers.*/
138+
#define portFPU_REGISTER_WORDS ( 32 * 2 )
139+
136140
/*-----------------------------------------------------------*/
137141

138142
/*
@@ -244,23 +248,47 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
244248
*pxTopOfStack = ( StackType_t ) 0x00; /* XZR - has no effect, used so there are an even number of registers. */
245249
pxTopOfStack--;
246250
*pxTopOfStack = ( StackType_t ) 0x00; /* R30 - procedure call link register. */
247-
pxTopOfStack--;
248251

249-
*pxTopOfStack = portINITIAL_PSTATE;
250-
pxTopOfStack--;
251-
252-
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
253252
pxTopOfStack--;
253+
*pxTopOfStack = portINITIAL_PSTATE;
254254

255-
/* The task will start with a critical nesting count of 0 as interrupts are
256-
* enabled. */
257-
*pxTopOfStack = portNO_CRITICAL_NESTING;
258255
pxTopOfStack--;
256+
*pxTopOfStack = ( StackType_t ) pxCode; /* Exception return address. */
259257

260-
/* The task will start without a floating point context. A task that uses
261-
* the floating point hardware must call vPortTaskUsesFPU() before executing
262-
* any floating point instructions. */
263-
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
258+
#if ( configUSE_TASK_FPU_SUPPORT == 1 )
259+
{
260+
/* The task will start with a critical nesting count of 0 as interrupts are
261+
* enabled. */
262+
pxTopOfStack--;
263+
*pxTopOfStack = portNO_CRITICAL_NESTING;
264+
265+
/* The task will start without a floating point context. A task that
266+
* uses the floating point hardware must call vPortTaskUsesFPU() before
267+
* executing any floating point instructions. */
268+
pxTopOfStack--;
269+
*pxTopOfStack = portNO_FLOATING_POINT_CONTEXT;
270+
}
271+
#elif ( configUSE_TASK_FPU_SUPPORT == 2 )
272+
{
273+
/* The task will start with a floating point context. Leave enough
274+
* space for the registers - and ensure they are initialised to 0. */
275+
pxTopOfStack -= portFPU_REGISTER_WORDS;
276+
memset( pxTopOfStack, 0x00, portFPU_REGISTER_WORDS * sizeof( StackType_t ) );
277+
278+
/* The task will start with a critical nesting count of 0 as interrupts are
279+
* enabled. */
280+
pxTopOfStack--;
281+
*pxTopOfStack = portNO_CRITICAL_NESTING;
282+
283+
pxTopOfStack--;
284+
*pxTopOfStack = pdTRUE;
285+
ullPortTaskHasFPUContext = pdTRUE;
286+
}
287+
#else /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
288+
{
289+
#error "Invalid configUSE_TASK_FPU_SUPPORT setting - configUSE_TASK_FPU_SUPPORT must be set to 1, 2, or left undefined."
290+
}
291+
#endif /* if ( configUSE_TASK_FPU_SUPPORT == 1 ) */
264292

265293
return pxTopOfStack;
266294
}

0 commit comments

Comments
 (0)