1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel dynamic_speed_select -- Enumerate and control features
4  * Copyright (c) 2019 Intel Corporation.
5  */
6 
7 #include "isst.h"
8 
9 static void printcpulist(int str_len, char *str, int mask_size,
10 			 cpu_set_t *cpu_mask)
11 {
12 	int i, first, curr_index, index;
13 
14 	if (!CPU_COUNT_S(mask_size, cpu_mask)) {
15 		snprintf(str, str_len, "none");
16 		return;
17 	}
18 
19 	curr_index = 0;
20 	first = 1;
21 	for (i = 0; i < get_topo_max_cpus(); ++i) {
22 		if (!CPU_ISSET_S(i, mask_size, cpu_mask))
23 			continue;
24 		if (!first) {
25 			index = snprintf(&str[curr_index],
26 					 str_len - curr_index, ",");
27 			curr_index += index;
28 			if (curr_index >= str_len)
29 				break;
30 		}
31 		index = snprintf(&str[curr_index], str_len - curr_index, "%d",
32 				 i);
33 		curr_index += index;
34 		if (curr_index >= str_len)
35 			break;
36 		first = 0;
37 	}
38 }
39 
40 static void printcpumask(int str_len, char *str, int mask_size,
41 			 cpu_set_t *cpu_mask)
42 {
43 	int i, max_cpus = get_topo_max_cpus();
44 	unsigned int *mask;
45 	int size, index, curr_index;
46 
47 	size = max_cpus / (sizeof(unsigned int) * 8);
48 	if (max_cpus % (sizeof(unsigned int) * 8))
49 		size++;
50 
51 	mask = calloc(size, sizeof(unsigned int));
52 	if (!mask)
53 		return;
54 
55 	for (i = 0; i < max_cpus; ++i) {
56 		int mask_index, bit_index;
57 
58 		if (!CPU_ISSET_S(i, mask_size, cpu_mask))
59 			continue;
60 
61 		mask_index = i / (sizeof(unsigned int) * 8);
62 		bit_index = i % (sizeof(unsigned int) * 8);
63 		mask[mask_index] |= BIT(bit_index);
64 	}
65 
66 	curr_index = 0;
67 	for (i = size - 1; i >= 0; --i) {
68 		index = snprintf(&str[curr_index], str_len - curr_index, "%08x",
69 				 mask[i]);
70 		curr_index += index;
71 		if (curr_index >= str_len)
72 			break;
73 		if (i) {
74 			strncat(&str[curr_index], ",", str_len - curr_index);
75 			curr_index++;
76 		}
77 		if (curr_index >= str_len)
78 			break;
79 	}
80 
81 	free(mask);
82 }
83 
84 static void format_and_print_txt(FILE *outf, int level, char *header,
85 				 char *value)
86 {
87 	char *spaces = "  ";
88 	static char delimiters[256];
89 	int i, j = 0;
90 
91 	if (!level)
92 		return;
93 
94 	if (level == 1) {
95 		strcpy(delimiters, " ");
96 	} else {
97 		for (i = 0; i < level - 1; ++i)
98 			j += snprintf(&delimiters[j], sizeof(delimiters) - j,
99 				      "%s", spaces);
100 	}
101 
102 	if (header && value) {
103 		fprintf(outf, "%s", delimiters);
104 		fprintf(outf, "%s:%s\n", header, value);
105 	} else if (header) {
106 		fprintf(outf, "%s", delimiters);
107 		fprintf(outf, "%s\n", header);
108 	}
109 }
110 
111 static int last_level;
112 static void format_and_print(FILE *outf, int level, char *header, char *value)
113 {
114 	char *spaces = "  ";
115 	static char delimiters[256];
116 	int i;
117 
118 	if (!out_format_is_json()) {
119 		format_and_print_txt(outf, level, header, value);
120 		return;
121 	}
122 
123 	if (level == 0) {
124 		if (header)
125 			fprintf(outf, "{");
126 		else
127 			fprintf(outf, "\n}\n");
128 
129 	} else {
130 		int j = 0;
131 
132 		for (i = 0; i < level; ++i)
133 			j += snprintf(&delimiters[j], sizeof(delimiters) - j,
134 				      "%s", spaces);
135 
136 		if (last_level == level)
137 			fprintf(outf, ",\n");
138 
139 		if (value) {
140 			if (last_level != level)
141 				fprintf(outf, "\n");
142 
143 			fprintf(outf, "%s\"%s\": ", delimiters, header);
144 			fprintf(outf, "\"%s\"", value);
145 		} else {
146 			for (i = last_level - 1; i >= level; --i) {
147 				int k = 0;
148 
149 				for (j = i; j > 0; --j)
150 					k += snprintf(&delimiters[k],
151 						      sizeof(delimiters) - k,
152 						      "%s", spaces);
153 				if (i == level && header)
154 					fprintf(outf, "\n%s},", delimiters);
155 				else
156 					fprintf(outf, "\n%s}", delimiters);
157 			}
158 			if (abs(last_level - level) < 3)
159 				fprintf(outf, "\n");
160 			if (header)
161 				fprintf(outf, "%s\"%s\": {", delimiters,
162 					header);
163 		}
164 	}
165 
166 	last_level = level;
167 }
168 
169 static int print_package_info(struct isst_id *id, FILE *outf)
170 {
171 	char header[256];
172 
173 	if (out_format_is_json()) {
174 		snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d",
175 			 id->pkg, id->die, id->cpu);
176 		format_and_print(outf, 1, header, NULL);
177 		return 1;
178 	}
179 	snprintf(header, sizeof(header), "package-%d", id->pkg);
180 	format_and_print(outf, 1, header, NULL);
181 	snprintf(header, sizeof(header), "die-%d", id->die);
182 	format_and_print(outf, 2, header, NULL);
183 	snprintf(header, sizeof(header), "cpu-%d", id->cpu);
184 	format_and_print(outf, 3, header, NULL);
185 
186 	return 3;
187 }
188 
189 static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int level,
190 					  struct isst_pbf_info *pbf_info,
191 					  int disp_level)
192 {
193 	char header[256];
194 	char value[512];
195 
196 	snprintf(header, sizeof(header), "speed-select-base-freq-properties");
197 	format_and_print(outf, disp_level, header, NULL);
198 
199 	snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)");
200 	snprintf(value, sizeof(value), "%d",
201 		 pbf_info->p1_high * DISP_FREQ_MULTIPLIER);
202 	format_and_print(outf, disp_level + 1, header, value);
203 
204 	snprintf(header, sizeof(header), "high-priority-cpu-mask");
205 	printcpumask(sizeof(value), value, pbf_info->core_cpumask_size,
206 		     pbf_info->core_cpumask);
207 	format_and_print(outf, disp_level + 1, header, value);
208 
209 	snprintf(header, sizeof(header), "high-priority-cpu-list");
210 	printcpulist(sizeof(value), value,
211 		     pbf_info->core_cpumask_size,
212 		     pbf_info->core_cpumask);
213 	format_and_print(outf, disp_level + 1, header, value);
214 
215 	snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)");
216 	snprintf(value, sizeof(value), "%d",
217 		 pbf_info->p1_low * DISP_FREQ_MULTIPLIER);
218 	format_and_print(outf, disp_level + 1, header, value);
219 
220 	if (is_clx_n_platform())
221 		return;
222 
223 	snprintf(header, sizeof(header), "tjunction-temperature(C)");
224 	snprintf(value, sizeof(value), "%d", pbf_info->t_prochot);
225 	format_and_print(outf, disp_level + 1, header, value);
226 
227 	snprintf(header, sizeof(header), "thermal-design-power(W)");
228 	snprintf(value, sizeof(value), "%d", pbf_info->tdp);
229 	format_and_print(outf, disp_level + 1, header, value);
230 }
231 
232 static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int level,
233 					   int fact_bucket, int fact_avx,
234 					   struct isst_fact_info *fact_info,
235 					   int base_level)
236 {
237 	struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
238 	char header[256];
239 	char value[256];
240 	int print = 0, j;
241 
242 	for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
243 		if (fact_bucket != 0xff && fact_bucket != j)
244 			continue;
245 
246 		if (!bucket_info[j].high_priority_cores_count)
247 			break;
248 
249 		print = 1;
250 	}
251 	if (!print) {
252 		fprintf(stderr, "Invalid bucket\n");
253 		return;
254 	}
255 
256 	snprintf(header, sizeof(header), "speed-select-turbo-freq-properties");
257 	format_and_print(outf, base_level, header, NULL);
258 	for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
259 		if (fact_bucket != 0xff && fact_bucket != j)
260 			continue;
261 
262 		if (!bucket_info[j].high_priority_cores_count)
263 			break;
264 
265 		snprintf(header, sizeof(header), "bucket-%d", j);
266 		format_and_print(outf, base_level + 1, header, NULL);
267 
268 		snprintf(header, sizeof(header), "high-priority-cores-count");
269 		snprintf(value, sizeof(value), "%d",
270 			 bucket_info[j].high_priority_cores_count);
271 		format_and_print(outf, base_level + 2, header, value);
272 
273 		if (fact_avx & 0x01) {
274 			snprintf(header, sizeof(header),
275 				 "high-priority-max-frequency(MHz)");
276 			snprintf(value, sizeof(value), "%d",
277 				 bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER);
278 			format_and_print(outf, base_level + 2, header, value);
279 		}
280 
281 		if (fact_avx & 0x02) {
282 			snprintf(header, sizeof(header),
283 				 "high-priority-max-avx2-frequency(MHz)");
284 			snprintf(value, sizeof(value), "%d",
285 				 bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER);
286 			format_and_print(outf, base_level + 2, header, value);
287 		}
288 
289 		if (fact_avx & 0x04) {
290 			snprintf(header, sizeof(header),
291 				 "high-priority-max-avx512-frequency(MHz)");
292 			snprintf(value, sizeof(value), "%d",
293 				 bucket_info[j].avx512_trl *
294 					 DISP_FREQ_MULTIPLIER);
295 			format_and_print(outf, base_level + 2, header, value);
296 		}
297 	}
298 	snprintf(header, sizeof(header),
299 		 "speed-select-turbo-freq-clip-frequencies");
300 	format_and_print(outf, base_level + 1, header, NULL);
301 	snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)");
302 	snprintf(value, sizeof(value), "%d",
303 		 fact_info->lp_clipping_ratio_license_sse *
304 			 DISP_FREQ_MULTIPLIER);
305 	format_and_print(outf, base_level + 2, header, value);
306 	snprintf(header, sizeof(header),
307 		 "low-priority-max-avx2-frequency(MHz)");
308 	snprintf(value, sizeof(value), "%d",
309 		 fact_info->lp_clipping_ratio_license_avx2 *
310 			 DISP_FREQ_MULTIPLIER);
311 	format_and_print(outf, base_level + 2, header, value);
312 	snprintf(header, sizeof(header),
313 		 "low-priority-max-avx512-frequency(MHz)");
314 	snprintf(value, sizeof(value), "%d",
315 		 fact_info->lp_clipping_ratio_license_avx512 *
316 			 DISP_FREQ_MULTIPLIER);
317 	format_and_print(outf, base_level + 2, header, value);
318 }
319 
320 void isst_ctdp_display_core_info(struct isst_id *id, FILE *outf, char *prefix,
321 				 unsigned int val, char *str0, char *str1)
322 {
323 	char header[256];
324 	char value[256];
325 	int level = 1;
326 
327 	if (out_format_is_json()) {
328 		snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d",
329 			 id->pkg, id->die, id->cpu);
330 		format_and_print(outf, level++, header, NULL);
331 	} else {
332 		snprintf(header, sizeof(header), "package-%d", id->pkg);
333 		format_and_print(outf, level++, header, NULL);
334 		snprintf(header, sizeof(header), "die-%d", id->die);
335 		format_and_print(outf, level++, header, NULL);
336 		snprintf(header, sizeof(header), "cpu-%d", id->cpu);
337 		format_and_print(outf, level++, header, NULL);
338 	}
339 
340 	if (str0 && !val)
341 		snprintf(value, sizeof(value), "%s", str0);
342 	else if (str1 && val)
343 		snprintf(value, sizeof(value), "%s", str1);
344 	else
345 		snprintf(value, sizeof(value), "%u", val);
346 	format_and_print(outf, level, prefix, value);
347 
348 	format_and_print(outf, 1, NULL, NULL);
349 }
350 
351 void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level,
352 				   struct isst_pkg_ctdp *pkg_dev)
353 {
354 	char header[256];
355 	char value[512];
356 	static int level;
357 	int i;
358 
359 	if (pkg_dev->processed)
360 		level = print_package_info(id, outf);
361 
362 	for (i = 0; i <= pkg_dev->levels; ++i) {
363 		struct isst_pkg_ctdp_level_info *ctdp_level;
364 		int j;
365 
366 		ctdp_level = &pkg_dev->ctdp_level[i];
367 		if (!ctdp_level->processed)
368 			continue;
369 
370 		snprintf(header, sizeof(header), "perf-profile-level-%d",
371 			 ctdp_level->level);
372 		format_and_print(outf, level + 1, header, NULL);
373 
374 		snprintf(header, sizeof(header), "cpu-count");
375 		j = get_cpu_count(id);
376 		snprintf(value, sizeof(value), "%d", j);
377 		format_and_print(outf, level + 2, header, value);
378 
379 		j = CPU_COUNT_S(ctdp_level->core_cpumask_size,
380 				ctdp_level->core_cpumask);
381 		if (j) {
382 			snprintf(header, sizeof(header), "enable-cpu-count");
383 			snprintf(value, sizeof(value), "%d", j);
384 			format_and_print(outf, level + 2, header, value);
385 		}
386 
387 		if (ctdp_level->core_cpumask_size) {
388 			snprintf(header, sizeof(header), "enable-cpu-mask");
389 			printcpumask(sizeof(value), value,
390 				     ctdp_level->core_cpumask_size,
391 				     ctdp_level->core_cpumask);
392 			format_and_print(outf, level + 2, header, value);
393 
394 			snprintf(header, sizeof(header), "enable-cpu-list");
395 			printcpulist(sizeof(value), value,
396 				     ctdp_level->core_cpumask_size,
397 				     ctdp_level->core_cpumask);
398 			format_and_print(outf, level + 2, header, value);
399 		}
400 
401 		snprintf(header, sizeof(header), "thermal-design-power-ratio");
402 		snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
403 		format_and_print(outf, level + 2, header, value);
404 
405 		snprintf(header, sizeof(header), "base-frequency(MHz)");
406 		if (!ctdp_level->sse_p1)
407 			ctdp_level->sse_p1 = ctdp_level->tdp_ratio;
408 		snprintf(value, sizeof(value), "%d",
409 			  ctdp_level->sse_p1 * DISP_FREQ_MULTIPLIER);
410 		format_and_print(outf, level + 2, header, value);
411 
412 		if (ctdp_level->avx2_p1) {
413 			snprintf(header, sizeof(header), "base-frequency-avx2(MHz)");
414 			snprintf(value, sizeof(value), "%d",
415 				 ctdp_level->avx2_p1 * DISP_FREQ_MULTIPLIER);
416 			format_and_print(outf, level + 2, header, value);
417 		}
418 
419 		if (ctdp_level->avx512_p1) {
420 			snprintf(header, sizeof(header), "base-frequency-avx512(MHz)");
421 			snprintf(value, sizeof(value), "%d",
422 				 ctdp_level->avx512_p1 * DISP_FREQ_MULTIPLIER);
423 			format_and_print(outf, level + 2, header, value);
424 		}
425 
426 		if (ctdp_level->uncore_pm) {
427 			snprintf(header, sizeof(header), "uncore-frequency-min(MHz)");
428 			snprintf(value, sizeof(value), "%d",
429 				 ctdp_level->uncore_pm * DISP_FREQ_MULTIPLIER);
430 			format_and_print(outf, level + 2, header, value);
431 		}
432 
433 		if (ctdp_level->uncore_p0) {
434 			snprintf(header, sizeof(header), "uncore-frequency-max(MHz)");
435 			snprintf(value, sizeof(value), "%d",
436 				 ctdp_level->uncore_p0 * DISP_FREQ_MULTIPLIER);
437 			format_and_print(outf, level + 2, header, value);
438 		}
439 
440 		if (ctdp_level->uncore_p1) {
441 			snprintf(header, sizeof(header), "uncore-frequency-base(MHz)");
442 			snprintf(value, sizeof(value), "%d",
443 				 ctdp_level->uncore_p1 * DISP_FREQ_MULTIPLIER);
444 			format_and_print(outf, level + 2, header, value);
445 		}
446 
447 		if (ctdp_level->mem_freq) {
448 			snprintf(header, sizeof(header), "mem-frequency(MHz)");
449 			snprintf(value, sizeof(value), "%d",
450 				 ctdp_level->mem_freq);
451 			format_and_print(outf, level + 2, header, value);
452 		}
453 
454 		snprintf(header, sizeof(header),
455 			 "speed-select-turbo-freq");
456 		if (ctdp_level->fact_support) {
457 			if (ctdp_level->fact_enabled)
458 				snprintf(value, sizeof(value), "enabled");
459 			else
460 				snprintf(value, sizeof(value), "disabled");
461 		} else
462 			snprintf(value, sizeof(value), "unsupported");
463 		format_and_print(outf, level + 2, header, value);
464 
465 		snprintf(header, sizeof(header),
466 			 "speed-select-base-freq");
467 		if (ctdp_level->pbf_support) {
468 			if (ctdp_level->pbf_enabled)
469 				snprintf(value, sizeof(value), "enabled");
470 			else
471 				snprintf(value, sizeof(value), "disabled");
472 		} else
473 			snprintf(value, sizeof(value), "unsupported");
474 		format_and_print(outf, level + 2, header, value);
475 
476 		snprintf(header, sizeof(header),
477 			 "speed-select-core-power");
478 		if (ctdp_level->sst_cp_support) {
479 			if (ctdp_level->sst_cp_enabled)
480 				snprintf(value, sizeof(value), "enabled");
481 			else
482 				snprintf(value, sizeof(value), "disabled");
483 		} else
484 			snprintf(value, sizeof(value), "unsupported");
485 		format_and_print(outf, level + 2, header, value);
486 
487 		if (is_clx_n_platform()) {
488 			if (ctdp_level->pbf_support)
489 				_isst_pbf_display_information(id, outf,
490 							      tdp_level,
491 							  &ctdp_level->pbf_info,
492 							      level + 2);
493 			continue;
494 		}
495 
496 		if (ctdp_level->pkg_tdp) {
497 			snprintf(header, sizeof(header), "thermal-design-power(W)");
498 			snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp);
499 			format_and_print(outf, level + 2, header, value);
500 		}
501 
502 		if (ctdp_level->t_proc_hot) {
503 			snprintf(header, sizeof(header), "tjunction-max(C)");
504 			snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot);
505 			format_and_print(outf, level + 2, header, value);
506 		}
507 
508 		snprintf(header, sizeof(header), "turbo-ratio-limits-sse");
509 		format_and_print(outf, level + 2, header, NULL);
510 		for (j = 0; j < 8; ++j) {
511 			snprintf(header, sizeof(header), "bucket-%d", j);
512 			format_and_print(outf, level + 3, header, NULL);
513 
514 			snprintf(header, sizeof(header), "core-count");
515 			snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
516 			format_and_print(outf, level + 4, header, value);
517 
518 			snprintf(header, sizeof(header),
519 				"max-turbo-frequency(MHz)");
520 			snprintf(value, sizeof(value), "%d",
521 				 ctdp_level->trl_sse_active_cores[j] *
522 				  DISP_FREQ_MULTIPLIER);
523 			format_and_print(outf, level + 4, header, value);
524 		}
525 
526 		if (ctdp_level->trl_avx_active_cores[0]) {
527 			snprintf(header, sizeof(header), "turbo-ratio-limits-avx2");
528 			format_and_print(outf, level + 2, header, NULL);
529 			for (j = 0; j < 8; ++j) {
530 				snprintf(header, sizeof(header), "bucket-%d", j);
531 				format_and_print(outf, level + 3, header, NULL);
532 
533 				snprintf(header, sizeof(header), "core-count");
534 				snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
535 				format_and_print(outf, level + 4, header, value);
536 
537 				snprintf(header, sizeof(header), "max-turbo-frequency(MHz)");
538 				snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_active_cores[j] * DISP_FREQ_MULTIPLIER);
539 				format_and_print(outf, level + 4, header, value);
540 			}
541 		}
542 
543 		if (ctdp_level->trl_avx_512_active_cores[0]) {
544 			snprintf(header, sizeof(header), "turbo-ratio-limits-avx512");
545 			format_and_print(outf, level + 2, header, NULL);
546 			for (j = 0; j < 8; ++j) {
547 				snprintf(header, sizeof(header), "bucket-%d", j);
548 				format_and_print(outf, level + 3, header, NULL);
549 
550 				snprintf(header, sizeof(header), "core-count");
551 				snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
552 				format_and_print(outf, level + 4, header, value);
553 
554 				snprintf(header, sizeof(header), "max-turbo-frequency(MHz)");
555 				snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_512_active_cores[j] * DISP_FREQ_MULTIPLIER);
556 				format_and_print(outf, level + 4, header, value);
557 			}
558 		}
559 
560 		if (ctdp_level->pbf_support)
561 			_isst_pbf_display_information(id, outf, i,
562 						      &ctdp_level->pbf_info,
563 						      level + 2);
564 		if (ctdp_level->fact_support)
565 			_isst_fact_display_information(id, outf, i, 0xff, 0xff,
566 						       &ctdp_level->fact_info,
567 						       level + 2);
568 	}
569 
570 	format_and_print(outf, 1, NULL, NULL);
571 }
572 
573 static int start;
574 void isst_ctdp_display_information_start(FILE *outf)
575 {
576 	last_level = 0;
577 	format_and_print(outf, 0, "start", NULL);
578 	start = 1;
579 }
580 
581 void isst_ctdp_display_information_end(FILE *outf)
582 {
583 	format_and_print(outf, 0, NULL, NULL);
584 	start = 0;
585 }
586 
587 void isst_pbf_display_information(struct isst_id *id, FILE *outf, int level,
588 				  struct isst_pbf_info *pbf_info)
589 {
590 	int _level;
591 
592 	_level = print_package_info(id, outf);
593 	_isst_pbf_display_information(id, outf, level, pbf_info, _level + 1);
594 	format_and_print(outf, 1, NULL, NULL);
595 }
596 
597 void isst_fact_display_information(struct isst_id *id, FILE *outf, int level,
598 				   int fact_bucket, int fact_avx,
599 				   struct isst_fact_info *fact_info)
600 {
601 	int _level;
602 
603 	_level = print_package_info(id, outf);
604 	_isst_fact_display_information(id, outf, level, fact_bucket, fact_avx,
605 				       fact_info, _level + 1);
606 	format_and_print(outf, 1, NULL, NULL);
607 }
608 
609 void isst_clos_display_information(struct isst_id *id, FILE *outf, int clos,
610 				   struct isst_clos_config *clos_config)
611 {
612 	char header[256];
613 	char value[256];
614 	int level;
615 
616 	level = print_package_info(id, outf);
617 
618 	snprintf(header, sizeof(header), "core-power");
619 	format_and_print(outf, level + 1, header, NULL);
620 
621 	snprintf(header, sizeof(header), "clos");
622 	snprintf(value, sizeof(value), "%d", clos);
623 	format_and_print(outf, level + 2, header, value);
624 
625 	snprintf(header, sizeof(header), "epp");
626 	snprintf(value, sizeof(value), "%d", clos_config->epp);
627 	format_and_print(outf, level + 2, header, value);
628 
629 	snprintf(header, sizeof(header), "clos-proportional-priority");
630 	snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio);
631 	format_and_print(outf, level + 2, header, value);
632 
633 	snprintf(header, sizeof(header), "clos-min");
634 	snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * DISP_FREQ_MULTIPLIER);
635 	format_and_print(outf, level + 2, header, value);
636 
637 	snprintf(header, sizeof(header), "clos-max");
638 	if (clos_config->clos_max == 0xff)
639 		snprintf(value, sizeof(value), "Max Turbo frequency");
640 	else
641 		snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * DISP_FREQ_MULTIPLIER);
642 	format_and_print(outf, level + 2, header, value);
643 
644 	snprintf(header, sizeof(header), "clos-desired");
645 	snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * DISP_FREQ_MULTIPLIER);
646 	format_and_print(outf, level + 2, header, value);
647 
648 	format_and_print(outf, level, NULL, NULL);
649 }
650 
651 void isst_clos_display_clos_information(struct isst_id *id, FILE *outf,
652 					int clos_enable, int type,
653 					int state, int cap)
654 {
655 	char header[256];
656 	char value[256];
657 	int level;
658 
659 	level = print_package_info(id, outf);
660 
661 	snprintf(header, sizeof(header), "core-power");
662 	format_and_print(outf, level + 1, header, NULL);
663 
664 	snprintf(header, sizeof(header), "support-status");
665 	if (cap)
666 		snprintf(value, sizeof(value), "supported");
667 	else
668 		snprintf(value, sizeof(value), "unsupported");
669 	format_and_print(outf, level + 2, header, value);
670 
671 	snprintf(header, sizeof(header), "enable-status");
672 	if (state)
673 		snprintf(value, sizeof(value), "enabled");
674 	else
675 		snprintf(value, sizeof(value), "disabled");
676 	format_and_print(outf, level + 2, header, value);
677 
678 	snprintf(header, sizeof(header), "clos-enable-status");
679 	if (clos_enable)
680 		snprintf(value, sizeof(value), "enabled");
681 	else
682 		snprintf(value, sizeof(value), "disabled");
683 	format_and_print(outf, level + 2, header, value);
684 
685 	snprintf(header, sizeof(header), "priority-type");
686 	if (type)
687 		snprintf(value, sizeof(value), "ordered");
688 	else
689 		snprintf(value, sizeof(value), "proportional");
690 	format_and_print(outf, level + 2, header, value);
691 
692 	format_and_print(outf, level, NULL, NULL);
693 }
694 
695 void isst_clos_display_assoc_information(struct isst_id *id, FILE *outf, int clos)
696 {
697 	char header[256];
698 	char value[256];
699 	int level;
700 
701 	level = print_package_info(id, outf);
702 
703 	snprintf(header, sizeof(header), "get-assoc");
704 	format_and_print(outf, level + 1, header, NULL);
705 
706 	snprintf(header, sizeof(header), "clos");
707 	snprintf(value, sizeof(value), "%d", clos);
708 	format_and_print(outf, level + 2, header, value);
709 
710 	format_and_print(outf, level, NULL, NULL);
711 }
712 
713 void isst_display_result(struct isst_id *id, FILE *outf, char *feature, char *cmd,
714 			 int result)
715 {
716 	char header[256];
717 	char value[256];
718 	int level = 3;
719 
720 	if (id->cpu >= 0)
721 		level = print_package_info(id, outf);
722 
723 	snprintf(header, sizeof(header), "%s", feature);
724 	format_and_print(outf, level + 1, header, NULL);
725 	snprintf(header, sizeof(header), "%s", cmd);
726 	if (!result)
727 		snprintf(value, sizeof(value), "success");
728 	else
729 		snprintf(value, sizeof(value), "failed(error %d)", result);
730 	format_and_print(outf, level + 2, header, value);
731 
732 	format_and_print(outf, level, NULL, NULL);
733 }
734 
735 void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg)
736 {
737 	FILE *outf = get_output_file();
738 	static int error_index;
739 	char header[256];
740 	char value[256];
741 
742 	if (!out_format_is_json()) {
743 		if (arg_valid)
744 			snprintf(value, sizeof(value), "%s %d", msg, arg);
745 		else
746 			snprintf(value, sizeof(value), "%s", msg);
747 
748 		if (error)
749 			fprintf(outf, "Error: %s\n", value);
750 		else
751 			fprintf(outf, "Information: %s\n", value);
752 		return;
753 	}
754 
755 	if (!start)
756 		format_and_print(outf, 0, "start", NULL);
757 
758 	if (error)
759 		snprintf(header, sizeof(header), "Error%d", error_index++);
760 	else
761 		snprintf(header, sizeof(header), "Information:%d", error_index++);
762 	format_and_print(outf, 1, header, NULL);
763 
764 	snprintf(header, sizeof(header), "message");
765 	if (arg_valid)
766 		snprintf(value, sizeof(value), "%s %d", msg, arg);
767 	else
768 		snprintf(value, sizeof(value), "%s", msg);
769 
770 	format_and_print(outf, 2, header, value);
771 	format_and_print(outf, 1, NULL, NULL);
772 	if (!start)
773 		format_and_print(outf, 0, NULL, NULL);
774 }
775 
776 void isst_trl_display_information(struct isst_id *id, FILE *outf, unsigned long long trl)
777 {
778 	char header[256];
779 	char value[256];
780 	int level;
781 
782 	level = print_package_info(id, outf);
783 
784 	snprintf(header, sizeof(header), "get-trl");
785 	format_and_print(outf, level + 1, header, NULL);
786 
787 	snprintf(header, sizeof(header), "trl");
788 	snprintf(value, sizeof(value), "0x%llx", trl);
789 	format_and_print(outf, level + 2, header, value);
790 
791 	format_and_print(outf, level, NULL, NULL);
792 }
793