Merge pull request #1746 from martin-frbg/issue1674
[platform/upstream/openblas.git] / cpuid_power.c
1 /*********************************************************************/
2 /* Copyright 2009, 2010 The University of Texas at Austin.           */
3 /* All rights reserved.                                              */
4 /*                                                                   */
5 /* Redistribution and use in source and binary forms, with or        */
6 /* without modification, are permitted provided that the following   */
7 /* conditions are met:                                               */
8 /*                                                                   */
9 /*   1. Redistributions of source code must retain the above         */
10 /*      copyright notice, this list of conditions and the following  */
11 /*      disclaimer.                                                  */
12 /*                                                                   */
13 /*   2. Redistributions in binary form must reproduce the above      */
14 /*      copyright notice, this list of conditions and the following  */
15 /*      disclaimer in the documentation and/or other materials       */
16 /*      provided with the distribution.                              */
17 /*                                                                   */
18 /*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
19 /*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
20 /*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
21 /*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
22 /*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
23 /*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
24 /*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
25 /*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
26 /*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
27 /*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
28 /*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
29 /*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
30 /*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
31 /*    POSSIBILITY OF SUCH DAMAGE.                                    */
32 /*                                                                   */
33 /* The views and conclusions contained in the software and           */
34 /* documentation are those of the authors and should not be          */
35 /* interpreted as representing official policies, either expressed   */
36 /* or implied, of The University of Texas at Austin.                 */
37 /*********************************************************************/
38
39 #include  <sys/utsname.h>
40 #ifdef _AIX
41 #include <sys/vminfo.h>
42 #endif
43 #ifdef __APPLE__
44 #include <mach/mach.h>
45 #include <mach/mach_host.h>
46 #include <mach/host_info.h>
47 #include <mach/machine.h>
48 #endif
49
50 #define CPUTYPE_UNKNOWN    0
51 #define CPUTYPE_POWER3     1
52 #define CPUTYPE_POWER4     2
53 #define CPUTYPE_PPC970     3
54 #define CPUTYPE_POWER5     4
55 #define CPUTYPE_POWER6     5
56 #define CPUTYPE_CELL       6
57 #define CPUTYPE_PPCG4      7
58 #define CPUTYPE_POWER8     8
59
60 char *cpuname[] = {
61   "UNKNOWN",
62   "POWER3",
63   "POWER4",
64   "PPC970",
65   "POWER5",
66   "POWER6",
67   "CELL",
68   "PPCG4",
69   "POWER8"
70 };
71
72 char *lowercpuname[] = {
73   "unknown",
74   "power3",
75   "power4",
76   "ppc970",
77   "power5",
78   "power6",
79   "cell",
80   "ppcg4",
81   "power8"
82 };
83
84 char *corename[] = {
85   "UNKNOWN",
86   "POWER3",
87   "POWER4",
88   "POWER4",
89   "POWER4",
90   "POWER6",
91   "CELL",
92   "PPCG4",
93   "POWER8"
94 };
95
96 int detect(void){
97
98 #ifdef linux
99   FILE *infile;
100   char buffer[512], *p;
101
102   p = (char *)NULL;
103   infile = fopen("/proc/cpuinfo", "r");
104   while (fgets(buffer, sizeof(buffer), infile)){
105     if (!strncmp("cpu", buffer, 3)){
106         p = strchr(buffer, ':') + 2;
107 #if 0
108         fprintf(stderr, "%s\n", p);
109 #endif
110         break;
111       }
112   }
113
114   fclose(infile);
115
116   if (!strncasecmp(p, "POWER3", 6)) return CPUTYPE_POWER3;
117   if (!strncasecmp(p, "POWER4", 6)) return CPUTYPE_POWER4;
118   if (!strncasecmp(p, "PPC970", 6)) return CPUTYPE_PPC970;
119   if (!strncasecmp(p, "POWER5", 6)) return CPUTYPE_POWER5;
120   if (!strncasecmp(p, "POWER6", 6)) return CPUTYPE_POWER6;
121   if (!strncasecmp(p, "POWER7", 6)) return CPUTYPE_POWER6;
122   if (!strncasecmp(p, "POWER8", 6)) return CPUTYPE_POWER8;
123   if (!strncasecmp(p, "Cell",   4)) return CPUTYPE_CELL;
124   if (!strncasecmp(p, "7447",   4)) return CPUTYPE_PPCG4;
125
126   return CPUTYPE_UNKNOWN;
127 #endif
128
129 #ifdef _AIX
130   return CPUTYPE_POWER5;
131 #endif
132
133 #ifdef __APPLE__
134   host_basic_info_data_t   hostInfo;
135   mach_msg_type_number_t  infoCount;
136
137   infoCount = HOST_BASIC_INFO_COUNT;
138   host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
139
140   if (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_7450) return CPUTYPE_PPCG4;
141   if (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970)  return CPUTYPE_PPC970;
142
143   return  CPUTYPE_PPC970;
144 #endif
145
146 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
147 int id;
148 id = __asm __volatile("mfpvr %0" : "=r"(id));
149 switch ( id >> 16 ) {
150   case 0x4e: // POWER9
151     return  return CPUTYPE_POWER8;
152     break;
153   case 0x4d:
154   case 0x4b: // POWER8/8E 
155     return CPUTYPE_POWER8;
156     break;
157   case 0x4a:
158   case 0x3f:  // POWER7/7E
159     return CPUTYPE_POWER6; 
160     break;
161   case 0x3e:
162     return CPUTYPE_POWER6;
163     break;
164   case 0x3a:
165     return CPUTYPE_POWER5;
166     break;
167   case 0x35:
168   case 0x38: // POWER4 /4+ 
169     return CPUTYPE_POWER4;
170     break;
171   case 0x40:
172   case 0x41: // POWER3 /3+ 
173     return CPUTYPE_POWER3;
174     break;
175   case 0x39:
176   case 0x3c:
177   case 0x44:
178   case 0x45:
179     return CPUTYPE_PPC970;
180     break;
181   case 0x70: 
182     return CPUTYPE_CELL;
183     break;
184   case 0x8003: 
185     return CPUTYPE_PPCG4;
186     break;
187   default:  
188     return  CPUTYPE_UNKNOWN;
189   }
190 #endif
191 }
192
193 void get_architecture(void){
194   printf("POWER");
195 }
196
197 void get_subdirname(void){
198     printf("power");
199 }
200
201
202 void get_subarchitecture(void){
203   printf("%s", cpuname[detect()]);
204 }
205
206 void get_cpuconfig(void){
207 #if 0
208 #ifdef _AIX
209   struct vminfo info;
210 #endif
211 #endif
212
213   printf("#define %s\n", cpuname[detect()]);
214   printf("#define CORE_%s\n", corename[detect()]);
215
216   printf("#define L1_DATA_SIZE 32768\n");
217   printf("#define L1_DATA_LINESIZE 128\n");
218   printf("#define L2_SIZE 524288\n");
219   printf("#define L2_LINESIZE 128 \n");
220   printf("#define DTB_DEFAULT_ENTRIES 128\n");
221   printf("#define DTB_SIZE 4096\n");
222   printf("#define L2_ASSOCIATIVE 8\n");
223
224 #if 0
225 #ifdef _AIX
226   if (vmgetinfo(&info, VMINFO, 0) == 0) {
227     if ((info.lgpg_size >> 20) >= 1024) {
228       printf("#define ALLOC_HUGETLB\n");
229     }
230   }
231 #endif
232 #endif
233
234 }
235
236 void get_libname(void){
237   printf("%s", lowercpuname[detect()]);
238 }
239
240 char *get_corename(void){
241   return cpuname[detect()];
242 }