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