xref: /openbmc/linux/arch/powerpc/include/asm/cpu_has_feature.h (revision 942baad211336efefb93a8369478888ab845c450)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
25a61ef74SNicholas Piggin #ifndef __ASM_POWERPC_CPU_HAS_FEATURE_H
35a61ef74SNicholas Piggin #define __ASM_POWERPC_CPU_HAS_FEATURE_H
4b92a226eSKevin Hao 
5b92a226eSKevin Hao #ifndef __ASSEMBLY__
6b92a226eSKevin Hao 
7c12e6f24SKevin Hao #include <linux/bug.h>
8b92a226eSKevin Hao #include <asm/cputable.h>
9b92a226eSKevin Hao 
early_cpu_has_feature(unsigned long feature)10*eed5fae0SChristophe Leroy static __always_inline bool early_cpu_has_feature(unsigned long feature)
11b92a226eSKevin Hao {
12b92a226eSKevin Hao 	return !!((CPU_FTRS_ALWAYS & feature) ||
13b92a226eSKevin Hao 		  (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature));
14b92a226eSKevin Hao }
15b92a226eSKevin Hao 
164db73271SKevin Hao #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS
174db73271SKevin Hao #include <linux/jump_label.h>
184db73271SKevin Hao 
19ffed15d3SMichael Ellerman #define NUM_CPU_FTR_KEYS	BITS_PER_LONG
204db73271SKevin Hao 
214db73271SKevin Hao extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS];
224db73271SKevin Hao 
cpu_has_feature(unsigned long feature)234db73271SKevin Hao static __always_inline bool cpu_has_feature(unsigned long feature)
244db73271SKevin Hao {
254db73271SKevin Hao 	int i;
264db73271SKevin Hao 
27b5fa0f7fSMichael Ellerman #ifndef __clang__ /* clang can't cope with this */
284db73271SKevin Hao 	BUILD_BUG_ON(!__builtin_constant_p(feature));
29b5fa0f7fSMichael Ellerman #endif
304db73271SKevin Hao 
31c812c7d8SAneesh Kumar K.V #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG
32c812c7d8SAneesh Kumar K.V 	if (!static_key_initialized) {
33c812c7d8SAneesh Kumar K.V 		printk("Warning! cpu_has_feature() used prior to jump label init!\n");
34c812c7d8SAneesh Kumar K.V 		dump_stack();
35c812c7d8SAneesh Kumar K.V 		return early_cpu_has_feature(feature);
36c812c7d8SAneesh Kumar K.V 	}
37c812c7d8SAneesh Kumar K.V #endif
38c812c7d8SAneesh Kumar K.V 
394db73271SKevin Hao 	if (CPU_FTRS_ALWAYS & feature)
404db73271SKevin Hao 		return true;
414db73271SKevin Hao 
424db73271SKevin Hao 	if (!(CPU_FTRS_POSSIBLE & feature))
434db73271SKevin Hao 		return false;
444db73271SKevin Hao 
454db73271SKevin Hao 	i = __builtin_ctzl(feature);
464db73271SKevin Hao 	return static_branch_likely(&cpu_feature_keys[i]);
474db73271SKevin Hao }
484db73271SKevin Hao #else
cpu_has_feature(unsigned long feature)49*eed5fae0SChristophe Leroy static __always_inline bool cpu_has_feature(unsigned long feature)
50b92a226eSKevin Hao {
51b92a226eSKevin Hao 	return early_cpu_has_feature(feature);
52b92a226eSKevin Hao }
534db73271SKevin Hao #endif
54b92a226eSKevin Hao 
55b92a226eSKevin Hao #endif /* __ASSEMBLY__ */
565a61ef74SNicholas Piggin #endif /* __ASM_POWERPC_CPU_HAS_FEATURE_H */
57