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