1 /*
2  *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3  *
4  *  Licensed under the terms of the GNU GPL License version 2.
5  */
6 
7 
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <getopt.h>
14 
15 #include <cpufreq.h>
16 #include "helpers/helpers.h"
17 #include "helpers/sysfs.h"
18 #include "helpers/bitmask.h"
19 
20 static struct option set_opts[] = {
21 	{ .name = "perf-bias",	.has_arg = required_argument,	.flag = NULL,	.val = 'b'},
22 	{ },
23 };
24 
25 static void print_wrong_arg_exit(void)
26 {
27 	printf(_("invalid or unknown argument\n"));
28 	exit(EXIT_FAILURE);
29 }
30 
31 int cmd_set(int argc, char **argv)
32 {
33 	extern char *optarg;
34 	extern int optind, opterr, optopt;
35 	unsigned int cpu;
36 
37 	union {
38 		struct {
39 			int perf_bias:1;
40 		};
41 		int params;
42 	} params;
43 	int perf_bias = 0;
44 	int ret = 0;
45 
46 	setlocale(LC_ALL, "");
47 	textdomain(PACKAGE);
48 
49 	params.params = 0;
50 	/* parameter parsing */
51 	while ((ret = getopt_long(argc, argv, "b:",
52 						set_opts, NULL)) != -1) {
53 		switch (ret) {
54 		case 'b':
55 			if (params.perf_bias)
56 				print_wrong_arg_exit();
57 			perf_bias = atoi(optarg);
58 			if (perf_bias < 0 || perf_bias > 15) {
59 				printf(_("--perf-bias param out "
60 					 "of range [0-%d]\n"), 15);
61 				print_wrong_arg_exit();
62 			}
63 			params.perf_bias = 1;
64 			break;
65 		default:
66 			print_wrong_arg_exit();
67 		}
68 	};
69 
70 	if (!params.params)
71 		print_wrong_arg_exit();
72 
73 	/* Default is: set all CPUs */
74 	if (bitmask_isallclear(cpus_chosen))
75 		bitmask_setall(cpus_chosen);
76 
77 	/* loop over CPUs */
78 	for (cpu = bitmask_first(cpus_chosen);
79 	     cpu <= bitmask_last(cpus_chosen); cpu++) {
80 
81 		if (!bitmask_isbitset(cpus_chosen, cpu) ||
82 		    cpufreq_cpu_exists(cpu))
83 			continue;
84 
85 		if (params.perf_bias) {
86 			ret = msr_intel_set_perf_bias(cpu, perf_bias);
87 			if (ret) {
88 				fprintf(stderr, _("Error setting perf-bias "
89 						  "value on CPU %d\n"), cpu);
90 				break;
91 			}
92 		}
93 	}
94 	return ret;
95 }
96