portable: aarch64_sre: Add support for vApplicationFPUSafeIRQHandler

The application writer needs to name their IRQ handler as:
1. vApplicationIRQHandler if the IRQ handler does not use FPU registers.
2. vApplicationFPUSafeIRQHandler is the IRQ handler uses FPU registers.

When the application uses vApplicationFPUSafeIRQHandler, a default
implementation of vApplicationIRQHandler is used which stores FPU
registers and then calls vApplicationFPUSafeIRQHandler.

Note that recent versions of GCC may use FP/SIMD registers to optimize 16-bytes
copy and especially when using va_start()/va_arg() functions (e.g printing some thing
in IRQ handlers may trigger usage of FPU registers)

This implementation is heavily inspired by both the ARM_CA9 port and the ARM_CRx_No_GIC
port done in [1]

[1] https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/1113

Signed-off-by: Marouen Ghodhbane <marouen.ghodhbane@nxp.com>
This commit is contained in:
Marouen Ghodhbane 2024-10-11 15:36:42 +02:00 committed by Archit Gupta
parent 630cfb5b79
commit 72bb476bf3
2 changed files with 101 additions and 0 deletions

View file

@ -133,6 +133,27 @@
*/
extern void vPortRestoreTaskContext( void );
/*
* If the application provides an implementation of vApplicationIRQHandler(),
* then it will get called directly without saving the FPU registers on
* interrupt entry, and this weak implementation of
* vApplicationFPUSafeIRQHandler() is just provided to remove linkage errors -
* it should never actually get called so its implementation contains a
* call to configASSERT() that will always fail.
*
* If the application provides its own implementation of
* vApplicationFPUSafeIRQHandler() then the implementation of
* vApplicationIRQHandler() provided in portASM.S will save the FPU registers
* before calling it.
*
* Therefore, if the application writer wants FPU registers to be saved on
* interrupt entry their IRQ handler must be called
* vApplicationFPUSafeIRQHandler(), and if the application writer does not want
* FPU registers to be saved on interrupt entry their IRQ handler must be
* called vApplicationIRQHandler().
*/
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR ) __attribute__((weak) );
/*-----------------------------------------------------------*/
/* A variable is used to keep track of the critical section nesting. This
@ -495,3 +516,9 @@ UBaseType_t uxPortSetInterruptMask( void )
#endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/
void vApplicationFPUSafeIRQHandler( uint32_t ulICCIAR )
{
( void ) ulICCIAR;
configASSERT( ( volatile void * ) NULL );
}