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)28 static 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)34 static 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