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