1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
4  */
5 
6 
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <errno.h>
11 #include <string.h>
12 #include <getopt.h>
13 #include <sys/utsname.h>
14 
15 #include "helpers/helpers.h"
16 #include "helpers/sysfs.h"
17 
18 static struct option set_opts[] = {
19      {"perf-bias", optional_argument, NULL, 'b'},
20      { },
21 };
22 
23 static void print_wrong_arg_exit(void)
24 {
25 	printf(_("invalid or unknown argument\n"));
26 	exit(EXIT_FAILURE);
27 }
28 
29 int cmd_info(int argc, char **argv)
30 {
31 	extern char *optarg;
32 	extern int optind, opterr, optopt;
33 	unsigned int cpu;
34 	struct utsname uts;
35 
36 	union {
37 		struct {
38 			int perf_bias:1;
39 		};
40 		int params;
41 	} params = {};
42 	int ret = 0;
43 
44 	ret = uname(&uts);
45 	if (!ret && (!strcmp(uts.machine, "ppc64le") ||
46 		     !strcmp(uts.machine, "ppc64"))) {
47 		fprintf(stderr, _("Subcommand not supported on POWER.\n"));
48 		return ret;
49 	}
50 
51 	setlocale(LC_ALL, "");
52 	textdomain(PACKAGE);
53 
54 	/* parameter parsing */
55 	while ((ret = getopt_long(argc, argv, "b", set_opts, NULL)) != -1) {
56 		switch (ret) {
57 		case 'b':
58 			if (params.perf_bias)
59 				print_wrong_arg_exit();
60 			params.perf_bias = 1;
61 			break;
62 		default:
63 			print_wrong_arg_exit();
64 		}
65 	}
66 
67 	if (!params.params)
68 		params.params = 0x7;
69 
70 	/* Default is: show output of CPU 0 only */
71 	if (bitmask_isallclear(cpus_chosen))
72 		bitmask_setbit(cpus_chosen, 0);
73 
74 	/* Add more per cpu options here */
75 	if (!params.perf_bias)
76 		return ret;
77 
78 	if (params.perf_bias) {
79 		if (!run_as_root) {
80 			params.perf_bias = 0;
81 			printf(_("Intel's performance bias setting needs root privileges\n"));
82 		} else if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) {
83 			printf(_("System does not support Intel's performance"
84 				 " bias setting\n"));
85 			params.perf_bias = 0;
86 		}
87 	}
88 
89 	/* loop over CPUs */
90 	for (cpu = bitmask_first(cpus_chosen);
91 	     cpu <= bitmask_last(cpus_chosen); cpu++) {
92 
93 		if (!bitmask_isbitset(cpus_chosen, cpu))
94 			continue;
95 
96 		printf(_("analyzing CPU %d:\n"), cpu);
97 
98 		if (sysfs_is_cpu_online(cpu) != 1){
99 			printf(_(" *is offline\n"));
100 			continue;
101 		}
102 
103 		if (params.perf_bias) {
104 			ret = msr_intel_get_perf_bias(cpu);
105 			if (ret < 0) {
106 				fprintf(stderr,
107 			_("Could not read perf-bias value[%d]\n"), ret);
108 				exit(EXIT_FAILURE);
109 			} else
110 				printf(_("perf-bias: %d\n"), ret);
111 		}
112 	}
113 	return 0;
114 }
115