Merge pull request #749 from lotheac/illumos_fixes
[platform/upstream/openblas.git] / cpuid_arm64.c
1 /**************************************************************************
2   Copyright (c) 2013, The OpenBLAS Project
3   All rights reserved.
4   Redistribution and use in source and binary forms, with or without
5   modification, are permitted provided that the following conditions are
6   met:
7   1. Redistributions of source code must retain the above copyright
8   notice, this list of conditions and the following disclaimer.
9   2. Redistributions in binary form must reproduce the above copyright
10   notice, this list of conditions and the following disclaimer in
11   the documentation and/or other materials provided with the
12   distribution.
13   3. Neither the name of the OpenBLAS project nor the names of
14   its contributors may be used to endorse or promote products
15   derived from this software without specific prior written permission.
16   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE
20   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25   USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *****************************************************************************/
27
28 #include <string.h>
29
30 #define CPU_UNKNOWN             0
31 #define CPU_ARMV8               1
32 #define CPU_CORTEXA57           2
33
34 static char *cpuname[] = {
35   "UNKNOWN",
36   "ARMV8" ,
37   "CORTEXA57"
38 };
39
40 static char *cpuname_lower[] = {
41   "unknown",
42   "armv8" ,
43   "cortexa57"
44 };
45
46 int get_feature(char *search)
47 {
48
49 #ifdef linux
50         FILE *infile;
51         char buffer[2048], *p,*t;
52         p = (char *) NULL ;
53
54         infile = fopen("/proc/cpuinfo", "r");
55
56         while (fgets(buffer, sizeof(buffer), infile))
57         {
58
59                 if (!strncmp("Features", buffer, 8))
60                 {
61                         p = strchr(buffer, ':') + 2;
62                         break;
63                 }
64         }
65
66         fclose(infile);
67
68
69         if( p == NULL ) return 0;
70
71         t = strtok(p," ");
72         while( t = strtok(NULL," "))
73         {
74                 if (!strcmp(t, search))   { return(1); }
75         }
76
77 #endif
78         return(0);
79 }
80
81
82 int detect(void)
83 {
84
85 #ifdef linux
86
87         FILE *infile;
88         char buffer[512], *p;
89         p = (char *) NULL ;
90
91         infile = fopen("/proc/cpuinfo", "r");
92         while (fgets(buffer, sizeof(buffer), infile))
93         {
94
95                 if (!strncmp("CPU part", buffer, 8))
96                 {
97                         p = strchr(buffer, ':') + 2;
98                         break;
99                 }
100         }
101
102         fclose(infile);
103         if(p != NULL) {
104           if (strstr(p, "0xd07")) {
105             return CPU_CORTEXA57;
106           }
107         }
108
109         p = (char *) NULL ;
110         infile = fopen("/proc/cpuinfo", "r");
111         while (fgets(buffer, sizeof(buffer), infile))
112         {
113
114                 if ((!strncmp("model name", buffer, 10)) || (!strncmp("Processor", buffer, 9)) ||
115                     (!strncmp("CPU architecture", buffer, 16)))
116                 {
117                         p = strchr(buffer, ':') + 2;
118                         break;
119                 }
120         }
121
122         fclose(infile);
123
124         if(p != NULL)
125         {
126
127                 if (strstr(p, "AArch64"))
128                 {
129                         return CPU_ARMV8;
130
131                 }
132
133
134         }
135 #endif
136
137         return CPU_UNKNOWN;
138 }
139
140 char *get_corename(void)
141 {
142         return cpuname[detect()];
143 }
144
145 void get_architecture(void)
146 {
147         printf("ARM64");
148 }
149
150 void get_subarchitecture(void)
151 {
152         int d = detect();
153         printf("%s", cpuname[d]);
154 }
155
156 void get_subdirname(void)
157 {
158         printf("arm64");
159 }
160
161 void get_cpuconfig(void)
162 {
163
164         int d = detect();
165         switch (d)
166         {
167
168                 case CPU_ARMV8:
169                         printf("#define ARMV8\n");
170                         printf("#define L1_DATA_SIZE 32768\n");
171                         printf("#define L1_DATA_LINESIZE 64\n");
172                         printf("#define L2_SIZE 262144\n");
173                         printf("#define L2_LINESIZE 64\n");
174                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
175                         printf("#define DTB_SIZE 4096\n");
176                         printf("#define L2_ASSOCIATIVE 4\n");
177                         break;
178
179                 case CPU_CORTEXA57:
180                         printf("#define CORTEXA57\n");
181                         printf("#define HAVE_VFP\n");
182                         printf("#define HAVE_VFPV3\n");
183                         printf("#define HAVE_NEON\n");
184                         printf("#define HAVE_VFPV4\n");
185                         printf("#define L1_CODE_SIZE 49152\n");
186                         printf("#define L1_CODE_LINESIZE 64\n");
187                         printf("#define L1_CODE_ASSOCIATIVE 3\n");
188                         printf("#define L1_DATA_SIZE 32768\n");
189                         printf("#define L1_DATA_LINESIZE 64\n");
190                         printf("#define L1_DATA_ASSOCIATIVE 2\n");
191                         printf("#define L2_SIZE 2097152\n");
192                         printf("#define L2_LINESIZE 64\n");
193                         printf("#define L2_ASSOCIATIVE 16\n");
194                         break;
195         }
196 }
197
198
199 void get_libname(void)
200 {
201         int d = detect();
202         printf("%s", cpuname_lower[d]);
203 }
204
205 void get_features(void)
206 {
207
208 #ifdef linux
209         FILE *infile;
210         char buffer[2048], *p,*t;
211         p = (char *) NULL ;
212
213         infile = fopen("/proc/cpuinfo", "r");
214
215         while (fgets(buffer, sizeof(buffer), infile))
216         {
217
218                 if (!strncmp("Features", buffer, 8))
219                 {
220                         p = strchr(buffer, ':') + 2;
221                         break;
222                 }
223         }
224
225         fclose(infile);
226
227
228         if( p == NULL ) return;
229
230         t = strtok(p," ");
231         while( t = strtok(NULL," "))
232         {
233         }
234
235 #endif
236         return;
237 }
238
239