1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2015, Linaro Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef KERNEL_VFP_H 30 #define KERNEL_VFP_H 31 32 #include <types_ext.h> 33 #include <compiler.h> 34 35 #ifdef ARM32 36 /* 37 * Advanced SIMD/floating point state on ARMv7-A or ARMv8-A AArch32 has: 38 * - 32 64-bit data registers 39 * - FPSCR (32 bits) 40 * - FPEXC (32 bits) 41 */ 42 43 #define VFP_NUM_REGS 32 44 45 struct vfp_reg { 46 uint64_t v; 47 }; 48 49 struct vfp_state { 50 uint32_t fpexc; 51 uint32_t fpscr; 52 struct vfp_reg reg[VFP_NUM_REGS]; 53 }; 54 #endif 55 56 #ifdef ARM64 57 /* 58 * Advanced SIMD/floating point state on ARMv8-A AArch64 has: 59 * - 32 128-bit data registers 60 * - FPSR (32 bits) 61 * - FPCR (32 bits) 62 * - CPACR_EL1.FPEN (2 bits) 63 */ 64 65 #define VFP_NUM_REGS 32 66 67 struct vfp_reg { 68 uint8_t v[16]; 69 } __aligned(16); 70 71 struct vfp_state { 72 struct vfp_reg reg[VFP_NUM_REGS]; 73 uint32_t fpsr; 74 uint32_t fpcr; 75 uint32_t cpacr_el1; 76 bool force_save; /* Save to reg even if VFP was not enabled */ 77 }; 78 #endif 79 80 #ifdef CFG_WITH_VFP 81 /* vfp_is_enabled() - Returns true if VFP is enabled */ 82 bool vfp_is_enabled(void); 83 84 /* vfp_enable() - Enables vfp */ 85 void vfp_enable(void); 86 87 /* vfp_disable() - Disables vfp */ 88 void vfp_disable(void); 89 #else 90 static inline bool vfp_is_enabled(void) 91 { 92 return false; 93 } 94 95 static inline void vfp_enable(void) 96 { 97 } 98 99 static inline void vfp_disable(void) 100 { 101 } 102 #endif 103 104 /* 105 * vfp_lazy_save_state_init() - Saves VFP enable status and disables VFP 106 * @state: VFP state structure to initialize 107 */ 108 void vfp_lazy_save_state_init(struct vfp_state *state); 109 110 /* 111 * vfp_lazy_save_state_final() - Saves rest of VFP state 112 * @state: VFP state to save to 113 * 114 * If VFP was enabled when vfp_lazy_save_state_init() was called: save rest 115 * of state and disable VFP. Otherwise, do nothing. 116 */ 117 void vfp_lazy_save_state_final(struct vfp_state *state); 118 119 /* 120 * vfp_lazy_restore_state() - Lazy restore VFP state 121 * @state: VFP state to restore 122 * 123 * Restores VFP enable status and also restores rest of VFP state if 124 * vfp_lazy_save_state_final() was called on this state. 125 */ 126 void vfp_lazy_restore_state(struct vfp_state *state, bool full_state); 127 128 #endif /*KERNEL_VFP_H*/ 129