1
2
3
4
5
6
7#ifndef __ASM_FACILITY_H
8#define __ASM_FACILITY_H
9
10#include <generated/facilities.h>
11
12#ifndef __ASSEMBLY__
13
14#include <linux/string.h>
15#include <linux/preempt.h>
16#include <asm/lowcore.h>
17
18#define MAX_FACILITY_BIT (256*8)
19
20static inline int __test_facility(unsigned long nr, void *facilities)
21{
22 unsigned char *ptr;
23
24 if (nr >= MAX_FACILITY_BIT)
25 return 0;
26 ptr = (unsigned char *) facilities + (nr >> 3);
27 return (*ptr & (0x80 >> (nr & 7))) != 0;
28}
29
30
31
32
33
34
35static inline int test_facility(unsigned long nr)
36{
37 unsigned long facilities_als[] = { FACILITIES_ALS };
38
39 if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
40 if (__test_facility(nr, &facilities_als))
41 return 1;
42 }
43 return __test_facility(nr, &S390_lowcore.stfle_fac_list);
44}
45
46
47
48
49
50
51static inline void stfle(u64 *stfle_fac_list, int size)
52{
53 unsigned long nr;
54
55 preempt_disable();
56 asm volatile(
57 " stfl 0(0)\n"
58 : "=m" (S390_lowcore.stfl_fac_list));
59 nr = 4;
60 memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
61 if (S390_lowcore.stfl_fac_list & 0x01000000) {
62
63 register unsigned long reg0 asm("0") = size - 1;
64
65 asm volatile(".insn s,0xb2b00000,0(%1)"
66 : "+d" (reg0)
67 : "a" (stfle_fac_list)
68 : "memory", "cc");
69 nr = (reg0 + 1) * 8;
70 }
71 memset((char *) stfle_fac_list + nr, 0, size * 8 - nr);
72 preempt_enable();
73}
74
75#endif
76#endif
77