riscv64: Add RISC-V target
[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/systemcfg.h>
42 #include <sys/vminfo.h>
43 #endif
44 #ifdef __APPLE__
45 #include <mach/mach.h>
46 #include <mach/mach_host.h>
47 #include <mach/host_info.h>
48 #include <mach/machine.h>
49 #endif
50
51 #define CPUTYPE_UNKNOWN    0
52 #define CPUTYPE_POWER3     1
53 #define CPUTYPE_POWER4     2
54 #define CPUTYPE_PPC970     3
55 #define CPUTYPE_POWER5     4
56 #define CPUTYPE_POWER6     5
57 #define CPUTYPE_CELL       6
58 #define CPUTYPE_PPCG4      7
59 #define CPUTYPE_POWER8     8
60 #define CPUTYPE_POWER9     9
61 #define CPUTYPE_POWER10   10
62
63 char *cpuname[] = {
64   "UNKNOWN",
65   "POWER3",
66   "POWER4",
67   "PPC970",
68   "POWER5",
69   "POWER6",
70   "CELL",
71   "PPCG4",
72   "POWER8",
73   "POWER9",
74   "POWER10"
75 };
76
77 char *lowercpuname[] = {
78   "unknown",
79   "power3",
80   "power4",
81   "ppc970",
82   "power5",
83   "power6",
84   "cell",
85   "ppcg4",
86   "power8",
87   "power9",     
88   "power10"     
89 };
90
91 char *corename[] = {
92   "UNKNOWN",
93   "POWER3",
94   "POWER4",
95   "POWER4",
96   "POWER4",
97   "POWER6",
98   "CELL",
99   "PPCG4",
100   "POWER8",
101   "POWER9",     
102   "POWER10"     
103 };
104
105 int detect(void){
106
107 #ifdef __linux
108   FILE *infile;
109   char buffer[512], *p;
110
111   p = (char *)NULL;
112   infile = fopen("/proc/cpuinfo", "r");
113   while (fgets(buffer, sizeof(buffer), infile)){
114     if (!strncmp("cpu", buffer, 3)){
115         p = strchr(buffer, ':') + 2;
116 #if 0
117         fprintf(stderr, "%s\n", p);
118 #endif
119         break;
120       }
121   }
122
123   fclose(infile);
124
125   if (!strncasecmp(p, "POWER3", 6)) return CPUTYPE_POWER3;
126   if (!strncasecmp(p, "POWER4", 6)) return CPUTYPE_POWER4;
127   if (!strncasecmp(p, "PPC970", 6)) return CPUTYPE_PPC970;
128   if (!strncasecmp(p, "POWER5", 6)) return CPUTYPE_POWER5;
129   if (!strncasecmp(p, "POWER6", 6)) return CPUTYPE_POWER6;
130   if (!strncasecmp(p, "POWER7", 6)) return CPUTYPE_POWER6;
131   if (!strncasecmp(p, "POWER8", 6)) return CPUTYPE_POWER8;
132   if (!strncasecmp(p, "POWER9", 6)) return CPUTYPE_POWER9;
133   if (!strncasecmp(p, "POWER10", 7)) return CPUTYPE_POWER10;
134   if (!strncasecmp(p, "Cell",   4)) return CPUTYPE_CELL;
135   if (!strncasecmp(p, "7447",   4)) return CPUTYPE_PPCG4;
136
137   return CPUTYPE_UNKNOWN;
138 #endif
139
140 #ifdef _AIX
141   // Cast from int to unsigned to ensure comparisons work for all bits in
142   // the bit mask, even the top bit
143   unsigned implementation = (unsigned) _system_configuration.implementation;
144
145   if (implementation >= 0x40000u) return CPUTYPE_POWER10;
146   else if (implementation & 0x20000) return CPUTYPE_POWER9;
147   else if (implementation & 0x10000) return CPUTYPE_POWER8;
148   else if (implementation & 0x08000) return CPUTYPE_POWER6; // POWER 7
149   else if (implementation & 0x04000) return CPUTYPE_POWER6;
150   else if (implementation & 0x02000) return CPUTYPE_POWER5;
151   else if (implementation & 0x01000) return CPUTYPE_POWER4; // MPC7450
152   else if (implementation & 0x00800) return CPUTYPE_POWER4;
153   else return CPUTYPE_POWER3;
154 #endif
155
156 #ifdef __APPLE__
157   host_basic_info_data_t   hostInfo;
158   mach_msg_type_number_t  infoCount;
159
160   infoCount = HOST_BASIC_INFO_COUNT;
161   host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
162
163   if (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_7450) return CPUTYPE_PPCG4;
164   if (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970)  return CPUTYPE_PPC970;
165
166   return  CPUTYPE_PPC970;
167 #endif
168
169 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
170 int id;
171 __asm __volatile("mfpvr %0" : "=r"(id));
172 switch ( id >> 16 ) {
173   case 0x80: // POWER10
174     return CPUTYPE_POWER10;
175     break;
176   case 0x4e: // POWER9
177     return CPUTYPE_POWER9;
178     break;
179   case 0x4d:
180   case 0x4b: // POWER8/8E 
181     return CPUTYPE_POWER8;
182     break;
183   case 0x4a:
184   case 0x3f:  // POWER7/7E
185     return CPUTYPE_POWER6; 
186     break;
187   case 0x3e:
188     return CPUTYPE_POWER6;
189     break;
190   case 0x3a:
191     return CPUTYPE_POWER5;
192     break;
193   case 0x35:
194   case 0x38: // POWER4 /4+ 
195     return CPUTYPE_POWER4;
196     break;
197   case 0x40:
198   case 0x41: // POWER3 /3+ 
199     return CPUTYPE_POWER3;
200     break;
201   case 0x39:
202   case 0x3c:
203   case 0x44:
204   case 0x45:
205     return CPUTYPE_PPC970;
206     break;
207   case 0x70: 
208     return CPUTYPE_CELL;
209     break;
210   case 0x8003: 
211     return CPUTYPE_PPCG4;
212     break;
213   default:  
214     return  CPUTYPE_UNKNOWN;
215   }
216 #endif
217         
218  return CPUTYPE_UNKNOWN;        
219 }
220
221 void get_architecture(void){
222   printf("POWER");
223 }
224
225 void get_subdirname(void){
226     printf("power");
227 }
228
229
230 void get_subarchitecture(void){
231   printf("%s", cpuname[detect()]);
232 }
233
234 void get_cpuconfig(void){
235 #if 0
236 #ifdef _AIX
237   struct vminfo info;
238 #endif
239 #endif
240
241   printf("#define %s\n", cpuname[detect()]);
242   printf("#define CORE_%s\n", corename[detect()]);
243
244   printf("#define L1_DATA_SIZE 32768\n");
245   printf("#define L1_DATA_LINESIZE 128\n");
246   printf("#define L2_SIZE 524288\n");
247   printf("#define L2_LINESIZE 128 \n");
248   printf("#define DTB_DEFAULT_ENTRIES 128\n");
249   printf("#define DTB_SIZE 4096\n");
250   printf("#define L2_ASSOCIATIVE 8\n");
251
252 #if 0
253 #ifdef _AIX
254   if (vmgetinfo(&info, VMINFO, 0) == 0) {
255     if ((info.lgpg_size >> 20) >= 1024) {
256       printf("#define ALLOC_HUGETLB\n");
257     }
258   }
259 #endif
260 #endif
261
262 }
263
264 void get_libname(void){
265   printf("%s", lowercpuname[detect()]);
266 }
267
268 char *get_corename(void){
269   return cpuname[detect()];
270 }