xref: /linux/arch/s390/include/asm/machine.h (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
1b7e81efcSHeiko Carstens /* SPDX-License-Identifier: GPL-2.0 */
2b7e81efcSHeiko Carstens /*
3b7e81efcSHeiko Carstens  * Copyright IBM Corp. 2024
4b7e81efcSHeiko Carstens  */
5b7e81efcSHeiko Carstens 
6b7e81efcSHeiko Carstens #ifndef __ASM_S390_MACHINE_H
7b7e81efcSHeiko Carstens #define __ASM_S390_MACHINE_H
8b7e81efcSHeiko Carstens 
9e4da8249SHeiko Carstens #include <linux/const.h>
10e4da8249SHeiko Carstens 
11e4da8249SHeiko Carstens #define MFEATURE_LOWCORE	0
12a1a8da0dSHeiko Carstens #define MFEATURE_PCI_MIO	1
13f931f67cSHeiko Carstens #define MFEATURE_SCC		2
1417d38048SHeiko Carstens #define MFEATURE_TLB_GUEST	3
15e82462fbSHeiko Carstens #define MFEATURE_TX		4
16aaab4a4fSHeiko Carstens #define MFEATURE_ESOP		5
17c2751699SHeiko Carstens #define MFEATURE_DIAG9C		6
18*52109a06SHeiko Carstens #define MFEATURE_VM		7
19*52109a06SHeiko Carstens #define MFEATURE_KVM		8
20*52109a06SHeiko Carstens #define MFEATURE_LPAR		9
21e4da8249SHeiko Carstens 
22b7e81efcSHeiko Carstens #ifndef __ASSEMBLY__
23b7e81efcSHeiko Carstens 
24b7e81efcSHeiko Carstens #include <linux/bitops.h>
25b7e81efcSHeiko Carstens #include <asm/alternative.h>
26b7e81efcSHeiko Carstens 
27b7e81efcSHeiko Carstens extern unsigned long machine_features[1];
28b7e81efcSHeiko Carstens 
29b7e81efcSHeiko Carstens #define MAX_MFEATURE_BIT (sizeof(machine_features) * BITS_PER_BYTE)
30b7e81efcSHeiko Carstens 
31b7e81efcSHeiko Carstens static inline void __set_machine_feature(unsigned int nr, unsigned long *mfeatures)
32b7e81efcSHeiko Carstens {
33b7e81efcSHeiko Carstens 	if (nr >= MAX_MFEATURE_BIT)
34b7e81efcSHeiko Carstens 		return;
35b7e81efcSHeiko Carstens 	__set_bit(nr, mfeatures);
36b7e81efcSHeiko Carstens }
37b7e81efcSHeiko Carstens 
38b7e81efcSHeiko Carstens static inline void set_machine_feature(unsigned int nr)
39b7e81efcSHeiko Carstens {
40b7e81efcSHeiko Carstens 	__set_machine_feature(nr, machine_features);
41b7e81efcSHeiko Carstens }
42b7e81efcSHeiko Carstens 
43b7e81efcSHeiko Carstens static inline void __clear_machine_feature(unsigned int nr, unsigned long *mfeatures)
44b7e81efcSHeiko Carstens {
45b7e81efcSHeiko Carstens 	if (nr >= MAX_MFEATURE_BIT)
46b7e81efcSHeiko Carstens 		return;
47b7e81efcSHeiko Carstens 	__clear_bit(nr, mfeatures);
48b7e81efcSHeiko Carstens }
49b7e81efcSHeiko Carstens 
50b7e81efcSHeiko Carstens static inline void clear_machine_feature(unsigned int nr)
51b7e81efcSHeiko Carstens {
52b7e81efcSHeiko Carstens 	__clear_machine_feature(nr, machine_features);
53b7e81efcSHeiko Carstens }
54b7e81efcSHeiko Carstens 
55b7e81efcSHeiko Carstens static bool __test_machine_feature(unsigned int nr, unsigned long *mfeatures)
56b7e81efcSHeiko Carstens {
57b7e81efcSHeiko Carstens 	if (nr >= MAX_MFEATURE_BIT)
58b7e81efcSHeiko Carstens 		return false;
59b7e81efcSHeiko Carstens 	return test_bit(nr, mfeatures);
60b7e81efcSHeiko Carstens }
61b7e81efcSHeiko Carstens 
62b7e81efcSHeiko Carstens static bool test_machine_feature(unsigned int nr)
63b7e81efcSHeiko Carstens {
64b7e81efcSHeiko Carstens 	return __test_machine_feature(nr, machine_features);
65b7e81efcSHeiko Carstens }
66b7e81efcSHeiko Carstens 
67b7e81efcSHeiko Carstens static __always_inline bool __test_machine_feature_constant(unsigned int nr)
68b7e81efcSHeiko Carstens {
69b7e81efcSHeiko Carstens 	asm goto(
70b7e81efcSHeiko Carstens 		ALTERNATIVE("brcl 15,%l[l_no]", "brcl 0,0", ALT_FEATURE(%[nr]))
71b7e81efcSHeiko Carstens 		:
72b7e81efcSHeiko Carstens 		: [nr] "i" (nr)
73b7e81efcSHeiko Carstens 		:
74b7e81efcSHeiko Carstens 		: l_no);
75b7e81efcSHeiko Carstens 	return true;
76b7e81efcSHeiko Carstens l_no:
77b7e81efcSHeiko Carstens 	return false;
78b7e81efcSHeiko Carstens }
79b7e81efcSHeiko Carstens 
80b7e81efcSHeiko Carstens #define DEFINE_MACHINE_HAS_FEATURE(name, feature)				\
81b7e81efcSHeiko Carstens static __always_inline bool machine_has_##name(void)				\
82b7e81efcSHeiko Carstens {										\
83b7e81efcSHeiko Carstens 	if (!__is_defined(__DECOMPRESSOR) && __builtin_constant_p(feature))	\
84b7e81efcSHeiko Carstens 		return __test_machine_feature_constant(feature);		\
85b7e81efcSHeiko Carstens 	return test_machine_feature(feature);					\
86b7e81efcSHeiko Carstens }
87b7e81efcSHeiko Carstens 
88e4da8249SHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(relocated_lowcore, MFEATURE_LOWCORE)
89f931f67cSHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(scc, MFEATURE_SCC)
9017d38048SHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(tlb_guest, MFEATURE_TLB_GUEST)
91e82462fbSHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(tx, MFEATURE_TX)
92aaab4a4fSHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(esop, MFEATURE_ESOP)
93c2751699SHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(diag9c, MFEATURE_DIAG9C)
94*52109a06SHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(vm, MFEATURE_VM)
95*52109a06SHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(kvm, MFEATURE_KVM)
96*52109a06SHeiko Carstens DEFINE_MACHINE_HAS_FEATURE(lpar, MFEATURE_LPAR)
97*52109a06SHeiko Carstens 
98*52109a06SHeiko Carstens #define machine_is_vm	machine_has_vm
99*52109a06SHeiko Carstens #define machine_is_kvm	machine_has_kvm
100*52109a06SHeiko Carstens #define machine_is_lpar	machine_has_lpar
101e4da8249SHeiko Carstens 
102b7e81efcSHeiko Carstens #endif /* __ASSEMBLY__ */
103b7e81efcSHeiko Carstens #endif /* __ASM_S390_MACHINE_H */
104