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
20static struct option set_opts[] = {
21	{ .name = "perf-bias",	.has_arg = required_argument,	.flag = NULL,	.val = 'b'},
22	{ },
23};
24
25static void print_wrong_arg_exit(void)
26{
27	printf(_("invalid or unknown argument\n"));
28	exit(EXIT_FAILURE);
29}
30
31int 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