1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * This file and its contents are supplied under the terms of the 4 * Common Development and Distribution License ("CDDL"), version 1.0. 5 * You may only use this file in accordance with the terms of version 6 * 1.0 of the CDDL. 7 * 8 * A full copy of the text of the CDDL should have accompanied this 9 * source. A copy of the CDDL is also available via the Internet at 10 * https://opensource.org/license/CDDL-1.0. 11 */ 12 /* 13 * Copyright (C) 2019 Romain Dolbeau 14 * <romain.dolbeau@european-processor-initiative.eu> 15 * Copyright (C) 2022 Tino Reichardt <milky-zfs@mcmilk.de> 16 */ 17 18 /* 19 * USER API: 20 * 21 * Kernel fpu methods: 22 * kfpu_allowed() 23 * kfpu_begin() 24 * kfpu_end() 25 * kfpu_init() 26 * kfpu_fini() 27 * 28 * SIMD support: 29 * 30 * Following functions should be called to determine whether CPU feature 31 * is supported. All functions are usable in kernel and user space. 32 * If a SIMD algorithm is using more than one instruction set 33 * all relevant feature test functions should be called. 34 * 35 * Supported features: 36 * zfs_altivec_available() 37 * zfs_vsx_available() 38 * zfs_isa207_available() 39 */ 40 41 #ifndef _LINUX_SIMD_POWERPC_H 42 #define _LINUX_SIMD_POWERPC_H 43 44 #include <linux/preempt.h> 45 #include <linux/export.h> 46 #include <linux/sched.h> 47 #include <asm/switch_to.h> 48 #include <sys/types.h> 49 #include <linux/version.h> 50 #include <asm/cpufeature.h> 51 52 #define kfpu_allowed() 1 53 54 #ifdef CONFIG_ALTIVEC 55 #define ENABLE_KERNEL_ALTIVEC enable_kernel_altivec(); 56 #define DISABLE_KERNEL_ALTIVEC disable_kernel_altivec(); 57 #else 58 #define ENABLE_KERNEL_ALTIVEC 59 #define DISABLE_KERNEL_ALTIVEC 60 #endif 61 #ifdef CONFIG_VSX 62 #define ENABLE_KERNEL_VSX enable_kernel_vsx(); 63 #define DISABLE_KERNEL_VSX disable_kernel_vsx(); 64 #else 65 #define ENABLE_KERNEL_VSX 66 #define DISABLE_KERNEL_VSX 67 #endif 68 #ifdef CONFIG_SPE 69 #define ENABLE_KERNEL_SPE enable_kernel_spe(); 70 #define DISABLE_KERNEL_SPE disable_kernel_spe(); 71 #else 72 #define ENABLE_KERNEL_SPE 73 #define DISABLE_KERNEL_SPE 74 #endif 75 #define kfpu_begin() \ 76 { \ 77 preempt_disable(); \ 78 ENABLE_KERNEL_ALTIVEC \ 79 ENABLE_KERNEL_VSX \ 80 ENABLE_KERNEL_SPE \ 81 } 82 #define kfpu_end() \ 83 { \ 84 DISABLE_KERNEL_SPE \ 85 DISABLE_KERNEL_VSX \ 86 DISABLE_KERNEL_ALTIVEC \ 87 preempt_enable(); \ 88 } 89 90 #define kfpu_init() 0 91 #define kfpu_fini() ((void) 0) 92 93 /* 94 * Linux 4.7 makes cpu_has_feature to use jump labels on powerpc if 95 * CONFIG_JUMP_LABEL_FEATURE_CHECKS is enabled, in this case however it 96 * references GPL-only symbol cpu_feature_keys. Therefore we overrides this 97 * interface when it is detected being GPL-only. 98 */ 99 #if defined(CONFIG_JUMP_LABEL_FEATURE_CHECKS) && \ 100 defined(HAVE_CPU_HAS_FEATURE_GPL_ONLY) 101 #define cpu_has_feature(feature) early_cpu_has_feature(feature) 102 #endif 103 104 /* 105 * Check if AltiVec instruction set is available 106 */ 107 static inline boolean_t zfs_altivec_available(void)108zfs_altivec_available(void) 109 { 110 return (cpu_has_feature(CPU_FTR_ALTIVEC)); 111 } 112 113 /* 114 * Check if VSX is available 115 */ 116 static inline boolean_t zfs_vsx_available(void)117zfs_vsx_available(void) 118 { 119 return (cpu_has_feature(CPU_FTR_VSX)); 120 } 121 122 /* 123 * Check if POWER ISA 2.07 is available (SHA2) 124 */ 125 static inline boolean_t zfs_isa207_available(void)126zfs_isa207_available(void) 127 { 128 return (cpu_has_feature(CPU_FTR_ARCH_207S)); 129 } 130 131 #endif /* _LINUX_SIMD_POWERPC_H */ 132