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