xref: /linux/tools/power/x86/intel-speed-select/isst-config.c (revision 3bc3d30ca324bfc3045a1a7fe1f5fe5ad5d92fd9)
13fb4f7cdSSrinivas Pandruvada // SPDX-License-Identifier: GPL-2.0
23fb4f7cdSSrinivas Pandruvada /*
33fb4f7cdSSrinivas Pandruvada  * Intel Speed Select -- Enumerate and control features
43fb4f7cdSSrinivas Pandruvada  * Copyright (c) 2019 Intel Corporation.
53fb4f7cdSSrinivas Pandruvada  */
63fb4f7cdSSrinivas Pandruvada 
73fb4f7cdSSrinivas Pandruvada #include <linux/isst_if.h>
83fb4f7cdSSrinivas Pandruvada 
93fb4f7cdSSrinivas Pandruvada #include "isst.h"
103fb4f7cdSSrinivas Pandruvada 
113fb4f7cdSSrinivas Pandruvada struct process_cmd_struct {
123fb4f7cdSSrinivas Pandruvada 	char *feature;
133fb4f7cdSSrinivas Pandruvada 	char *command;
143fb4f7cdSSrinivas Pandruvada 	void (*process_fn)(void);
153fb4f7cdSSrinivas Pandruvada };
163fb4f7cdSSrinivas Pandruvada 
173fb4f7cdSSrinivas Pandruvada static const char *version_str = "v1.0";
183fb4f7cdSSrinivas Pandruvada static const int supported_api_ver = 1;
193fb4f7cdSSrinivas Pandruvada static struct isst_if_platform_info isst_platform_info;
203fb4f7cdSSrinivas Pandruvada static char *progname;
213fb4f7cdSSrinivas Pandruvada static int debug_flag;
223fb4f7cdSSrinivas Pandruvada static FILE *outf;
233fb4f7cdSSrinivas Pandruvada 
243fb4f7cdSSrinivas Pandruvada static int cpu_model;
253fb4f7cdSSrinivas Pandruvada 
263fb4f7cdSSrinivas Pandruvada #define MAX_CPUS_IN_ONE_REQ 64
273fb4f7cdSSrinivas Pandruvada static short max_target_cpus;
283fb4f7cdSSrinivas Pandruvada static unsigned short target_cpus[MAX_CPUS_IN_ONE_REQ];
293fb4f7cdSSrinivas Pandruvada 
303fb4f7cdSSrinivas Pandruvada static int topo_max_cpus;
313fb4f7cdSSrinivas Pandruvada static size_t present_cpumask_size;
323fb4f7cdSSrinivas Pandruvada static cpu_set_t *present_cpumask;
333fb4f7cdSSrinivas Pandruvada static size_t target_cpumask_size;
343fb4f7cdSSrinivas Pandruvada static cpu_set_t *target_cpumask;
353fb4f7cdSSrinivas Pandruvada static int tdp_level = 0xFF;
363fb4f7cdSSrinivas Pandruvada static int fact_bucket = 0xFF;
373fb4f7cdSSrinivas Pandruvada static int fact_avx = 0xFF;
383fb4f7cdSSrinivas Pandruvada static unsigned long long fact_trl;
393fb4f7cdSSrinivas Pandruvada static int out_format_json;
403fb4f7cdSSrinivas Pandruvada static int cmd_help;
413fb4f7cdSSrinivas Pandruvada 
423fb4f7cdSSrinivas Pandruvada /* clos related */
433fb4f7cdSSrinivas Pandruvada static int current_clos = -1;
443fb4f7cdSSrinivas Pandruvada static int clos_epp = -1;
453fb4f7cdSSrinivas Pandruvada static int clos_prop_prio = -1;
463fb4f7cdSSrinivas Pandruvada static int clos_min = -1;
473fb4f7cdSSrinivas Pandruvada static int clos_max = -1;
483fb4f7cdSSrinivas Pandruvada static int clos_desired = -1;
493fb4f7cdSSrinivas Pandruvada static int clos_priority_type;
503fb4f7cdSSrinivas Pandruvada 
513fb4f7cdSSrinivas Pandruvada struct _cpu_map {
523fb4f7cdSSrinivas Pandruvada 	unsigned short core_id;
533fb4f7cdSSrinivas Pandruvada 	unsigned short pkg_id;
543fb4f7cdSSrinivas Pandruvada 	unsigned short die_id;
553fb4f7cdSSrinivas Pandruvada 	unsigned short punit_cpu;
563fb4f7cdSSrinivas Pandruvada 	unsigned short punit_cpu_core;
573fb4f7cdSSrinivas Pandruvada };
583fb4f7cdSSrinivas Pandruvada struct _cpu_map *cpu_map;
593fb4f7cdSSrinivas Pandruvada 
603fb4f7cdSSrinivas Pandruvada void debug_printf(const char *format, ...)
613fb4f7cdSSrinivas Pandruvada {
623fb4f7cdSSrinivas Pandruvada 	va_list args;
633fb4f7cdSSrinivas Pandruvada 
643fb4f7cdSSrinivas Pandruvada 	va_start(args, format);
653fb4f7cdSSrinivas Pandruvada 
663fb4f7cdSSrinivas Pandruvada 	if (debug_flag)
673fb4f7cdSSrinivas Pandruvada 		vprintf(format, args);
683fb4f7cdSSrinivas Pandruvada 
693fb4f7cdSSrinivas Pandruvada 	va_end(args);
703fb4f7cdSSrinivas Pandruvada }
713fb4f7cdSSrinivas Pandruvada 
723fb4f7cdSSrinivas Pandruvada static void update_cpu_model(void)
733fb4f7cdSSrinivas Pandruvada {
743fb4f7cdSSrinivas Pandruvada 	unsigned int ebx, ecx, edx;
753fb4f7cdSSrinivas Pandruvada 	unsigned int fms, family;
763fb4f7cdSSrinivas Pandruvada 
773fb4f7cdSSrinivas Pandruvada 	__cpuid(1, fms, ebx, ecx, edx);
783fb4f7cdSSrinivas Pandruvada 	family = (fms >> 8) & 0xf;
793fb4f7cdSSrinivas Pandruvada 	cpu_model = (fms >> 4) & 0xf;
803fb4f7cdSSrinivas Pandruvada 	if (family == 6 || family == 0xf)
813fb4f7cdSSrinivas Pandruvada 		cpu_model += ((fms >> 16) & 0xf) << 4;
823fb4f7cdSSrinivas Pandruvada }
833fb4f7cdSSrinivas Pandruvada 
843fb4f7cdSSrinivas Pandruvada /* Open a file, and exit on failure */
853fb4f7cdSSrinivas Pandruvada static FILE *fopen_or_exit(const char *path, const char *mode)
863fb4f7cdSSrinivas Pandruvada {
873fb4f7cdSSrinivas Pandruvada 	FILE *filep = fopen(path, mode);
883fb4f7cdSSrinivas Pandruvada 
893fb4f7cdSSrinivas Pandruvada 	if (!filep)
903fb4f7cdSSrinivas Pandruvada 		err(1, "%s: open failed", path);
913fb4f7cdSSrinivas Pandruvada 
923fb4f7cdSSrinivas Pandruvada 	return filep;
933fb4f7cdSSrinivas Pandruvada }
943fb4f7cdSSrinivas Pandruvada 
953fb4f7cdSSrinivas Pandruvada /* Parse a file containing a single int */
963fb4f7cdSSrinivas Pandruvada static int parse_int_file(int fatal, const char *fmt, ...)
973fb4f7cdSSrinivas Pandruvada {
983fb4f7cdSSrinivas Pandruvada 	va_list args;
993fb4f7cdSSrinivas Pandruvada 	char path[PATH_MAX];
1003fb4f7cdSSrinivas Pandruvada 	FILE *filep;
1013fb4f7cdSSrinivas Pandruvada 	int value;
1023fb4f7cdSSrinivas Pandruvada 
1033fb4f7cdSSrinivas Pandruvada 	va_start(args, fmt);
1043fb4f7cdSSrinivas Pandruvada 	vsnprintf(path, sizeof(path), fmt, args);
1053fb4f7cdSSrinivas Pandruvada 	va_end(args);
1063fb4f7cdSSrinivas Pandruvada 	if (fatal) {
1073fb4f7cdSSrinivas Pandruvada 		filep = fopen_or_exit(path, "r");
1083fb4f7cdSSrinivas Pandruvada 	} else {
1093fb4f7cdSSrinivas Pandruvada 		filep = fopen(path, "r");
1103fb4f7cdSSrinivas Pandruvada 		if (!filep)
1113fb4f7cdSSrinivas Pandruvada 			return -1;
1123fb4f7cdSSrinivas Pandruvada 	}
1133fb4f7cdSSrinivas Pandruvada 	if (fscanf(filep, "%d", &value) != 1)
1143fb4f7cdSSrinivas Pandruvada 		err(1, "%s: failed to parse number from file", path);
1153fb4f7cdSSrinivas Pandruvada 	fclose(filep);
1163fb4f7cdSSrinivas Pandruvada 
1173fb4f7cdSSrinivas Pandruvada 	return value;
1183fb4f7cdSSrinivas Pandruvada }
1193fb4f7cdSSrinivas Pandruvada 
1203fb4f7cdSSrinivas Pandruvada int cpufreq_sysfs_present(void)
1213fb4f7cdSSrinivas Pandruvada {
1223fb4f7cdSSrinivas Pandruvada 	DIR *dir;
1233fb4f7cdSSrinivas Pandruvada 
1243fb4f7cdSSrinivas Pandruvada 	dir = opendir("/sys/devices/system/cpu/cpu0/cpufreq");
1253fb4f7cdSSrinivas Pandruvada 	if (dir) {
1263fb4f7cdSSrinivas Pandruvada 		closedir(dir);
1273fb4f7cdSSrinivas Pandruvada 		return 1;
1283fb4f7cdSSrinivas Pandruvada 	}
1293fb4f7cdSSrinivas Pandruvada 
1303fb4f7cdSSrinivas Pandruvada 	return 0;
1313fb4f7cdSSrinivas Pandruvada }
1323fb4f7cdSSrinivas Pandruvada 
1333fb4f7cdSSrinivas Pandruvada int out_format_is_json(void)
1343fb4f7cdSSrinivas Pandruvada {
1353fb4f7cdSSrinivas Pandruvada 	return out_format_json;
1363fb4f7cdSSrinivas Pandruvada }
1373fb4f7cdSSrinivas Pandruvada 
1383fb4f7cdSSrinivas Pandruvada int get_physical_package_id(int cpu)
1393fb4f7cdSSrinivas Pandruvada {
1403fb4f7cdSSrinivas Pandruvada 	return parse_int_file(
1413fb4f7cdSSrinivas Pandruvada 		1, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id",
1423fb4f7cdSSrinivas Pandruvada 		cpu);
1433fb4f7cdSSrinivas Pandruvada }
1443fb4f7cdSSrinivas Pandruvada 
1453fb4f7cdSSrinivas Pandruvada int get_physical_core_id(int cpu)
1463fb4f7cdSSrinivas Pandruvada {
1473fb4f7cdSSrinivas Pandruvada 	return parse_int_file(
1483fb4f7cdSSrinivas Pandruvada 		1, "/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
1493fb4f7cdSSrinivas Pandruvada }
1503fb4f7cdSSrinivas Pandruvada 
1513fb4f7cdSSrinivas Pandruvada int get_physical_die_id(int cpu)
1523fb4f7cdSSrinivas Pandruvada {
1533fb4f7cdSSrinivas Pandruvada 	int ret;
1543fb4f7cdSSrinivas Pandruvada 
1553fb4f7cdSSrinivas Pandruvada 	ret = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/topology/die_id",
1563fb4f7cdSSrinivas Pandruvada 			     cpu);
1573fb4f7cdSSrinivas Pandruvada 	if (ret < 0)
1583fb4f7cdSSrinivas Pandruvada 		ret = 0;
1593fb4f7cdSSrinivas Pandruvada 
1603fb4f7cdSSrinivas Pandruvada 	return ret;
1613fb4f7cdSSrinivas Pandruvada }
1623fb4f7cdSSrinivas Pandruvada 
1633fb4f7cdSSrinivas Pandruvada int get_topo_max_cpus(void)
1643fb4f7cdSSrinivas Pandruvada {
1653fb4f7cdSSrinivas Pandruvada 	return topo_max_cpus;
1663fb4f7cdSSrinivas Pandruvada }
1673fb4f7cdSSrinivas Pandruvada 
1683fb4f7cdSSrinivas Pandruvada #define MAX_PACKAGE_COUNT 8
1693fb4f7cdSSrinivas Pandruvada #define MAX_DIE_PER_PACKAGE 2
1703fb4f7cdSSrinivas Pandruvada static void for_each_online_package_in_set(void (*callback)(int, void *, void *,
1713fb4f7cdSSrinivas Pandruvada 							    void *, void *),
1723fb4f7cdSSrinivas Pandruvada 					   void *arg1, void *arg2, void *arg3,
1733fb4f7cdSSrinivas Pandruvada 					   void *arg4)
1743fb4f7cdSSrinivas Pandruvada {
1753fb4f7cdSSrinivas Pandruvada 	int max_packages[MAX_PACKAGE_COUNT * MAX_PACKAGE_COUNT];
1763fb4f7cdSSrinivas Pandruvada 	int pkg_index = 0, i;
1773fb4f7cdSSrinivas Pandruvada 
1783fb4f7cdSSrinivas Pandruvada 	memset(max_packages, 0xff, sizeof(max_packages));
1793fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
1803fb4f7cdSSrinivas Pandruvada 		int j, online, pkg_id, die_id = 0, skip = 0;
1813fb4f7cdSSrinivas Pandruvada 
1823fb4f7cdSSrinivas Pandruvada 		if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
1833fb4f7cdSSrinivas Pandruvada 			continue;
1843fb4f7cdSSrinivas Pandruvada 		if (i)
1853fb4f7cdSSrinivas Pandruvada 			online = parse_int_file(
1863fb4f7cdSSrinivas Pandruvada 				1, "/sys/devices/system/cpu/cpu%d/online", i);
1873fb4f7cdSSrinivas Pandruvada 		else
1883fb4f7cdSSrinivas Pandruvada 			online =
1893fb4f7cdSSrinivas Pandruvada 				1; /* online entry for CPU 0 needs some special configs */
1903fb4f7cdSSrinivas Pandruvada 
1913fb4f7cdSSrinivas Pandruvada 		die_id = get_physical_die_id(i);
1923fb4f7cdSSrinivas Pandruvada 		if (die_id < 0)
1933fb4f7cdSSrinivas Pandruvada 			die_id = 0;
1943fb4f7cdSSrinivas Pandruvada 		pkg_id = get_physical_package_id(i);
1953fb4f7cdSSrinivas Pandruvada 		/* Create an unique id for package, die combination to store */
1963fb4f7cdSSrinivas Pandruvada 		pkg_id = (MAX_PACKAGE_COUNT * pkg_id + die_id);
1973fb4f7cdSSrinivas Pandruvada 
1983fb4f7cdSSrinivas Pandruvada 		for (j = 0; j < pkg_index; ++j) {
1993fb4f7cdSSrinivas Pandruvada 			if (max_packages[j] == pkg_id) {
2003fb4f7cdSSrinivas Pandruvada 				skip = 1;
2013fb4f7cdSSrinivas Pandruvada 				break;
2023fb4f7cdSSrinivas Pandruvada 			}
2033fb4f7cdSSrinivas Pandruvada 		}
2043fb4f7cdSSrinivas Pandruvada 
2053fb4f7cdSSrinivas Pandruvada 		if (!skip && online && callback) {
2063fb4f7cdSSrinivas Pandruvada 			callback(i, arg1, arg2, arg3, arg4);
2073fb4f7cdSSrinivas Pandruvada 			max_packages[pkg_index++] = pkg_id;
2083fb4f7cdSSrinivas Pandruvada 		}
2093fb4f7cdSSrinivas Pandruvada 	}
2103fb4f7cdSSrinivas Pandruvada }
2113fb4f7cdSSrinivas Pandruvada 
2123fb4f7cdSSrinivas Pandruvada static void for_each_online_target_cpu_in_set(
2133fb4f7cdSSrinivas Pandruvada 	void (*callback)(int, void *, void *, void *, void *), void *arg1,
2143fb4f7cdSSrinivas Pandruvada 	void *arg2, void *arg3, void *arg4)
2153fb4f7cdSSrinivas Pandruvada {
2163fb4f7cdSSrinivas Pandruvada 	int i;
2173fb4f7cdSSrinivas Pandruvada 
2183fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
2193fb4f7cdSSrinivas Pandruvada 		int online;
2203fb4f7cdSSrinivas Pandruvada 
2213fb4f7cdSSrinivas Pandruvada 		if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask))
2223fb4f7cdSSrinivas Pandruvada 			continue;
2233fb4f7cdSSrinivas Pandruvada 		if (i)
2243fb4f7cdSSrinivas Pandruvada 			online = parse_int_file(
2253fb4f7cdSSrinivas Pandruvada 				1, "/sys/devices/system/cpu/cpu%d/online", i);
2263fb4f7cdSSrinivas Pandruvada 		else
2273fb4f7cdSSrinivas Pandruvada 			online =
2283fb4f7cdSSrinivas Pandruvada 				1; /* online entry for CPU 0 needs some special configs */
2293fb4f7cdSSrinivas Pandruvada 
2303fb4f7cdSSrinivas Pandruvada 		if (online && callback)
2313fb4f7cdSSrinivas Pandruvada 			callback(i, arg1, arg2, arg3, arg4);
2323fb4f7cdSSrinivas Pandruvada 	}
2333fb4f7cdSSrinivas Pandruvada }
2343fb4f7cdSSrinivas Pandruvada 
2353fb4f7cdSSrinivas Pandruvada #define BITMASK_SIZE 32
2363fb4f7cdSSrinivas Pandruvada static void set_max_cpu_num(void)
2373fb4f7cdSSrinivas Pandruvada {
2383fb4f7cdSSrinivas Pandruvada 	FILE *filep;
2393fb4f7cdSSrinivas Pandruvada 	unsigned long dummy;
2403fb4f7cdSSrinivas Pandruvada 
2413fb4f7cdSSrinivas Pandruvada 	topo_max_cpus = 0;
2423fb4f7cdSSrinivas Pandruvada 	filep = fopen_or_exit(
2433fb4f7cdSSrinivas Pandruvada 		"/sys/devices/system/cpu/cpu0/topology/thread_siblings", "r");
2443fb4f7cdSSrinivas Pandruvada 	while (fscanf(filep, "%lx,", &dummy) == 1)
2453fb4f7cdSSrinivas Pandruvada 		topo_max_cpus += BITMASK_SIZE;
2463fb4f7cdSSrinivas Pandruvada 	fclose(filep);
2473fb4f7cdSSrinivas Pandruvada 	topo_max_cpus--; /* 0 based */
2483fb4f7cdSSrinivas Pandruvada 
2493fb4f7cdSSrinivas Pandruvada 	debug_printf("max cpus %d\n", topo_max_cpus);
2503fb4f7cdSSrinivas Pandruvada }
2513fb4f7cdSSrinivas Pandruvada 
2523fb4f7cdSSrinivas Pandruvada size_t alloc_cpu_set(cpu_set_t **cpu_set)
2533fb4f7cdSSrinivas Pandruvada {
2543fb4f7cdSSrinivas Pandruvada 	cpu_set_t *_cpu_set;
2553fb4f7cdSSrinivas Pandruvada 	size_t size;
2563fb4f7cdSSrinivas Pandruvada 
2573fb4f7cdSSrinivas Pandruvada 	_cpu_set = CPU_ALLOC((topo_max_cpus + 1));
2583fb4f7cdSSrinivas Pandruvada 	if (_cpu_set == NULL)
2593fb4f7cdSSrinivas Pandruvada 		err(3, "CPU_ALLOC");
2603fb4f7cdSSrinivas Pandruvada 	size = CPU_ALLOC_SIZE((topo_max_cpus + 1));
2613fb4f7cdSSrinivas Pandruvada 	CPU_ZERO_S(size, _cpu_set);
2623fb4f7cdSSrinivas Pandruvada 
2633fb4f7cdSSrinivas Pandruvada 	*cpu_set = _cpu_set;
2643fb4f7cdSSrinivas Pandruvada 	return size;
2653fb4f7cdSSrinivas Pandruvada }
2663fb4f7cdSSrinivas Pandruvada 
2673fb4f7cdSSrinivas Pandruvada void free_cpu_set(cpu_set_t *cpu_set)
2683fb4f7cdSSrinivas Pandruvada {
2693fb4f7cdSSrinivas Pandruvada 	CPU_FREE(cpu_set);
2703fb4f7cdSSrinivas Pandruvada }
2713fb4f7cdSSrinivas Pandruvada 
2723fb4f7cdSSrinivas Pandruvada static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE];
2733fb4f7cdSSrinivas Pandruvada static void set_cpu_present_cpu_mask(void)
2743fb4f7cdSSrinivas Pandruvada {
2753fb4f7cdSSrinivas Pandruvada 	size_t size;
2763fb4f7cdSSrinivas Pandruvada 	DIR *dir;
2773fb4f7cdSSrinivas Pandruvada 	int i;
2783fb4f7cdSSrinivas Pandruvada 
2793fb4f7cdSSrinivas Pandruvada 	size = alloc_cpu_set(&present_cpumask);
2803fb4f7cdSSrinivas Pandruvada 	present_cpumask_size = size;
2813fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
2823fb4f7cdSSrinivas Pandruvada 		char buffer[256];
2833fb4f7cdSSrinivas Pandruvada 
2843fb4f7cdSSrinivas Pandruvada 		snprintf(buffer, sizeof(buffer),
2853fb4f7cdSSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d", i);
2863fb4f7cdSSrinivas Pandruvada 		dir = opendir(buffer);
2873fb4f7cdSSrinivas Pandruvada 		if (dir) {
2883fb4f7cdSSrinivas Pandruvada 			int pkg_id, die_id;
2893fb4f7cdSSrinivas Pandruvada 
2903fb4f7cdSSrinivas Pandruvada 			CPU_SET_S(i, size, present_cpumask);
2913fb4f7cdSSrinivas Pandruvada 			die_id = get_physical_die_id(i);
2923fb4f7cdSSrinivas Pandruvada 			if (die_id < 0)
2933fb4f7cdSSrinivas Pandruvada 				die_id = 0;
2943fb4f7cdSSrinivas Pandruvada 
2953fb4f7cdSSrinivas Pandruvada 			pkg_id = get_physical_package_id(i);
2963fb4f7cdSSrinivas Pandruvada 			if (pkg_id < MAX_PACKAGE_COUNT &&
2973fb4f7cdSSrinivas Pandruvada 			    die_id < MAX_DIE_PER_PACKAGE)
2983fb4f7cdSSrinivas Pandruvada 				cpu_cnt[pkg_id][die_id]++;
2993fb4f7cdSSrinivas Pandruvada 		}
3003fb4f7cdSSrinivas Pandruvada 		closedir(dir);
3013fb4f7cdSSrinivas Pandruvada 	}
3023fb4f7cdSSrinivas Pandruvada }
3033fb4f7cdSSrinivas Pandruvada 
3043fb4f7cdSSrinivas Pandruvada int get_cpu_count(int pkg_id, int die_id)
3053fb4f7cdSSrinivas Pandruvada {
3063fb4f7cdSSrinivas Pandruvada 	if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE)
3073ec2aef1SPrarit Bhargava 		return cpu_cnt[pkg_id][die_id];
3083fb4f7cdSSrinivas Pandruvada 
3093fb4f7cdSSrinivas Pandruvada 	return 0;
3103fb4f7cdSSrinivas Pandruvada }
3113fb4f7cdSSrinivas Pandruvada 
3123fb4f7cdSSrinivas Pandruvada static void set_cpu_target_cpu_mask(void)
3133fb4f7cdSSrinivas Pandruvada {
3143fb4f7cdSSrinivas Pandruvada 	size_t size;
3153fb4f7cdSSrinivas Pandruvada 	int i;
3163fb4f7cdSSrinivas Pandruvada 
3173fb4f7cdSSrinivas Pandruvada 	size = alloc_cpu_set(&target_cpumask);
3183fb4f7cdSSrinivas Pandruvada 	target_cpumask_size = size;
3193fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < max_target_cpus; ++i) {
3203fb4f7cdSSrinivas Pandruvada 		if (!CPU_ISSET_S(target_cpus[i], present_cpumask_size,
3213fb4f7cdSSrinivas Pandruvada 				 present_cpumask))
3223fb4f7cdSSrinivas Pandruvada 			continue;
3233fb4f7cdSSrinivas Pandruvada 
3243fb4f7cdSSrinivas Pandruvada 		CPU_SET_S(target_cpus[i], size, target_cpumask);
3253fb4f7cdSSrinivas Pandruvada 	}
3263fb4f7cdSSrinivas Pandruvada }
3273fb4f7cdSSrinivas Pandruvada 
3283fb4f7cdSSrinivas Pandruvada static void create_cpu_map(void)
3293fb4f7cdSSrinivas Pandruvada {
3303fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
3313fb4f7cdSSrinivas Pandruvada 	int i, fd = 0;
3323fb4f7cdSSrinivas Pandruvada 	struct isst_if_cpu_maps map;
3333fb4f7cdSSrinivas Pandruvada 
3343fb4f7cdSSrinivas Pandruvada 	cpu_map = malloc(sizeof(*cpu_map) * topo_max_cpus);
3353fb4f7cdSSrinivas Pandruvada 	if (!cpu_map)
3363fb4f7cdSSrinivas Pandruvada 		err(3, "cpumap");
3373fb4f7cdSSrinivas Pandruvada 
3383fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
3393fb4f7cdSSrinivas Pandruvada 	if (fd < 0)
3403fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
3413fb4f7cdSSrinivas Pandruvada 
3423fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
3433fb4f7cdSSrinivas Pandruvada 		if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
3443fb4f7cdSSrinivas Pandruvada 			continue;
3453fb4f7cdSSrinivas Pandruvada 
3463fb4f7cdSSrinivas Pandruvada 		map.cmd_count = 1;
3473fb4f7cdSSrinivas Pandruvada 		map.cpu_map[0].logical_cpu = i;
3483fb4f7cdSSrinivas Pandruvada 
3493fb4f7cdSSrinivas Pandruvada 		debug_printf(" map logical_cpu:%d\n",
3503fb4f7cdSSrinivas Pandruvada 			     map.cpu_map[0].logical_cpu);
3513fb4f7cdSSrinivas Pandruvada 		if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) {
3523fb4f7cdSSrinivas Pandruvada 			perror("ISST_IF_GET_PHY_ID");
3533fb4f7cdSSrinivas Pandruvada 			fprintf(outf, "Error: map logical_cpu:%d\n",
3543fb4f7cdSSrinivas Pandruvada 				map.cpu_map[0].logical_cpu);
3553fb4f7cdSSrinivas Pandruvada 			continue;
3563fb4f7cdSSrinivas Pandruvada 		}
3573fb4f7cdSSrinivas Pandruvada 		cpu_map[i].core_id = get_physical_core_id(i);
3583fb4f7cdSSrinivas Pandruvada 		cpu_map[i].pkg_id = get_physical_package_id(i);
3593fb4f7cdSSrinivas Pandruvada 		cpu_map[i].die_id = get_physical_die_id(i);
3603fb4f7cdSSrinivas Pandruvada 		cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu;
3613fb4f7cdSSrinivas Pandruvada 		cpu_map[i].punit_cpu_core = (map.cpu_map[0].physical_cpu >>
3623fb4f7cdSSrinivas Pandruvada 					     1); // shift to get core id
3633fb4f7cdSSrinivas Pandruvada 
3643fb4f7cdSSrinivas Pandruvada 		debug_printf(
3653fb4f7cdSSrinivas Pandruvada 			"map logical_cpu:%d core: %d die:%d pkg:%d punit_cpu:%d punit_core:%d\n",
3663fb4f7cdSSrinivas Pandruvada 			i, cpu_map[i].core_id, cpu_map[i].die_id,
3673fb4f7cdSSrinivas Pandruvada 			cpu_map[i].pkg_id, cpu_map[i].punit_cpu,
3683fb4f7cdSSrinivas Pandruvada 			cpu_map[i].punit_cpu_core);
3693fb4f7cdSSrinivas Pandruvada 	}
3703fb4f7cdSSrinivas Pandruvada 
3713fb4f7cdSSrinivas Pandruvada 	if (fd)
3723fb4f7cdSSrinivas Pandruvada 		close(fd);
3733fb4f7cdSSrinivas Pandruvada }
3743fb4f7cdSSrinivas Pandruvada 
3753fb4f7cdSSrinivas Pandruvada int find_logical_cpu(int pkg_id, int die_id, int punit_core_id)
3763fb4f7cdSSrinivas Pandruvada {
3773fb4f7cdSSrinivas Pandruvada 	int i;
3783fb4f7cdSSrinivas Pandruvada 
3793fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
3803fb4f7cdSSrinivas Pandruvada 		if (cpu_map[i].pkg_id == pkg_id &&
3813fb4f7cdSSrinivas Pandruvada 		    cpu_map[i].die_id == die_id &&
3823fb4f7cdSSrinivas Pandruvada 		    cpu_map[i].punit_cpu_core == punit_core_id)
3833fb4f7cdSSrinivas Pandruvada 			return i;
3843fb4f7cdSSrinivas Pandruvada 	}
3853fb4f7cdSSrinivas Pandruvada 
3863fb4f7cdSSrinivas Pandruvada 	return -EINVAL;
3873fb4f7cdSSrinivas Pandruvada }
3883fb4f7cdSSrinivas Pandruvada 
3893fb4f7cdSSrinivas Pandruvada void set_cpu_mask_from_punit_coremask(int cpu, unsigned long long core_mask,
3903fb4f7cdSSrinivas Pandruvada 				      size_t core_cpumask_size,
3913fb4f7cdSSrinivas Pandruvada 				      cpu_set_t *core_cpumask, int *cpu_cnt)
3923fb4f7cdSSrinivas Pandruvada {
3933fb4f7cdSSrinivas Pandruvada 	int i, cnt = 0;
3943fb4f7cdSSrinivas Pandruvada 	int die_id, pkg_id;
3953fb4f7cdSSrinivas Pandruvada 
3963fb4f7cdSSrinivas Pandruvada 	*cpu_cnt = 0;
3973fb4f7cdSSrinivas Pandruvada 	die_id = get_physical_die_id(cpu);
3983fb4f7cdSSrinivas Pandruvada 	pkg_id = get_physical_package_id(cpu);
3993fb4f7cdSSrinivas Pandruvada 
4003fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < 64; ++i) {
4013fb4f7cdSSrinivas Pandruvada 		if (core_mask & BIT(i)) {
4023fb4f7cdSSrinivas Pandruvada 			int j;
4033fb4f7cdSSrinivas Pandruvada 
4043fb4f7cdSSrinivas Pandruvada 			for (j = 0; j < topo_max_cpus; ++j) {
4053fb4f7cdSSrinivas Pandruvada 				if (cpu_map[j].pkg_id == pkg_id &&
4063fb4f7cdSSrinivas Pandruvada 				    cpu_map[j].die_id == die_id &&
4073fb4f7cdSSrinivas Pandruvada 				    cpu_map[j].punit_cpu_core == i) {
4083fb4f7cdSSrinivas Pandruvada 					CPU_SET_S(j, core_cpumask_size,
4093fb4f7cdSSrinivas Pandruvada 						  core_cpumask);
4103fb4f7cdSSrinivas Pandruvada 					++cnt;
4113fb4f7cdSSrinivas Pandruvada 				}
4123fb4f7cdSSrinivas Pandruvada 			}
4133fb4f7cdSSrinivas Pandruvada 		}
4143fb4f7cdSSrinivas Pandruvada 	}
4153fb4f7cdSSrinivas Pandruvada 
4163fb4f7cdSSrinivas Pandruvada 	*cpu_cnt = cnt;
4173fb4f7cdSSrinivas Pandruvada }
4183fb4f7cdSSrinivas Pandruvada 
4193fb4f7cdSSrinivas Pandruvada int find_phy_core_num(int logical_cpu)
4203fb4f7cdSSrinivas Pandruvada {
4213fb4f7cdSSrinivas Pandruvada 	if (logical_cpu < topo_max_cpus)
4223fb4f7cdSSrinivas Pandruvada 		return cpu_map[logical_cpu].punit_cpu_core;
4233fb4f7cdSSrinivas Pandruvada 
4243fb4f7cdSSrinivas Pandruvada 	return -EINVAL;
4253fb4f7cdSSrinivas Pandruvada }
4263fb4f7cdSSrinivas Pandruvada 
4273fb4f7cdSSrinivas Pandruvada static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write,
4283fb4f7cdSSrinivas Pandruvada 				  unsigned int *value)
4293fb4f7cdSSrinivas Pandruvada {
4303fb4f7cdSSrinivas Pandruvada 	struct isst_if_io_regs io_regs;
4313fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
4323fb4f7cdSSrinivas Pandruvada 	int cmd;
4333fb4f7cdSSrinivas Pandruvada 	int fd;
4343fb4f7cdSSrinivas Pandruvada 
4353fb4f7cdSSrinivas Pandruvada 	debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write);
4363fb4f7cdSSrinivas Pandruvada 
4373fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
4383fb4f7cdSSrinivas Pandruvada 	if (fd < 0)
4393fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
4403fb4f7cdSSrinivas Pandruvada 
4413fb4f7cdSSrinivas Pandruvada 	io_regs.req_count = 1;
4423fb4f7cdSSrinivas Pandruvada 	io_regs.io_reg[0].logical_cpu = cpu;
4433fb4f7cdSSrinivas Pandruvada 	io_regs.io_reg[0].reg = reg;
4443fb4f7cdSSrinivas Pandruvada 	cmd = ISST_IF_IO_CMD;
4453fb4f7cdSSrinivas Pandruvada 	if (write) {
4463fb4f7cdSSrinivas Pandruvada 		io_regs.io_reg[0].read_write = 1;
4473fb4f7cdSSrinivas Pandruvada 		io_regs.io_reg[0].value = *value;
4483fb4f7cdSSrinivas Pandruvada 	} else {
4493fb4f7cdSSrinivas Pandruvada 		io_regs.io_reg[0].read_write = 0;
4503fb4f7cdSSrinivas Pandruvada 	}
4513fb4f7cdSSrinivas Pandruvada 
4523fb4f7cdSSrinivas Pandruvada 	if (ioctl(fd, cmd, &io_regs) == -1) {
4533fb4f7cdSSrinivas Pandruvada 		perror("ISST_IF_IO_CMD");
4543fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n",
4553fb4f7cdSSrinivas Pandruvada 			cpu, reg, write);
4563fb4f7cdSSrinivas Pandruvada 	} else {
4573fb4f7cdSSrinivas Pandruvada 		if (!write)
4583fb4f7cdSSrinivas Pandruvada 			*value = io_regs.io_reg[0].value;
4593fb4f7cdSSrinivas Pandruvada 
4603fb4f7cdSSrinivas Pandruvada 		debug_printf(
4613fb4f7cdSSrinivas Pandruvada 			"mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n",
4623fb4f7cdSSrinivas Pandruvada 			cpu, reg, write, *value);
4633fb4f7cdSSrinivas Pandruvada 	}
4643fb4f7cdSSrinivas Pandruvada 
4653fb4f7cdSSrinivas Pandruvada 	close(fd);
4663fb4f7cdSSrinivas Pandruvada 
4673fb4f7cdSSrinivas Pandruvada 	return 0;
4683fb4f7cdSSrinivas Pandruvada }
4693fb4f7cdSSrinivas Pandruvada 
4703fb4f7cdSSrinivas Pandruvada int isst_send_mbox_command(unsigned int cpu, unsigned char command,
4713fb4f7cdSSrinivas Pandruvada 			   unsigned char sub_command, unsigned int parameter,
4723fb4f7cdSSrinivas Pandruvada 			   unsigned int req_data, unsigned int *resp)
4733fb4f7cdSSrinivas Pandruvada {
4743fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
4753fb4f7cdSSrinivas Pandruvada 	int fd;
4763fb4f7cdSSrinivas Pandruvada 	struct isst_if_mbox_cmds mbox_cmds = { 0 };
4773fb4f7cdSSrinivas Pandruvada 
4783fb4f7cdSSrinivas Pandruvada 	debug_printf(
4793fb4f7cdSSrinivas Pandruvada 		"mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n",
4803fb4f7cdSSrinivas Pandruvada 		cpu, command, sub_command, parameter, req_data);
4813fb4f7cdSSrinivas Pandruvada 
4823fb4f7cdSSrinivas Pandruvada 	if (isst_platform_info.mmio_supported && command == CONFIG_CLOS) {
4833fb4f7cdSSrinivas Pandruvada 		unsigned int value;
4843fb4f7cdSSrinivas Pandruvada 		int write = 0;
4853fb4f7cdSSrinivas Pandruvada 		int clos_id, core_id, ret = 0;
4863fb4f7cdSSrinivas Pandruvada 
4873fb4f7cdSSrinivas Pandruvada 		debug_printf("CLOS %d\n", cpu);
4883fb4f7cdSSrinivas Pandruvada 
4893fb4f7cdSSrinivas Pandruvada 		if (parameter & BIT(MBOX_CMD_WRITE_BIT)) {
4903fb4f7cdSSrinivas Pandruvada 			value = req_data;
4913fb4f7cdSSrinivas Pandruvada 			write = 1;
4923fb4f7cdSSrinivas Pandruvada 		}
4933fb4f7cdSSrinivas Pandruvada 
4943fb4f7cdSSrinivas Pandruvada 		switch (sub_command) {
4953fb4f7cdSSrinivas Pandruvada 		case CLOS_PQR_ASSOC:
4963fb4f7cdSSrinivas Pandruvada 			core_id = parameter & 0xff;
4973fb4f7cdSSrinivas Pandruvada 			ret = isst_send_mmio_command(
4983fb4f7cdSSrinivas Pandruvada 				cpu, PQR_ASSOC_OFFSET + core_id * 4, write,
4993fb4f7cdSSrinivas Pandruvada 				&value);
5003fb4f7cdSSrinivas Pandruvada 			if (!ret && !write)
5013fb4f7cdSSrinivas Pandruvada 				*resp = value;
5023fb4f7cdSSrinivas Pandruvada 			break;
5033fb4f7cdSSrinivas Pandruvada 		case CLOS_PM_CLOS:
5043fb4f7cdSSrinivas Pandruvada 			clos_id = parameter & 0x03;
5053fb4f7cdSSrinivas Pandruvada 			ret = isst_send_mmio_command(
5063fb4f7cdSSrinivas Pandruvada 				cpu, PM_CLOS_OFFSET + clos_id * 4, write,
5073fb4f7cdSSrinivas Pandruvada 				&value);
5083fb4f7cdSSrinivas Pandruvada 			if (!ret && !write)
5093fb4f7cdSSrinivas Pandruvada 				*resp = value;
5103fb4f7cdSSrinivas Pandruvada 			break;
5113fb4f7cdSSrinivas Pandruvada 		case CLOS_PM_QOS_CONFIG:
5123fb4f7cdSSrinivas Pandruvada 			ret = isst_send_mmio_command(cpu, PM_QOS_CONFIG_OFFSET,
5133fb4f7cdSSrinivas Pandruvada 						     write, &value);
5143fb4f7cdSSrinivas Pandruvada 			if (!ret && !write)
5153fb4f7cdSSrinivas Pandruvada 				*resp = value;
5163fb4f7cdSSrinivas Pandruvada 			break;
5173fb4f7cdSSrinivas Pandruvada 		case CLOS_STATUS:
5183fb4f7cdSSrinivas Pandruvada 			break;
5193fb4f7cdSSrinivas Pandruvada 		default:
5203fb4f7cdSSrinivas Pandruvada 			break;
5213fb4f7cdSSrinivas Pandruvada 		}
5223fb4f7cdSSrinivas Pandruvada 		return ret;
5233fb4f7cdSSrinivas Pandruvada 	}
5243fb4f7cdSSrinivas Pandruvada 
5253fb4f7cdSSrinivas Pandruvada 	mbox_cmds.cmd_count = 1;
5263fb4f7cdSSrinivas Pandruvada 	mbox_cmds.mbox_cmd[0].logical_cpu = cpu;
5273fb4f7cdSSrinivas Pandruvada 	mbox_cmds.mbox_cmd[0].command = command;
5283fb4f7cdSSrinivas Pandruvada 	mbox_cmds.mbox_cmd[0].sub_command = sub_command;
5293fb4f7cdSSrinivas Pandruvada 	mbox_cmds.mbox_cmd[0].parameter = parameter;
5303fb4f7cdSSrinivas Pandruvada 	mbox_cmds.mbox_cmd[0].req_data = req_data;
5313fb4f7cdSSrinivas Pandruvada 
5323fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
5333fb4f7cdSSrinivas Pandruvada 	if (fd < 0)
5343fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
5353fb4f7cdSSrinivas Pandruvada 
5363fb4f7cdSSrinivas Pandruvada 	if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) {
5373fb4f7cdSSrinivas Pandruvada 		perror("ISST_IF_MBOX_COMMAND");
5383fb4f7cdSSrinivas Pandruvada 		fprintf(outf,
5393fb4f7cdSSrinivas Pandruvada 			"Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n",
5403fb4f7cdSSrinivas Pandruvada 			cpu, command, sub_command, parameter, req_data);
5413fb4f7cdSSrinivas Pandruvada 	} else {
5423fb4f7cdSSrinivas Pandruvada 		*resp = mbox_cmds.mbox_cmd[0].resp_data;
5433fb4f7cdSSrinivas Pandruvada 		debug_printf(
5443fb4f7cdSSrinivas Pandruvada 			"mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n",
5453fb4f7cdSSrinivas Pandruvada 			cpu, command, sub_command, parameter, req_data, *resp);
5463fb4f7cdSSrinivas Pandruvada 	}
5473fb4f7cdSSrinivas Pandruvada 
5483fb4f7cdSSrinivas Pandruvada 	close(fd);
5493fb4f7cdSSrinivas Pandruvada 
5503fb4f7cdSSrinivas Pandruvada 	return 0;
5513fb4f7cdSSrinivas Pandruvada }
5523fb4f7cdSSrinivas Pandruvada 
5533fb4f7cdSSrinivas Pandruvada int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write,
5543fb4f7cdSSrinivas Pandruvada 			  unsigned long long *req_resp)
5553fb4f7cdSSrinivas Pandruvada {
5563fb4f7cdSSrinivas Pandruvada 	struct isst_if_msr_cmds msr_cmds;
5573fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
5583fb4f7cdSSrinivas Pandruvada 	int fd;
5593fb4f7cdSSrinivas Pandruvada 
5603fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
5613fb4f7cdSSrinivas Pandruvada 	if (fd < 0)
5623fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
5633fb4f7cdSSrinivas Pandruvada 
5643fb4f7cdSSrinivas Pandruvada 	msr_cmds.cmd_count = 1;
5653fb4f7cdSSrinivas Pandruvada 	msr_cmds.msr_cmd[0].logical_cpu = cpu;
5663fb4f7cdSSrinivas Pandruvada 	msr_cmds.msr_cmd[0].msr = msr;
5673fb4f7cdSSrinivas Pandruvada 	msr_cmds.msr_cmd[0].read_write = write;
5683fb4f7cdSSrinivas Pandruvada 	if (write)
5693fb4f7cdSSrinivas Pandruvada 		msr_cmds.msr_cmd[0].data = *req_resp;
5703fb4f7cdSSrinivas Pandruvada 
5713fb4f7cdSSrinivas Pandruvada 	if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) {
5723fb4f7cdSSrinivas Pandruvada 		perror("ISST_IF_MSR_COMMAD");
5733fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n",
5743fb4f7cdSSrinivas Pandruvada 			cpu, msr, write);
5753fb4f7cdSSrinivas Pandruvada 	} else {
5763fb4f7cdSSrinivas Pandruvada 		if (!write)
5773fb4f7cdSSrinivas Pandruvada 			*req_resp = msr_cmds.msr_cmd[0].data;
5783fb4f7cdSSrinivas Pandruvada 
5793fb4f7cdSSrinivas Pandruvada 		debug_printf(
5803fb4f7cdSSrinivas Pandruvada 			"msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n",
5813fb4f7cdSSrinivas Pandruvada 			cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data);
5823fb4f7cdSSrinivas Pandruvada 	}
5833fb4f7cdSSrinivas Pandruvada 
5843fb4f7cdSSrinivas Pandruvada 	close(fd);
5853fb4f7cdSSrinivas Pandruvada 
5863fb4f7cdSSrinivas Pandruvada 	return 0;
5873fb4f7cdSSrinivas Pandruvada }
5883fb4f7cdSSrinivas Pandruvada 
5893fb4f7cdSSrinivas Pandruvada static int isst_fill_platform_info(void)
5903fb4f7cdSSrinivas Pandruvada {
5913fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
5923fb4f7cdSSrinivas Pandruvada 	int fd;
5933fb4f7cdSSrinivas Pandruvada 
5943fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
5953fb4f7cdSSrinivas Pandruvada 	if (fd < 0)
5963fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
5973fb4f7cdSSrinivas Pandruvada 
5983fb4f7cdSSrinivas Pandruvada 	if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &isst_platform_info) == -1) {
5993fb4f7cdSSrinivas Pandruvada 		perror("ISST_IF_GET_PLATFORM_INFO");
6003fb4f7cdSSrinivas Pandruvada 		close(fd);
6013fb4f7cdSSrinivas Pandruvada 		return -1;
6023fb4f7cdSSrinivas Pandruvada 	}
6033fb4f7cdSSrinivas Pandruvada 
6043fb4f7cdSSrinivas Pandruvada 	close(fd);
6053fb4f7cdSSrinivas Pandruvada 
606*3bc3d30cSPrarit Bhargava 	if (isst_platform_info.api_version > supported_api_ver) {
607*3bc3d30cSPrarit Bhargava 		printf("Incompatible API versions; Upgrade of tool is required\n");
608*3bc3d30cSPrarit Bhargava 		return -1;
609*3bc3d30cSPrarit Bhargava 	}
6103fb4f7cdSSrinivas Pandruvada 	return 0;
6113fb4f7cdSSrinivas Pandruvada }
6123fb4f7cdSSrinivas Pandruvada 
6133fb4f7cdSSrinivas Pandruvada static void isst_print_platform_information(void)
6143fb4f7cdSSrinivas Pandruvada {
6153fb4f7cdSSrinivas Pandruvada 	struct isst_if_platform_info platform_info;
6163fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
6173fb4f7cdSSrinivas Pandruvada 	int fd;
6183fb4f7cdSSrinivas Pandruvada 
6193fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
6203fb4f7cdSSrinivas Pandruvada 	if (fd < 0)
6213fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
6223fb4f7cdSSrinivas Pandruvada 
6233fb4f7cdSSrinivas Pandruvada 	if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &platform_info) == -1) {
6243fb4f7cdSSrinivas Pandruvada 		perror("ISST_IF_GET_PLATFORM_INFO");
6253fb4f7cdSSrinivas Pandruvada 	} else {
6263fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Platform: API version : %d\n",
6273fb4f7cdSSrinivas Pandruvada 			platform_info.api_version);
6283fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Platform: Driver version : %d\n",
6293fb4f7cdSSrinivas Pandruvada 			platform_info.driver_version);
6303fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Platform: mbox supported : %d\n",
6313fb4f7cdSSrinivas Pandruvada 			platform_info.mbox_supported);
6323fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Platform: mmio supported : %d\n",
6333fb4f7cdSSrinivas Pandruvada 			platform_info.mmio_supported);
6343fb4f7cdSSrinivas Pandruvada 	}
6353fb4f7cdSSrinivas Pandruvada 
6363fb4f7cdSSrinivas Pandruvada 	close(fd);
6373fb4f7cdSSrinivas Pandruvada 
6383fb4f7cdSSrinivas Pandruvada 	exit(0);
6393fb4f7cdSSrinivas Pandruvada }
6403fb4f7cdSSrinivas Pandruvada 
6413fb4f7cdSSrinivas Pandruvada static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3,
6423fb4f7cdSSrinivas Pandruvada 				 void *arg4)
6433fb4f7cdSSrinivas Pandruvada {
6443fb4f7cdSSrinivas Pandruvada 	int (*fn_ptr)(int cpu, void *arg);
6453fb4f7cdSSrinivas Pandruvada 	int ret;
6463fb4f7cdSSrinivas Pandruvada 
6473fb4f7cdSSrinivas Pandruvada 	fn_ptr = arg1;
6483fb4f7cdSSrinivas Pandruvada 	ret = fn_ptr(cpu, arg2);
6493fb4f7cdSSrinivas Pandruvada 	if (ret)
6503fb4f7cdSSrinivas Pandruvada 		perror("get_tdp_*");
6513fb4f7cdSSrinivas Pandruvada 	else
6523fb4f7cdSSrinivas Pandruvada 		isst_display_result(cpu, outf, "perf-profile", (char *)arg3,
6533fb4f7cdSSrinivas Pandruvada 				    *(unsigned int *)arg4);
6543fb4f7cdSSrinivas Pandruvada }
6553fb4f7cdSSrinivas Pandruvada 
6563fb4f7cdSSrinivas Pandruvada #define _get_tdp_level(desc, suffix, object, help)                                \
6573fb4f7cdSSrinivas Pandruvada 	static void get_tdp_##object(void)                                        \
6583fb4f7cdSSrinivas Pandruvada 	{                                                                         \
6593fb4f7cdSSrinivas Pandruvada 		struct isst_pkg_ctdp ctdp;                                        \
6603fb4f7cdSSrinivas Pandruvada \
6613fb4f7cdSSrinivas Pandruvada 		if (cmd_help) {                                                   \
6623fb4f7cdSSrinivas Pandruvada 			fprintf(stderr,                                           \
6633fb4f7cdSSrinivas Pandruvada 				"Print %s [No command arguments are required]\n", \
6643fb4f7cdSSrinivas Pandruvada 				help);                                            \
6653fb4f7cdSSrinivas Pandruvada 			exit(0);                                                  \
6663fb4f7cdSSrinivas Pandruvada 		}                                                                 \
6673fb4f7cdSSrinivas Pandruvada 		isst_ctdp_display_information_start(outf);                        \
6683fb4f7cdSSrinivas Pandruvada 		if (max_target_cpus)                                              \
6693fb4f7cdSSrinivas Pandruvada 			for_each_online_target_cpu_in_set(                        \
6703fb4f7cdSSrinivas Pandruvada 				exec_on_get_ctdp_cpu, isst_get_ctdp_##suffix,     \
6713fb4f7cdSSrinivas Pandruvada 				&ctdp, desc, &ctdp.object);                       \
6723fb4f7cdSSrinivas Pandruvada 		else                                                              \
6733fb4f7cdSSrinivas Pandruvada 			for_each_online_package_in_set(exec_on_get_ctdp_cpu,      \
6743fb4f7cdSSrinivas Pandruvada 						       isst_get_ctdp_##suffix,    \
6753fb4f7cdSSrinivas Pandruvada 						       &ctdp, desc,               \
6763fb4f7cdSSrinivas Pandruvada 						       &ctdp.object);             \
6773fb4f7cdSSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);                          \
6783fb4f7cdSSrinivas Pandruvada 	}
6793fb4f7cdSSrinivas Pandruvada 
6803fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-config-levels", levels, levels, "TDP levels");
6813fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-config-version", levels, version, "TDP version");
6823fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-config-enabled", levels, enabled, "TDP enable status");
6833fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-config-current_level", levels, current_level,
6843fb4f7cdSSrinivas Pandruvada 	       "Current TDP Level");
6853fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-lock-status", levels, locked, "TDP lock status");
6863fb4f7cdSSrinivas Pandruvada 
6873fb4f7cdSSrinivas Pandruvada static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2,
6883fb4f7cdSSrinivas Pandruvada 				     void *arg3, void *arg4)
6893fb4f7cdSSrinivas Pandruvada {
6903fb4f7cdSSrinivas Pandruvada 	struct isst_pkg_ctdp pkg_dev;
6913fb4f7cdSSrinivas Pandruvada 	int ret;
6923fb4f7cdSSrinivas Pandruvada 
6933fb4f7cdSSrinivas Pandruvada 	memset(&pkg_dev, 0, sizeof(pkg_dev));
6943fb4f7cdSSrinivas Pandruvada 	ret = isst_get_process_ctdp(cpu, tdp_level, &pkg_dev);
6953fb4f7cdSSrinivas Pandruvada 	if (ret) {
6963fb4f7cdSSrinivas Pandruvada 		perror("isst_get_process_ctdp");
6973fb4f7cdSSrinivas Pandruvada 	} else {
6983fb4f7cdSSrinivas Pandruvada 		isst_ctdp_display_information(cpu, outf, tdp_level, &pkg_dev);
6993fb4f7cdSSrinivas Pandruvada 		isst_get_process_ctdp_complete(cpu, &pkg_dev);
7003fb4f7cdSSrinivas Pandruvada 	}
7013fb4f7cdSSrinivas Pandruvada }
7023fb4f7cdSSrinivas Pandruvada 
7033fb4f7cdSSrinivas Pandruvada static void dump_isst_config(void)
7043fb4f7cdSSrinivas Pandruvada {
7053fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
7063fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
7073fb4f7cdSSrinivas Pandruvada 			"Print Intel(R) Speed Select Technology Performance profile configuration\n");
7083fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
7093fb4f7cdSSrinivas Pandruvada 			"including base frequency and turbo frequency configurations\n");
7103fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Optional: -l|--level : Specify tdp level\n");
7113fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
7123fb4f7cdSSrinivas Pandruvada 			"\tIf no arguments, dump information for all TDP levels\n");
7133fb4f7cdSSrinivas Pandruvada 		exit(0);
7143fb4f7cdSSrinivas Pandruvada 	}
7153fb4f7cdSSrinivas Pandruvada 
7163fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
7173fb4f7cdSSrinivas Pandruvada 
7183fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
7193fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(dump_isst_config_for_cpu,
7203fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL, NULL);
7213fb4f7cdSSrinivas Pandruvada 	else
7223fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(dump_isst_config_for_cpu, NULL,
7233fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
7243fb4f7cdSSrinivas Pandruvada 
7253fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
7263fb4f7cdSSrinivas Pandruvada }
7273fb4f7cdSSrinivas Pandruvada 
7283fb4f7cdSSrinivas Pandruvada static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
7293fb4f7cdSSrinivas Pandruvada 				  void *arg4)
7303fb4f7cdSSrinivas Pandruvada {
7313fb4f7cdSSrinivas Pandruvada 	int ret;
7323fb4f7cdSSrinivas Pandruvada 
7333fb4f7cdSSrinivas Pandruvada 	ret = isst_set_tdp_level(cpu, tdp_level);
7343fb4f7cdSSrinivas Pandruvada 	if (ret)
7353fb4f7cdSSrinivas Pandruvada 		perror("set_tdp_level_for_cpu");
7363fb4f7cdSSrinivas Pandruvada 	else
7373fb4f7cdSSrinivas Pandruvada 		isst_display_result(cpu, outf, "perf-profile", "set_tdp_level",
7383fb4f7cdSSrinivas Pandruvada 				    ret);
7393fb4f7cdSSrinivas Pandruvada }
7403fb4f7cdSSrinivas Pandruvada 
7413fb4f7cdSSrinivas Pandruvada static void set_tdp_level(void)
7423fb4f7cdSSrinivas Pandruvada {
7433fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
7443fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Set Config TDP level\n");
7453fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
7463fb4f7cdSSrinivas Pandruvada 			"\t Arguments: -l|--level : Specify tdp level\n");
7473fb4f7cdSSrinivas Pandruvada 		exit(0);
7483fb4f7cdSSrinivas Pandruvada 	}
7493fb4f7cdSSrinivas Pandruvada 
7503fb4f7cdSSrinivas Pandruvada 	if (tdp_level == 0xff) {
7513fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Invalid command: specify tdp_level\n");
7523fb4f7cdSSrinivas Pandruvada 		exit(1);
7533fb4f7cdSSrinivas Pandruvada 	}
7543fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
7553fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
7563fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_tdp_level_for_cpu, NULL,
7573fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
7583fb4f7cdSSrinivas Pandruvada 	else
7593fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(set_tdp_level_for_cpu, NULL,
7603fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
7613fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
7623fb4f7cdSSrinivas Pandruvada }
7633fb4f7cdSSrinivas Pandruvada 
7643fb4f7cdSSrinivas Pandruvada static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
7653fb4f7cdSSrinivas Pandruvada 				    void *arg4)
7663fb4f7cdSSrinivas Pandruvada {
7673fb4f7cdSSrinivas Pandruvada 	struct isst_pbf_info pbf_info;
7683fb4f7cdSSrinivas Pandruvada 	int ret;
7693fb4f7cdSSrinivas Pandruvada 
7703fb4f7cdSSrinivas Pandruvada 	ret = isst_get_pbf_info(cpu, tdp_level, &pbf_info);
7713fb4f7cdSSrinivas Pandruvada 	if (ret) {
7723fb4f7cdSSrinivas Pandruvada 		perror("isst_get_pbf_info");
7733fb4f7cdSSrinivas Pandruvada 	} else {
7743fb4f7cdSSrinivas Pandruvada 		isst_pbf_display_information(cpu, outf, tdp_level, &pbf_info);
7753fb4f7cdSSrinivas Pandruvada 		isst_get_pbf_info_complete(&pbf_info);
7763fb4f7cdSSrinivas Pandruvada 	}
7773fb4f7cdSSrinivas Pandruvada }
7783fb4f7cdSSrinivas Pandruvada 
7793fb4f7cdSSrinivas Pandruvada static void dump_pbf_config(void)
7803fb4f7cdSSrinivas Pandruvada {
7813fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
7823fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
7833fb4f7cdSSrinivas Pandruvada 			"Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n");
7843fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
7853fb4f7cdSSrinivas Pandruvada 			"\tArguments: -l|--level : Specify tdp level\n");
7863fb4f7cdSSrinivas Pandruvada 		exit(0);
7873fb4f7cdSSrinivas Pandruvada 	}
7883fb4f7cdSSrinivas Pandruvada 
7893fb4f7cdSSrinivas Pandruvada 	if (tdp_level == 0xff) {
7903fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Invalid command: specify tdp_level\n");
7913fb4f7cdSSrinivas Pandruvada 		exit(1);
7923fb4f7cdSSrinivas Pandruvada 	}
7933fb4f7cdSSrinivas Pandruvada 
7943fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
7953fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
7963fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(dump_pbf_config_for_cpu, NULL,
7973fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
7983fb4f7cdSSrinivas Pandruvada 	else
7993fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(dump_pbf_config_for_cpu, NULL,
8003fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
8013fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
8023fb4f7cdSSrinivas Pandruvada }
8033fb4f7cdSSrinivas Pandruvada 
8043fb4f7cdSSrinivas Pandruvada static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
8053fb4f7cdSSrinivas Pandruvada 			    void *arg4)
8063fb4f7cdSSrinivas Pandruvada {
8073fb4f7cdSSrinivas Pandruvada 	int ret;
8083fb4f7cdSSrinivas Pandruvada 	int status = *(int *)arg4;
8093fb4f7cdSSrinivas Pandruvada 
8103fb4f7cdSSrinivas Pandruvada 	ret = isst_set_pbf_fact_status(cpu, 1, status);
8113fb4f7cdSSrinivas Pandruvada 	if (ret) {
8123fb4f7cdSSrinivas Pandruvada 		perror("isst_set_pbf");
8133fb4f7cdSSrinivas Pandruvada 	} else {
8143fb4f7cdSSrinivas Pandruvada 		if (status)
8153fb4f7cdSSrinivas Pandruvada 			isst_display_result(cpu, outf, "base-freq", "enable",
8163fb4f7cdSSrinivas Pandruvada 					    ret);
8173fb4f7cdSSrinivas Pandruvada 		else
8183fb4f7cdSSrinivas Pandruvada 			isst_display_result(cpu, outf, "base-freq", "disable",
8193fb4f7cdSSrinivas Pandruvada 					    ret);
8203fb4f7cdSSrinivas Pandruvada 	}
8213fb4f7cdSSrinivas Pandruvada }
8223fb4f7cdSSrinivas Pandruvada 
8233fb4f7cdSSrinivas Pandruvada static void set_pbf_enable(void)
8243fb4f7cdSSrinivas Pandruvada {
8253fb4f7cdSSrinivas Pandruvada 	int status = 1;
8263fb4f7cdSSrinivas Pandruvada 
8273fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
8283fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
8293fb4f7cdSSrinivas Pandruvada 			"Enable Intel Speed Select Technology base frequency feature [No command arguments are required]\n");
8303fb4f7cdSSrinivas Pandruvada 		exit(0);
8313fb4f7cdSSrinivas Pandruvada 	}
8323fb4f7cdSSrinivas Pandruvada 
8333fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
8343fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
8353fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL,
8363fb4f7cdSSrinivas Pandruvada 						  NULL, &status);
8373fb4f7cdSSrinivas Pandruvada 	else
8383fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL,
8393fb4f7cdSSrinivas Pandruvada 					       NULL, &status);
8403fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
8413fb4f7cdSSrinivas Pandruvada }
8423fb4f7cdSSrinivas Pandruvada 
8433fb4f7cdSSrinivas Pandruvada static void set_pbf_disable(void)
8443fb4f7cdSSrinivas Pandruvada {
8453fb4f7cdSSrinivas Pandruvada 	int status = 0;
8463fb4f7cdSSrinivas Pandruvada 
8473fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
8483fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
8493fb4f7cdSSrinivas Pandruvada 			"Disable Intel Speed Select Technology base frequency feature [No command arguments are required]\n");
8503fb4f7cdSSrinivas Pandruvada 		exit(0);
8513fb4f7cdSSrinivas Pandruvada 	}
8523fb4f7cdSSrinivas Pandruvada 
8533fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
8543fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
8553fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL,
8563fb4f7cdSSrinivas Pandruvada 						  NULL, &status);
8573fb4f7cdSSrinivas Pandruvada 	else
8583fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL,
8593fb4f7cdSSrinivas Pandruvada 					       NULL, &status);
8603fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
8613fb4f7cdSSrinivas Pandruvada }
8623fb4f7cdSSrinivas Pandruvada 
8633fb4f7cdSSrinivas Pandruvada static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2,
8643fb4f7cdSSrinivas Pandruvada 				     void *arg3, void *arg4)
8653fb4f7cdSSrinivas Pandruvada {
8663fb4f7cdSSrinivas Pandruvada 	struct isst_fact_info fact_info;
8673fb4f7cdSSrinivas Pandruvada 	int ret;
8683fb4f7cdSSrinivas Pandruvada 
8693fb4f7cdSSrinivas Pandruvada 	ret = isst_get_fact_info(cpu, tdp_level, &fact_info);
8703fb4f7cdSSrinivas Pandruvada 	if (ret)
8713fb4f7cdSSrinivas Pandruvada 		perror("isst_get_fact_bucket_info");
8723fb4f7cdSSrinivas Pandruvada 	else
8733fb4f7cdSSrinivas Pandruvada 		isst_fact_display_information(cpu, outf, tdp_level, fact_bucket,
8743fb4f7cdSSrinivas Pandruvada 					      fact_avx, &fact_info);
8753fb4f7cdSSrinivas Pandruvada }
8763fb4f7cdSSrinivas Pandruvada 
8773fb4f7cdSSrinivas Pandruvada static void dump_fact_config(void)
8783fb4f7cdSSrinivas Pandruvada {
8793fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
8803fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
8813fb4f7cdSSrinivas Pandruvada 			"Print complete Intel Speed Select Technology turbo frequency configuration for a TDP level. Other arguments are optional.\n");
8823fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
8833fb4f7cdSSrinivas Pandruvada 			"\tArguments: -l|--level : Specify tdp level\n");
8843fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
8853fb4f7cdSSrinivas Pandruvada 			"\tArguments: -b|--bucket : Bucket index to dump\n");
8863fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
8873fb4f7cdSSrinivas Pandruvada 			"\tArguments: -r|--trl-type : Specify trl type: sse|avx2|avx512\n");
8883fb4f7cdSSrinivas Pandruvada 		exit(0);
8893fb4f7cdSSrinivas Pandruvada 	}
8903fb4f7cdSSrinivas Pandruvada 
8913fb4f7cdSSrinivas Pandruvada 	if (tdp_level == 0xff) {
8923fb4f7cdSSrinivas Pandruvada 		fprintf(outf, "Invalid command: specify tdp_level\n");
8933fb4f7cdSSrinivas Pandruvada 		exit(1);
8943fb4f7cdSSrinivas Pandruvada 	}
8953fb4f7cdSSrinivas Pandruvada 
8963fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
8973fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
8983fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(dump_fact_config_for_cpu,
8993fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL, NULL);
9003fb4f7cdSSrinivas Pandruvada 	else
9013fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(dump_fact_config_for_cpu, NULL,
9023fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
9033fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
9043fb4f7cdSSrinivas Pandruvada }
9053fb4f7cdSSrinivas Pandruvada 
9063fb4f7cdSSrinivas Pandruvada static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
9073fb4f7cdSSrinivas Pandruvada 			     void *arg4)
9083fb4f7cdSSrinivas Pandruvada {
9093fb4f7cdSSrinivas Pandruvada 	int ret;
9103fb4f7cdSSrinivas Pandruvada 	int status = *(int *)arg4;
9113fb4f7cdSSrinivas Pandruvada 
9123fb4f7cdSSrinivas Pandruvada 	ret = isst_set_pbf_fact_status(cpu, 0, status);
9133fb4f7cdSSrinivas Pandruvada 	if (ret)
9143fb4f7cdSSrinivas Pandruvada 		perror("isst_set_fact");
9153fb4f7cdSSrinivas Pandruvada 	else {
9163fb4f7cdSSrinivas Pandruvada 		if (status) {
9173fb4f7cdSSrinivas Pandruvada 			struct isst_pkg_ctdp pkg_dev;
9183fb4f7cdSSrinivas Pandruvada 
9193fb4f7cdSSrinivas Pandruvada 			ret = isst_get_ctdp_levels(cpu, &pkg_dev);
9203fb4f7cdSSrinivas Pandruvada 			if (ret) {
9213fb4f7cdSSrinivas Pandruvada 				isst_display_result(cpu, outf, "turbo-freq",
9223fb4f7cdSSrinivas Pandruvada 						    "enable", ret);
9233fb4f7cdSSrinivas Pandruvada 				return;
9243fb4f7cdSSrinivas Pandruvada 			}
9253fb4f7cdSSrinivas Pandruvada 			ret = isst_set_trl(cpu, fact_trl);
9263fb4f7cdSSrinivas Pandruvada 			isst_display_result(cpu, outf, "turbo-freq", "enable",
9273fb4f7cdSSrinivas Pandruvada 					    ret);
9283fb4f7cdSSrinivas Pandruvada 		} else {
9293fb4f7cdSSrinivas Pandruvada 			/* Since we modified TRL during Fact enable, restore it */
9303fb4f7cdSSrinivas Pandruvada 			isst_set_trl_from_current_tdp(cpu, fact_trl);
9313fb4f7cdSSrinivas Pandruvada 			isst_display_result(cpu, outf, "turbo-freq", "disable",
9323fb4f7cdSSrinivas Pandruvada 					    ret);
9333fb4f7cdSSrinivas Pandruvada 		}
9343fb4f7cdSSrinivas Pandruvada 	}
9353fb4f7cdSSrinivas Pandruvada }
9363fb4f7cdSSrinivas Pandruvada 
9373fb4f7cdSSrinivas Pandruvada static void set_fact_enable(void)
9383fb4f7cdSSrinivas Pandruvada {
9393fb4f7cdSSrinivas Pandruvada 	int status = 1;
9403fb4f7cdSSrinivas Pandruvada 
9413fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
9423fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
9433fb4f7cdSSrinivas Pandruvada 			"Enable Intel Speed Select Technology Turbo frequency feature\n");
9443fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
9453fb4f7cdSSrinivas Pandruvada 			"Optional: -t|--trl : Specify turbo ratio limit\n");
9463fb4f7cdSSrinivas Pandruvada 		exit(0);
9473fb4f7cdSSrinivas Pandruvada 	}
9483fb4f7cdSSrinivas Pandruvada 
9493fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
9503fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
9513fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL,
9523fb4f7cdSSrinivas Pandruvada 						  NULL, &status);
9533fb4f7cdSSrinivas Pandruvada 	else
9543fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL,
9553fb4f7cdSSrinivas Pandruvada 					       NULL, &status);
9563fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
9573fb4f7cdSSrinivas Pandruvada }
9583fb4f7cdSSrinivas Pandruvada 
9593fb4f7cdSSrinivas Pandruvada static void set_fact_disable(void)
9603fb4f7cdSSrinivas Pandruvada {
9613fb4f7cdSSrinivas Pandruvada 	int status = 0;
9623fb4f7cdSSrinivas Pandruvada 
9633fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
9643fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
9653fb4f7cdSSrinivas Pandruvada 			"Disable Intel Speed Select Technology turbo frequency feature\n");
9663fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
9673fb4f7cdSSrinivas Pandruvada 			"Optional: -t|--trl : Specify turbo ratio limit\n");
9683fb4f7cdSSrinivas Pandruvada 		exit(0);
9693fb4f7cdSSrinivas Pandruvada 	}
9703fb4f7cdSSrinivas Pandruvada 
9713fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
9723fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
9733fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL,
9743fb4f7cdSSrinivas Pandruvada 						  NULL, &status);
9753fb4f7cdSSrinivas Pandruvada 	else
9763fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL,
9773fb4f7cdSSrinivas Pandruvada 					       NULL, &status);
9783fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
9793fb4f7cdSSrinivas Pandruvada }
9803fb4f7cdSSrinivas Pandruvada 
9813fb4f7cdSSrinivas Pandruvada static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3,
9823fb4f7cdSSrinivas Pandruvada 				   void *arg4)
9833fb4f7cdSSrinivas Pandruvada {
9843fb4f7cdSSrinivas Pandruvada 	int ret;
9853fb4f7cdSSrinivas Pandruvada 	int status = *(int *)arg4;
9863fb4f7cdSSrinivas Pandruvada 
9873fb4f7cdSSrinivas Pandruvada 	ret = isst_pm_qos_config(cpu, status, clos_priority_type);
9883fb4f7cdSSrinivas Pandruvada 	if (ret) {
9893fb4f7cdSSrinivas Pandruvada 		perror("isst_pm_qos_config");
9903fb4f7cdSSrinivas Pandruvada 	} else {
9913fb4f7cdSSrinivas Pandruvada 		if (status)
9923fb4f7cdSSrinivas Pandruvada 			isst_display_result(cpu, outf, "core-power", "enable",
9933fb4f7cdSSrinivas Pandruvada 					    ret);
9943fb4f7cdSSrinivas Pandruvada 		else
9953fb4f7cdSSrinivas Pandruvada 			isst_display_result(cpu, outf, "core-power", "disable",
9963fb4f7cdSSrinivas Pandruvada 					    ret);
9973fb4f7cdSSrinivas Pandruvada 	}
9983fb4f7cdSSrinivas Pandruvada }
9993fb4f7cdSSrinivas Pandruvada 
10003fb4f7cdSSrinivas Pandruvada static void set_clos_enable(void)
10013fb4f7cdSSrinivas Pandruvada {
10023fb4f7cdSSrinivas Pandruvada 	int status = 1;
10033fb4f7cdSSrinivas Pandruvada 
10043fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
10053fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Enable core-power for a package/die\n");
10063fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
10073fb4f7cdSSrinivas Pandruvada 			"\tClos Enable: Specify priority type with [--priority|-p]\n");
10083fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n");
10093fb4f7cdSSrinivas Pandruvada 		exit(0);
10103fb4f7cdSSrinivas Pandruvada 	}
10113fb4f7cdSSrinivas Pandruvada 
10123fb4f7cdSSrinivas Pandruvada 	if (cpufreq_sysfs_present()) {
10133fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
10143fb4f7cdSSrinivas Pandruvada 			"cpufreq subsystem and core-power enable will interfere with each other!\n");
10153fb4f7cdSSrinivas Pandruvada 	}
10163fb4f7cdSSrinivas Pandruvada 
10173fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
10183fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
10193fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL,
10203fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, &status);
10213fb4f7cdSSrinivas Pandruvada 	else
10223fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(enable_clos_qos_config, NULL,
10233fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, &status);
10243fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
10253fb4f7cdSSrinivas Pandruvada }
10263fb4f7cdSSrinivas Pandruvada 
10273fb4f7cdSSrinivas Pandruvada static void set_clos_disable(void)
10283fb4f7cdSSrinivas Pandruvada {
10293fb4f7cdSSrinivas Pandruvada 	int status = 0;
10303fb4f7cdSSrinivas Pandruvada 
10313fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
10323fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
10333fb4f7cdSSrinivas Pandruvada 			"Disable core-power: [No command arguments are required]\n");
10343fb4f7cdSSrinivas Pandruvada 		exit(0);
10353fb4f7cdSSrinivas Pandruvada 	}
10363fb4f7cdSSrinivas Pandruvada 
10373fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
10383fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
10393fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL,
10403fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, &status);
10413fb4f7cdSSrinivas Pandruvada 	else
10423fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(enable_clos_qos_config, NULL,
10433fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, &status);
10443fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
10453fb4f7cdSSrinivas Pandruvada }
10463fb4f7cdSSrinivas Pandruvada 
10473fb4f7cdSSrinivas Pandruvada static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2,
10483fb4f7cdSSrinivas Pandruvada 				     void *arg3, void *arg4)
10493fb4f7cdSSrinivas Pandruvada {
10503fb4f7cdSSrinivas Pandruvada 	struct isst_clos_config clos_config;
10513fb4f7cdSSrinivas Pandruvada 	int ret;
10523fb4f7cdSSrinivas Pandruvada 
10533fb4f7cdSSrinivas Pandruvada 	ret = isst_pm_get_clos(cpu, current_clos, &clos_config);
10543fb4f7cdSSrinivas Pandruvada 	if (ret)
10553fb4f7cdSSrinivas Pandruvada 		perror("isst_pm_get_clos");
10563fb4f7cdSSrinivas Pandruvada 	else
10573fb4f7cdSSrinivas Pandruvada 		isst_clos_display_information(cpu, outf, current_clos,
10583fb4f7cdSSrinivas Pandruvada 					      &clos_config);
10593fb4f7cdSSrinivas Pandruvada }
10603fb4f7cdSSrinivas Pandruvada 
10613fb4f7cdSSrinivas Pandruvada static void dump_clos_config(void)
10623fb4f7cdSSrinivas Pandruvada {
10633fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
10643fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
10653fb4f7cdSSrinivas Pandruvada 			"Print Intel Speed Select Technology core power configuration\n");
10663fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
10673fb4f7cdSSrinivas Pandruvada 			"\tArguments: [-c | --clos]: Specify clos id\n");
10683fb4f7cdSSrinivas Pandruvada 		exit(0);
10693fb4f7cdSSrinivas Pandruvada 	}
10703fb4f7cdSSrinivas Pandruvada 	if (current_clos < 0 || current_clos > 3) {
10713fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Invalid clos id\n");
10723fb4f7cdSSrinivas Pandruvada 		exit(0);
10733fb4f7cdSSrinivas Pandruvada 	}
10743fb4f7cdSSrinivas Pandruvada 
10753fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
10763fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
10773fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(dump_clos_config_for_cpu,
10783fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL, NULL);
10793fb4f7cdSSrinivas Pandruvada 	else
10803fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(dump_clos_config_for_cpu, NULL,
10813fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
10823fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
10833fb4f7cdSSrinivas Pandruvada }
10843fb4f7cdSSrinivas Pandruvada 
10853fb4f7cdSSrinivas Pandruvada static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
10863fb4f7cdSSrinivas Pandruvada 				    void *arg4)
10873fb4f7cdSSrinivas Pandruvada {
10883fb4f7cdSSrinivas Pandruvada 	struct isst_clos_config clos_config;
10893fb4f7cdSSrinivas Pandruvada 	int ret;
10903fb4f7cdSSrinivas Pandruvada 
10913fb4f7cdSSrinivas Pandruvada 	clos_config.pkg_id = get_physical_package_id(cpu);
10923fb4f7cdSSrinivas Pandruvada 	clos_config.die_id = get_physical_die_id(cpu);
10933fb4f7cdSSrinivas Pandruvada 
10943fb4f7cdSSrinivas Pandruvada 	clos_config.epp = clos_epp;
10953fb4f7cdSSrinivas Pandruvada 	clos_config.clos_prop_prio = clos_prop_prio;
10963fb4f7cdSSrinivas Pandruvada 	clos_config.clos_min = clos_min;
10973fb4f7cdSSrinivas Pandruvada 	clos_config.clos_max = clos_max;
10983fb4f7cdSSrinivas Pandruvada 	clos_config.clos_desired = clos_desired;
10993fb4f7cdSSrinivas Pandruvada 	ret = isst_set_clos(cpu, current_clos, &clos_config);
11003fb4f7cdSSrinivas Pandruvada 	if (ret)
11013fb4f7cdSSrinivas Pandruvada 		perror("isst_set_clos");
11023fb4f7cdSSrinivas Pandruvada 	else
11033fb4f7cdSSrinivas Pandruvada 		isst_display_result(cpu, outf, "core-power", "config", ret);
11043fb4f7cdSSrinivas Pandruvada }
11053fb4f7cdSSrinivas Pandruvada 
11063fb4f7cdSSrinivas Pandruvada static void set_clos_config(void)
11073fb4f7cdSSrinivas Pandruvada {
11083fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
11093fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
11103fb4f7cdSSrinivas Pandruvada 			"Set core-power configuration for one of the four clos ids\n");
11113fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
11123fb4f7cdSSrinivas Pandruvada 			"\tSpecify targeted clos id with [--clos|-c]\n");
11133fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n");
11143fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
11153fb4f7cdSSrinivas Pandruvada 			"\tSpecify clos Proportional Priority [--weight|-w]\n");
11163fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify clos min with [--min|-n]\n");
11173fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify clos max with [--max|-m]\n");
11183fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify clos desired with [--desired|-d]\n");
11193fb4f7cdSSrinivas Pandruvada 		exit(0);
11203fb4f7cdSSrinivas Pandruvada 	}
11213fb4f7cdSSrinivas Pandruvada 
11223fb4f7cdSSrinivas Pandruvada 	if (current_clos < 0 || current_clos > 3) {
11233fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Invalid clos id\n");
11243fb4f7cdSSrinivas Pandruvada 		exit(0);
11253fb4f7cdSSrinivas Pandruvada 	}
11263fb4f7cdSSrinivas Pandruvada 	if (clos_epp < 0 || clos_epp > 0x0F) {
11273fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "clos epp is not specified, default: 0\n");
11283fb4f7cdSSrinivas Pandruvada 		clos_epp = 0;
11293fb4f7cdSSrinivas Pandruvada 	}
11303fb4f7cdSSrinivas Pandruvada 	if (clos_prop_prio < 0 || clos_prop_prio > 0x0F) {
11313fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
11323fb4f7cdSSrinivas Pandruvada 			"clos frequency weight is not specified, default: 0\n");
11333fb4f7cdSSrinivas Pandruvada 		clos_prop_prio = 0;
11343fb4f7cdSSrinivas Pandruvada 	}
11353fb4f7cdSSrinivas Pandruvada 	if (clos_min < 0) {
11363fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "clos min is not specified, default: 0\n");
11373fb4f7cdSSrinivas Pandruvada 		clos_min = 0;
11383fb4f7cdSSrinivas Pandruvada 	}
11393fb4f7cdSSrinivas Pandruvada 	if (clos_max < 0) {
11403fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "clos max is not specified, default: 0xff\n");
11413fb4f7cdSSrinivas Pandruvada 		clos_max = 0xff;
11423fb4f7cdSSrinivas Pandruvada 	}
11433fb4f7cdSSrinivas Pandruvada 	if (clos_desired < 0) {
11443fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "clos desired is not specified, default: 0\n");
11453fb4f7cdSSrinivas Pandruvada 		clos_desired = 0x00;
11463fb4f7cdSSrinivas Pandruvada 	}
11473fb4f7cdSSrinivas Pandruvada 
11483fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
11493fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
11503fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_clos_config_for_cpu, NULL,
11513fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
11523fb4f7cdSSrinivas Pandruvada 	else
11533fb4f7cdSSrinivas Pandruvada 		for_each_online_package_in_set(set_clos_config_for_cpu, NULL,
11543fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
11553fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
11563fb4f7cdSSrinivas Pandruvada }
11573fb4f7cdSSrinivas Pandruvada 
11583fb4f7cdSSrinivas Pandruvada static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
11593fb4f7cdSSrinivas Pandruvada 				   void *arg4)
11603fb4f7cdSSrinivas Pandruvada {
11613fb4f7cdSSrinivas Pandruvada 	int ret;
11623fb4f7cdSSrinivas Pandruvada 
11633fb4f7cdSSrinivas Pandruvada 	ret = isst_clos_associate(cpu, current_clos);
11643fb4f7cdSSrinivas Pandruvada 	if (ret)
11653fb4f7cdSSrinivas Pandruvada 		perror("isst_clos_associate");
11663fb4f7cdSSrinivas Pandruvada 	else
11673fb4f7cdSSrinivas Pandruvada 		isst_display_result(cpu, outf, "core-power", "assoc", ret);
11683fb4f7cdSSrinivas Pandruvada }
11693fb4f7cdSSrinivas Pandruvada 
11703fb4f7cdSSrinivas Pandruvada static void set_clos_assoc(void)
11713fb4f7cdSSrinivas Pandruvada {
11723fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
11733fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Associate a clos id to a CPU\n");
11743fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
11753fb4f7cdSSrinivas Pandruvada 			"\tSpecify targeted clos id with [--clos|-c]\n");
11763fb4f7cdSSrinivas Pandruvada 		exit(0);
11773fb4f7cdSSrinivas Pandruvada 	}
11783fb4f7cdSSrinivas Pandruvada 
11793fb4f7cdSSrinivas Pandruvada 	if (current_clos < 0 || current_clos > 3) {
11803fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Invalid clos id\n");
11813fb4f7cdSSrinivas Pandruvada 		exit(0);
11823fb4f7cdSSrinivas Pandruvada 	}
11833fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
11843fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL,
11853fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
11863fb4f7cdSSrinivas Pandruvada 	else {
11873fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
11883fb4f7cdSSrinivas Pandruvada 			"Invalid target cpu. Specify with [-c|--cpu]\n");
11893fb4f7cdSSrinivas Pandruvada 	}
11903fb4f7cdSSrinivas Pandruvada }
11913fb4f7cdSSrinivas Pandruvada 
11923fb4f7cdSSrinivas Pandruvada static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
11933fb4f7cdSSrinivas Pandruvada 				   void *arg4)
11943fb4f7cdSSrinivas Pandruvada {
11953fb4f7cdSSrinivas Pandruvada 	int clos, ret;
11963fb4f7cdSSrinivas Pandruvada 
11973fb4f7cdSSrinivas Pandruvada 	ret = isst_clos_get_assoc_status(cpu, &clos);
11983fb4f7cdSSrinivas Pandruvada 	if (ret)
11993fb4f7cdSSrinivas Pandruvada 		perror("isst_clos_get_assoc_status");
12003fb4f7cdSSrinivas Pandruvada 	else
12013fb4f7cdSSrinivas Pandruvada 		isst_display_result(cpu, outf, "core-power", "get-assoc", clos);
12023fb4f7cdSSrinivas Pandruvada }
12033fb4f7cdSSrinivas Pandruvada 
12043fb4f7cdSSrinivas Pandruvada static void get_clos_assoc(void)
12053fb4f7cdSSrinivas Pandruvada {
12063fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
12073fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Get associate clos id to a CPU\n");
12083fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n");
12093fb4f7cdSSrinivas Pandruvada 		exit(0);
12103fb4f7cdSSrinivas Pandruvada 	}
12113fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
12123fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL,
12133fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
12143fb4f7cdSSrinivas Pandruvada 	else {
12153fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
12163fb4f7cdSSrinivas Pandruvada 			"Invalid target cpu. Specify with [-c|--cpu]\n");
12173fb4f7cdSSrinivas Pandruvada 	}
12183fb4f7cdSSrinivas Pandruvada }
12193fb4f7cdSSrinivas Pandruvada 
12203fb4f7cdSSrinivas Pandruvada static struct process_cmd_struct isst_cmds[] = {
12213fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", "get-lock-status", get_tdp_locked },
12223fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", "get-config-levels", get_tdp_levels },
12233fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", "get-config-version", get_tdp_version },
12243fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", "get-config-enabled", get_tdp_enabled },
12253fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", "get-config-current-level", get_tdp_current_level },
12263fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", "set-config-level", set_tdp_level },
12273fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", "info", dump_isst_config },
12283fb4f7cdSSrinivas Pandruvada 	{ "base-freq", "info", dump_pbf_config },
12293fb4f7cdSSrinivas Pandruvada 	{ "base-freq", "enable", set_pbf_enable },
12303fb4f7cdSSrinivas Pandruvada 	{ "base-freq", "disable", set_pbf_disable },
12313fb4f7cdSSrinivas Pandruvada 	{ "turbo-freq", "info", dump_fact_config },
12323fb4f7cdSSrinivas Pandruvada 	{ "turbo-freq", "enable", set_fact_enable },
12333fb4f7cdSSrinivas Pandruvada 	{ "turbo-freq", "disable", set_fact_disable },
12343fb4f7cdSSrinivas Pandruvada 	{ "core-power", "info", dump_clos_config },
12353fb4f7cdSSrinivas Pandruvada 	{ "core-power", "enable", set_clos_enable },
12363fb4f7cdSSrinivas Pandruvada 	{ "core-power", "disable", set_clos_disable },
12373fb4f7cdSSrinivas Pandruvada 	{ "core-power", "config", set_clos_config },
12383fb4f7cdSSrinivas Pandruvada 	{ "core-power", "assoc", set_clos_assoc },
12393fb4f7cdSSrinivas Pandruvada 	{ "core-power", "get-assoc", get_clos_assoc },
12403fb4f7cdSSrinivas Pandruvada 	{ NULL, NULL, NULL }
12413fb4f7cdSSrinivas Pandruvada };
12423fb4f7cdSSrinivas Pandruvada 
12433fb4f7cdSSrinivas Pandruvada /*
12443fb4f7cdSSrinivas Pandruvada  * parse cpuset with following syntax
12453fb4f7cdSSrinivas Pandruvada  * 1,2,4..6,8-10 and set bits in cpu_subset
12463fb4f7cdSSrinivas Pandruvada  */
12473fb4f7cdSSrinivas Pandruvada void parse_cpu_command(char *optarg)
12483fb4f7cdSSrinivas Pandruvada {
12493fb4f7cdSSrinivas Pandruvada 	unsigned int start, end;
12503fb4f7cdSSrinivas Pandruvada 	char *next;
12513fb4f7cdSSrinivas Pandruvada 
12523fb4f7cdSSrinivas Pandruvada 	next = optarg;
12533fb4f7cdSSrinivas Pandruvada 
12543fb4f7cdSSrinivas Pandruvada 	while (next && *next) {
12553fb4f7cdSSrinivas Pandruvada 		if (*next == '-') /* no negative cpu numbers */
12563fb4f7cdSSrinivas Pandruvada 			goto error;
12573fb4f7cdSSrinivas Pandruvada 
12583fb4f7cdSSrinivas Pandruvada 		start = strtoul(next, &next, 10);
12593fb4f7cdSSrinivas Pandruvada 
12603fb4f7cdSSrinivas Pandruvada 		if (max_target_cpus < MAX_CPUS_IN_ONE_REQ)
12613fb4f7cdSSrinivas Pandruvada 			target_cpus[max_target_cpus++] = start;
12623fb4f7cdSSrinivas Pandruvada 
12633fb4f7cdSSrinivas Pandruvada 		if (*next == '\0')
12643fb4f7cdSSrinivas Pandruvada 			break;
12653fb4f7cdSSrinivas Pandruvada 
12663fb4f7cdSSrinivas Pandruvada 		if (*next == ',') {
12673fb4f7cdSSrinivas Pandruvada 			next += 1;
12683fb4f7cdSSrinivas Pandruvada 			continue;
12693fb4f7cdSSrinivas Pandruvada 		}
12703fb4f7cdSSrinivas Pandruvada 
12713fb4f7cdSSrinivas Pandruvada 		if (*next == '-') {
12723fb4f7cdSSrinivas Pandruvada 			next += 1; /* start range */
12733fb4f7cdSSrinivas Pandruvada 		} else if (*next == '.') {
12743fb4f7cdSSrinivas Pandruvada 			next += 1;
12753fb4f7cdSSrinivas Pandruvada 			if (*next == '.')
12763fb4f7cdSSrinivas Pandruvada 				next += 1; /* start range */
12773fb4f7cdSSrinivas Pandruvada 			else
12783fb4f7cdSSrinivas Pandruvada 				goto error;
12793fb4f7cdSSrinivas Pandruvada 		}
12803fb4f7cdSSrinivas Pandruvada 
12813fb4f7cdSSrinivas Pandruvada 		end = strtoul(next, &next, 10);
12823fb4f7cdSSrinivas Pandruvada 		if (end <= start)
12833fb4f7cdSSrinivas Pandruvada 			goto error;
12843fb4f7cdSSrinivas Pandruvada 
12853fb4f7cdSSrinivas Pandruvada 		while (++start <= end) {
12863fb4f7cdSSrinivas Pandruvada 			if (max_target_cpus < MAX_CPUS_IN_ONE_REQ)
12873fb4f7cdSSrinivas Pandruvada 				target_cpus[max_target_cpus++] = start;
12883fb4f7cdSSrinivas Pandruvada 		}
12893fb4f7cdSSrinivas Pandruvada 
12903fb4f7cdSSrinivas Pandruvada 		if (*next == ',')
12913fb4f7cdSSrinivas Pandruvada 			next += 1;
12923fb4f7cdSSrinivas Pandruvada 		else if (*next != '\0')
12933fb4f7cdSSrinivas Pandruvada 			goto error;
12943fb4f7cdSSrinivas Pandruvada 	}
12953fb4f7cdSSrinivas Pandruvada 
12963fb4f7cdSSrinivas Pandruvada #ifdef DEBUG
12973fb4f7cdSSrinivas Pandruvada 	{
12983fb4f7cdSSrinivas Pandruvada 		int i;
12993fb4f7cdSSrinivas Pandruvada 
13003fb4f7cdSSrinivas Pandruvada 		for (i = 0; i < max_target_cpus; ++i)
13013fb4f7cdSSrinivas Pandruvada 			printf("cpu [%d] in arg\n", target_cpus[i]);
13023fb4f7cdSSrinivas Pandruvada 	}
13033fb4f7cdSSrinivas Pandruvada #endif
13043fb4f7cdSSrinivas Pandruvada 	return;
13053fb4f7cdSSrinivas Pandruvada 
13063fb4f7cdSSrinivas Pandruvada error:
13073fb4f7cdSSrinivas Pandruvada 	fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
13083fb4f7cdSSrinivas Pandruvada 	exit(-1);
13093fb4f7cdSSrinivas Pandruvada }
13103fb4f7cdSSrinivas Pandruvada 
13113fb4f7cdSSrinivas Pandruvada static void parse_cmd_args(int argc, int start, char **argv)
13123fb4f7cdSSrinivas Pandruvada {
13133fb4f7cdSSrinivas Pandruvada 	int opt;
13143fb4f7cdSSrinivas Pandruvada 	int option_index;
13153fb4f7cdSSrinivas Pandruvada 
13163fb4f7cdSSrinivas Pandruvada 	static struct option long_options[] = {
13173fb4f7cdSSrinivas Pandruvada 		{ "bucket", required_argument, 0, 'b' },
13183fb4f7cdSSrinivas Pandruvada 		{ "level", required_argument, 0, 'l' },
13193fb4f7cdSSrinivas Pandruvada 		{ "trl-type", required_argument, 0, 'r' },
13203fb4f7cdSSrinivas Pandruvada 		{ "trl", required_argument, 0, 't' },
13213fb4f7cdSSrinivas Pandruvada 		{ "help", no_argument, 0, 'h' },
13223fb4f7cdSSrinivas Pandruvada 		{ "clos", required_argument, 0, 'c' },
13233fb4f7cdSSrinivas Pandruvada 		{ "desired", required_argument, 0, 'd' },
13243fb4f7cdSSrinivas Pandruvada 		{ "epp", required_argument, 0, 'e' },
13253fb4f7cdSSrinivas Pandruvada 		{ "min", required_argument, 0, 'n' },
13263fb4f7cdSSrinivas Pandruvada 		{ "max", required_argument, 0, 'm' },
13273fb4f7cdSSrinivas Pandruvada 		{ "priority", required_argument, 0, 'p' },
13283fb4f7cdSSrinivas Pandruvada 		{ "weight", required_argument, 0, 'w' },
13293fb4f7cdSSrinivas Pandruvada 		{ 0, 0, 0, 0 }
13303fb4f7cdSSrinivas Pandruvada 	};
13313fb4f7cdSSrinivas Pandruvada 
13323fb4f7cdSSrinivas Pandruvada 	option_index = start;
13333fb4f7cdSSrinivas Pandruvada 
13343fb4f7cdSSrinivas Pandruvada 	optind = start + 1;
13353fb4f7cdSSrinivas Pandruvada 	while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:h",
13363fb4f7cdSSrinivas Pandruvada 				  long_options, &option_index)) != -1) {
13373fb4f7cdSSrinivas Pandruvada 		switch (opt) {
13383fb4f7cdSSrinivas Pandruvada 		case 'b':
13393fb4f7cdSSrinivas Pandruvada 			fact_bucket = atoi(optarg);
13403fb4f7cdSSrinivas Pandruvada 			break;
13413fb4f7cdSSrinivas Pandruvada 		case 'h':
13423fb4f7cdSSrinivas Pandruvada 			cmd_help = 1;
13433fb4f7cdSSrinivas Pandruvada 			break;
13443fb4f7cdSSrinivas Pandruvada 		case 'l':
13453fb4f7cdSSrinivas Pandruvada 			tdp_level = atoi(optarg);
13463fb4f7cdSSrinivas Pandruvada 			break;
13473fb4f7cdSSrinivas Pandruvada 		case 't':
13483fb4f7cdSSrinivas Pandruvada 			sscanf(optarg, "0x%llx", &fact_trl);
13493fb4f7cdSSrinivas Pandruvada 			break;
13503fb4f7cdSSrinivas Pandruvada 		case 'r':
13513fb4f7cdSSrinivas Pandruvada 			if (!strncmp(optarg, "sse", 3)) {
13523fb4f7cdSSrinivas Pandruvada 				fact_avx = 0x01;
13533fb4f7cdSSrinivas Pandruvada 			} else if (!strncmp(optarg, "avx2", 4)) {
13543fb4f7cdSSrinivas Pandruvada 				fact_avx = 0x02;
13553fb4f7cdSSrinivas Pandruvada 			} else if (!strncmp(optarg, "avx512", 4)) {
13563fb4f7cdSSrinivas Pandruvada 				fact_avx = 0x04;
13573fb4f7cdSSrinivas Pandruvada 			} else {
13583fb4f7cdSSrinivas Pandruvada 				fprintf(outf, "Invalid sse,avx options\n");
13593fb4f7cdSSrinivas Pandruvada 				exit(1);
13603fb4f7cdSSrinivas Pandruvada 			}
13613fb4f7cdSSrinivas Pandruvada 			break;
13623fb4f7cdSSrinivas Pandruvada 		/* CLOS related */
13633fb4f7cdSSrinivas Pandruvada 		case 'c':
13643fb4f7cdSSrinivas Pandruvada 			current_clos = atoi(optarg);
13653fb4f7cdSSrinivas Pandruvada 			printf("clos %d\n", current_clos);
13663fb4f7cdSSrinivas Pandruvada 			break;
13673fb4f7cdSSrinivas Pandruvada 		case 'd':
13683fb4f7cdSSrinivas Pandruvada 			clos_desired = atoi(optarg);
13693fb4f7cdSSrinivas Pandruvada 			break;
13703fb4f7cdSSrinivas Pandruvada 		case 'e':
13713fb4f7cdSSrinivas Pandruvada 			clos_epp = atoi(optarg);
13723fb4f7cdSSrinivas Pandruvada 			break;
13733fb4f7cdSSrinivas Pandruvada 		case 'n':
13743fb4f7cdSSrinivas Pandruvada 			clos_min = atoi(optarg);
13753fb4f7cdSSrinivas Pandruvada 			break;
13763fb4f7cdSSrinivas Pandruvada 		case 'm':
13773fb4f7cdSSrinivas Pandruvada 			clos_max = atoi(optarg);
13783fb4f7cdSSrinivas Pandruvada 			break;
13793fb4f7cdSSrinivas Pandruvada 		case 'p':
13803fb4f7cdSSrinivas Pandruvada 			clos_priority_type = atoi(optarg);
13813fb4f7cdSSrinivas Pandruvada 			break;
13823fb4f7cdSSrinivas Pandruvada 		case 'w':
13833fb4f7cdSSrinivas Pandruvada 			clos_prop_prio = atoi(optarg);
13843fb4f7cdSSrinivas Pandruvada 			break;
13853fb4f7cdSSrinivas Pandruvada 		default:
13863fb4f7cdSSrinivas Pandruvada 			printf("no match\n");
13873fb4f7cdSSrinivas Pandruvada 		}
13883fb4f7cdSSrinivas Pandruvada 	}
13893fb4f7cdSSrinivas Pandruvada }
13903fb4f7cdSSrinivas Pandruvada 
13913fb4f7cdSSrinivas Pandruvada static void isst_help(void)
13923fb4f7cdSSrinivas Pandruvada {
13933fb4f7cdSSrinivas Pandruvada 	printf("perf-profile:\tAn architectural mechanism that allows multiple optimized \n\
13943fb4f7cdSSrinivas Pandruvada 		performance profiles per system via static and/or dynamic\n\
13953fb4f7cdSSrinivas Pandruvada 		adjustment of core count, workload, Tjmax, and\n\
13963fb4f7cdSSrinivas Pandruvada 		TDP, etc.\n");
13973fb4f7cdSSrinivas Pandruvada 	printf("\nCommands : For feature=perf-profile\n");
13983fb4f7cdSSrinivas Pandruvada 	printf("\tinfo\n");
13993fb4f7cdSSrinivas Pandruvada 	printf("\tget-lock-status\n");
14003fb4f7cdSSrinivas Pandruvada 	printf("\tget-config-levels\n");
14013fb4f7cdSSrinivas Pandruvada 	printf("\tget-config-version\n");
14023fb4f7cdSSrinivas Pandruvada 	printf("\tget-config-enabled\n");
14033fb4f7cdSSrinivas Pandruvada 	printf("\tget-config-current-level\n");
14043fb4f7cdSSrinivas Pandruvada 	printf("\tset-config-level\n");
14053fb4f7cdSSrinivas Pandruvada }
14063fb4f7cdSSrinivas Pandruvada 
14073fb4f7cdSSrinivas Pandruvada static void pbf_help(void)
14083fb4f7cdSSrinivas Pandruvada {
14093fb4f7cdSSrinivas Pandruvada 	printf("base-freq:\tEnables users to increase guaranteed base frequency\n\
14103fb4f7cdSSrinivas Pandruvada 		on certain cores (high priority cores) in exchange for lower\n\
14113fb4f7cdSSrinivas Pandruvada 		base frequency on remaining cores (low priority cores).\n");
14123fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : info\n");
14133fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : enable\n");
14143fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : disable\n");
14153fb4f7cdSSrinivas Pandruvada }
14163fb4f7cdSSrinivas Pandruvada 
14173fb4f7cdSSrinivas Pandruvada static void fact_help(void)
14183fb4f7cdSSrinivas Pandruvada {
14193fb4f7cdSSrinivas Pandruvada 	printf("turbo-freq:\tEnables the ability to set different turbo ratio\n\
14203fb4f7cdSSrinivas Pandruvada 		limits to cores based on priority.\n");
14213fb4f7cdSSrinivas Pandruvada 	printf("\nCommand: For feature=turbo-freq\n");
14223fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : info\n");
14233fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : enable\n");
14243fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : disable\n");
14253fb4f7cdSSrinivas Pandruvada }
14263fb4f7cdSSrinivas Pandruvada 
14273fb4f7cdSSrinivas Pandruvada static void core_power_help(void)
14283fb4f7cdSSrinivas Pandruvada {
14293fb4f7cdSSrinivas Pandruvada 	printf("core-power:\tInterface that allows user to define per core/tile\n\
14303fb4f7cdSSrinivas Pandruvada 		priority.\n");
14313fb4f7cdSSrinivas Pandruvada 	printf("\nCommands : For feature=core-power\n");
14323fb4f7cdSSrinivas Pandruvada 	printf("\tinfo\n");
14333fb4f7cdSSrinivas Pandruvada 	printf("\tenable\n");
14343fb4f7cdSSrinivas Pandruvada 	printf("\tdisable\n");
14353fb4f7cdSSrinivas Pandruvada 	printf("\tconfig\n");
14363fb4f7cdSSrinivas Pandruvada 	printf("\tassoc\n");
14373fb4f7cdSSrinivas Pandruvada 	printf("\tget-assoc\n");
14383fb4f7cdSSrinivas Pandruvada }
14393fb4f7cdSSrinivas Pandruvada 
14403fb4f7cdSSrinivas Pandruvada struct process_cmd_help_struct {
14413fb4f7cdSSrinivas Pandruvada 	char *feature;
14423fb4f7cdSSrinivas Pandruvada 	void (*process_fn)(void);
14433fb4f7cdSSrinivas Pandruvada };
14443fb4f7cdSSrinivas Pandruvada 
14453fb4f7cdSSrinivas Pandruvada static struct process_cmd_help_struct isst_help_cmds[] = {
14463fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", isst_help },
14473fb4f7cdSSrinivas Pandruvada 	{ "base-freq", pbf_help },
14483fb4f7cdSSrinivas Pandruvada 	{ "turbo-freq", fact_help },
14493fb4f7cdSSrinivas Pandruvada 	{ "core-power", core_power_help },
14503fb4f7cdSSrinivas Pandruvada 	{ NULL, NULL }
14513fb4f7cdSSrinivas Pandruvada };
14523fb4f7cdSSrinivas Pandruvada 
14533fb4f7cdSSrinivas Pandruvada void process_command(int argc, char **argv)
14543fb4f7cdSSrinivas Pandruvada {
14553fb4f7cdSSrinivas Pandruvada 	int i = 0, matched = 0;
14563fb4f7cdSSrinivas Pandruvada 	char *feature = argv[optind];
14573fb4f7cdSSrinivas Pandruvada 	char *cmd = argv[optind + 1];
14583fb4f7cdSSrinivas Pandruvada 
14593fb4f7cdSSrinivas Pandruvada 	if (!feature || !cmd)
14603fb4f7cdSSrinivas Pandruvada 		return;
14613fb4f7cdSSrinivas Pandruvada 
14623fb4f7cdSSrinivas Pandruvada 	debug_printf("feature name [%s] command [%s]\n", feature, cmd);
14633fb4f7cdSSrinivas Pandruvada 	if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) {
14643fb4f7cdSSrinivas Pandruvada 		while (isst_help_cmds[i].feature) {
14653fb4f7cdSSrinivas Pandruvada 			if (!strcmp(isst_help_cmds[i].feature, feature)) {
14663fb4f7cdSSrinivas Pandruvada 				isst_help_cmds[i].process_fn();
14673fb4f7cdSSrinivas Pandruvada 				exit(0);
14683fb4f7cdSSrinivas Pandruvada 			}
14693fb4f7cdSSrinivas Pandruvada 			++i;
14703fb4f7cdSSrinivas Pandruvada 		}
14713fb4f7cdSSrinivas Pandruvada 	}
14723fb4f7cdSSrinivas Pandruvada 
14733fb4f7cdSSrinivas Pandruvada 	create_cpu_map();
14743fb4f7cdSSrinivas Pandruvada 
14753fb4f7cdSSrinivas Pandruvada 	i = 0;
14763fb4f7cdSSrinivas Pandruvada 	while (isst_cmds[i].feature) {
14773fb4f7cdSSrinivas Pandruvada 		if (!strcmp(isst_cmds[i].feature, feature) &&
14783fb4f7cdSSrinivas Pandruvada 		    !strcmp(isst_cmds[i].command, cmd)) {
14793fb4f7cdSSrinivas Pandruvada 			parse_cmd_args(argc, optind + 1, argv);
14803fb4f7cdSSrinivas Pandruvada 			isst_cmds[i].process_fn();
14813fb4f7cdSSrinivas Pandruvada 			matched = 1;
14823fb4f7cdSSrinivas Pandruvada 			break;
14833fb4f7cdSSrinivas Pandruvada 		}
14843fb4f7cdSSrinivas Pandruvada 		++i;
14853fb4f7cdSSrinivas Pandruvada 	}
14863fb4f7cdSSrinivas Pandruvada 
14873fb4f7cdSSrinivas Pandruvada 	if (!matched)
14883fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Invalid command\n");
14893fb4f7cdSSrinivas Pandruvada }
14903fb4f7cdSSrinivas Pandruvada 
14913fb4f7cdSSrinivas Pandruvada static void usage(void)
14923fb4f7cdSSrinivas Pandruvada {
14933fb4f7cdSSrinivas Pandruvada 	printf("Intel(R) Speed Select Technology\n");
14943fb4f7cdSSrinivas Pandruvada 	printf("\nUsage:\n");
14953fb4f7cdSSrinivas Pandruvada 	printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n");
14963fb4f7cdSSrinivas Pandruvada 	printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features,\n");
14973fb4f7cdSSrinivas Pandruvada 	printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power]\n");
149843774c0dSPrarit Bhargava 	printf("\nFor help on each feature, use -h|--help\n");
14993fb4f7cdSSrinivas Pandruvada 	printf("\tFor example:  intel-speed-select perf-profile -h\n");
15003fb4f7cdSSrinivas Pandruvada 
15013fb4f7cdSSrinivas Pandruvada 	printf("\nFor additional help on each command for a feature, use --h|--help\n");
15023fb4f7cdSSrinivas Pandruvada 	printf("\tFor example:  intel-speed-select perf-profile get-lock-status -h\n");
15033fb4f7cdSSrinivas Pandruvada 	printf("\t\t This will print help for the command \"get-lock-status\" for the feature \"perf-profile\"\n");
15043fb4f7cdSSrinivas Pandruvada 
15053fb4f7cdSSrinivas Pandruvada 	printf("\nOPTIONS\n");
15063fb4f7cdSSrinivas Pandruvada 	printf("\t[-c|--cpu] : logical cpu number\n");
15073fb4f7cdSSrinivas Pandruvada 	printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n");
15083fb4f7cdSSrinivas Pandruvada 	printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n");
15093fb4f7cdSSrinivas Pandruvada 	printf("\t[-d|--debug] : Debug mode\n");
15103fb4f7cdSSrinivas Pandruvada 	printf("\t[-h|--help] : Print help\n");
15113fb4f7cdSSrinivas Pandruvada 	printf("\t[-i|--info] : Print platform information\n");
15123fb4f7cdSSrinivas Pandruvada 	printf("\t[-o|--out] : Output file\n");
15133fb4f7cdSSrinivas Pandruvada 	printf("\t\t\tDefault : stderr\n");
15143fb4f7cdSSrinivas Pandruvada 	printf("\t[-f|--format] : output format [json|text]. Default: text\n");
15153fb4f7cdSSrinivas Pandruvada 	printf("\t[-v|--version] : Print version\n");
15163fb4f7cdSSrinivas Pandruvada 
15173fb4f7cdSSrinivas Pandruvada 	printf("\nResult format\n");
15183fb4f7cdSSrinivas Pandruvada 	printf("\tResult display uses a common format for each command:\n");
15193fb4f7cdSSrinivas Pandruvada 	printf("\tResults are formatted in text/JSON with\n");
15203fb4f7cdSSrinivas Pandruvada 	printf("\t\tPackage, Die, CPU, and command specific results.\n");
15213fb4f7cdSSrinivas Pandruvada 	exit(1);
15223fb4f7cdSSrinivas Pandruvada }
15233fb4f7cdSSrinivas Pandruvada 
15243fb4f7cdSSrinivas Pandruvada static void print_version(void)
15253fb4f7cdSSrinivas Pandruvada {
15263fb4f7cdSSrinivas Pandruvada 	fprintf(outf, "Version %s\n", version_str);
15273fb4f7cdSSrinivas Pandruvada 	fprintf(outf, "Build date %s time %s\n", __DATE__, __TIME__);
15283fb4f7cdSSrinivas Pandruvada 	exit(0);
15293fb4f7cdSSrinivas Pandruvada }
15303fb4f7cdSSrinivas Pandruvada 
15313fb4f7cdSSrinivas Pandruvada static void cmdline(int argc, char **argv)
15323fb4f7cdSSrinivas Pandruvada {
15333fb4f7cdSSrinivas Pandruvada 	int opt;
15343fb4f7cdSSrinivas Pandruvada 	int option_index = 0;
1535*3bc3d30cSPrarit Bhargava 	int ret;
15363fb4f7cdSSrinivas Pandruvada 
15373fb4f7cdSSrinivas Pandruvada 	static struct option long_options[] = {
15383fb4f7cdSSrinivas Pandruvada 		{ "cpu", required_argument, 0, 'c' },
15393fb4f7cdSSrinivas Pandruvada 		{ "debug", no_argument, 0, 'd' },
15403fb4f7cdSSrinivas Pandruvada 		{ "format", required_argument, 0, 'f' },
15413fb4f7cdSSrinivas Pandruvada 		{ "help", no_argument, 0, 'h' },
15423fb4f7cdSSrinivas Pandruvada 		{ "info", no_argument, 0, 'i' },
15433fb4f7cdSSrinivas Pandruvada 		{ "out", required_argument, 0, 'o' },
15443fb4f7cdSSrinivas Pandruvada 		{ "version", no_argument, 0, 'v' },
15453fb4f7cdSSrinivas Pandruvada 		{ 0, 0, 0, 0 }
15463fb4f7cdSSrinivas Pandruvada 	};
15473fb4f7cdSSrinivas Pandruvada 
15483fb4f7cdSSrinivas Pandruvada 	progname = argv[0];
15493fb4f7cdSSrinivas Pandruvada 	while ((opt = getopt_long_only(argc, argv, "+c:df:hio:v", long_options,
15503fb4f7cdSSrinivas Pandruvada 				       &option_index)) != -1) {
15513fb4f7cdSSrinivas Pandruvada 		switch (opt) {
15523fb4f7cdSSrinivas Pandruvada 		case 'c':
15533fb4f7cdSSrinivas Pandruvada 			parse_cpu_command(optarg);
15543fb4f7cdSSrinivas Pandruvada 			break;
15553fb4f7cdSSrinivas Pandruvada 		case 'd':
15563fb4f7cdSSrinivas Pandruvada 			debug_flag = 1;
15573fb4f7cdSSrinivas Pandruvada 			printf("Debug Mode ON\n");
15583fb4f7cdSSrinivas Pandruvada 			break;
15593fb4f7cdSSrinivas Pandruvada 		case 'f':
15603fb4f7cdSSrinivas Pandruvada 			if (!strncmp(optarg, "json", 4))
15613fb4f7cdSSrinivas Pandruvada 				out_format_json = 1;
15623fb4f7cdSSrinivas Pandruvada 			break;
15633fb4f7cdSSrinivas Pandruvada 		case 'h':
15643fb4f7cdSSrinivas Pandruvada 			usage();
15653fb4f7cdSSrinivas Pandruvada 			break;
15663fb4f7cdSSrinivas Pandruvada 		case 'i':
15673fb4f7cdSSrinivas Pandruvada 			isst_print_platform_information();
15683fb4f7cdSSrinivas Pandruvada 			break;
15693fb4f7cdSSrinivas Pandruvada 		case 'o':
15703fb4f7cdSSrinivas Pandruvada 			if (outf)
15713fb4f7cdSSrinivas Pandruvada 				fclose(outf);
15723fb4f7cdSSrinivas Pandruvada 			outf = fopen_or_exit(optarg, "w");
15733fb4f7cdSSrinivas Pandruvada 			break;
15743fb4f7cdSSrinivas Pandruvada 		case 'v':
15753fb4f7cdSSrinivas Pandruvada 			print_version();
15763fb4f7cdSSrinivas Pandruvada 			break;
15773fb4f7cdSSrinivas Pandruvada 		default:
15783fb4f7cdSSrinivas Pandruvada 			usage();
15793fb4f7cdSSrinivas Pandruvada 		}
15803fb4f7cdSSrinivas Pandruvada 	}
15813fb4f7cdSSrinivas Pandruvada 
15823fb4f7cdSSrinivas Pandruvada 	if (geteuid() != 0) {
15833fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Must run as root\n");
15843fb4f7cdSSrinivas Pandruvada 		exit(0);
15853fb4f7cdSSrinivas Pandruvada 	}
15863fb4f7cdSSrinivas Pandruvada 
15873fb4f7cdSSrinivas Pandruvada 	if (optind > (argc - 2)) {
15883fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Feature name and|or command not specified\n");
15893fb4f7cdSSrinivas Pandruvada 		exit(0);
15903fb4f7cdSSrinivas Pandruvada 	}
15913fb4f7cdSSrinivas Pandruvada 	update_cpu_model();
15923fb4f7cdSSrinivas Pandruvada 	printf("Intel(R) Speed Select Technology\n");
15933fb4f7cdSSrinivas Pandruvada 	printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model);
15943fb4f7cdSSrinivas Pandruvada 	set_max_cpu_num();
15953fb4f7cdSSrinivas Pandruvada 	set_cpu_present_cpu_mask();
15963fb4f7cdSSrinivas Pandruvada 	set_cpu_target_cpu_mask();
1597*3bc3d30cSPrarit Bhargava 	ret = isst_fill_platform_info();
1598*3bc3d30cSPrarit Bhargava 	if (ret)
1599*3bc3d30cSPrarit Bhargava 		goto out;
16003fb4f7cdSSrinivas Pandruvada 
16013fb4f7cdSSrinivas Pandruvada 	process_command(argc, argv);
1602*3bc3d30cSPrarit Bhargava out:
1603*3bc3d30cSPrarit Bhargava 	free_cpu_set(present_cpumask);
1604*3bc3d30cSPrarit Bhargava 	free_cpu_set(target_cpumask);
16053fb4f7cdSSrinivas Pandruvada }
16063fb4f7cdSSrinivas Pandruvada 
16073fb4f7cdSSrinivas Pandruvada int main(int argc, char **argv)
16083fb4f7cdSSrinivas Pandruvada {
16093fb4f7cdSSrinivas Pandruvada 	outf = stderr;
16103fb4f7cdSSrinivas Pandruvada 	cmdline(argc, argv);
16113fb4f7cdSSrinivas Pandruvada 	return 0;
16123fb4f7cdSSrinivas Pandruvada }
1613