1 /**************************************************************************
2 Copyright (c) 2013, The OpenBLAS Project
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
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
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 *****************************************************************************/
32 #define CPU_CORTEXA57 2
34 #define CPU_THUNDERX 4
35 #define CPU_THUNDERX2T99 5
37 static char *cpuname[] = {
46 static char *cpuname_lower[] = {
55 int get_feature(char *search)
60 char buffer[2048], *p,*t;
63 infile = fopen("/proc/cpuinfo", "r");
65 while (fgets(buffer, sizeof(buffer), infile))
68 if (!strncmp("Features", buffer, 8))
70 p = strchr(buffer, ':') + 2;
78 if( p == NULL ) return 0;
81 while( t = strtok(NULL," "))
83 if (!strcmp(t, search)) { return(1); }
97 char buffer[512], *p, *cpu_part = NULL, *cpu_implementer = NULL;
100 infile = fopen("/proc/cpuinfo", "r");
101 while (fgets(buffer, sizeof(buffer), infile)) {
102 if ((cpu_part != NULL) && (cpu_implementer != NULL)) {
106 if ((cpu_part == NULL) && !strncmp("CPU part", buffer, 8)) {
107 cpu_part = strchr(buffer, ':') + 2;
108 cpu_part = strdup(cpu_part);
109 } else if ((cpu_implementer == NULL) && !strncmp("CPU implementer", buffer, 15)) {
110 cpu_implementer = strchr(buffer, ':') + 2;
111 cpu_implementer = strdup(cpu_implementer);
116 if(cpu_part != NULL && cpu_implementer != NULL) {
117 if (strstr(cpu_implementer, "0x41") &&
118 (strstr(cpu_part, "0xd07") || strstr(cpu_part,"0xd08") || strstr(cpu_part,"0xd03") ))
119 return CPU_CORTEXA57; //or compatible A53, A72
120 else if (strstr(cpu_part, "0x516") && strstr(cpu_implementer, "0x42"))
122 else if (strstr(cpu_part, "0x0a1") && strstr(cpu_implementer, "0x43"))
124 else if (strstr(cpu_part, "0x0af") && strstr(cpu_implementer, "0x43"))
125 return CPU_THUNDERX2T99;
129 infile = fopen("/proc/cpuinfo", "r");
130 while (fgets(buffer, sizeof(buffer), infile))
133 if ((!strncmp("model name", buffer, 10)) || (!strncmp("Processor", buffer, 9)) ||
134 (!strncmp("CPU architecture", buffer, 16)))
136 p = strchr(buffer, ':') + 2;
146 if ((strstr(p, "AArch64")) || (strstr(p, "8")))
159 char *get_corename(void)
161 return cpuname[detect()];
164 void get_architecture(void)
169 void get_subarchitecture(void)
172 printf("%s", cpuname[d]);
175 void get_subdirname(void)
180 void get_cpuconfig(void)
188 printf("#define ARMV8\n");
189 printf("#define L1_DATA_SIZE 32768\n");
190 printf("#define L1_DATA_LINESIZE 64\n");
191 printf("#define L2_SIZE 262144\n");
192 printf("#define L2_LINESIZE 64\n");
193 printf("#define DTB_DEFAULT_ENTRIES 64\n");
194 printf("#define DTB_SIZE 4096\n");
195 printf("#define L2_ASSOCIATIVE 4\n");
199 printf("#define VULCAN \n");
200 printf("#define HAVE_VFP \n");
201 printf("#define HAVE_VFPV3 \n");
202 printf("#define HAVE_NEON \n");
203 printf("#define HAVE_VFPV4 \n");
204 printf("#define L1_CODE_SIZE 32768 \n");
205 printf("#define L1_CODE_LINESIZE 64 \n");
206 printf("#define L1_CODE_ASSOCIATIVE 8 \n");
207 printf("#define L1_DATA_SIZE 32768 \n");
208 printf("#define L1_DATA_LINESIZE 64 \n");
209 printf("#define L1_DATA_ASSOCIATIVE 8 \n");
210 printf("#define L2_SIZE 262144 \n");
211 printf("#define L2_LINESIZE 64 \n");
212 printf("#define L2_ASSOCIATIVE 8 \n");
213 printf("#define L3_SIZE 33554432 \n");
214 printf("#define L3_LINESIZE 64 \n");
215 printf("#define L3_ASSOCIATIVE 32 \n");
216 printf("#define DTB_DEFAULT_ENTRIES 64 \n");
217 printf("#define DTB_SIZE 4096 \n");
221 printf("#define CORTEXA57\n");
222 printf("#define HAVE_VFP\n");
223 printf("#define HAVE_VFPV3\n");
224 printf("#define HAVE_NEON\n");
225 printf("#define HAVE_VFPV4\n");
226 printf("#define L1_CODE_SIZE 49152\n");
227 printf("#define L1_CODE_LINESIZE 64\n");
228 printf("#define L1_CODE_ASSOCIATIVE 3\n");
229 printf("#define L1_DATA_SIZE 32768\n");
230 printf("#define L1_DATA_LINESIZE 64\n");
231 printf("#define L1_DATA_ASSOCIATIVE 2\n");
232 printf("#define L2_SIZE 2097152\n");
233 printf("#define L2_LINESIZE 64\n");
234 printf("#define L2_ASSOCIATIVE 16\n");
235 printf("#define DTB_DEFAULT_ENTRIES 64\n");
236 printf("#define DTB_SIZE 4096\n");
240 printf("#define ARMV8\n");
241 printf("#define THUNDERX\n");
242 printf("#define L1_DATA_SIZE 32768\n");
243 printf("#define L1_DATA_LINESIZE 128\n");
244 printf("#define L2_SIZE 16777216\n");
245 printf("#define L2_LINESIZE 128\n");
246 printf("#define DTB_DEFAULT_ENTRIES 64\n");
247 printf("#define DTB_SIZE 4096\n");
248 printf("#define L2_ASSOCIATIVE 16\n");
251 case CPU_THUNDERX2T99:
252 printf("#define VULCAN \n");
253 printf("#define HAVE_VFP \n");
254 printf("#define HAVE_VFPV3 \n");
255 printf("#define HAVE_NEON \n");
256 printf("#define HAVE_VFPV4 \n");
257 printf("#define L1_CODE_SIZE 32768 \n");
258 printf("#define L1_CODE_LINESIZE 64 \n");
259 printf("#define L1_CODE_ASSOCIATIVE 8 \n");
260 printf("#define L1_DATA_SIZE 32768 \n");
261 printf("#define L1_DATA_LINESIZE 64 \n");
262 printf("#define L1_DATA_ASSOCIATIVE 8 \n");
263 printf("#define L2_SIZE 262144 \n");
264 printf("#define L2_LINESIZE 64 \n");
265 printf("#define L2_ASSOCIATIVE 8 \n");
266 printf("#define L3_SIZE 33554432 \n");
267 printf("#define L3_LINESIZE 64 \n");
268 printf("#define L3_ASSOCIATIVE 32 \n");
269 printf("#define DTB_DEFAULT_ENTRIES 64 \n");
270 printf("#define DTB_SIZE 4096 \n");
276 void get_libname(void)
279 printf("%s", cpuname_lower[d]);
282 void get_features(void)
287 char buffer[2048], *p,*t;
290 infile = fopen("/proc/cpuinfo", "r");
292 while (fgets(buffer, sizeof(buffer), infile))
295 if (!strncmp("Features", buffer, 8))
297 p = strchr(buffer, ':') + 2;
305 if( p == NULL ) return;
308 while( t = strtok(NULL," "))