xref: /kvm-unit-tests/lib/s390x/asm/facility.h (revision 4c8a99ca02252d4a2bee43f4558fe47ce5ab7ec0)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2017 Red Hat Inc
4  *
5  * Authors:
6  *  David Hildenbrand <david@redhat.com>
7  */
8 #ifndef _ASMS390X_FACILITY_H_
9 #define _ASMS390X_FACILITY_H_
10 
11 #include <libcflat.h>
12 #include <asm/facility.h>
13 #include <asm/arch_def.h>
14 #include <bitops.h>
15 #include <sclp.h>
16 
17 #define NB_STFL_DOUBLEWORDS 32
18 extern uint64_t stfl_doublewords[];
19 
20 static inline bool test_facility(int nr)
21 {
22 	return test_bit_inv(nr, stfl_doublewords);
23 }
24 
25 static inline void stfl(void)
26 {
27 	asm volatile("	stfl	0(0)\n" : : : "memory");
28 }
29 
30 static inline void stfle(uint64_t *fac, unsigned int nb_doublewords)
31 {
32 	register unsigned long r0 asm("0") = nb_doublewords - 1;
33 
34 	asm volatile("	.insn	s,0xb2b00000,0(%1)\n"
35 		     : "+d" (r0) : "a" (fac) : "memory", "cc");
36 }
37 
38 static inline void setup_facilities(void)
39 {
40 	stfl();
41 	memcpy(stfl_doublewords, &lowcore.stfl, sizeof(lowcore.stfl));
42 	if (test_facility(7))
43 		stfle(stfl_doublewords, NB_STFL_DOUBLEWORDS);
44 }
45 
46 enum supp_on_prot_facility {
47 	SOP_NONE,
48 	SOP_BASIC,
49 	SOP_ENHANCED_1,
50 	SOP_ENHANCED_2,
51 };
52 
53 static inline enum supp_on_prot_facility get_supp_on_prot_facility(void)
54 {
55 	if (sclp_facilities.has_esop) {
56 		if (test_facility(131)) /* side-effect-access facility */
57 			return SOP_ENHANCED_2;
58 		else
59 			return SOP_ENHANCED_1;
60 	}
61 	if (sclp_facilities.has_sop)
62 		return SOP_BASIC;
63 	return SOP_NONE;
64 }
65 
66 #endif
67