xref: /freebsd/sys/contrib/openzfs/include/os/linux/kernel/linux/simd_powerpc.h (revision 7a7741af18d6c8a804cc643cb7ecda9d730c6aa6)
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)117 zfs_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)126 zfs_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)135 zfs_isa207_available(void)
136 {
137 	return (cpu_has_feature(CPU_FTR_ARCH_207S));
138 }
139 
140 #endif /* _LINUX_SIMD_POWERPC_H */
141