xref: /freebsd/sys/contrib/openzfs/include/os/linux/kernel/linux/simd_powerpc.h (revision 22649d4dba730d46244fd2dff4fd174903c8379f)
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)108 zfs_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)117 zfs_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)126 zfs_isa207_available(void)
127 {
128 	return (cpu_has_feature(CPU_FTR_ARCH_207S));
129 }
130 
131 #endif /* _LINUX_SIMD_POWERPC_H */
132