xref: /freebsd-src/sys/contrib/openzfs/include/os/linux/kernel/linux/simd_powerpc.h (revision ed549cb0c53f8438c52593ce811f6fcc812248e9)
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 #define	kfpu_begin()				\
73 	{					\
74 		preempt_disable();		\
75 		enable_kernel_altivec();	\
76 		enable_kernel_vsx();		\
77 		enable_kernel_spe();		\
78 	}
79 #define	kfpu_end()				\
80 	{					\
81 		disable_kernel_spe();		\
82 		disable_kernel_vsx();		\
83 		disable_kernel_altivec();	\
84 		preempt_enable();		\
85 	}
86 #else
87 /* seems that before 4.5 no-one bothered */
88 #define	kfpu_begin()
89 #define	kfpu_end()		preempt_enable()
90 #endif
91 
92 #define	kfpu_init()		0
93 #define	kfpu_fini()		((void) 0)
94 
95 /*
96  * Check if AltiVec instruction set is available
97  */
98 static inline boolean_t
99 zfs_altivec_available(void)
100 {
101 	return (cpu_has_feature(CPU_FTR_ALTIVEC));
102 }
103 
104 /*
105  * Check if VSX is available
106  */
107 static inline boolean_t
108 zfs_vsx_available(void)
109 {
110 	return (cpu_has_feature(CPU_FTR_VSX));
111 }
112 
113 /*
114  * Check if POWER ISA 2.07 is available (SHA2)
115  */
116 static inline boolean_t
117 zfs_isa207_available(void)
118 {
119 	return (cpu_has_feature(CPU_FTR_ARCH_207S));
120 }
121 
122 #endif /* defined(__powerpc) */
123 
124 #endif /* _LINUX_SIMD_POWERPC_H */
125