1 /* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7 #pragma once 8 9 #include <config.h> 10 #include <object/structures.h> 11 #include <model/statedata.h> 12 #include <arch/machine/fpu.h> 13 14 #ifdef CONFIG_HAVE_FPU 15 16 /* Perform any actions required for the deletion of the given thread. */ 17 void fpuThreadDelete(tcb_t *thread); 18 19 /* Handle an FPU exception. */ 20 exception_t handleFPUFault(void); 21 22 void switchLocalFpuOwner(user_fpu_state_t *new_owner); 23 24 /* Switch the current owner of the FPU state on the core specified by 'cpu'. */ 25 void switchFpuOwner(user_fpu_state_t *new_owner, word_t cpu); 26 27 /* Returns whether or not the passed thread is using the current active fpu state */ nativeThreadUsingFPU(tcb_t * thread)28static inline bool_t nativeThreadUsingFPU(tcb_t *thread) 29 { 30 return &thread->tcbArch.tcbContext.fpuState == 31 NODE_STATE_ON_CORE(ksActiveFPUState, thread->tcbAffinity); 32 } 33 lazyFPURestore(tcb_t * thread)34static inline void FORCE_INLINE lazyFPURestore(tcb_t *thread) 35 { 36 if (unlikely(NODE_STATE(ksActiveFPUState))) { 37 /* If we have enabled/disabled the FPU too many times without 38 * someone else trying to use it, we assume it is no longer 39 * in use and switch out its state. */ 40 if (unlikely(NODE_STATE(ksFPURestoresSinceSwitch) > CONFIG_FPU_MAX_RESTORES_SINCE_SWITCH)) { 41 switchLocalFpuOwner(NULL); 42 NODE_STATE(ksFPURestoresSinceSwitch) = 0; 43 } else { 44 if (likely(nativeThreadUsingFPU(thread))) { 45 /* We are using the FPU, make sure it is enabled */ 46 enableFpu(); 47 } else { 48 /* Someone is using the FPU and it might be enabled */ 49 disableFpu(); 50 } 51 NODE_STATE(ksFPURestoresSinceSwitch)++; 52 } 53 } else { 54 /* No-one (including us) is using the FPU, so we assume it 55 * is currently disabled */ 56 } 57 } 58 59 #endif /* CONFIG_HAVE_FPU */ 60 61