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 bool vfp_is_enabled(void); 80 void vfp_enable(void); 81 void vfp_disable(void); 82 83 /* 84 * vfp_lazy_save_state_init() - Saves VFP enable status and disables VFP 85 * @state: VFP state structure to initialize 86 */ 87 void vfp_lazy_save_state_init(struct vfp_state *state); 88 89 /* 90 * vfp_lazy_save_state_final() - Saves rest of VFP state 91 * @state: VFP state to save to 92 * 93 * If VFP was enabled when vfp_lazy_save_state_init() was called: save rest 94 * of state and disable VFP. Otherwise, do nothing. 95 */ 96 void vfp_lazy_save_state_final(struct vfp_state *state); 97 98 /* 99 * vfp_lazy_restore_state() - Lazy restore VFP state 100 * @state: VFP state to restore 101 * 102 * Restores VFP enable status and also restores rest of VFP state if 103 * vfp_lazy_save_state_final() was called on this state. 104 */ 105 void vfp_lazy_restore_state(struct vfp_state *state, bool full_state); 106 107 #endif /*KERNEL_VFP_H*/ 108