169 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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 19static 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 27static void print_wrong_arg_exit(void)28{29 printf(_("invalid or unknown argument\n"));30 exit(EXIT_FAILURE);31}32 33int 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