ARM64: Add the VULCAN Target
[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 #define CPU_VULCAN              3
34
35 static char *cpuname[] = {
36   "UNKNOWN",
37   "ARMV8" ,
38   "CORTEXA57"
39   "VULCAN"
40 };
41
42 static char *cpuname_lower[] = {
43   "unknown",
44   "armv8" ,
45   "cortexa57"
46   "vulcan"
47 };
48
49 int get_feature(char *search)
50 {
51
52 #ifdef linux
53         FILE *infile;
54         char buffer[2048], *p,*t;
55         p = (char *) NULL ;
56
57         infile = fopen("/proc/cpuinfo", "r");
58
59         while (fgets(buffer, sizeof(buffer), infile))
60         {
61
62                 if (!strncmp("Features", buffer, 8))
63                 {
64                         p = strchr(buffer, ':') + 2;
65                         break;
66                 }
67         }
68
69         fclose(infile);
70
71
72         if( p == NULL ) return 0;
73
74         t = strtok(p," ");
75         while( t = strtok(NULL," "))
76         {
77                 if (!strcmp(t, search))   { return(1); }
78         }
79
80 #endif
81         return(0);
82 }
83
84
85 int detect(void)
86 {
87
88 #ifdef linux
89
90         FILE *infile;
91         char buffer[512], *p, *cpu_part, *cpu_implementer;
92         p = (char *) NULL ;
93
94         infile = fopen("/proc/cpuinfo", "r");
95         while (fgets(buffer, sizeof(buffer), infile)) {
96
97                 if (!strncmp("CPU part", buffer, 8)) {
98                         cpu_part = strchr(buffer, ':') + 2;
99                         break;
100                 } else if (!strncmp("CPU implementer", buffer, 15)) {
101                         cpu_implementer = strchr(buffer, ':') + 2;
102                         break;
103                 }
104         }
105
106         fclose(infile);
107         if(cpu_part != NULL && cpu_implementer != NULL) {
108                 if (strstr(cpu_part, "0xd07") && strstr(cpu_implementer, "0x41"))
109                         return CPU_CORTEXA57;
110                 else if (strstr(cpu_part, "0x516") && strstr(cpu_implementer, "0x42"))
111                         return CPU_VULCAN;
112         }
113
114         p = (char *) NULL ;
115         infile = fopen("/proc/cpuinfo", "r");
116         while (fgets(buffer, sizeof(buffer), infile))
117         {
118
119                 if ((!strncmp("model name", buffer, 10)) || (!strncmp("Processor", buffer, 9)) ||
120                     (!strncmp("CPU architecture", buffer, 16)))
121                 {
122                         p = strchr(buffer, ':') + 2;
123                         break;
124                 }
125         }
126
127         fclose(infile);
128
129         if(p != NULL)
130         {
131
132                 if (strstr(p, "AArch64"))
133                 {
134                         return CPU_ARMV8;
135
136                 }
137
138
139         }
140 #endif
141
142         return CPU_UNKNOWN;
143 }
144
145 char *get_corename(void)
146 {
147         return cpuname[detect()];
148 }
149
150 void get_architecture(void)
151 {
152         printf("ARM64");
153 }
154
155 void get_subarchitecture(void)
156 {
157         int d = detect();
158         printf("%s", cpuname[d]);
159 }
160
161 void get_subdirname(void)
162 {
163         printf("arm64");
164 }
165
166 void get_cpuconfig(void)
167 {
168
169         int d = detect();
170         switch (d)
171         {
172
173                 case CPU_ARMV8:
174                         printf("#define ARMV8\n");
175                         printf("#define L1_DATA_SIZE 32768\n");
176                         printf("#define L1_DATA_LINESIZE 64\n");
177                         printf("#define L2_SIZE 262144\n");
178                         printf("#define L2_LINESIZE 64\n");
179                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
180                         printf("#define DTB_SIZE 4096\n");
181                         printf("#define L2_ASSOCIATIVE 4\n");
182                         break;
183
184                 case CPU_VULCAN:
185                         printf("#define VULCAN                        \n");
186                         printf("#define HAVE_VFP                      \n");
187                         printf("#define HAVE_VFPV3                    \n");
188                         printf("#define HAVE_NEON                     \n");
189                         printf("#define HAVE_VFPV4                    \n");
190                         printf("#define L1_CODE_SIZE         32768    \n");
191                         printf("#define L1_CODE_LINESIZE     64       \n");
192                         printf("#define L1_CODE_ASSOCIATIVE  8        \n");
193                         printf("#define L1_DATA_SIZE         32768    \n");
194                         printf("#define L1_DATA_LINESIZE     64       \n");
195                         printf("#define L1_DATA_ASSOCIATIVE  8        \n");
196                         printf("#define L2_SIZE              262144   \n");
197                         printf("#define L2_LINESIZE          64       \n");
198                         printf("#define L2_ASSOCIATIVE       8        \n");
199                         printf("#define L3_SIZE              33554432 \n");
200                         printf("#define L3_LINESIZE          64       \n");
201                         printf("#define L3_ASSOCIATIVE       32       \n");
202                         printf("#define DTB_DEFAULT_ENTRIES  64       \n");
203                         printf("#define DTB_SIZE             4096     \n");
204                         break;
205
206                 case CPU_CORTEXA57:
207                         printf("#define CORTEXA57\n");
208                         printf("#define HAVE_VFP\n");
209                         printf("#define HAVE_VFPV3\n");
210                         printf("#define HAVE_NEON\n");
211                         printf("#define HAVE_VFPV4\n");
212                         printf("#define L1_CODE_SIZE 49152\n");
213                         printf("#define L1_CODE_LINESIZE 64\n");
214                         printf("#define L1_CODE_ASSOCIATIVE 3\n");
215                         printf("#define L1_DATA_SIZE 32768\n");
216                         printf("#define L1_DATA_LINESIZE 64\n");
217                         printf("#define L1_DATA_ASSOCIATIVE 2\n");
218                         printf("#define L2_SIZE 2097152\n");
219                         printf("#define L2_LINESIZE 64\n");
220                         printf("#define L2_ASSOCIATIVE 16\n");
221                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
222                         printf("#define DTB_SIZE 4096\n");
223                         break;
224         }
225 }
226
227
228 void get_libname(void)
229 {
230         int d = detect();
231         printf("%s", cpuname_lower[d]);
232 }
233
234 void get_features(void)
235 {
236
237 #ifdef linux
238         FILE *infile;
239         char buffer[2048], *p,*t;
240         p = (char *) NULL ;
241
242         infile = fopen("/proc/cpuinfo", "r");
243
244         while (fgets(buffer, sizeof(buffer), infile))
245         {
246
247                 if (!strncmp("Features", buffer, 8))
248                 {
249                         p = strchr(buffer, ':') + 2;
250                         break;
251                 }
252         }
253
254         fclose(infile);
255
256
257         if( p == NULL ) return;
258
259         t = strtok(p," ");
260         while( t = strtok(NULL," "))
261         {
262         }
263
264 #endif
265         return;
266 }
267
268