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 #include "helpers/bitmask.h"
18
19 static struct option set_opts[] = {
20 {"perf-bias", required_argument, NULL, 'b'},
21 {"epp", required_argument, NULL, 'e'},
22 {"amd-pstate-mode", required_argument, NULL, 'm'},
23 {"turbo-boost", required_argument, NULL, 't'},
24 {"boost", required_argument, NULL, 't'},
25 { },
26 };
27
print_wrong_arg_exit(void)28 static void print_wrong_arg_exit(void)
29 {
30 printf(_("invalid or unknown argument\n"));
31 exit(EXIT_FAILURE);
32 }
33
cmd_set(int argc,char ** argv)34 int cmd_set(int argc, char **argv)
35 {
36 unsigned int cpu;
37 struct utsname uts;
38
39 union {
40 struct {
41 int perf_bias:1;
42 int epp:1;
43 int mode:1;
44 int turbo_boost:1;
45 };
46 int params;
47 } params;
48 int perf_bias = 0, turbo_boost = 1;
49 int ret = 0;
50 char epp[30], mode[20];
51
52 ret = uname(&uts);
53 if (!ret && (!strcmp(uts.machine, "ppc64le") ||
54 !strcmp(uts.machine, "ppc64"))) {
55 fprintf(stderr, _("Subcommand not supported on POWER.\n"));
56 return ret;
57 }
58
59 setlocale(LC_ALL, "");
60 textdomain(PACKAGE);
61
62 params.params = 0;
63 /* parameter parsing */
64 while ((ret = getopt_long(argc, argv, "b:e:m:t:",
65 set_opts, NULL)) != -1) {
66 switch (ret) {
67 case 'b':
68 if (params.perf_bias)
69 print_wrong_arg_exit();
70 perf_bias = atoi(optarg);
71 if (perf_bias < 0 || perf_bias > 15) {
72 printf(_("--perf-bias param out "
73 "of range [0-%d]\n"), 15);
74 print_wrong_arg_exit();
75 }
76 params.perf_bias = 1;
77 break;
78 case 'e':
79 if (params.epp)
80 print_wrong_arg_exit();
81 if (sscanf(optarg, "%29s", epp) != 1) {
82 print_wrong_arg_exit();
83 return -EINVAL;
84 }
85 params.epp = 1;
86 break;
87 case 'm':
88 if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
89 print_wrong_arg_exit();
90 if (params.mode)
91 print_wrong_arg_exit();
92 if (sscanf(optarg, "%19s", mode) != 1) {
93 print_wrong_arg_exit();
94 return -EINVAL;
95 }
96 params.mode = 1;
97 break;
98 case 't':
99 if (params.turbo_boost)
100 print_wrong_arg_exit();
101 turbo_boost = atoi(optarg);
102 if (turbo_boost < 0 || turbo_boost > 1) {
103 printf("--turbo-boost param out of range [0-1]\n");
104 print_wrong_arg_exit();
105 }
106 params.turbo_boost = 1;
107 break;
108
109
110 default:
111 print_wrong_arg_exit();
112 }
113 }
114
115 if (!params.params)
116 print_wrong_arg_exit();
117
118 if (params.mode) {
119 ret = cpupower_set_amd_pstate_mode(mode);
120 if (ret)
121 fprintf(stderr, "Error setting mode\n");
122 }
123
124 if (params.turbo_boost) {
125 if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL)
126 ret = cpupower_set_intel_turbo_boost(turbo_boost);
127 else
128 ret = cpupower_set_generic_turbo_boost(turbo_boost);
129
130 if (ret)
131 fprintf(stderr, "Error setting turbo-boost\n");
132 }
133
134 /* Default is: set all CPUs */
135 if (bitmask_isallclear(cpus_chosen))
136 bitmask_setall(cpus_chosen);
137
138 /* loop over CPUs */
139 for (cpu = bitmask_first(cpus_chosen);
140 cpu <= bitmask_last(cpus_chosen); cpu++) {
141
142 if (!bitmask_isbitset(cpus_chosen, cpu))
143 continue;
144
145 if (sysfs_is_cpu_online(cpu) != 1){
146 fprintf(stderr, _("Cannot set values on CPU %d:"), cpu);
147 fprintf(stderr, _(" *is offline\n"));
148 continue;
149 }
150
151 if (params.perf_bias) {
152 ret = cpupower_intel_set_perf_bias(cpu, perf_bias);
153 if (ret) {
154 fprintf(stderr, _("Error setting perf-bias "
155 "value on CPU %d\n"), cpu);
156 break;
157 }
158 }
159
160 if (params.epp) {
161 ret = cpupower_set_epp(cpu, epp);
162 if (ret) {
163 fprintf(stderr,
164 "Error setting epp value on CPU %d\n", cpu);
165 break;
166 }
167 }
168
169 }
170 return ret;
171 }
172