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 	int level = 1;
173 
174 	if (out_format_is_json()) {
175 		if (api_version() > 1)
176 			snprintf(header, sizeof(header), "package-%d:die-%d:powerdomain-%d:cpu-%d",
177 				 id->pkg, id->die, id->punit, id->cpu);
178 		else
179 			snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d",
180 				 id->pkg, id->die, id->cpu);
181 		format_and_print(outf, level, header, NULL);
182 		return 1;
183 	}
184 	snprintf(header, sizeof(header), "package-%d", id->pkg);
185 	format_and_print(outf, level++, header, NULL);
186 	snprintf(header, sizeof(header), "die-%d", id->die);
187 	format_and_print(outf, level++, header, NULL);
188 	if (api_version() > 1) {
189 		snprintf(header, sizeof(header), "powerdomain-%d", id->punit);
190 		format_and_print(outf, level++, header, NULL);
191 	}
192 	snprintf(header, sizeof(header), "cpu-%d", id->cpu);
193 	format_and_print(outf, level, header, NULL);
194 
195 	return level;
196 }
197 
198 static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int level,
199 					  struct isst_pbf_info *pbf_info,
200 					  int disp_level)
201 {
202 	char header[256];
203 	char value[512];
204 
205 	snprintf(header, sizeof(header), "speed-select-base-freq-properties");
206 	format_and_print(outf, disp_level, header, NULL);
207 
208 	snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)");
209 	snprintf(value, sizeof(value), "%d",
210 		 pbf_info->p1_high * isst_get_disp_freq_multiplier());
211 	format_and_print(outf, disp_level + 1, header, value);
212 
213 	snprintf(header, sizeof(header), "high-priority-cpu-mask");
214 	printcpumask(sizeof(value), value, pbf_info->core_cpumask_size,
215 		     pbf_info->core_cpumask);
216 	format_and_print(outf, disp_level + 1, header, value);
217 
218 	snprintf(header, sizeof(header), "high-priority-cpu-list");
219 	printcpulist(sizeof(value), value,
220 		     pbf_info->core_cpumask_size,
221 		     pbf_info->core_cpumask);
222 	format_and_print(outf, disp_level + 1, header, value);
223 
224 	snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)");
225 	snprintf(value, sizeof(value), "%d",
226 		 pbf_info->p1_low * isst_get_disp_freq_multiplier());
227 	format_and_print(outf, disp_level + 1, header, value);
228 
229 	if (is_clx_n_platform())
230 		return;
231 
232 	snprintf(header, sizeof(header), "tjunction-temperature(C)");
233 	snprintf(value, sizeof(value), "%d", pbf_info->t_prochot);
234 	format_and_print(outf, disp_level + 1, header, value);
235 
236 	snprintf(header, sizeof(header), "thermal-design-power(W)");
237 	snprintf(value, sizeof(value), "%d", pbf_info->tdp);
238 	format_and_print(outf, disp_level + 1, header, value);
239 }
240 
241 static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int level,
242 					   int fact_bucket, int fact_avx,
243 					   struct isst_fact_info *fact_info,
244 					   int base_level)
245 {
246 	struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
247 	int trl_max_levels = isst_get_trl_max_levels();
248 	char header[256];
249 	char value[256];
250 	int print = 0, j;
251 
252 	for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
253 		if (fact_bucket != 0xff && fact_bucket != j)
254 			continue;
255 
256 		/* core count must be valid for CPU power domain */
257 		if (!bucket_info[j].hp_cores && id->cpu >= 0)
258 			break;
259 
260 		print = 1;
261 	}
262 	if (!print) {
263 		fprintf(stderr, "Invalid bucket\n");
264 		return;
265 	}
266 
267 	snprintf(header, sizeof(header), "speed-select-turbo-freq-properties");
268 	format_and_print(outf, base_level, header, NULL);
269 	for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
270 		int i;
271 
272 		if (fact_bucket != 0xff && fact_bucket != j)
273 			continue;
274 
275 		if (!bucket_info[j].hp_cores)
276 			break;
277 
278 		snprintf(header, sizeof(header), "bucket-%d", j);
279 		format_and_print(outf, base_level + 1, header, NULL);
280 
281 		snprintf(header, sizeof(header), "high-priority-cores-count");
282 		snprintf(value, sizeof(value), "%d",
283 			 bucket_info[j].hp_cores);
284 		format_and_print(outf, base_level + 2, header, value);
285 		for (i = 0; i < trl_max_levels; i++) {
286 			if (!bucket_info[j].hp_ratios[i] || (fact_avx != 0xFF && !(fact_avx & (1 << i))))
287 				continue;
288 			if (i == 0 && api_version() == 1 && !is_emr_platform())
289 				snprintf(header, sizeof(header),
290 					"high-priority-max-frequency(MHz)");
291 			else
292 				snprintf(header, sizeof(header),
293 					"high-priority-max-%s-frequency(MHz)", isst_get_trl_level_name(i));
294 			snprintf(value, sizeof(value), "%d",
295 				bucket_info[j].hp_ratios[i] * isst_get_disp_freq_multiplier());
296 			format_and_print(outf, base_level + 2, header, value);
297 		}
298 	}
299 	snprintf(header, sizeof(header),
300 		 "speed-select-turbo-freq-clip-frequencies");
301 	format_and_print(outf, base_level + 1, header, NULL);
302 
303 	for (j = 0; j < trl_max_levels; j++) {
304 		if (!fact_info->lp_ratios[j])
305 			continue;
306 
307 		/* No AVX level name for SSE to be consistent with previous formatting */
308 		if (j == 0 && api_version() == 1 && !is_emr_platform())
309 			snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)");
310 		else
311 			snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)",
312 				isst_get_trl_level_name(j));
313 		snprintf(value, sizeof(value), "%d",
314 			 fact_info->lp_ratios[j] * isst_get_disp_freq_multiplier());
315 		format_and_print(outf, base_level + 2, header, value);
316 	}
317 }
318 
319 void isst_ctdp_display_core_info(struct isst_id *id, FILE *outf, char *prefix,
320 				 unsigned int val, char *str0, char *str1)
321 {
322 	char value[256];
323 	int level = print_package_info(id, outf);
324 
325 	level++;
326 
327 	if (str0 && !val)
328 		snprintf(value, sizeof(value), "%s", str0);
329 	else if (str1 && val)
330 		snprintf(value, sizeof(value), "%s", str1);
331 	else
332 		snprintf(value, sizeof(value), "%u", val);
333 	format_and_print(outf, level, prefix, value);
334 
335 	format_and_print(outf, 1, NULL, NULL);
336 }
337 
338 void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level,
339 				   struct isst_pkg_ctdp *pkg_dev)
340 {
341 	char header[256];
342 	char value[512];
343 	static int level;
344 	int trl_max_levels = isst_get_trl_max_levels();
345 	int i;
346 
347 	if (pkg_dev->processed)
348 		level = print_package_info(id, outf);
349 
350 	for (i = 0; i <= pkg_dev->levels; ++i) {
351 		struct isst_pkg_ctdp_level_info *ctdp_level;
352 		int j, k;
353 
354 		ctdp_level = &pkg_dev->ctdp_level[i];
355 		if (!ctdp_level->processed)
356 			continue;
357 
358 		snprintf(header, sizeof(header), "perf-profile-level-%d",
359 			 ctdp_level->level);
360 		format_and_print(outf, level + 1, header, NULL);
361 
362 		if (id->cpu >= 0) {
363 			snprintf(header, sizeof(header), "cpu-count");
364 			j = get_cpu_count(id);
365 			snprintf(value, sizeof(value), "%d", j);
366 			format_and_print(outf, level + 2, header, value);
367 
368 			j = CPU_COUNT_S(ctdp_level->core_cpumask_size,
369 					ctdp_level->core_cpumask);
370 			if (j) {
371 				snprintf(header, sizeof(header), "enable-cpu-count");
372 				snprintf(value, sizeof(value), "%d", j);
373 				format_and_print(outf, level + 2, header, value);
374 			}
375 
376 			if (ctdp_level->core_cpumask_size) {
377 				snprintf(header, sizeof(header), "enable-cpu-mask");
378 				printcpumask(sizeof(value), value,
379 					     ctdp_level->core_cpumask_size,
380 					     ctdp_level->core_cpumask);
381 				format_and_print(outf, level + 2, header, value);
382 
383 				snprintf(header, sizeof(header), "enable-cpu-list");
384 				printcpulist(sizeof(value), value,
385 					     ctdp_level->core_cpumask_size,
386 					     ctdp_level->core_cpumask);
387 				format_and_print(outf, level + 2, header, value);
388 			}
389 		}
390 
391 		snprintf(header, sizeof(header), "thermal-design-power-ratio");
392 		snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
393 		format_and_print(outf, level + 2, header, value);
394 
395 		snprintf(header, sizeof(header), "base-frequency(MHz)");
396 		if (!ctdp_level->sse_p1)
397 			ctdp_level->sse_p1 = ctdp_level->tdp_ratio;
398 		snprintf(value, sizeof(value), "%d",
399 			  ctdp_level->sse_p1 * isst_get_disp_freq_multiplier());
400 		format_and_print(outf, level + 2, header, value);
401 
402 		if (ctdp_level->avx2_p1) {
403 			snprintf(header, sizeof(header), "base-frequency-avx2(MHz)");
404 			snprintf(value, sizeof(value), "%d",
405 				 ctdp_level->avx2_p1 * isst_get_disp_freq_multiplier());
406 			format_and_print(outf, level + 2, header, value);
407 		}
408 
409 		if (ctdp_level->avx512_p1) {
410 			snprintf(header, sizeof(header), "base-frequency-avx512(MHz)");
411 			snprintf(value, sizeof(value), "%d",
412 				 ctdp_level->avx512_p1 * isst_get_disp_freq_multiplier());
413 			format_and_print(outf, level + 2, header, value);
414 		}
415 
416 		if (ctdp_level->uncore_pm) {
417 			snprintf(header, sizeof(header), "uncore-frequency-min(MHz)");
418 			snprintf(value, sizeof(value), "%d",
419 				 ctdp_level->uncore_pm * isst_get_disp_freq_multiplier());
420 			format_and_print(outf, level + 2, header, value);
421 		}
422 
423 		if (ctdp_level->uncore_p0) {
424 			snprintf(header, sizeof(header), "uncore-frequency-max(MHz)");
425 			snprintf(value, sizeof(value), "%d",
426 				 ctdp_level->uncore_p0 * isst_get_disp_freq_multiplier());
427 			format_and_print(outf, level + 2, header, value);
428 		}
429 
430 		if (ctdp_level->amx_p1) {
431 			snprintf(header, sizeof(header), "base-frequency-amx(MHz)");
432 			snprintf(value, sizeof(value), "%d",
433 			ctdp_level->amx_p1 * isst_get_disp_freq_multiplier());
434 			format_and_print(outf, level + 2, header, value);
435 		}
436 
437 		if (ctdp_level->uncore_p1) {
438 			snprintf(header, sizeof(header), "uncore-frequency-base(MHz)");
439 			snprintf(value, sizeof(value), "%d",
440 				 ctdp_level->uncore_p1 * isst_get_disp_freq_multiplier());
441 			format_and_print(outf, level + 2, header, value);
442 		}
443 
444 		if (ctdp_level->mem_freq) {
445 			snprintf(header, sizeof(header), "mem-frequency(MHz)");
446 			snprintf(value, sizeof(value), "%d",
447 				 ctdp_level->mem_freq);
448 			format_and_print(outf, level + 2, header, value);
449 		}
450 
451 		if (api_version() > 1) {
452 			snprintf(header, sizeof(header), "cooling_type");
453 			snprintf(value, sizeof(value), "%d",
454 				ctdp_level->cooling_type);
455 			format_and_print(outf, level + 2, header, value);
456 		}
457 
458 		snprintf(header, sizeof(header),
459 			 "speed-select-turbo-freq");
460 		if (ctdp_level->fact_support) {
461 			if (ctdp_level->fact_enabled)
462 				snprintf(value, sizeof(value), "enabled");
463 			else
464 				snprintf(value, sizeof(value), "disabled");
465 		} else
466 			snprintf(value, sizeof(value), "unsupported");
467 		format_and_print(outf, level + 2, header, value);
468 
469 		snprintf(header, sizeof(header),
470 			 "speed-select-base-freq");
471 		if (ctdp_level->pbf_support) {
472 			if (ctdp_level->pbf_enabled)
473 				snprintf(value, sizeof(value), "enabled");
474 			else
475 				snprintf(value, sizeof(value), "disabled");
476 		} else
477 			snprintf(value, sizeof(value), "unsupported");
478 		format_and_print(outf, level + 2, header, value);
479 
480 		snprintf(header, sizeof(header),
481 			 "speed-select-core-power");
482 		if (ctdp_level->sst_cp_support) {
483 			if (ctdp_level->sst_cp_enabled)
484 				snprintf(value, sizeof(value), "enabled");
485 			else
486 				snprintf(value, sizeof(value), "disabled");
487 		} else
488 			snprintf(value, sizeof(value), "unsupported");
489 		format_and_print(outf, level + 2, header, value);
490 
491 		if (is_clx_n_platform()) {
492 			if (ctdp_level->pbf_support)
493 				_isst_pbf_display_information(id, outf,
494 							      tdp_level,
495 							  &ctdp_level->pbf_info,
496 							      level + 2);
497 			continue;
498 		}
499 
500 		if (ctdp_level->pkg_tdp) {
501 			snprintf(header, sizeof(header), "thermal-design-power(W)");
502 			snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp);
503 			format_and_print(outf, level + 2, header, value);
504 		}
505 
506 		if (ctdp_level->t_proc_hot) {
507 			snprintf(header, sizeof(header), "tjunction-max(C)");
508 			snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot);
509 			format_and_print(outf, level + 2, header, value);
510 		}
511 
512 		for (k = 0; k < trl_max_levels; k++) {
513 			if (!ctdp_level->trl_ratios[k][0])
514 				continue;
515 
516 			snprintf(header, sizeof(header), "turbo-ratio-limits-%s", isst_get_trl_level_name(k));
517 			format_and_print(outf, level + 2, header, NULL);
518 
519 			for (j = 0; j < 8; ++j) {
520 				snprintf(header, sizeof(header), "bucket-%d", j);
521 				format_and_print(outf, level + 3, header, NULL);
522 
523 				snprintf(header, sizeof(header), "core-count");
524 
525 				snprintf(value, sizeof(value), "%llu", (ctdp_level->trl_cores >> (j * 8)) & 0xff);
526 				format_and_print(outf, level + 4, header, value);
527 
528 				snprintf(header, sizeof(header), "max-turbo-frequency(MHz)");
529 				snprintf(value, sizeof(value), "%d", ctdp_level->trl_ratios[k][j] * isst_get_disp_freq_multiplier());
530 				format_and_print(outf, level + 4, header, value);
531 			}
532 		}
533 
534 		if (ctdp_level->pbf_support)
535 			_isst_pbf_display_information(id, outf, i,
536 						      &ctdp_level->pbf_info,
537 						      level + 2);
538 		if (ctdp_level->fact_support)
539 			_isst_fact_display_information(id, outf, i, 0xff, 0xff,
540 						       &ctdp_level->fact_info,
541 						       level + 2);
542 	}
543 
544 	format_and_print(outf, 1, NULL, NULL);
545 }
546 
547 static int start;
548 void isst_ctdp_display_information_start(FILE *outf)
549 {
550 	last_level = 0;
551 	format_and_print(outf, 0, "start", NULL);
552 	start = 1;
553 }
554 
555 void isst_ctdp_display_information_end(FILE *outf)
556 {
557 	format_and_print(outf, 0, NULL, NULL);
558 	start = 0;
559 }
560 
561 void isst_pbf_display_information(struct isst_id *id, FILE *outf, int level,
562 				  struct isst_pbf_info *pbf_info)
563 {
564 	int _level;
565 
566 	_level = print_package_info(id, outf);
567 	_isst_pbf_display_information(id, outf, level, pbf_info, _level + 1);
568 	format_and_print(outf, 1, NULL, NULL);
569 }
570 
571 void isst_fact_display_information(struct isst_id *id, FILE *outf, int level,
572 				   int fact_bucket, int fact_avx,
573 				   struct isst_fact_info *fact_info)
574 {
575 	int _level;
576 
577 	_level = print_package_info(id, outf);
578 	_isst_fact_display_information(id, outf, level, fact_bucket, fact_avx,
579 				       fact_info, _level + 1);
580 	format_and_print(outf, 1, NULL, NULL);
581 }
582 
583 void isst_clos_display_information(struct isst_id *id, FILE *outf, int clos,
584 				   struct isst_clos_config *clos_config)
585 {
586 	char header[256];
587 	char value[256];
588 	int level;
589 
590 	level = print_package_info(id, outf);
591 
592 	snprintf(header, sizeof(header), "core-power");
593 	format_and_print(outf, level + 1, header, NULL);
594 
595 	snprintf(header, sizeof(header), "clos");
596 	snprintf(value, sizeof(value), "%d", clos);
597 	format_and_print(outf, level + 2, header, value);
598 
599 	snprintf(header, sizeof(header), "epp");
600 	snprintf(value, sizeof(value), "%d", clos_config->epp);
601 	format_and_print(outf, level + 2, header, value);
602 
603 	snprintf(header, sizeof(header), "clos-proportional-priority");
604 	snprintf(value, sizeof(value), "%d", clos_config->clos_prop_prio);
605 	format_and_print(outf, level + 2, header, value);
606 
607 	snprintf(header, sizeof(header), "clos-min");
608 	snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * isst_get_disp_freq_multiplier());
609 	format_and_print(outf, level + 2, header, value);
610 
611 	snprintf(header, sizeof(header), "clos-max");
612 	if ((clos_config->clos_max * isst_get_disp_freq_multiplier()) == 25500)
613 		snprintf(value, sizeof(value), "Max Turbo frequency");
614 	else
615 		snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * isst_get_disp_freq_multiplier());
616 	format_and_print(outf, level + 2, header, value);
617 
618 	snprintf(header, sizeof(header), "clos-desired");
619 	snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * isst_get_disp_freq_multiplier());
620 	format_and_print(outf, level + 2, header, value);
621 
622 	format_and_print(outf, level, NULL, NULL);
623 }
624 
625 void isst_clos_display_clos_information(struct isst_id *id, FILE *outf,
626 					int clos_enable, int type,
627 					int state, int cap)
628 {
629 	char header[256];
630 	char value[256];
631 	int level;
632 
633 	level = print_package_info(id, outf);
634 
635 	snprintf(header, sizeof(header), "core-power");
636 	format_and_print(outf, level + 1, header, NULL);
637 
638 	snprintf(header, sizeof(header), "support-status");
639 	if (cap)
640 		snprintf(value, sizeof(value), "supported");
641 	else
642 		snprintf(value, sizeof(value), "unsupported");
643 	format_and_print(outf, level + 2, header, value);
644 
645 	snprintf(header, sizeof(header), "enable-status");
646 	if (state)
647 		snprintf(value, sizeof(value), "enabled");
648 	else
649 		snprintf(value, sizeof(value), "disabled");
650 	format_and_print(outf, level + 2, header, value);
651 
652 	snprintf(header, sizeof(header), "clos-enable-status");
653 	if (clos_enable)
654 		snprintf(value, sizeof(value), "enabled");
655 	else
656 		snprintf(value, sizeof(value), "disabled");
657 	format_and_print(outf, level + 2, header, value);
658 
659 	snprintf(header, sizeof(header), "priority-type");
660 	if (type)
661 		snprintf(value, sizeof(value), "ordered");
662 	else
663 		snprintf(value, sizeof(value), "proportional");
664 	format_and_print(outf, level + 2, header, value);
665 
666 	format_and_print(outf, level, NULL, NULL);
667 }
668 
669 void isst_clos_display_assoc_information(struct isst_id *id, FILE *outf, int clos)
670 {
671 	char header[256];
672 	char value[256];
673 	int level;
674 
675 	level = print_package_info(id, outf);
676 
677 	snprintf(header, sizeof(header), "get-assoc");
678 	format_and_print(outf, level + 1, header, NULL);
679 
680 	snprintf(header, sizeof(header), "clos");
681 	snprintf(value, sizeof(value), "%d", clos);
682 	format_and_print(outf, level + 2, header, value);
683 
684 	format_and_print(outf, level, NULL, NULL);
685 }
686 
687 void isst_display_result(struct isst_id *id, FILE *outf, char *feature, char *cmd,
688 			 int result)
689 {
690 	char header[256];
691 	char value[256];
692 	int level = 3;
693 
694 	level = print_package_info(id, outf);
695 
696 	snprintf(header, sizeof(header), "%s", feature);
697 	format_and_print(outf, level + 1, header, NULL);
698 	snprintf(header, sizeof(header), "%s", cmd);
699 	if (!result)
700 		snprintf(value, sizeof(value), "success");
701 	else
702 		snprintf(value, sizeof(value), "failed(error %d)", result);
703 	format_and_print(outf, level + 2, header, value);
704 
705 	format_and_print(outf, level, NULL, NULL);
706 }
707 
708 void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg)
709 {
710 	FILE *outf = get_output_file();
711 	static int error_index;
712 	char header[256];
713 	char value[256];
714 
715 	if (!out_format_is_json()) {
716 		if (arg_valid)
717 			snprintf(value, sizeof(value), "%s %d", msg, arg);
718 		else
719 			snprintf(value, sizeof(value), "%s", msg);
720 
721 		if (error)
722 			fprintf(outf, "Error: %s\n", value);
723 		else
724 			fprintf(outf, "Information: %s\n", value);
725 		return;
726 	}
727 
728 	if (!start)
729 		format_and_print(outf, 0, "start", NULL);
730 
731 	if (error)
732 		snprintf(header, sizeof(header), "Error%d", error_index++);
733 	else
734 		snprintf(header, sizeof(header), "Information:%d", error_index++);
735 	format_and_print(outf, 1, header, NULL);
736 
737 	snprintf(header, sizeof(header), "message");
738 	if (arg_valid)
739 		snprintf(value, sizeof(value), "%s %d", msg, arg);
740 	else
741 		snprintf(value, sizeof(value), "%s", msg);
742 
743 	format_and_print(outf, 2, header, value);
744 	format_and_print(outf, 1, NULL, NULL);
745 	if (!start)
746 		format_and_print(outf, 0, NULL, NULL);
747 }
748 
749 void isst_trl_display_information(struct isst_id *id, FILE *outf, unsigned long long trl)
750 {
751 	char header[256];
752 	char value[256];
753 	int level;
754 
755 	level = print_package_info(id, outf);
756 
757 	snprintf(header, sizeof(header), "get-trl");
758 	format_and_print(outf, level + 1, header, NULL);
759 
760 	snprintf(header, sizeof(header), "trl");
761 	snprintf(value, sizeof(value), "0x%llx", trl);
762 	format_and_print(outf, level + 2, header, value);
763 
764 	format_and_print(outf, level, NULL, NULL);
765 }
766