Skip to content
Permalink
Browse files

arch: arm: enable lazy state preservation at boot in FP sharing mode

In FP Sharing mode we enable both automatic and lazy state
preservation of the FP context. This configuration improves
interrupt latency. Under this configuration the FP registers
will only be stacked when the thread is swapped out during
context-switch. Before jumping to main() we clear the FPCA
flag of the CONTROL register, so the FP context can be used
by the main thread.

Signed-off-by: Ioannis Glaropoulos <Ioannis.Glaropoulos@nordicsemi.no>
  • Loading branch information...
ioannisg authored and nashif committed Apr 22, 2019
1 parent c8f43b9 commit eecf4b03a3841a5373c21b133e6e4c90458451a4
Showing with 16 additions and 5 deletions.
  1. +9 −3 arch/arm/core/cortex_m/prep_c.c
  2. +7 −2 arch/arm/include/kernel_arch_func.h
@@ -107,10 +107,16 @@ static inline void enable_floating_point(void)
FPU->FPCCR &= (~(FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk));
#else
/*
* Disable lazy state preservation so the volatile FP registers are
* always saved on exception.
* Enable both automatic and lazy state preservation of the FP context.
* The FPCA bit of the CONTROL register will be automatically set, if
* the thread uses the floating point registers. Because of lazy state
* preservation the volatile FP registers will not be stacked upon
* exception entry, however, the required area in the stack frame will
* be reserved for them. This configuration improves interrupt latency.
* The registers will eventually be stacked when the thread is swapped
* out during context-switch.
*/
FPU->FPCCR = FPU_FPCCR_ASPEN_Msk; /* FPU_FPCCR_LSPEN = 0 */
FPU->FPCCR = FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk;
#endif /* CONFIG_FP_SHARING */

/* Make the side-effects of modifying the FPCCR be realized
@@ -48,13 +48,18 @@ z_arch_switch_to_main_thread(struct k_thread *main_thread,
k_thread_stack_t *main_stack,
size_t main_stack_size, k_thread_entry_t _main)
{
#if defined(CONFIG_FLOAT) && !defined(CONFIG_FP_SHARING)
#if defined(CONFIG_FLOAT)
/* Initialize the Floating Point Status and Control Register when in
* Unshared FP Registers mode (In Shared FP Registers mode, FPSCR is
* initialized at thread creation for threads that make use of the FP).
*/
__set_FPSCR(0);
#endif
#if defined(CONFIG_FP_SHARING)
/* In Sharing mode clearing FPSCR may set the CONTROL.FPCA flag. */
__set_CONTROL(__get_CONTROL() & (~(CONTROL_FPCA_Msk)));
__ISB();
#endif /* CONFIG_FP_SHARING */
#endif /* CONFIG_FLOAT */

#ifdef CONFIG_ARM_MPU
/* Configure static memory map. This will program MPU regions,

0 comments on commit eecf4b0

Please sign in to comment.
You can’t perform that action at this time.