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
9static 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
40static 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
84static 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
111static int last_level;
112static 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
169static 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
198static 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
241static 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
319void 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
338void 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), "max-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
547static int start;
548void 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
555void isst_ctdp_display_information_end(FILE *outf)
556{
557	format_and_print(outf, 0, NULL, NULL);
558	start = 0;
559}
560
561void 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
571void 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
583void 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
625void 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
669void 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
687void 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
708void 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
749void 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