1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h>
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Number of double words needed to store all facility bits. */
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define S390_NUM_FACILITY_DW 2
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovunsigned long long stfle(unsigned long dw, unsigned bit_to_test)
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  unsigned long long hoststfle[S390_NUM_FACILITY_DW], match;
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  register unsigned long long __nr asm("0") = dw - 1;
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  int cc;
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  asm volatile(" .insn s,0xb2b00000,%0 \n" /* stfle */
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               "ipm %2\n"
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               "srl %2,28\n"
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               : "=m" (*hoststfle), "+d" (__nr), "=d" (cc) : : "cc", "memory");
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  printf("the value of cc is %d and #double words is %llu\n", cc, __nr + 1);
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (bit_to_test < 64)
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    match = (hoststfle[0] & (1ULL << (63 - bit_to_test)));
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  else if (bit_to_test < 128)
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    match = (hoststfle[1] & (1ULL << (63 - bit_to_test)));
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  else
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    printf("code needs to be updated\n");
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return match;
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main()
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  int dw = S390_NUM_FACILITY_DW;
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  /* Test #1: Make sure STFLE returns sensible values. z/Arch facilities
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              must be present. */
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if ((stfle(dw, 1)) && stfle(dw, 2))
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    printf("The z/Architecture architectural mode is installed and active\n");
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  else
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    printf("The z/Architecture architectural mode is not installed\n");
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  /* Test #2: Make sure the STFLE is supported. */
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if (stfle(dw, 7))
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    printf("STFLE facility is installed\n");
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  else
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    printf("STFLE facility is not installed\n");
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  /* Test #3: Tell STFLE to only write 1 DW of facility bits. Expected condition
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              code should be 3 because this test is run on those machines only
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              that need 2 do double words to store facility bits. */
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  dw = 1;
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  if ((stfle(dw, 1)) && stfle(dw, 2))
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    printf("The z/Architecture architectural mode is installed and active\n");
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  else
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    printf("The z/Architecture architectural mode is not installed\n");
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  /* Test #4: Message security assist */
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  if (stfle(dw, 17)) {
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     printf("MSA facility is present\n");
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  } else {
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     printf("No MSA facility available\n");
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov  }
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  return 0;
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
63