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 #include <linux/preempt.h> 54 #include <linux/export.h> 55 #include <linux/sched.h> 56 #include <asm/switch_to.h> 57 #include <sys/types.h> 58 #include <linux/version.h> 59 #include <asm/cpufeature.h> 60 61 #define kfpu_allowed() 1 62 63 #ifdef CONFIG_ALTIVEC 64 #define ENABLE_KERNEL_ALTIVEC enable_kernel_altivec(); 65 #define DISABLE_KERNEL_ALTIVEC disable_kernel_altivec(); 66 #else 67 #define ENABLE_KERNEL_ALTIVEC 68 #define DISABLE_KERNEL_ALTIVEC 69 #endif 70 #ifdef CONFIG_VSX 71 #define ENABLE_KERNEL_VSX enable_kernel_vsx(); 72 #define DISABLE_KERNEL_VSX disable_kernel_vsx(); 73 #else 74 #define ENABLE_KERNEL_VSX 75 #define DISABLE_KERNEL_VSX 76 #endif 77 #ifdef CONFIG_SPE 78 #define ENABLE_KERNEL_SPE enable_kernel_spe(); 79 #define DISABLE_KERNEL_SPE disable_kernel_spe(); 80 #else 81 #define ENABLE_KERNEL_SPE 82 #define DISABLE_KERNEL_SPE 83 #endif 84 #define kfpu_begin() \ 85 { \ 86 preempt_disable(); \ 87 ENABLE_KERNEL_ALTIVEC \ 88 ENABLE_KERNEL_VSX \ 89 ENABLE_KERNEL_SPE \ 90 } 91 #define kfpu_end() \ 92 { \ 93 DISABLE_KERNEL_SPE \ 94 DISABLE_KERNEL_VSX \ 95 DISABLE_KERNEL_ALTIVEC \ 96 preempt_enable(); \ 97 } 98 99 #define kfpu_init() 0 100 #define kfpu_fini() ((void) 0) 101 102 /* 103 * Linux 4.7 makes cpu_has_feature to use jump labels on powerpc if 104 * CONFIG_JUMP_LABEL_FEATURE_CHECKS is enabled, in this case however it 105 * references GPL-only symbol cpu_feature_keys. Therefore we overrides this 106 * interface when it is detected being GPL-only. 107 */ 108 #if defined(CONFIG_JUMP_LABEL_FEATURE_CHECKS) && \ 109 defined(HAVE_CPU_HAS_FEATURE_GPL_ONLY) 110 #define cpu_has_feature(feature) early_cpu_has_feature(feature) 111 #endif 112 113 /* 114 * Check if AltiVec instruction set is available 115 */ 116 static inline boolean_t zfs_altivec_available(void)117zfs_altivec_available(void) 118 { 119 return (cpu_has_feature(CPU_FTR_ALTIVEC)); 120 } 121 122 /* 123 * Check if VSX is available 124 */ 125 static inline boolean_t zfs_vsx_available(void)126zfs_vsx_available(void) 127 { 128 return (cpu_has_feature(CPU_FTR_VSX)); 129 } 130 131 /* 132 * Check if POWER ISA 2.07 is available (SHA2) 133 */ 134 static inline boolean_t zfs_isa207_available(void)135zfs_isa207_available(void) 136 { 137 return (cpu_has_feature(CPU_FTR_ARCH_207S)); 138 } 139 140 #endif /* _LINUX_SIMD_POWERPC_H */ 141