162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <unistd.h>
862306a36Sopenharmony_ci#include <stdio.h>
962306a36Sopenharmony_ci#include <stdlib.h>
1062306a36Sopenharmony_ci#include <errno.h>
1162306a36Sopenharmony_ci#include <string.h>
1262306a36Sopenharmony_ci#include <getopt.h>
1362306a36Sopenharmony_ci#include <sys/utsname.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include "helpers/helpers.h"
1662306a36Sopenharmony_ci#include "helpers/sysfs.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistatic struct option set_opts[] = {
1962306a36Sopenharmony_ci     {"perf-bias", optional_argument, NULL, 'b'},
2062306a36Sopenharmony_ci     { },
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic void print_wrong_arg_exit(void)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	printf(_("invalid or unknown argument\n"));
2662306a36Sopenharmony_ci	exit(EXIT_FAILURE);
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciint cmd_info(int argc, char **argv)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	extern char *optarg;
3262306a36Sopenharmony_ci	extern int optind, opterr, optopt;
3362306a36Sopenharmony_ci	unsigned int cpu;
3462306a36Sopenharmony_ci	struct utsname uts;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	union {
3762306a36Sopenharmony_ci		struct {
3862306a36Sopenharmony_ci			int perf_bias:1;
3962306a36Sopenharmony_ci		};
4062306a36Sopenharmony_ci		int params;
4162306a36Sopenharmony_ci	} params = {};
4262306a36Sopenharmony_ci	int ret = 0;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	ret = uname(&uts);
4562306a36Sopenharmony_ci	if (!ret && (!strcmp(uts.machine, "ppc64le") ||
4662306a36Sopenharmony_ci		     !strcmp(uts.machine, "ppc64"))) {
4762306a36Sopenharmony_ci		fprintf(stderr, _("Subcommand not supported on POWER.\n"));
4862306a36Sopenharmony_ci		return ret;
4962306a36Sopenharmony_ci	}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	setlocale(LC_ALL, "");
5262306a36Sopenharmony_ci	textdomain(PACKAGE);
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	/* parameter parsing */
5562306a36Sopenharmony_ci	while ((ret = getopt_long(argc, argv, "b", set_opts, NULL)) != -1) {
5662306a36Sopenharmony_ci		switch (ret) {
5762306a36Sopenharmony_ci		case 'b':
5862306a36Sopenharmony_ci			if (params.perf_bias)
5962306a36Sopenharmony_ci				print_wrong_arg_exit();
6062306a36Sopenharmony_ci			params.perf_bias = 1;
6162306a36Sopenharmony_ci			break;
6262306a36Sopenharmony_ci		default:
6362306a36Sopenharmony_ci			print_wrong_arg_exit();
6462306a36Sopenharmony_ci		}
6562306a36Sopenharmony_ci	}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	if (!params.params)
6862306a36Sopenharmony_ci		params.params = 0x7;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	/* Default is: show output of base_cpu only */
7162306a36Sopenharmony_ci	if (bitmask_isallclear(cpus_chosen))
7262306a36Sopenharmony_ci		bitmask_setbit(cpus_chosen, base_cpu);
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	/* Add more per cpu options here */
7562306a36Sopenharmony_ci	if (!params.perf_bias)
7662306a36Sopenharmony_ci		return ret;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (params.perf_bias) {
7962306a36Sopenharmony_ci		if (!run_as_root) {
8062306a36Sopenharmony_ci			params.perf_bias = 0;
8162306a36Sopenharmony_ci			printf(_("Intel's performance bias setting needs root privileges\n"));
8262306a36Sopenharmony_ci		} else if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) {
8362306a36Sopenharmony_ci			printf(_("System does not support Intel's performance"
8462306a36Sopenharmony_ci				 " bias setting\n"));
8562306a36Sopenharmony_ci			params.perf_bias = 0;
8662306a36Sopenharmony_ci		}
8762306a36Sopenharmony_ci	}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	/* loop over CPUs */
9062306a36Sopenharmony_ci	for (cpu = bitmask_first(cpus_chosen);
9162306a36Sopenharmony_ci	     cpu <= bitmask_last(cpus_chosen); cpu++) {
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci		if (!bitmask_isbitset(cpus_chosen, cpu))
9462306a36Sopenharmony_ci			continue;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci		printf(_("analyzing CPU %d:\n"), cpu);
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci		if (sysfs_is_cpu_online(cpu) != 1){
9962306a36Sopenharmony_ci			printf(_(" *is offline\n"));
10062306a36Sopenharmony_ci			continue;
10162306a36Sopenharmony_ci		}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci		if (params.perf_bias) {
10462306a36Sopenharmony_ci			ret = cpupower_intel_get_perf_bias(cpu);
10562306a36Sopenharmony_ci			if (ret < 0) {
10662306a36Sopenharmony_ci				fprintf(stderr,
10762306a36Sopenharmony_ci			_("Could not read perf-bias value[%d]\n"), ret);
10862306a36Sopenharmony_ci				exit(EXIT_FAILURE);
10962306a36Sopenharmony_ci			} else
11062306a36Sopenharmony_ci				printf(_("perf-bias: %d\n"), ret);
11162306a36Sopenharmony_ci		}
11262306a36Sopenharmony_ci	}
11362306a36Sopenharmony_ci	return 0;
11462306a36Sopenharmony_ci}
115