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