1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or https://opensource.org/licenses/CDDL-1.0. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (C) 2019 Romain Dolbeau 23 * <romain.dolbeau@european-processor-initiative.eu> 24 * Copyright (C) 2022 Tino Reichardt <milky-zfs@mcmilk.de> 25 */ 26 27 /* 28 * USER API: 29 * 30 * Kernel fpu methods: 31 * kfpu_allowed() 32 * kfpu_begin() 33 * kfpu_end() 34 * kfpu_init() 35 * kfpu_fini() 36 * 37 * SIMD support: 38 * 39 * Following functions should be called to determine whether CPU feature 40 * is supported. All functions are usable in kernel and user space. 41 * If a SIMD algorithm is using more than one instruction set 42 * all relevant feature test functions should be called. 43 * 44 * Supported features: 45 * zfs_altivec_available() 46 * zfs_vsx_available() 47 * zfs_isa207_available() 48 */ 49 50 #ifndef _LINUX_SIMD_POWERPC_H 51 #define _LINUX_SIMD_POWERPC_H 52 53 /* only for __powerpc__ */ 54 #if defined(__powerpc__) 55 56 #include <linux/preempt.h> 57 #include <linux/export.h> 58 #include <linux/sched.h> 59 #include <asm/switch_to.h> 60 #include <sys/types.h> 61 #include <linux/version.h> 62 63 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0) 64 #include <asm/cpufeature.h> 65 #else 66 #include <asm/cputable.h> 67 #endif 68 69 #define kfpu_allowed() 1 70 71 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) 72 #ifdef CONFIG_SPE 73 #define kfpu_begin() \ 74 { \ 75 preempt_disable(); \ 76 enable_kernel_altivec(); \ 77 enable_kernel_vsx(); \ 78 enable_kernel_spe(); \ 79 } 80 #define kfpu_end() \ 81 { \ 82 disable_kernel_spe(); \ 83 disable_kernel_vsx(); \ 84 disable_kernel_altivec(); \ 85 preempt_enable(); \ 86 } 87 #else /* CONFIG_SPE */ 88 #define kfpu_begin() \ 89 { \ 90 preempt_disable(); \ 91 enable_kernel_altivec(); \ 92 enable_kernel_vsx(); \ 93 } 94 #define kfpu_end() \ 95 { \ 96 disable_kernel_vsx(); \ 97 disable_kernel_altivec(); \ 98 preempt_enable(); \ 99 } 100 #endif 101 #else 102 /* seems that before 4.5 no-one bothered */ 103 #define kfpu_begin() 104 #define kfpu_end() preempt_enable() 105 #endif 106 107 #define kfpu_init() 0 108 #define kfpu_fini() ((void) 0) 109 110 /* 111 * Check if AltiVec instruction set is available 112 */ 113 static inline boolean_t 114 zfs_altivec_available(void) 115 { 116 return (cpu_has_feature(CPU_FTR_ALTIVEC)); 117 } 118 119 /* 120 * Check if VSX is available 121 */ 122 static inline boolean_t 123 zfs_vsx_available(void) 124 { 125 return (cpu_has_feature(CPU_FTR_VSX)); 126 } 127 128 /* 129 * Check if POWER ISA 2.07 is available (SHA2) 130 */ 131 static inline boolean_t 132 zfs_isa207_available(void) 133 { 134 return (cpu_has_feature(CPU_FTR_ARCH_207S)); 135 } 136 137 #endif /* defined(__powerpc) */ 138 139 #endif /* _LINUX_SIMD_POWERPC_H */ 140