Merge pull request #426 from wernsaar/develop
[platform/upstream/openblas.git] / cpuid_arm.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_ARMV6               1
32 #define CPU_ARMV7               2
33 #define CPU_CORTEXA15           3
34
35 static char *cpuname[] = {
36   "UNKOWN",
37   "ARMV6",
38   "ARMV7",
39   "CORTEXA15"
40 };
41
42
43 int get_feature(char *search)
44 {
45
46 #ifdef linux
47         FILE *infile;
48         char buffer[2048], *p,*t;
49         p = (char *) NULL ;
50
51         infile = fopen("/proc/cpuinfo", "r");
52
53         while (fgets(buffer, sizeof(buffer), infile))
54         {
55
56                 if (!strncmp("Features", buffer, 8))
57                 {
58                         p = strchr(buffer, ':') + 2;
59                         break;
60                 }
61         }
62
63         fclose(infile);
64
65
66         if( p == NULL ) return;
67
68         t = strtok(p," ");
69         while( t = strtok(NULL," "))
70         {
71                 if (!strcmp(t, search))   { return(1); }
72         }
73
74 #endif
75         return(0);
76 }
77
78
79 int detect(void)
80 {
81
82 #ifdef linux
83
84         FILE *infile;
85         char buffer[512], *p;
86         p = (char *) NULL ;
87
88         infile = fopen("/proc/cpuinfo", "r");
89
90         while (fgets(buffer, sizeof(buffer), infile))
91         {
92
93                 if ((!strncmp("model name", buffer, 10)) || (!strncmp("Processor", buffer, 9)))
94                 {
95                         p = strchr(buffer, ':') + 2;
96                         break;
97                 }
98         }
99
100         fclose(infile);
101
102         if(p != NULL)
103         {
104
105                 if (strstr(p, "ARMv7"))
106                 {
107                          if ( get_feature("vfpv4"))
108                                 return CPU_ARMV7;
109
110                          if ( get_feature("vfpv3"))
111                                 return CPU_ARMV7;
112
113                          if ( get_feature("vfp"))
114                                 return CPU_ARMV6;
115
116
117                 }
118
119                 if (strstr(p, "ARMv6"))
120                 {
121                          if ( get_feature("vfp"))
122                                 return CPU_ARMV6;
123                 }
124
125
126         }
127 #endif
128
129         return CPU_UNKNOWN;
130 }
131
132 char *get_corename(void)
133 {
134         return cpuname[detect()];
135 }
136
137 void get_architecture(void)
138 {
139         printf("ARM");
140 }
141
142 void get_subarchitecture(void)
143 {
144         int d = detect();
145         switch (d)
146         {
147
148                 case CPU_ARMV7:
149                         printf("ARMV7");
150                         break;
151
152                 case CPU_ARMV6:
153                         printf("ARMV6");
154                         break;
155
156                 default:
157                         printf("UNKNOWN");
158                         break;
159         }
160 }
161
162 void get_subdirname(void)
163 {
164         printf("arm");
165 }
166
167 void get_cpuconfig(void)
168 {
169
170         int d = detect();
171         switch (d)
172         {
173
174                 case CPU_ARMV7:
175                         printf("#define ARMV7\n");
176                         printf("#define HAVE_VFP\n");
177                         printf("#define HAVE_VFPV3\n");
178                         if ( get_feature("neon"))       printf("#define HAVE_NEON\n");
179                         if ( get_feature("vfpv4"))      printf("#define HAVE_VFPV4\n");
180                         printf("#define L1_DATA_SIZE 65536\n");
181                         printf("#define L1_DATA_LINESIZE 32\n");
182                         printf("#define L2_SIZE 512488\n");
183                         printf("#define L2_LINESIZE 32\n");
184                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
185                         printf("#define DTB_SIZE 4096\n");
186                         printf("#define L2_ASSOCIATIVE 4\n");
187                         break;
188
189                 case CPU_ARMV6:
190                         printf("#define ARMV6\n");
191                         printf("#define HAVE_VFP\n");
192                         printf("#define L1_DATA_SIZE 65536\n");
193                         printf("#define L1_DATA_LINESIZE 32\n");
194                         printf("#define L2_SIZE 512488\n");
195                         printf("#define L2_LINESIZE 32\n");
196                         printf("#define DTB_DEFAULT_ENTRIES 64\n");
197                         printf("#define DTB_SIZE 4096\n");
198                         printf("#define L2_ASSOCIATIVE 4\n");
199                         break;
200
201         }
202 }
203
204
205 void get_libname(void)
206 {
207
208         int d = detect();
209         switch (d)
210         {
211
212                 case CPU_ARMV7:
213                         printf("armv7\n");
214                         break;
215
216                 case CPU_ARMV6:
217                         printf("armv6\n");
218                         break;
219
220         }
221 }
222
223
224 void get_features(void)
225 {
226
227 #ifdef linux
228         FILE *infile;
229         char buffer[2048], *p,*t;
230         p = (char *) NULL ;
231
232         infile = fopen("/proc/cpuinfo", "r");
233
234         while (fgets(buffer, sizeof(buffer), infile))
235         {
236
237                 if (!strncmp("Features", buffer, 8))
238                 {
239                         p = strchr(buffer, ':') + 2;
240                         break;
241                 }
242         }
243
244         fclose(infile);
245
246
247         if( p == NULL ) return;
248
249         t = strtok(p," ");
250         while( t = strtok(NULL," "))
251         {
252                 if (!strcmp(t, "vfp"))   { printf("HAVE_VFP=1\n"); continue; }
253                 if (!strcmp(t, "vfpv3")) { printf("HAVE_VFPV3=1\n"); continue; }
254                 if (!strcmp(t, "vfpv4")) { printf("HAVE_VFPV4=1\n"); continue; }
255                 if (!strcmp(t, "neon"))  { printf("HAVE_NEON=1\n"); continue; }
256         }
257
258 #endif
259         return;
260 }
261
262