1
2
3
4
5
6
7#include "isst.h"
8
9#define DISP_FREQ_MULTIPLIER 100000
10
11static void printcpumask(int str_len, char *str, int mask_size,
12 cpu_set_t *cpu_mask)
13{
14 int i, max_cpus = get_topo_max_cpus();
15 unsigned int *mask;
16 int size, index, curr_index;
17
18 size = max_cpus / (sizeof(unsigned int) * 8);
19 if (max_cpus % (sizeof(unsigned int) * 8))
20 size++;
21
22 mask = calloc(size, sizeof(unsigned int));
23 if (!mask)
24 return;
25
26 for (i = 0; i < max_cpus; ++i) {
27 int mask_index, bit_index;
28
29 if (!CPU_ISSET_S(i, mask_size, cpu_mask))
30 continue;
31
32 mask_index = i / (sizeof(unsigned int) * 8);
33 bit_index = i % (sizeof(unsigned int) * 8);
34 mask[mask_index] |= BIT(bit_index);
35 }
36
37 curr_index = 0;
38 for (i = size - 1; i >= 0; --i) {
39 index = snprintf(&str[curr_index], str_len - curr_index, "%08x",
40 mask[i]);
41 curr_index += index;
42 if (i) {
43 strncat(&str[curr_index], ",", str_len - curr_index);
44 curr_index++;
45 }
46 }
47
48 free(mask);
49}
50
51static void format_and_print_txt(FILE *outf, int level, char *header,
52 char *value)
53{
54 char *spaces = " ";
55 static char delimiters[256];
56 int i, j = 0;
57
58 if (!level)
59 return;
60
61 if (level == 1) {
62 strcpy(delimiters, " ");
63 } else {
64 for (i = 0; i < level - 1; ++i)
65 j += snprintf(&delimiters[j], sizeof(delimiters) - j,
66 "%s", spaces);
67 }
68
69 if (header && value) {
70 fprintf(outf, "%s", delimiters);
71 fprintf(outf, "%s:%s\n", header, value);
72 } else if (header) {
73 fprintf(outf, "%s", delimiters);
74 fprintf(outf, "%s\n", header);
75 }
76}
77
78static int last_level;
79static void format_and_print(FILE *outf, int level, char *header, char *value)
80{
81 char *spaces = " ";
82 static char delimiters[256];
83 int i;
84
85 if (!out_format_is_json()) {
86 format_and_print_txt(outf, level, header, value);
87 return;
88 }
89
90 if (level == 0) {
91 if (header)
92 fprintf(outf, "{");
93 else
94 fprintf(outf, "\n}\n");
95
96 } else {
97 int j = 0;
98
99 for (i = 0; i < level; ++i)
100 j += snprintf(&delimiters[j], sizeof(delimiters) - j,
101 "%s", spaces);
102
103 if (last_level == level)
104 fprintf(outf, ",\n");
105
106 if (value) {
107 if (last_level != level)
108 fprintf(outf, "\n");
109
110 fprintf(outf, "%s\"%s\": ", delimiters, header);
111 fprintf(outf, "\"%s\"", value);
112 } else {
113 for (i = last_level - 1; i >= level; --i) {
114 int k = 0;
115
116 for (j = i; j > 0; --j)
117 k += snprintf(&delimiters[k],
118 sizeof(delimiters) - k,
119 "%s", spaces);
120 if (i == level && header)
121 fprintf(outf, "\n%s},", delimiters);
122 else
123 fprintf(outf, "\n%s}", delimiters);
124 }
125 if (abs(last_level - level) < 3)
126 fprintf(outf, "\n");
127 if (header)
128 fprintf(outf, "%s\"%s\": {", delimiters,
129 header);
130 }
131 }
132
133 last_level = level;
134}
135
136static void print_packag_info(int cpu, FILE *outf)
137{
138 char header[256];
139
140 snprintf(header, sizeof(header), "package-%d",
141 get_physical_package_id(cpu));
142 format_and_print(outf, 1, header, NULL);
143 snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
144 format_and_print(outf, 2, header, NULL);
145 snprintf(header, sizeof(header), "cpu-%d", cpu);
146 format_and_print(outf, 3, header, NULL);
147}
148
149static void _isst_pbf_display_information(int cpu, FILE *outf, int level,
150 struct isst_pbf_info *pbf_info,
151 int disp_level)
152{
153 char header[256];
154 char value[256];
155
156 snprintf(header, sizeof(header), "speed-select-base-freq");
157 format_and_print(outf, disp_level, header, NULL);
158
159 snprintf(header, sizeof(header), "high-priority-base-frequency(KHz)");
160 snprintf(value, sizeof(value), "%d",
161 pbf_info->p1_high * DISP_FREQ_MULTIPLIER);
162 format_and_print(outf, disp_level + 1, header, value);
163
164 snprintf(header, sizeof(header), "high-priority-cpu-mask");
165 printcpumask(sizeof(value), value, pbf_info->core_cpumask_size,
166 pbf_info->core_cpumask);
167 format_and_print(outf, disp_level + 1, header, value);
168
169 snprintf(header, sizeof(header), "low-priority-base-frequency(KHz)");
170 snprintf(value, sizeof(value), "%d",
171 pbf_info->p1_low * DISP_FREQ_MULTIPLIER);
172 format_and_print(outf, disp_level + 1, header, value);
173
174 snprintf(header, sizeof(header), "tjunction-temperature(C)");
175 snprintf(value, sizeof(value), "%d", pbf_info->t_prochot);
176 format_and_print(outf, disp_level + 1, header, value);
177
178 snprintf(header, sizeof(header), "thermal-design-power(W)");
179 snprintf(value, sizeof(value), "%d", pbf_info->tdp);
180 format_and_print(outf, disp_level + 1, header, value);
181}
182
183static void _isst_fact_display_information(int cpu, FILE *outf, int level,
184 int fact_bucket, int fact_avx,
185 struct isst_fact_info *fact_info,
186 int base_level)
187{
188 struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
189 char header[256];
190 char value[256];
191 int j;
192
193 snprintf(header, sizeof(header), "speed-select-turbo-freq");
194 format_and_print(outf, base_level, header, NULL);
195 for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
196 if (fact_bucket != 0xff && fact_bucket != j)
197 continue;
198
199 if (!bucket_info[j].high_priority_cores_count)
200 break;
201
202 snprintf(header, sizeof(header), "bucket-%d", j);
203 format_and_print(outf, base_level + 1, header, NULL);
204
205 snprintf(header, sizeof(header), "high-priority-cores-count");
206 snprintf(value, sizeof(value), "%d",
207 bucket_info[j].high_priority_cores_count);
208 format_and_print(outf, base_level + 2, header, value);
209
210 if (fact_avx & 0x01) {
211 snprintf(header, sizeof(header),
212 "high-priority-max-frequency(KHz)");
213 snprintf(value, sizeof(value), "%d",
214 bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER);
215 format_and_print(outf, base_level + 2, header, value);
216 }
217
218 if (fact_avx & 0x02) {
219 snprintf(header, sizeof(header),
220 "high-priority-max-avx2-frequency(KHz)");
221 snprintf(value, sizeof(value), "%d",
222 bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER);
223 format_and_print(outf, base_level + 2, header, value);
224 }
225
226 if (fact_avx & 0x04) {
227 snprintf(header, sizeof(header),
228 "high-priority-max-avx512-frequency(KHz)");
229 snprintf(value, sizeof(value), "%d",
230 bucket_info[j].avx512_trl *
231 DISP_FREQ_MULTIPLIER);
232 format_and_print(outf, base_level + 2, header, value);
233 }
234 }
235 snprintf(header, sizeof(header),
236 "speed-select-turbo-freq-clip-frequencies");
237 format_and_print(outf, base_level + 1, header, NULL);
238 snprintf(header, sizeof(header), "low-priority-max-frequency(KHz)");
239 snprintf(value, sizeof(value), "%d",
240 fact_info->lp_clipping_ratio_license_sse *
241 DISP_FREQ_MULTIPLIER);
242 format_and_print(outf, base_level + 2, header, value);
243 snprintf(header, sizeof(header),
244 "low-priority-max-avx2-frequency(KHz)");
245 snprintf(value, sizeof(value), "%d",
246 fact_info->lp_clipping_ratio_license_avx2 *
247 DISP_FREQ_MULTIPLIER);
248 format_and_print(outf, base_level + 2, header, value);
249 snprintf(header, sizeof(header),
250 "low-priority-max-avx512-frequency(KHz)");
251 snprintf(value, sizeof(value), "%d",
252 fact_info->lp_clipping_ratio_license_avx512 *
253 DISP_FREQ_MULTIPLIER);
254 format_and_print(outf, base_level + 2, header, value);
255}
256
257void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level,
258 struct isst_pkg_ctdp *pkg_dev)
259{
260 char header[256];
261 char value[256];
262 int i, base_level = 1;
263
264 print_packag_info(cpu, outf);
265
266 for (i = 0; i <= pkg_dev->levels; ++i) {
267 struct isst_pkg_ctdp_level_info *ctdp_level;
268 int j;
269
270 ctdp_level = &pkg_dev->ctdp_level[i];
271 if (!ctdp_level->processed)
272 continue;
273
274 snprintf(header, sizeof(header), "perf-profile-level-%d",
275 ctdp_level->level);
276 format_and_print(outf, base_level + 3, header, NULL);
277
278 snprintf(header, sizeof(header), "cpu-count");
279 j = get_cpu_count(get_physical_die_id(cpu),
280 get_physical_die_id(cpu));
281 snprintf(value, sizeof(value), "%d", j);
282 format_and_print(outf, base_level + 4, header, value);
283
284 snprintf(header, sizeof(header), "enable-cpu-mask");
285 printcpumask(sizeof(value), value,
286 ctdp_level->core_cpumask_size,
287 ctdp_level->core_cpumask);
288 format_and_print(outf, base_level + 4, header, value);
289
290 snprintf(header, sizeof(header), "thermal-design-power-ratio");
291 snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
292 format_and_print(outf, base_level + 4, header, value);
293
294 snprintf(header, sizeof(header), "base-frequency(KHz)");
295 snprintf(value, sizeof(value), "%d",
296 ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER);
297 format_and_print(outf, base_level + 4, header, value);
298
299 snprintf(header, sizeof(header),
300 "speed-select-turbo-freq-support");
301 snprintf(value, sizeof(value), "%d", ctdp_level->fact_support);
302 format_and_print(outf, base_level + 4, header, value);
303
304 snprintf(header, sizeof(header),
305 "speed-select-base-freq-support");
306 snprintf(value, sizeof(value), "%d", ctdp_level->pbf_support);
307 format_and_print(outf, base_level + 4, header, value);
308
309 snprintf(header, sizeof(header),
310 "speed-select-base-freq-enabled");
311 snprintf(value, sizeof(value), "%d", ctdp_level->pbf_enabled);
312 format_and_print(outf, base_level + 4, header, value);
313
314 snprintf(header, sizeof(header),
315 "speed-select-turbo-freq-enabled");
316 snprintf(value, sizeof(value), "%d", ctdp_level->fact_enabled);
317 format_and_print(outf, base_level + 4, header, value);
318
319 snprintf(header, sizeof(header), "thermal-design-power(W)");
320 snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp);
321 format_and_print(outf, base_level + 4, header, value);
322
323 snprintf(header, sizeof(header), "tjunction-max(C)");
324 snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot);
325 format_and_print(outf, base_level + 4, header, value);
326
327 snprintf(header, sizeof(header), "turbo-ratio-limits-sse");
328 format_and_print(outf, base_level + 4, header, NULL);
329 for (j = 0; j < 8; ++j) {
330 snprintf(header, sizeof(header), "bucket-%d", j);
331 format_and_print(outf, base_level + 5, header, NULL);
332
333 snprintf(header, sizeof(header), "core-count");
334 snprintf(value, sizeof(value), "%d", j);
335 format_and_print(outf, base_level + 6, header, value);
336
337 snprintf(header, sizeof(header), "turbo-ratio");
338 snprintf(value, sizeof(value), "%d",
339 ctdp_level->trl_sse_active_cores[j]);
340 format_and_print(outf, base_level + 6, header, value);
341 }
342 snprintf(header, sizeof(header), "turbo-ratio-limits-avx");
343 format_and_print(outf, base_level + 4, header, NULL);
344 for (j = 0; j < 8; ++j) {
345 snprintf(header, sizeof(header), "bucket-%d", j);
346 format_and_print(outf, base_level + 5, header, NULL);
347
348 snprintf(header, sizeof(header), "core-count");
349 snprintf(value, sizeof(value), "%d", j);
350 format_and_print(outf, base_level + 6, header, value);
351
352 snprintf(header, sizeof(header), "turbo-ratio");
353 snprintf(value, sizeof(value), "%d",
354 ctdp_level->trl_avx_active_cores[j]);
355 format_and_print(outf, base_level + 6, header, value);
356 }
357
358 snprintf(header, sizeof(header), "turbo-ratio-limits-avx512");
359 format_and_print(outf, base_level + 4, header, NULL);
360 for (j = 0; j < 8; ++j) {
361 snprintf(header, sizeof(header), "bucket-%d", j);
362 format_and_print(outf, base_level + 5, header, NULL);
363
364 snprintf(header, sizeof(header), "core-count");
365 snprintf(value, sizeof(value), "%d", j);
366 format_and_print(outf, base_level + 6, header, value);
367
368 snprintf(header, sizeof(header), "turbo-ratio");
369 snprintf(value, sizeof(value), "%d",
370 ctdp_level->trl_avx_512_active_cores[j]);
371 format_and_print(outf, base_level + 6, header, value);
372 }
373 if (ctdp_level->pbf_support)
374 _isst_pbf_display_information(cpu, outf, i,
375 &ctdp_level->pbf_info,
376 base_level + 4);
377 if (ctdp_level->fact_support)
378 _isst_fact_display_information(cpu, outf, i, 0xff, 0xff,
379 &ctdp_level->fact_info,
380 base_level + 4);
381 }
382
383 format_and_print(outf, 1, NULL, NULL);
384}
385
386void isst_ctdp_display_information_start(FILE *outf)
387{
388 last_level = 0;
389 format_and_print(outf, 0, "start", NULL);
390}
391
392void isst_ctdp_display_information_end(FILE *outf)
393{
394 format_and_print(outf, 0, NULL, NULL);
395}
396
397void isst_pbf_display_information(int cpu, FILE *outf, int level,
398 struct isst_pbf_info *pbf_info)
399{
400 print_packag_info(cpu, outf);
401 _isst_pbf_display_information(cpu, outf, level, pbf_info, 4);
402 format_and_print(outf, 1, NULL, NULL);
403}
404
405void isst_fact_display_information(int cpu, FILE *outf, int level,
406 int fact_bucket, int fact_avx,
407 struct isst_fact_info *fact_info)
408{
409 print_packag_info(cpu, outf);
410 _isst_fact_display_information(cpu, outf, level, fact_bucket, fact_avx,
411 fact_info, 4);
412 format_and_print(outf, 1, NULL, NULL);
413}
414
415void isst_clos_display_information(int cpu, FILE *outf, int clos,
416 struct isst_clos_config *clos_config)
417{
418 char header[256];
419 char value[256];
420
421 snprintf(header, sizeof(header), "package-%d",
422 get_physical_package_id(cpu));
423 format_and_print(outf, 1, header, NULL);
424 snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
425 format_and_print(outf, 2, header, NULL);
426 snprintf(header, sizeof(header), "cpu-%d", cpu);
427 format_and_print(outf, 3, header, NULL);
428
429 snprintf(header, sizeof(header), "core-power");
430 format_and_print(outf, 4, header, NULL);
431
432 snprintf(header, sizeof(header), "clos");
433 snprintf(value, sizeof(value), "%d", clos);
434 format_and_print(outf, 5, header, value);
435
436 snprintf(header, sizeof(header), "epp");
437 snprintf(value, sizeof(value), "%d", clos_config->epp);
438 format_and_print(outf, 5, header, value);
439
440 snprintf(header, sizeof(header), "clos-proportional-priority");
441 snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio);
442 format_and_print(outf, 5, header, value);
443
444 snprintf(header, sizeof(header), "clos-min");
445 snprintf(value, sizeof(value), "%d", clos_config->clos_min);
446 format_and_print(outf, 5, header, value);
447
448 snprintf(header, sizeof(header), "clos-max");
449 snprintf(value, sizeof(value), "%d", clos_config->clos_max);
450 format_and_print(outf, 5, header, value);
451
452 snprintf(header, sizeof(header), "clos-desired");
453 snprintf(value, sizeof(value), "%d", clos_config->clos_desired);
454 format_and_print(outf, 5, header, value);
455
456 format_and_print(outf, 1, NULL, NULL);
457}
458
459void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd,
460 int result)
461{
462 char header[256];
463 char value[256];
464
465 snprintf(header, sizeof(header), "package-%d",
466 get_physical_package_id(cpu));
467 format_and_print(outf, 1, header, NULL);
468 snprintf(header, sizeof(header), "die-%d", get_physical_die_id(cpu));
469 format_and_print(outf, 2, header, NULL);
470 snprintf(header, sizeof(header), "cpu-%d", cpu);
471 format_and_print(outf, 3, header, NULL);
472 snprintf(header, sizeof(header), "%s", feature);
473 format_and_print(outf, 4, header, NULL);
474 snprintf(header, sizeof(header), "%s", cmd);
475 snprintf(value, sizeof(value), "%d", result);
476 format_and_print(outf, 5, header, value);
477
478 format_and_print(outf, 1, NULL, NULL);
479}
480