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 *****************************************************************************/
33 #define CPU_CORTEXA53 2
34 #define CPU_CORTEXA57 3
35 #define CPU_CORTEXA72 4
36 #define CPU_CORTEXA73 5
40 #define CPU_THUNDERX 7
41 #define CPU_THUNDERX2T99 8
43 static char *cpuname[] = {
55 static char *cpuname_lower[] = {
67 int get_feature(char *search)
72 char buffer[2048], *p,*t;
75 infile = fopen("/proc/cpuinfo", "r");
77 while (fgets(buffer, sizeof(buffer), infile))
80 if (!strncmp("Features", buffer, 8))
82 p = strchr(buffer, ':') + 2;
90 if( p == NULL ) return 0;
93 while( t = strtok(NULL," "))
95 if (!strcmp(t, search)) { return(1); }
109 char buffer[512], *p, *cpu_part = NULL, *cpu_implementer = NULL;
112 infile = fopen("/proc/cpuinfo", "r");
113 while (fgets(buffer, sizeof(buffer), infile)) {
114 if ((cpu_part != NULL) && (cpu_implementer != NULL)) {
118 if ((cpu_part == NULL) && !strncmp("CPU part", buffer, 8)) {
119 cpu_part = strchr(buffer, ':') + 2;
120 cpu_part = strdup(cpu_part);
121 } else if ((cpu_implementer == NULL) && !strncmp("CPU implementer", buffer, 15)) {
122 cpu_implementer = strchr(buffer, ':') + 2;
123 cpu_implementer = strdup(cpu_implementer);
128 if(cpu_part != NULL && cpu_implementer != NULL) {
130 if (strstr(cpu_implementer, "0x41")) {
131 if (strstr(cpu_part, "0xd03"))
132 return CPU_CORTEXA53;
133 else if (strstr(cpu_part, "0xd07"))
134 return CPU_CORTEXA57;
135 else if (strstr(cpu_part, "0xd08"))
136 return CPU_CORTEXA72;
137 else if (strstr(cpu_part, "0xd09"))
138 return CPU_CORTEXA73;
141 else if (strstr(cpu_implementer, "0x51") && strstr(cpu_part, "0xc00"))
144 else if (strstr(cpu_implementer, "0x43") && strstr(cpu_part, "0x0a1"))
146 else if (strstr(cpu_implementer, "0x43") && strstr(cpu_part, "0x0af"))
147 return CPU_THUNDERX2T99;
151 infile = fopen("/proc/cpuinfo", "r");
152 while (fgets(buffer, sizeof(buffer), infile))
155 if ((!strncmp("model name", buffer, 10)) || (!strncmp("Processor", buffer, 9)) ||
156 (!strncmp("CPU architecture", buffer, 16)))
158 p = strchr(buffer, ':') + 2;
168 if ((strstr(p, "AArch64")) || (strstr(p, "8")))
181 char *get_corename(void)
183 return cpuname[detect()];
186 void get_architecture(void)
191 void get_subarchitecture(void)
194 printf("%s", cpuname[d]);
197 void get_subdirname(void)
202 void get_cpuconfig(void)
205 // All arches should define ARMv8
206 printf("#define ARMV8\n");
207 printf("#define HAVE_NEON\n"); // This shouldn't be necessary
208 printf("#define HAVE_VFPV4\n"); // This shouldn't be necessary
215 printf("#define %s\n", cpuname[d]);
218 // Minimum parameters for ARMv8 (based on A53)
219 printf("#define L1_DATA_SIZE 32768\n");
220 printf("#define L1_DATA_LINESIZE 64\n");
221 printf("#define L2_SIZE 262144\n");
222 printf("#define L2_LINESIZE 64\n");
223 printf("#define DTB_DEFAULT_ENTRIES 64\n");
224 printf("#define DTB_SIZE 4096\n");
225 printf("#define L2_ASSOCIATIVE 4\n");
231 // Common minimum settings for these Arm cores
232 // Can change a lot, but we need to be conservative
233 // TODO: detect info from /sys if possible
234 printf("#define %s\n", cpuname[d]);
235 printf("#define L1_CODE_SIZE 49152\n");
236 printf("#define L1_CODE_LINESIZE 64\n");
237 printf("#define L1_CODE_ASSOCIATIVE 3\n");
238 printf("#define L1_DATA_SIZE 32768\n");
239 printf("#define L1_DATA_LINESIZE 64\n");
240 printf("#define L1_DATA_ASSOCIATIVE 2\n");
241 printf("#define L2_SIZE 524288\n");
242 printf("#define L2_LINESIZE 64\n");
243 printf("#define L2_ASSOCIATIVE 16\n");
244 printf("#define DTB_DEFAULT_ENTRIES 64\n");
245 printf("#define DTB_SIZE 4096\n");
249 printf("#define FALKOR\n");
250 printf("#define L1_CODE_SIZE 65536\n");
251 printf("#define L1_CODE_LINESIZE 64\n");
252 printf("#define L1_DATA_SIZE 32768\n");
253 printf("#define L1_DATA_LINESIZE 128\n");
254 printf("#define L2_SIZE 524288\n");
255 printf("#define L2_LINESIZE 64\n");
256 printf("#define DTB_DEFAULT_ENTRIES 64\n");
257 printf("#define DTB_SIZE 4096\n");
258 printf("#define L2_ASSOCIATIVE 16\n");
262 printf("#define THUNDERX\n");
263 printf("#define L1_DATA_SIZE 32768\n");
264 printf("#define L1_DATA_LINESIZE 128\n");
265 printf("#define L2_SIZE 16777216\n");
266 printf("#define L2_LINESIZE 128\n");
267 printf("#define DTB_DEFAULT_ENTRIES 64\n");
268 printf("#define DTB_SIZE 4096\n");
269 printf("#define L2_ASSOCIATIVE 16\n");
272 case CPU_THUNDERX2T99:
273 printf("#define THUNDERX2T99 \n");
274 printf("#define L1_CODE_SIZE 32768 \n");
275 printf("#define L1_CODE_LINESIZE 64 \n");
276 printf("#define L1_CODE_ASSOCIATIVE 8 \n");
277 printf("#define L1_DATA_SIZE 32768 \n");
278 printf("#define L1_DATA_LINESIZE 64 \n");
279 printf("#define L1_DATA_ASSOCIATIVE 8 \n");
280 printf("#define L2_SIZE 262144 \n");
281 printf("#define L2_LINESIZE 64 \n");
282 printf("#define L2_ASSOCIATIVE 8 \n");
283 printf("#define L3_SIZE 33554432 \n");
284 printf("#define L3_LINESIZE 64 \n");
285 printf("#define L3_ASSOCIATIVE 32 \n");
286 printf("#define DTB_DEFAULT_ENTRIES 64 \n");
287 printf("#define DTB_SIZE 4096 \n");
293 void get_libname(void)
296 printf("%s", cpuname_lower[d]);
299 void get_features(void)
304 char buffer[2048], *p,*t;
307 infile = fopen("/proc/cpuinfo", "r");
309 while (fgets(buffer, sizeof(buffer), infile))
312 if (!strncmp("Features", buffer, 8))
314 p = strchr(buffer, ':') + 2;
322 if( p == NULL ) return;
325 while( t = strtok(NULL," "))