blob: 1e9e8e216fe813bde44fa4956d4c463236b0b776 [file] [log] [blame]
sewardj02b89e82011-05-17 16:19:53 +00001#include <setjmp.h>
2#include <signal.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <assert.h>
7
8// This file determines s390x features a processor supports.
9//
10// We return:
11// - 0 if the machine matches the asked-for feature.
12// - 1 if the machine does not.
13// - 2 if the asked-for feature isn't recognised (this will be the case for
14// any feature if run on a non-s390x machine).
15// - 3 if there was a usage error (it also prints an error message).
16
17jmp_buf env;
18
19#if defined(VGA_s390x)
20
21void handle_sigill(int signum)
22{
23 longjmp(env, 1);
24}
25
26unsigned long long stfle(void)
27{
28
29 unsigned long long ret;
30
31 signal(SIGILL, handle_sigill);
32 if (setjmp(env)) {
33 /* stfle not available: assume no facilities */
34 return 0;
35 } else {
36 asm volatile("lghi 0, 0\n"
37 ".insn s,0xb2b00000,%0\n" /* stfle */
38 : "=Q" (ret)::"0", "cc");
39 return ret;
40 }
41}
42
43static int go(char* cpu)
44{
45 unsigned long long facilities;
46 unsigned long long match;
47
48 facilities = stfle();
49
50 if (strcmp(cpu, "s390x-zarch") == 0 ) {
51 match = (facilities & (1ULL << 62) && (facilities & (1ULL << 61)));
52 } else if (strcmp(cpu, "s390x-n3") == 0 ) {
53 match = (facilities & (1ULL << 63));
54 } else if (strcmp(cpu, "s390x-stfle") == 0 ) {
55 match = (facilities & (1ULL << 56));
56 } else if (strcmp(cpu, "s390x-ldisp") == 0 ) {
57 match = (facilities & (1ULL << 45) && (facilities & (1ULL << 44)));
58 } else if (strcmp(cpu, "s390x-eimm") == 0 ) {
59 match = (facilities & (1ULL << 42));
60 } else if (strcmp(cpu, "s390x-stckf") == 0 ) {
61 match = (facilities & (1ULL << 38));
62 } else if (strcmp(cpu, "s390x-genins") == 0 ) {
63 match = (facilities & (1ULL << 29));
64 } else if (strcmp(cpu, "s390x-exrl") == 0 ) {
65 match = (facilities & (1ULL << 28));
66 } else {
67 return 2; // Unrecognised feature.
68 }
69
70 return match == 0;
71}
72
73#else
74
75static int go(char* cpu)
76{
77 return 2; // Feature not recognised (non-s390x machine!)
78}
79
80#endif
81
82
83//---------------------------------------------------------------------------
84// main
85//---------------------------------------------------------------------------
86int main(int argc, char **argv)
87{
88 if ( argc != 2 ) {
89 fprintf( stderr, "usage: s390x_features <feature>\n" );
90 exit(3); // Usage error.
91 }
92 return go(argv[1]);
93}