This source file includes following definitions.
- assign_value
- assign_string_value
- search_table
- probe_cpu
- probe_picl
- hwloc_solaris_get_chip_info
- hwloc_solaris_get_chip_info
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <private/autogen/config.h>
14 #include <hwloc.h>
15 #include <private/solaris-chiptype.h>
16 #include <private/misc.h>
17 #include <private/debug.h>
18
19 #include <stdlib.h>
20 #include <strings.h>
21
22 #ifdef HAVE_PICL_H
23 #include <sys/systeminfo.h>
24 #include <picl.h>
25
26
27 #define IMPL_SPARC64_VI 0x6
28 #define IMPL_SPARC64_VII 0x7
29 #define IMPL_SPITFIRE 0x10
30 #define IMPL_BLACKBIRD 0x11
31 #define IMPL_SABRE 0x12
32 #define IMPL_HUMMINGBIRD 0x13
33 #define IMPL_CHEETAH 0x14
34 #define IMPL_CHEETAHPLUS 0x15
35 #define IMPL_JALAPENO 0x16
36 #define IMPL_JAGUAR 0x18
37 #define IMPL_PANTHER 0x19
38 #define IMPL_NIAGARA 0x23
39 #define IMPL_NIAGARA_2 0x24
40 #define IMPL_ROCK 0x25
41
42
43 #define TI_MANUFACTURER 0x17
44 #define TWO_MEG_CACHE 2097152
45 #define SPITFIRE_SPEED 142943750
46
47
48
49
50
51
52 static const char* items[] = {
53 #define INDEX_PROCESSOR_TYPE 0
54 "ProcessorType",
55 #define INDEX_BRAND_STRING 1
56 "brand-string",
57 #define INDEX_COMPATIBLE 2
58 "compatible",
59 #define INDEX_IMPLEMENTATION 3
60 "implementation#",
61
62
63 #define INDEX_L1I_CACHE_SIZE 4
64 "l1-icache-size",
65 #define INDEX_L1D_CACHE_SIZE 5
66 "l1-dcache-size",
67 #define INDEX_L2I_CACHE_SIZE 6
68 "l2-icache-size",
69 #define INDEX_L2D_CACHE_SIZE 7
70 "l2-dcache-size",
71 #define INDEX_L3_CACHE_SIZE 8
72 "l3-cache-size",
73
74 #define INDEX_L1I_CACHE_LINESIZE 9
75 "l1-icache-line-size",
76 #define INDEX_L1D_CACHE_LINESIZE 10
77 "l1-dcache-line-size",
78 #define INDEX_L2I_CACHE_LINESIZE 11
79 "l2-icache-line-size",
80 #define INDEX_L2D_CACHE_LINESIZE 12
81 "l2-dcache-line-size",
82 #define INDEX_L3_CACHE_LINESIZE 13
83 "l3-cache-line-size",
84
85 #define INDEX_L1I_CACHE_ASSOCIATIVITY 14
86 "l1-icache-associativity",
87 #define INDEX_L1D_CACHE_ASSOCIATIVITY 15
88 "l1-dcache-associativity",
89 #define INDEX_L2I_CACHE_ASSOCIATIVITY 16
90 "l2-icache-associativity",
91 #define INDEX_L2D_CACHE_ASSOCIATIVITY 17
92 "l2-dcache-associativity",
93 #define INDEX_L3_CACHE_ASSOCIATIVITY 18
94 "l3-cache-associativity",
95
96 #define INDEX_L2U_CACHE_SIZE 19
97 "l2-cache-size",
98 #define INDEX_L2U_CACHE_LINESIZE 20
99 "l2-cache-line-size",
100 #define INDEX_L2U_CACHE_ASSOCIATIVITY 21
101 "l2-cache-associativity",
102
103 #define INDEX_SL2_CACHE_SIZE 22
104 "sectored-l2-cache-size",
105 #define INDEX_SL2_CACHE_LINESIZE 23
106 "sectored-l2-cache-line-size",
107 #define INDEX_SL2_CACHE_ASSOCIATIVITY 24
108 "sectored-l2-cache-associativity",
109 };
110
111 #define NUM_ITEMS (sizeof(items) / sizeof(items[0]))
112
113
114
115
116 static const char* sparc_modes[] = {
117 #define MODE_UNKNOWN 0
118 "UNKNOWN",
119 #define MODE_SPITFIRE 1
120 "SPITFIRE",
121 #define MODE_BLACKBIRD 2
122 "BLACKBIRD",
123 #define MODE_CHEETAH 3
124 "CHEETAH",
125 #define MODE_SPARC64_VI 4
126 "SPARC64_VI",
127 #define MODE_T1 5
128 "T1",
129 #define MODE_T2 6
130 "T2",
131
132 #define MODE_SPARC64_VII 7
133 "SPARC64_VII",
134 #define MODE_ROCK 8
135 "ROCK",
136 #define MODE_T5 9
137 "T5",
138 #define MODE_T6 10
139 "T6",
140 #define MODE_M7 11
141 "M7",
142 #define MODE_S7 12
143 "S7",
144 #define MODE_M8 13
145 "M8"
146 };
147
148
149
150
151
152 static int called_cpu_probe = 0;
153 static char dss_chip_type[PICL_PROPNAMELEN_MAX];
154 static char dss_chip_model[PICL_PROPNAMELEN_MAX];
155 static long dss_chip_mode = MODE_UNKNOWN;
156
157 struct hwloc_solaris_chip_info_s chip_info;
158
159
160
161
162
163 static void assign_value(int index, long long val) {
164 if (index == INDEX_IMPLEMENTATION) {
165
166 long dss_chip_impl = val;
167 if (dss_chip_impl == IMPL_SPITFIRE) {
168 dss_chip_mode = MODE_SPITFIRE;
169 }
170 else if ((dss_chip_impl >= IMPL_BLACKBIRD) &&
171 (dss_chip_impl <= IMPL_HUMMINGBIRD)) {
172 dss_chip_mode = MODE_BLACKBIRD;
173 }
174 else if ((dss_chip_impl >= IMPL_CHEETAH) &&
175 (dss_chip_impl <= IMPL_PANTHER)) {
176 dss_chip_mode = MODE_CHEETAH;
177 }
178 else if (dss_chip_impl == IMPL_SPARC64_VI) {
179 dss_chip_mode = MODE_SPARC64_VI;
180 }
181 else if (dss_chip_impl == IMPL_NIAGARA) {
182 dss_chip_mode = MODE_T1;
183 }
184 else if (dss_chip_impl == IMPL_NIAGARA_2) {
185 dss_chip_mode = MODE_T2;
186 }
187 else if (dss_chip_impl == IMPL_SPARC64_VII) {
188 dss_chip_mode = MODE_SPARC64_VII;
189 }
190 else if (dss_chip_impl == IMPL_ROCK) {
191 dss_chip_mode = MODE_ROCK;
192 }
193 }
194
195 else if ((index >= INDEX_L1I_CACHE_SIZE) && (index <= INDEX_L3_CACHE_SIZE)) {
196
197 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_SIZE);
198 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_SIZE);
199 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_SIZE);
200 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_SIZE);
201 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L3 == INDEX_L3_CACHE_SIZE);
202
203 chip_info.cache_size[index-INDEX_L1I_CACHE_SIZE] = val;
204 }
205 else if ((index >= INDEX_L1I_CACHE_LINESIZE) && (index <= INDEX_L3_CACHE_LINESIZE)) {
206
207 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_LINESIZE);
208 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_LINESIZE);
209 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_LINESIZE);
210 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_LINESIZE);
211 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L3 == INDEX_L3_CACHE_LINESIZE);
212
213 chip_info.cache_linesize[index-INDEX_L1I_CACHE_LINESIZE] = val;
214 }
215 else if ((index >= INDEX_L1I_CACHE_ASSOCIATIVITY) && (index <= INDEX_L3_CACHE_ASSOCIATIVITY)) {
216
217 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_ASSOCIATIVITY);
218 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_ASSOCIATIVITY);
219 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_ASSOCIATIVITY);
220 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_ASSOCIATIVITY);
221 HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L3 == INDEX_L3_CACHE_ASSOCIATIVITY);
222
223 chip_info.cache_associativity[index-INDEX_L1I_CACHE_ASSOCIATIVITY] = val;
224 }
225
226
227 else if (index == INDEX_L2U_CACHE_SIZE) {
228 chip_info.cache_size[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
229 chip_info.l2_unified = 1;
230 }
231 else if (index == INDEX_L2U_CACHE_LINESIZE) {
232 chip_info.cache_linesize[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
233 chip_info.l2_unified = 1;
234 }
235 else if (index == INDEX_L2U_CACHE_ASSOCIATIVITY) {
236 chip_info.cache_associativity[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
237 chip_info.l2_unified = 1;
238 }
239
240
241 else if (index == INDEX_SL2_CACHE_SIZE) {
242 chip_info.cache_size[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
243 chip_info.l2_unified = 1;
244 }
245 else if (index == INDEX_SL2_CACHE_LINESIZE) {
246 chip_info.cache_linesize[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
247 chip_info.l2_unified = 1;
248 }
249 else if (index == INDEX_SL2_CACHE_ASSOCIATIVITY) {
250 chip_info.cache_associativity[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
251 chip_info.l2_unified = 1;
252 }
253 }
254
255
256
257
258
259 static void assign_string_value(int index, char* string_val) {
260 if (index == INDEX_COMPATIBLE) {
261 if (strncasecmp(string_val, "FJSV,SPARC64-VI",
262 PICL_PROPNAMELEN_MAX) == 0) {
263 dss_chip_mode = MODE_SPARC64_VI;
264 }
265 else if (strncasecmp(string_val, "SUNW,UltraSPARC-T1",
266 PICL_PROPNAMELEN_MAX) == 0) {
267 dss_chip_mode = MODE_T1;
268 }
269 else if (strncasecmp(string_val, "SUNW,UltraSPARC-T2",
270 PICL_PROPNAMELEN_MAX) == 0) {
271 dss_chip_mode = MODE_T2;
272 }
273 else if (strncasecmp(string_val, "FJSV,SPARC64-VII",
274 PICL_PROPNAMELEN_MAX) == 0) {
275 dss_chip_mode = MODE_SPARC64_VII;
276 }
277 else if (strncasecmp(string_val, "SUNW,Rock",
278 PICL_PROPNAMELEN_MAX) == 0) {
279 dss_chip_mode = MODE_ROCK;
280 }
281 else if (strncasecmp(string_val, "SPARC-T5",
282 PICL_PROPNAMELEN_MAX) == 0) {
283 dss_chip_mode = MODE_T5;
284 }
285 else if (strncasecmp(string_val, "SPARC-T6",
286 PICL_PROPNAMELEN_MAX) == 0) {
287 dss_chip_mode = MODE_T6;
288 }
289 else if (strncasecmp(string_val, "SPARC-M7",
290 PICL_PROPNAMELEN_MAX) == 0) {
291 dss_chip_mode = MODE_M7;
292 }
293 else if (strncasecmp(string_val, "SPARC-S7",
294 PICL_PROPNAMELEN_MAX) == 0) {
295 dss_chip_mode = MODE_S7;
296 }
297 else if (strncasecmp(string_val, "SPARC-M8",
298 PICL_PROPNAMELEN_MAX) == 0) {
299 dss_chip_mode = MODE_M8;
300 }
301 } else if (index == INDEX_PROCESSOR_TYPE) {
302 strncpy(&dss_chip_type[0], string_val, PICL_PROPNAMELEN_MAX);
303 } else if (index == INDEX_BRAND_STRING) {
304 strncpy(&dss_chip_model[0], string_val, PICL_PROPNAMELEN_MAX);
305 }
306 }
307
308
309
310
311
312 static void search_table(int index, picl_prophdl_t table_hdl) {
313
314 picl_prophdl_t col_hdl;
315 picl_prophdl_t row_hdl;
316 picl_propinfo_t p_info;
317 int val;
318 char string_val[PICL_PROPNAMELEN_MAX];
319
320 for (val = picl_get_next_by_col(table_hdl, &row_hdl); val != PICL_ENDOFLIST;
321 val = picl_get_next_by_col(row_hdl, &row_hdl)) {
322 if (val == PICL_SUCCESS) {
323 for (col_hdl = row_hdl; val != PICL_ENDOFLIST;
324 val = picl_get_next_by_row(col_hdl, &col_hdl)) {
325 if (val == PICL_SUCCESS) {
326 val = picl_get_propinfo(col_hdl, &p_info);
327 if (val == PICL_SUCCESS) {
328 if (p_info.type == PICL_PTYPE_CHARSTRING) {
329 val = picl_get_propval(col_hdl, &string_val, sizeof(string_val));
330 if (val == PICL_SUCCESS) {
331 assign_string_value(index, string_val);
332 }
333 }
334 }
335 }
336 }
337 }
338 }
339 }
340
341
342
343
344
345
346
347
348
349 static int probe_cpu(picl_nodehdl_t node_hdl, void* dummy_arg __hwloc_attribute_unused) {
350
351 picl_prophdl_t p_hdl;
352 picl_prophdl_t table_hdl;
353 picl_propinfo_t p_info;
354 long long long_long_val;
355 unsigned int uint_val;
356 unsigned int index;
357 int int_val;
358 int val;
359 char string_val[PICL_PROPNAMELEN_MAX];
360
361 val = picl_get_first_prop(node_hdl, &p_hdl);
362 while (val == PICL_SUCCESS) {
363 called_cpu_probe = 1;
364 val = picl_get_propinfo(p_hdl, &p_info);
365 if (val == PICL_SUCCESS) {
366 for (index = 0; index < NUM_ITEMS; index++) {
367 if (strcasecmp(p_info.name, items[index]) == 0) {
368 if (p_info.type == PICL_PTYPE_UNSIGNED_INT) {
369 if (p_info.size == sizeof(uint_val)) {
370 val = picl_get_propval(p_hdl, &uint_val, sizeof(uint_val));
371 if (val == PICL_SUCCESS) {
372 long_long_val = uint_val;
373 assign_value(index, long_long_val);
374 }
375 }
376 else if (p_info.size == sizeof(long_long_val)) {
377 val = picl_get_propval(p_hdl, &long_long_val,
378 sizeof(long_long_val));
379 if (val == PICL_SUCCESS) {
380 assign_value(index, long_long_val);
381 }
382 }
383 }
384 else if (p_info.type == PICL_PTYPE_INT) {
385 if (p_info.size == sizeof(int_val)) {
386 val = picl_get_propval(p_hdl, &int_val, sizeof(int_val));
387 if (val == PICL_SUCCESS) {
388 long_long_val = int_val;
389 assign_value(index, long_long_val);
390 }
391 }
392 else if (p_info.size == sizeof(long_long_val)) {
393 val = picl_get_propval(p_hdl, &long_long_val,
394 sizeof(long_long_val));
395 if (val == PICL_SUCCESS) {
396 assign_value(index, long_long_val);
397 }
398 }
399 }
400 else if (p_info.type == PICL_PTYPE_CHARSTRING) {
401 val = picl_get_propval(p_hdl, &string_val, sizeof(string_val));
402 if (val == PICL_SUCCESS) {
403 assign_string_value(index, string_val);
404 }
405 }
406 else if (p_info.type == PICL_PTYPE_TABLE) {
407 val = picl_get_propval(p_hdl, &table_hdl, p_info.size);
408 if (val == PICL_SUCCESS) {
409 search_table(index, table_hdl);
410 }
411 }
412 break;
413 }
414 }
415 }
416
417 val = picl_get_next_prop(p_hdl, &p_hdl);
418 }
419 return PICL_WALK_TERMINATE;
420 }
421
422
423
424
425
426
427
428
429 static void probe_picl(void)
430 {
431 char *env;
432 int ret;
433
434 memset(&chip_info, 0, sizeof(chip_info));
435
436
437
438
439
440
441
442 env = getenv("HWLOC_PICL_HETEROGENEOUS");
443 if (env && atoi(env))
444 return;
445
446 ret = picl_initialize();
447 if (ret == PICL_SUCCESS) {
448 picl_nodehdl_t root;
449 ret = picl_get_root(&root);
450 if (ret == PICL_SUCCESS) {
451 ret = picl_walk_tree_by_class(root, "cpu", (void *)NULL, probe_cpu);
452 ret = picl_walk_tree_by_class(root, "core", (void *)NULL, probe_cpu);
453 }
454 picl_shutdown();
455 }
456
457 if (called_cpu_probe) {
458 #if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_X86_32_ARCH)
459
460
461
462 dss_chip_type[0] = '\0';
463 #endif
464 if (dss_chip_mode != MODE_UNKNOWN) {
465 strncpy(dss_chip_model, sparc_modes[dss_chip_mode],
466 PICL_PROPNAMELEN_MAX);
467 }
468 } else {
469
470 sysinfo(SI_HW_PROVIDER, dss_chip_type, PICL_PROPNAMELEN_MAX);
471 sysinfo(SI_PLATFORM, dss_chip_model, PICL_PROPNAMELEN_MAX);
472 }
473
474 #ifdef HWLOC_DEBUG
475 {
476 unsigned i;
477 for(i=0; i<sizeof(chip_info.cache_size)/sizeof(*chip_info.cache_size); i++)
478 hwloc_debug("PICL gave cache #%u size %lu line %u associativity %u\n",
479 i, chip_info.cache_size[i], chip_info.cache_linesize[i], chip_info.cache_associativity[i]);
480 }
481 #endif
482
483
484 dss_chip_type[sizeof(dss_chip_type)-1] = '\0';
485 dss_chip_model[sizeof(dss_chip_model)-1] = '\0';
486
487
488 if (dss_chip_type[0])
489 chip_info.type = dss_chip_type;
490 if (dss_chip_model[0])
491 chip_info.model = dss_chip_model;
492 }
493
494 void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info)
495 {
496 static int probe_done = 0;
497 if (!probe_done) {
498 probe_picl();
499 probe_done = 1;
500 }
501
502 memcpy(info, &chip_info, sizeof(*info));
503 }
504
505 #else
506 void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info)
507 {
508 memset(info, 0, sizeof(*info));
509 }
510 #endif