xref: /linux/tools/power/x86/intel-speed-select/isst-config.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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 
761f3d868SSrinivas Pandruvada #include <ctype.h>
83fb4f7cdSSrinivas Pandruvada #include <linux/isst_if.h>
93fb4f7cdSSrinivas Pandruvada 
103fb4f7cdSSrinivas Pandruvada #include "isst.h"
113fb4f7cdSSrinivas Pandruvada 
123fb4f7cdSSrinivas Pandruvada struct process_cmd_struct {
133fb4f7cdSSrinivas Pandruvada 	char *feature;
143fb4f7cdSSrinivas Pandruvada 	char *command;
15ce1326a2SPrarit Bhargava 	void (*process_fn)(int arg);
16ce1326a2SPrarit Bhargava 	int arg;
173fb4f7cdSSrinivas Pandruvada };
183fb4f7cdSSrinivas Pandruvada 
19*d8d4f57eSSrinivas Pandruvada static const char *version_str = "v1.20";
20f3874e96SSrinivas Pandruvada 
211fcf670eSSrinivas Pandruvada static const int supported_api_ver = 3;
223fb4f7cdSSrinivas Pandruvada static struct isst_if_platform_info isst_platform_info;
233fb4f7cdSSrinivas Pandruvada static char *progname;
243fb4f7cdSSrinivas Pandruvada static int debug_flag;
253fb4f7cdSSrinivas Pandruvada static FILE *outf;
263fb4f7cdSSrinivas Pandruvada 
273fb4f7cdSSrinivas Pandruvada static int cpu_model;
281c1d935cSPrarit Bhargava static int cpu_stepping;
293fb4f7cdSSrinivas Pandruvada 
30bc5370ccSSrinivas Pandruvada #define MAX_CPUS_IN_ONE_REQ 512
313fb4f7cdSSrinivas Pandruvada static short max_target_cpus;
323fb4f7cdSSrinivas Pandruvada static unsigned short target_cpus[MAX_CPUS_IN_ONE_REQ];
333fb4f7cdSSrinivas Pandruvada 
343fb4f7cdSSrinivas Pandruvada static int topo_max_cpus;
353fb4f7cdSSrinivas Pandruvada static size_t present_cpumask_size;
363fb4f7cdSSrinivas Pandruvada static cpu_set_t *present_cpumask;
373fb4f7cdSSrinivas Pandruvada static size_t target_cpumask_size;
383fb4f7cdSSrinivas Pandruvada static cpu_set_t *target_cpumask;
393fb4f7cdSSrinivas Pandruvada static int tdp_level = 0xFF;
403fb4f7cdSSrinivas Pandruvada static int fact_bucket = 0xFF;
413fb4f7cdSSrinivas Pandruvada static int fact_avx = 0xFF;
423fb4f7cdSSrinivas Pandruvada static unsigned long long fact_trl;
433fb4f7cdSSrinivas Pandruvada static int out_format_json;
443fb4f7cdSSrinivas Pandruvada static int cmd_help;
453c64c81aSSrinivas Pandruvada static int force_online_offline;
46354bd06fSSrinivas Pandruvada static int auto_mode;
4714a8aa49SSrinivas Pandruvada static int fact_enable_fail;
48997074dfSSrinivas Pandruvada static int cgroupv2;
49f9264471SSrinivas Pandruvada static int max_die_id;
50f9264471SSrinivas Pandruvada static int max_punit_id;
513fb4f7cdSSrinivas Pandruvada 
523fb4f7cdSSrinivas Pandruvada /* clos related */
533fb4f7cdSSrinivas Pandruvada static int current_clos = -1;
543fb4f7cdSSrinivas Pandruvada static int clos_epp = -1;
553fb4f7cdSSrinivas Pandruvada static int clos_prop_prio = -1;
563fb4f7cdSSrinivas Pandruvada static int clos_min = -1;
573fb4f7cdSSrinivas Pandruvada static int clos_max = -1;
583fb4f7cdSSrinivas Pandruvada static int clos_desired = -1;
593fb4f7cdSSrinivas Pandruvada static int clos_priority_type;
603bc0f20aSSrinivas Pandruvada static int cpu_0_cgroupv2;
613bc0f20aSSrinivas Pandruvada static int cpu_0_workaround(int isolate);
623fb4f7cdSSrinivas Pandruvada 
633fb4f7cdSSrinivas Pandruvada struct _cpu_map {
643fb4f7cdSSrinivas Pandruvada 	unsigned short core_id;
653fb4f7cdSSrinivas Pandruvada 	unsigned short pkg_id;
663fb4f7cdSSrinivas Pandruvada 	unsigned short die_id;
67e157c847SZhang Rui 	unsigned short punit_id;
683fb4f7cdSSrinivas Pandruvada 	unsigned short punit_cpu;
693fb4f7cdSSrinivas Pandruvada 	unsigned short punit_cpu_core;
70ca56725dSZhang Rui 	unsigned short initialized;
713fb4f7cdSSrinivas Pandruvada };
723fb4f7cdSSrinivas Pandruvada struct _cpu_map *cpu_map;
733fb4f7cdSSrinivas Pandruvada 
74fb186158SSrinivas Pandruvada struct cpu_topology {
75fb186158SSrinivas Pandruvada 	short cpu;
76fb186158SSrinivas Pandruvada 	short core_id;
77fb186158SSrinivas Pandruvada 	short pkg_id;
78fb186158SSrinivas Pandruvada 	short die_id;
79fb186158SSrinivas Pandruvada };
80fb186158SSrinivas Pandruvada 
get_output_file(void)8187e115b3SSrinivas Pandruvada FILE *get_output_file(void)
8287e115b3SSrinivas Pandruvada {
8387e115b3SSrinivas Pandruvada 	return outf;
8487e115b3SSrinivas Pandruvada }
8587e115b3SSrinivas Pandruvada 
is_debug_enabled(void)869798768cSZhang Rui int is_debug_enabled(void)
879798768cSZhang Rui {
889798768cSZhang Rui 	return debug_flag;
899798768cSZhang Rui }
909798768cSZhang Rui 
debug_printf(const char * format,...)913fb4f7cdSSrinivas Pandruvada void debug_printf(const char *format, ...)
923fb4f7cdSSrinivas Pandruvada {
933fb4f7cdSSrinivas Pandruvada 	va_list args;
943fb4f7cdSSrinivas Pandruvada 
953fb4f7cdSSrinivas Pandruvada 	va_start(args, format);
963fb4f7cdSSrinivas Pandruvada 
973fb4f7cdSSrinivas Pandruvada 	if (debug_flag)
983fb4f7cdSSrinivas Pandruvada 		vprintf(format, args);
993fb4f7cdSSrinivas Pandruvada 
1003fb4f7cdSSrinivas Pandruvada 	va_end(args);
1013fb4f7cdSSrinivas Pandruvada }
1023fb4f7cdSSrinivas Pandruvada 
1031c1d935cSPrarit Bhargava 
is_clx_n_platform(void)1041c1d935cSPrarit Bhargava int is_clx_n_platform(void)
1051c1d935cSPrarit Bhargava {
1061c1d935cSPrarit Bhargava 	if (cpu_model == 0x55)
1071c1d935cSPrarit Bhargava 		if (cpu_stepping == 0x6 || cpu_stepping == 0x7)
1081c1d935cSPrarit Bhargava 			return 1;
1091c1d935cSPrarit Bhargava 	return 0;
1101c1d935cSPrarit Bhargava }
1111c1d935cSPrarit Bhargava 
is_skx_based_platform(void)11295f8e569SSrinivas Pandruvada int is_skx_based_platform(void)
11395f8e569SSrinivas Pandruvada {
11495f8e569SSrinivas Pandruvada 	if (cpu_model == 0x55)
11595f8e569SSrinivas Pandruvada 		return 1;
11695f8e569SSrinivas Pandruvada 
11795f8e569SSrinivas Pandruvada 	return 0;
11895f8e569SSrinivas Pandruvada }
11995f8e569SSrinivas Pandruvada 
is_spr_platform(void)120159f130fSSrinivas Pandruvada int is_spr_platform(void)
121159f130fSSrinivas Pandruvada {
1221d54b139SSrinivas Pandruvada 	if (cpu_model == 0x8F)
123159f130fSSrinivas Pandruvada 		return 1;
124159f130fSSrinivas Pandruvada 
125159f130fSSrinivas Pandruvada 	return 0;
126159f130fSSrinivas Pandruvada }
127159f130fSSrinivas Pandruvada 
is_emr_platform(void)1281d54b139SSrinivas Pandruvada int is_emr_platform(void)
1291d54b139SSrinivas Pandruvada {
1301d54b139SSrinivas Pandruvada 	if (cpu_model == 0xCF)
1311d54b139SSrinivas Pandruvada 		return 1;
1321d54b139SSrinivas Pandruvada 
1331d54b139SSrinivas Pandruvada 	return 0;
1341d54b139SSrinivas Pandruvada }
1351d54b139SSrinivas Pandruvada 
1361d54b139SSrinivas Pandruvada 
is_icx_platform(void)137159f130fSSrinivas Pandruvada int is_icx_platform(void)
138159f130fSSrinivas Pandruvada {
139159f130fSSrinivas Pandruvada 	if (cpu_model == 0x6A || cpu_model == 0x6C)
140159f130fSSrinivas Pandruvada 		return 1;
141159f130fSSrinivas Pandruvada 
142159f130fSSrinivas Pandruvada 	return 0;
143159f130fSSrinivas Pandruvada }
144159f130fSSrinivas Pandruvada 
update_cpu_model(void)1451c1d935cSPrarit Bhargava static int update_cpu_model(void)
1463fb4f7cdSSrinivas Pandruvada {
1473fb4f7cdSSrinivas Pandruvada 	unsigned int ebx, ecx, edx;
1483fb4f7cdSSrinivas Pandruvada 	unsigned int fms, family;
1493fb4f7cdSSrinivas Pandruvada 
1503fb4f7cdSSrinivas Pandruvada 	__cpuid(1, fms, ebx, ecx, edx);
1513fb4f7cdSSrinivas Pandruvada 	family = (fms >> 8) & 0xf;
1523fb4f7cdSSrinivas Pandruvada 	cpu_model = (fms >> 4) & 0xf;
1533fb4f7cdSSrinivas Pandruvada 	if (family == 6 || family == 0xf)
1543fb4f7cdSSrinivas Pandruvada 		cpu_model += ((fms >> 16) & 0xf) << 4;
1551c1d935cSPrarit Bhargava 
1561c1d935cSPrarit Bhargava 	cpu_stepping = fms & 0xf;
1571c1d935cSPrarit Bhargava 	/* only three CascadeLake-N models are supported */
1581c1d935cSPrarit Bhargava 	if (is_clx_n_platform()) {
1591c1d935cSPrarit Bhargava 		FILE *fp;
1601c1d935cSPrarit Bhargava 		size_t n = 0;
1611c1d935cSPrarit Bhargava 		char *line = NULL;
1621c1d935cSPrarit Bhargava 		int ret = 1;
1631c1d935cSPrarit Bhargava 
1641c1d935cSPrarit Bhargava 		fp = fopen("/proc/cpuinfo", "r");
1651c1d935cSPrarit Bhargava 		if (!fp)
1661c1d935cSPrarit Bhargava 			err(-1, "cannot open /proc/cpuinfo\n");
1671c1d935cSPrarit Bhargava 
1681c1d935cSPrarit Bhargava 		while (getline(&line, &n, fp) > 0) {
1691c1d935cSPrarit Bhargava 			if (strstr(line, "model name")) {
1701c1d935cSPrarit Bhargava 				if (strstr(line, "6252N") ||
1711c1d935cSPrarit Bhargava 				    strstr(line, "6230N") ||
1721c1d935cSPrarit Bhargava 				    strstr(line, "5218N"))
1731c1d935cSPrarit Bhargava 					ret = 0;
1741c1d935cSPrarit Bhargava 				break;
1751c1d935cSPrarit Bhargava 			}
1761c1d935cSPrarit Bhargava 		}
1771c1d935cSPrarit Bhargava 		free(line);
1781c1d935cSPrarit Bhargava 		fclose(fp);
1791c1d935cSPrarit Bhargava 		return ret;
1801c1d935cSPrarit Bhargava 	}
1811c1d935cSPrarit Bhargava 	return 0;
1823fb4f7cdSSrinivas Pandruvada }
1833fb4f7cdSSrinivas Pandruvada 
api_version(void)184887e5be9SZhang Rui int api_version(void)
185887e5be9SZhang Rui {
186887e5be9SZhang Rui         return isst_platform_info.api_version;
187887e5be9SZhang Rui }
188887e5be9SZhang Rui 
1893fb4f7cdSSrinivas Pandruvada /* Open a file, and exit on failure */
fopen_or_exit(const char * path,const char * mode)1903fb4f7cdSSrinivas Pandruvada static FILE *fopen_or_exit(const char *path, const char *mode)
1913fb4f7cdSSrinivas Pandruvada {
1923fb4f7cdSSrinivas Pandruvada 	FILE *filep = fopen(path, mode);
1933fb4f7cdSSrinivas Pandruvada 
1943fb4f7cdSSrinivas Pandruvada 	if (!filep)
1953fb4f7cdSSrinivas Pandruvada 		err(1, "%s: open failed", path);
1963fb4f7cdSSrinivas Pandruvada 
1973fb4f7cdSSrinivas Pandruvada 	return filep;
1983fb4f7cdSSrinivas Pandruvada }
1993fb4f7cdSSrinivas Pandruvada 
2003fb4f7cdSSrinivas Pandruvada /* Parse a file containing a single int */
parse_int_file(int fatal,const char * fmt,...)2013fb4f7cdSSrinivas Pandruvada static int parse_int_file(int fatal, const char *fmt, ...)
2023fb4f7cdSSrinivas Pandruvada {
2033fb4f7cdSSrinivas Pandruvada 	va_list args;
2043fb4f7cdSSrinivas Pandruvada 	char path[PATH_MAX];
2053fb4f7cdSSrinivas Pandruvada 	FILE *filep;
2063fb4f7cdSSrinivas Pandruvada 	int value;
2073fb4f7cdSSrinivas Pandruvada 
2083fb4f7cdSSrinivas Pandruvada 	va_start(args, fmt);
2093fb4f7cdSSrinivas Pandruvada 	vsnprintf(path, sizeof(path), fmt, args);
2103fb4f7cdSSrinivas Pandruvada 	va_end(args);
2113fb4f7cdSSrinivas Pandruvada 	if (fatal) {
2123fb4f7cdSSrinivas Pandruvada 		filep = fopen_or_exit(path, "r");
2133fb4f7cdSSrinivas Pandruvada 	} else {
2143fb4f7cdSSrinivas Pandruvada 		filep = fopen(path, "r");
2153fb4f7cdSSrinivas Pandruvada 		if (!filep)
2163fb4f7cdSSrinivas Pandruvada 			return -1;
2173fb4f7cdSSrinivas Pandruvada 	}
2183fb4f7cdSSrinivas Pandruvada 	if (fscanf(filep, "%d", &value) != 1)
2193fb4f7cdSSrinivas Pandruvada 		err(1, "%s: failed to parse number from file", path);
2203fb4f7cdSSrinivas Pandruvada 	fclose(filep);
2213fb4f7cdSSrinivas Pandruvada 
2223fb4f7cdSSrinivas Pandruvada 	return value;
2233fb4f7cdSSrinivas Pandruvada }
2243fb4f7cdSSrinivas Pandruvada 
cpufreq_sysfs_present(void)2253fb4f7cdSSrinivas Pandruvada int cpufreq_sysfs_present(void)
2263fb4f7cdSSrinivas Pandruvada {
2273fb4f7cdSSrinivas Pandruvada 	DIR *dir;
2283fb4f7cdSSrinivas Pandruvada 
2293fb4f7cdSSrinivas Pandruvada 	dir = opendir("/sys/devices/system/cpu/cpu0/cpufreq");
2303fb4f7cdSSrinivas Pandruvada 	if (dir) {
2313fb4f7cdSSrinivas Pandruvada 		closedir(dir);
2323fb4f7cdSSrinivas Pandruvada 		return 1;
2333fb4f7cdSSrinivas Pandruvada 	}
2343fb4f7cdSSrinivas Pandruvada 
2353fb4f7cdSSrinivas Pandruvada 	return 0;
2363fb4f7cdSSrinivas Pandruvada }
2373fb4f7cdSSrinivas Pandruvada 
out_format_is_json(void)2383fb4f7cdSSrinivas Pandruvada int out_format_is_json(void)
2393fb4f7cdSSrinivas Pandruvada {
2403fb4f7cdSSrinivas Pandruvada 	return out_format_json;
2413fb4f7cdSSrinivas Pandruvada }
2423fb4f7cdSSrinivas Pandruvada 
get_stored_topology_info(int cpu,int * core_id,int * pkg_id,int * die_id)243fb186158SSrinivas Pandruvada static int get_stored_topology_info(int cpu, int *core_id, int *pkg_id, int *die_id)
244fb186158SSrinivas Pandruvada {
245b1d12cefSSrinivas Pandruvada 	const char *pathname = "/var/run/isst_cpu_topology.dat";
246fb186158SSrinivas Pandruvada 	struct cpu_topology cpu_top;
247fb186158SSrinivas Pandruvada 	FILE *fp;
248fb186158SSrinivas Pandruvada 	int ret;
249fb186158SSrinivas Pandruvada 
250fb186158SSrinivas Pandruvada 	fp = fopen(pathname, "rb");
251fb186158SSrinivas Pandruvada 	if (!fp)
252fb186158SSrinivas Pandruvada 		return -1;
253fb186158SSrinivas Pandruvada 
254fb186158SSrinivas Pandruvada 	ret = fseek(fp, cpu * sizeof(cpu_top), SEEK_SET);
255fb186158SSrinivas Pandruvada 	if (ret)
256fb186158SSrinivas Pandruvada 		goto err_ret;
257fb186158SSrinivas Pandruvada 
258fb186158SSrinivas Pandruvada 	ret = fread(&cpu_top, sizeof(cpu_top), 1, fp);
259fb186158SSrinivas Pandruvada 	if (ret != 1) {
260fb186158SSrinivas Pandruvada 		ret = -1;
261fb186158SSrinivas Pandruvada 		goto err_ret;
262fb186158SSrinivas Pandruvada 	}
263fb186158SSrinivas Pandruvada 
264fb186158SSrinivas Pandruvada 	*pkg_id = cpu_top.pkg_id;
265fb186158SSrinivas Pandruvada 	*core_id = cpu_top.core_id;
266fb186158SSrinivas Pandruvada 	*die_id = cpu_top.die_id;
267fb186158SSrinivas Pandruvada 	ret = 0;
268fb186158SSrinivas Pandruvada 
269fb186158SSrinivas Pandruvada err_ret:
270fb186158SSrinivas Pandruvada 	fclose(fp);
271fb186158SSrinivas Pandruvada 
272fb186158SSrinivas Pandruvada 	return ret;
273fb186158SSrinivas Pandruvada }
274fb186158SSrinivas Pandruvada 
store_cpu_topology(void)275fb186158SSrinivas Pandruvada static void store_cpu_topology(void)
276fb186158SSrinivas Pandruvada {
277b1d12cefSSrinivas Pandruvada 	const char *pathname = "/var/run/isst_cpu_topology.dat";
278fb186158SSrinivas Pandruvada 	FILE *fp;
279fb186158SSrinivas Pandruvada 	int i;
280fb186158SSrinivas Pandruvada 
281fb186158SSrinivas Pandruvada 	fp = fopen(pathname, "rb");
282fb186158SSrinivas Pandruvada 	if (fp) {
283fb186158SSrinivas Pandruvada 		/* Mapping already exists */
284fb186158SSrinivas Pandruvada 		fclose(fp);
285fb186158SSrinivas Pandruvada 		return;
286fb186158SSrinivas Pandruvada 	}
287fb186158SSrinivas Pandruvada 
288fb186158SSrinivas Pandruvada 	fp = fopen(pathname, "wb");
289fb186158SSrinivas Pandruvada 	if (!fp) {
290fb186158SSrinivas Pandruvada 		fprintf(stderr, "Can't create file:%s\n", pathname);
291fb186158SSrinivas Pandruvada 		return;
292fb186158SSrinivas Pandruvada 	}
293fb186158SSrinivas Pandruvada 
294b1d12cefSSrinivas Pandruvada 	fprintf(stderr, "Caching topology information\n");
295b1d12cefSSrinivas Pandruvada 
296fb186158SSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
297fb186158SSrinivas Pandruvada 		struct cpu_topology cpu_top;
298fb186158SSrinivas Pandruvada 
299fb186158SSrinivas Pandruvada 		cpu_top.core_id = parse_int_file(0,
300fb186158SSrinivas Pandruvada 			"/sys/devices/system/cpu/cpu%d/topology/core_id", i);
301fb186158SSrinivas Pandruvada 		if (cpu_top.core_id < 0)
302fb186158SSrinivas Pandruvada 			cpu_top.core_id = -1;
303fb186158SSrinivas Pandruvada 
304fb186158SSrinivas Pandruvada 		cpu_top.pkg_id = parse_int_file(0,
305fb186158SSrinivas Pandruvada 			"/sys/devices/system/cpu/cpu%d/topology/physical_package_id", i);
306fb186158SSrinivas Pandruvada 		if (cpu_top.pkg_id < 0)
307fb186158SSrinivas Pandruvada 			cpu_top.pkg_id = -1;
308fb186158SSrinivas Pandruvada 
309fb186158SSrinivas Pandruvada 		cpu_top.die_id = parse_int_file(0,
310fb186158SSrinivas Pandruvada 			"/sys/devices/system/cpu/cpu%d/topology/die_id", i);
311fb186158SSrinivas Pandruvada 		if (cpu_top.die_id < 0)
312fb186158SSrinivas Pandruvada 			cpu_top.die_id = -1;
313fb186158SSrinivas Pandruvada 
314fb186158SSrinivas Pandruvada 		cpu_top.cpu = i;
315fb186158SSrinivas Pandruvada 
316fb186158SSrinivas Pandruvada 		if (fwrite(&cpu_top, sizeof(cpu_top), 1, fp) != 1) {
317fb186158SSrinivas Pandruvada 			fprintf(stderr, "Can't write to:%s\n", pathname);
318fb186158SSrinivas Pandruvada 			break;
319fb186158SSrinivas Pandruvada 		}
320fb186158SSrinivas Pandruvada 	}
321fb186158SSrinivas Pandruvada 
322fb186158SSrinivas Pandruvada 	fclose(fp);
323fb186158SSrinivas Pandruvada }
324fb186158SSrinivas Pandruvada 
get_physical_package_id(int cpu)325e616059eSZhang Rui static int get_physical_package_id(int cpu)
3263fb4f7cdSSrinivas Pandruvada {
327fb186158SSrinivas Pandruvada 	int ret;
328fb186158SSrinivas Pandruvada 
329ca56725dSZhang Rui 	if (cpu < 0)
330ca56725dSZhang Rui 		return -1;
331ca56725dSZhang Rui 
332ca56725dSZhang Rui 	if (cpu_map && cpu_map[cpu].initialized)
333ca56725dSZhang Rui 		return cpu_map[cpu].pkg_id;
334ca56725dSZhang Rui 
335fb186158SSrinivas Pandruvada 	ret = parse_int_file(0,
336fb186158SSrinivas Pandruvada 			"/sys/devices/system/cpu/cpu%d/topology/physical_package_id",
3373fb4f7cdSSrinivas Pandruvada 			cpu);
338fb186158SSrinivas Pandruvada 	if (ret < 0) {
339fb186158SSrinivas Pandruvada 		int core_id, pkg_id, die_id;
340fb186158SSrinivas Pandruvada 
341fb186158SSrinivas Pandruvada 		ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id);
342fb186158SSrinivas Pandruvada 		if (!ret)
343fb186158SSrinivas Pandruvada 			return pkg_id;
344fb186158SSrinivas Pandruvada 	}
345fb186158SSrinivas Pandruvada 
346fb186158SSrinivas Pandruvada 	return ret;
3473fb4f7cdSSrinivas Pandruvada }
3483fb4f7cdSSrinivas Pandruvada 
get_physical_core_id(int cpu)349e616059eSZhang Rui static int get_physical_core_id(int cpu)
3503fb4f7cdSSrinivas Pandruvada {
351fb186158SSrinivas Pandruvada 	int ret;
352fb186158SSrinivas Pandruvada 
353ca56725dSZhang Rui 	if (cpu < 0)
354ca56725dSZhang Rui 		return -1;
355ca56725dSZhang Rui 
356ca56725dSZhang Rui 	if (cpu_map && cpu_map[cpu].initialized)
357ca56725dSZhang Rui 		return cpu_map[cpu].core_id;
358ca56725dSZhang Rui 
359fb186158SSrinivas Pandruvada 	ret = parse_int_file(0,
360fb186158SSrinivas Pandruvada 			"/sys/devices/system/cpu/cpu%d/topology/core_id",
361fb186158SSrinivas Pandruvada 			cpu);
362fb186158SSrinivas Pandruvada 	if (ret < 0) {
363fb186158SSrinivas Pandruvada 		int core_id, pkg_id, die_id;
364fb186158SSrinivas Pandruvada 
365fb186158SSrinivas Pandruvada 		ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id);
366fb186158SSrinivas Pandruvada 		if (!ret)
367fb186158SSrinivas Pandruvada 			return core_id;
368fb186158SSrinivas Pandruvada 	}
369fb186158SSrinivas Pandruvada 
370fb186158SSrinivas Pandruvada 	return ret;
3713fb4f7cdSSrinivas Pandruvada }
3723fb4f7cdSSrinivas Pandruvada 
get_physical_die_id(int cpu)373e616059eSZhang Rui static int get_physical_die_id(int cpu)
3743fb4f7cdSSrinivas Pandruvada {
3753fb4f7cdSSrinivas Pandruvada 	int ret;
3763fb4f7cdSSrinivas Pandruvada 
377ca56725dSZhang Rui 	if (cpu < 0)
378ca56725dSZhang Rui 		return -1;
379ca56725dSZhang Rui 
380ca56725dSZhang Rui 	if (cpu_map && cpu_map[cpu].initialized)
381ca56725dSZhang Rui 		return cpu_map[cpu].die_id;
382ca56725dSZhang Rui 
383fb186158SSrinivas Pandruvada 	ret = parse_int_file(0,
384fb186158SSrinivas Pandruvada 			"/sys/devices/system/cpu/cpu%d/topology/die_id",
3853fb4f7cdSSrinivas Pandruvada 			cpu);
386fb186158SSrinivas Pandruvada 	if (ret < 0) {
387fb186158SSrinivas Pandruvada 		int core_id, pkg_id, die_id;
388fb186158SSrinivas Pandruvada 
389fb186158SSrinivas Pandruvada 		ret = get_stored_topology_info(cpu, &core_id, &pkg_id, &die_id);
3906c483225SSrinivas Pandruvada 		if (!ret) {
3916c483225SSrinivas Pandruvada 			if (die_id < 0)
3926c483225SSrinivas Pandruvada 				die_id = 0;
3936c483225SSrinivas Pandruvada 
394fb186158SSrinivas Pandruvada 			return die_id;
395fb186158SSrinivas Pandruvada 		}
3966c483225SSrinivas Pandruvada 	}
397fb186158SSrinivas Pandruvada 
3983fb4f7cdSSrinivas Pandruvada 	if (ret < 0)
3993fb4f7cdSSrinivas Pandruvada 		ret = 0;
4003fb4f7cdSSrinivas Pandruvada 
4013fb4f7cdSSrinivas Pandruvada 	return ret;
4023fb4f7cdSSrinivas Pandruvada }
4033fb4f7cdSSrinivas Pandruvada 
get_physical_punit_id(int cpu)404e157c847SZhang Rui static int get_physical_punit_id(int cpu)
405e157c847SZhang Rui {
406e157c847SZhang Rui 	if (cpu < 0)
407e157c847SZhang Rui 		return -1;
408e157c847SZhang Rui 
409e157c847SZhang Rui 	if (cpu_map && cpu_map[cpu].initialized)
410e157c847SZhang Rui 		return cpu_map[cpu].punit_id;
411e157c847SZhang Rui 
412e157c847SZhang Rui 	return -1;
413e157c847SZhang Rui }
414e157c847SZhang Rui 
set_isst_id(struct isst_id * id,int cpu)415850337ecSZhang Rui void set_isst_id(struct isst_id *id, int cpu)
416850337ecSZhang Rui {
417850337ecSZhang Rui 	id->cpu = cpu;
4183ba6a275SZhang Rui 
41932d6ab45SZhang Rui 	id->pkg = get_physical_package_id(cpu);
420507fa17aSZhang Rui 	if (id->pkg >= MAX_PACKAGE_COUNT)
4213ba6a275SZhang Rui 		id->pkg = -1;
4223ba6a275SZhang Rui 
42332d6ab45SZhang Rui 	id->die = get_physical_die_id(cpu);
424507fa17aSZhang Rui 	if (id->die >= MAX_DIE_PER_PACKAGE)
4253ba6a275SZhang Rui 		id->die = -1;
426e157c847SZhang Rui 
427e157c847SZhang Rui 	id->punit = get_physical_punit_id(cpu);
428e157c847SZhang Rui 	if (id->punit >= MAX_PUNIT_PER_DIE)
429e157c847SZhang Rui 		id->punit = -1;
430850337ecSZhang Rui }
431850337ecSZhang Rui 
is_cpu_in_power_domain(int cpu,struct isst_id * id)43200bb07dbSZhang Rui int is_cpu_in_power_domain(int cpu, struct isst_id *id)
43300bb07dbSZhang Rui {
43400bb07dbSZhang Rui 	struct isst_id tid;
43500bb07dbSZhang Rui 
43600bb07dbSZhang Rui 	set_isst_id(&tid, cpu);
43700bb07dbSZhang Rui 
438e157c847SZhang Rui 	if (id->pkg == tid.pkg && id->die == tid.die && id->punit == tid.punit)
43900bb07dbSZhang Rui 		return 1;
44000bb07dbSZhang Rui 
44100bb07dbSZhang Rui 	return 0;
44200bb07dbSZhang Rui }
44300bb07dbSZhang Rui 
get_cpufreq_base_freq(int cpu)4447af5a95bSSrinivas Pandruvada int get_cpufreq_base_freq(int cpu)
4457af5a95bSSrinivas Pandruvada {
4467af5a95bSSrinivas Pandruvada 	return parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", cpu);
4477af5a95bSSrinivas Pandruvada }
4487af5a95bSSrinivas Pandruvada 
get_topo_max_cpus(void)4493fb4f7cdSSrinivas Pandruvada int get_topo_max_cpus(void)
4503fb4f7cdSSrinivas Pandruvada {
4513fb4f7cdSSrinivas Pandruvada 	return topo_max_cpus;
4523fb4f7cdSSrinivas Pandruvada }
4533fb4f7cdSSrinivas Pandruvada 
is_cpu_online(int cpu)454cf3b8e8fSSrinivas Pandruvada static unsigned int is_cpu_online(int cpu)
455cf3b8e8fSSrinivas Pandruvada {
456cf3b8e8fSSrinivas Pandruvada 	char buffer[128];
457cf3b8e8fSSrinivas Pandruvada 	int fd, ret;
458cf3b8e8fSSrinivas Pandruvada 	unsigned char online;
459cf3b8e8fSSrinivas Pandruvada 
460cf3b8e8fSSrinivas Pandruvada 	snprintf(buffer, sizeof(buffer),
461cf3b8e8fSSrinivas Pandruvada 		 "/sys/devices/system/cpu/cpu%d/online", cpu);
462cf3b8e8fSSrinivas Pandruvada 
463cf3b8e8fSSrinivas Pandruvada 	fd = open(buffer, O_RDONLY);
464cf3b8e8fSSrinivas Pandruvada 	if (fd < 0)
465cf3b8e8fSSrinivas Pandruvada 		return fd;
466cf3b8e8fSSrinivas Pandruvada 
467cf3b8e8fSSrinivas Pandruvada 	ret = read(fd, &online, sizeof(online));
468cf3b8e8fSSrinivas Pandruvada 	close(fd);
469cf3b8e8fSSrinivas Pandruvada 
470cf3b8e8fSSrinivas Pandruvada 	if (ret == -1)
471cf3b8e8fSSrinivas Pandruvada 		return ret;
472cf3b8e8fSSrinivas Pandruvada 
473cf3b8e8fSSrinivas Pandruvada 	if (online == '1')
474cf3b8e8fSSrinivas Pandruvada 		online = 1;
475cf3b8e8fSSrinivas Pandruvada 	else
476cf3b8e8fSSrinivas Pandruvada 		online = 0;
477cf3b8e8fSSrinivas Pandruvada 
478cf3b8e8fSSrinivas Pandruvada 	return online;
479cf3b8e8fSSrinivas Pandruvada }
480cf3b8e8fSSrinivas Pandruvada 
set_cpu_online_offline(int cpu,int state)4817fd786dfSSrinivas Pandruvada void set_cpu_online_offline(int cpu, int state)
4823c64c81aSSrinivas Pandruvada {
4833c64c81aSSrinivas Pandruvada 	char buffer[128];
484abd120e3SSrinivas Pandruvada 	int fd, ret;
4853c64c81aSSrinivas Pandruvada 
4863bc0f20aSSrinivas Pandruvada 	if (cpu_0_cgroupv2 && !cpu) {
4873bc0f20aSSrinivas Pandruvada 		fprintf(stderr, "Will use cgroup v2 for CPU 0\n");
4883bc0f20aSSrinivas Pandruvada 		cpu_0_workaround(!state);
48901bcb56fSSrinivas Pandruvada 		return;
49001bcb56fSSrinivas Pandruvada 	}
49101bcb56fSSrinivas Pandruvada 
4923c64c81aSSrinivas Pandruvada 	snprintf(buffer, sizeof(buffer),
4933c64c81aSSrinivas Pandruvada 		 "/sys/devices/system/cpu/cpu%d/online", cpu);
4943c64c81aSSrinivas Pandruvada 
4953c64c81aSSrinivas Pandruvada 	fd = open(buffer, O_WRONLY);
49669669198SSrinivas Pandruvada 	if (fd < 0) {
4973bc0f20aSSrinivas Pandruvada 		if (!cpu) {
49869669198SSrinivas Pandruvada 			fprintf(stderr, "This system is not configured for CPU 0 online/offline\n");
4993bc0f20aSSrinivas Pandruvada 			fprintf(stderr, "Will use cgroup v2\n");
5003bc0f20aSSrinivas Pandruvada 			cpu_0_workaround(!state);
50169669198SSrinivas Pandruvada 			return;
50269669198SSrinivas Pandruvada 		}
5033c64c81aSSrinivas Pandruvada 		err(-1, "%s open failed", buffer);
50469669198SSrinivas Pandruvada 	}
5053c64c81aSSrinivas Pandruvada 
5063c64c81aSSrinivas Pandruvada 	if (state)
507abd120e3SSrinivas Pandruvada 		ret = write(fd, "1\n", 2);
5083c64c81aSSrinivas Pandruvada 	else
509abd120e3SSrinivas Pandruvada 		ret = write(fd, "0\n", 2);
510abd120e3SSrinivas Pandruvada 
511abd120e3SSrinivas Pandruvada 	if (ret == -1)
512abd120e3SSrinivas Pandruvada 		perror("Online/Offline: Operation failed\n");
5133c64c81aSSrinivas Pandruvada 
5143c64c81aSSrinivas Pandruvada 	close(fd);
5153c64c81aSSrinivas Pandruvada }
5163c64c81aSSrinivas Pandruvada 
force_all_cpus_online(void)5170d3dfd75SSrinivas Pandruvada static void force_all_cpus_online(void)
5180d3dfd75SSrinivas Pandruvada {
5190d3dfd75SSrinivas Pandruvada 	int i;
5200d3dfd75SSrinivas Pandruvada 
5210d3dfd75SSrinivas Pandruvada 	fprintf(stderr, "Forcing all CPUs online\n");
5220d3dfd75SSrinivas Pandruvada 
5230d3dfd75SSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i)
5240d3dfd75SSrinivas Pandruvada 		set_cpu_online_offline(i, 1);
5250d3dfd75SSrinivas Pandruvada 
5260d3dfd75SSrinivas Pandruvada 	unlink("/var/run/isst_cpu_topology.dat");
5270d3dfd75SSrinivas Pandruvada }
5280d3dfd75SSrinivas Pandruvada 
for_each_online_power_domain_in_set(void (* callback)(struct isst_id *,void *,void *,void *,void *),void * arg1,void * arg2,void * arg3,void * arg4)529c77a8d4aSZhang Rui void for_each_online_power_domain_in_set(void (*callback)(struct isst_id *, void *, void *,
5303fb4f7cdSSrinivas Pandruvada 						     void *, void *),
5313fb4f7cdSSrinivas Pandruvada 				    void *arg1, void *arg2, void *arg3,
5323fb4f7cdSSrinivas Pandruvada 				    void *arg4)
5333fb4f7cdSSrinivas Pandruvada {
534850337ecSZhang Rui 	struct isst_id id;
535b4edf385SZhang Rui 	int cpus[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE];
536b4edf385SZhang Rui 	int valid_mask[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE] = {0};
537b4edf385SZhang Rui 	int i, j, k;
5383fb4f7cdSSrinivas Pandruvada 
539b4edf385SZhang Rui 	memset(cpus, -1, sizeof(cpus));
540b4edf385SZhang Rui 
5413fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
542b4edf385SZhang Rui 		int online;
5433fb4f7cdSSrinivas Pandruvada 
5443fb4f7cdSSrinivas Pandruvada 		if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
5453fb4f7cdSSrinivas Pandruvada 			continue;
546b4edf385SZhang Rui 
5473fb4f7cdSSrinivas Pandruvada 		online = parse_int_file(
548b4edf385SZhang Rui 			i != 0, "/sys/devices/system/cpu/cpu%d/online", i);
549b4edf385SZhang Rui 		if (online < 0)
550b4edf385SZhang Rui 			online = 1; /* online entry for CPU 0 needs some special configs */
5513fb4f7cdSSrinivas Pandruvada 
552b4edf385SZhang Rui 		if (!online)
553f0e0b4d1SSrinivas Pandruvada 			continue;
554fb186158SSrinivas Pandruvada 
555850337ecSZhang Rui 		set_isst_id(&id, i);
556b4edf385SZhang Rui 
557b4edf385SZhang Rui 		if (id.pkg < 0 || id.die < 0 || id.punit < 0)
558b4edf385SZhang Rui 			continue;
559b4edf385SZhang Rui 
560b4edf385SZhang Rui 		valid_mask[id.pkg][id.die] = 1;
561b4edf385SZhang Rui 
562b4edf385SZhang Rui 		if (cpus[id.pkg][id.die][id.punit] == -1)
563b4edf385SZhang Rui 			cpus[id.pkg][id.die][id.punit] = i;
564b4edf385SZhang Rui 	}
565b4edf385SZhang Rui 
566b4edf385SZhang Rui 	for (i = 0; i < MAX_PACKAGE_COUNT; i++) {
567f9264471SSrinivas Pandruvada 		if (max_die_id == max_punit_id) {
568f9264471SSrinivas Pandruvada 			for (k = 0; k < MAX_PUNIT_PER_DIE && k < MAX_DIE_PER_PACKAGE; k++) {
569f9264471SSrinivas Pandruvada 				id.cpu = cpus[i][k][k];
570f9264471SSrinivas Pandruvada 				id.pkg = i;
571f9264471SSrinivas Pandruvada 				id.die = k;
572f9264471SSrinivas Pandruvada 				id.punit = k;
573f9264471SSrinivas Pandruvada 				if (isst_is_punit_valid(&id))
574f9264471SSrinivas Pandruvada 					callback(&id, arg1, arg2, arg3, arg4);
575f9264471SSrinivas Pandruvada 			}
576f9264471SSrinivas Pandruvada 			continue;
577f9264471SSrinivas Pandruvada 		}
578f9264471SSrinivas Pandruvada 
579b4edf385SZhang Rui 		for (j = 0; j < MAX_DIE_PER_PACKAGE; j++) {
580b4edf385SZhang Rui 			/*
581b4edf385SZhang Rui 			 * Fix me:
582b4edf385SZhang Rui 			 * How to check a non-cpu die for a package/die with all cpu offlined?
583b4edf385SZhang Rui 			 */
584b4edf385SZhang Rui 			if (!valid_mask[i][j])
585b4edf385SZhang Rui 				continue;
586b4edf385SZhang Rui 			for (k = 0; k < MAX_PUNIT_PER_DIE; k++) {
587b4edf385SZhang Rui 				id.cpu = cpus[i][j][k];
588b4edf385SZhang Rui 				id.pkg = i;
589b4edf385SZhang Rui 				id.die = j;
590b4edf385SZhang Rui 				id.punit = k;
591b4edf385SZhang Rui 				if (isst_is_punit_valid(&id))
592850337ecSZhang Rui 					callback(&id, arg1, arg2, arg3, arg4);
593b4edf385SZhang Rui 			}
5943fb4f7cdSSrinivas Pandruvada 		}
5953fb4f7cdSSrinivas Pandruvada 	}
5963fb4f7cdSSrinivas Pandruvada }
5973fb4f7cdSSrinivas Pandruvada 
for_each_online_target_cpu_in_set(void (* callback)(struct isst_id *,void *,void *,void *,void *),void * arg1,void * arg2,void * arg3,void * arg4)5983fb4f7cdSSrinivas Pandruvada static void for_each_online_target_cpu_in_set(
599850337ecSZhang Rui 	void (*callback)(struct isst_id *, void *, void *, void *, void *), void *arg1,
6003fb4f7cdSSrinivas Pandruvada 	void *arg2, void *arg3, void *arg4)
6013fb4f7cdSSrinivas Pandruvada {
602070fdea1SSrinivas Pandruvada 	int i, found = 0;
603850337ecSZhang Rui 	struct isst_id id;
6043fb4f7cdSSrinivas Pandruvada 
6053fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
6063fb4f7cdSSrinivas Pandruvada 		int online;
6073fb4f7cdSSrinivas Pandruvada 
6083fb4f7cdSSrinivas Pandruvada 		if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask))
6093fb4f7cdSSrinivas Pandruvada 			continue;
6103fb4f7cdSSrinivas Pandruvada 		if (i)
6113fb4f7cdSSrinivas Pandruvada 			online = parse_int_file(
6123fb4f7cdSSrinivas Pandruvada 				1, "/sys/devices/system/cpu/cpu%d/online", i);
6133fb4f7cdSSrinivas Pandruvada 		else
6143fb4f7cdSSrinivas Pandruvada 			online =
6153fb4f7cdSSrinivas Pandruvada 				1; /* online entry for CPU 0 needs some special configs */
6163fb4f7cdSSrinivas Pandruvada 
617850337ecSZhang Rui 		set_isst_id(&id, i);
618070fdea1SSrinivas Pandruvada 		if (online && callback) {
619850337ecSZhang Rui 			callback(&id, arg1, arg2, arg3, arg4);
620070fdea1SSrinivas Pandruvada 			found = 1;
6213fb4f7cdSSrinivas Pandruvada 		}
6223fb4f7cdSSrinivas Pandruvada 	}
6233fb4f7cdSSrinivas Pandruvada 
624070fdea1SSrinivas Pandruvada 	if (!found)
625070fdea1SSrinivas Pandruvada 		fprintf(stderr, "No valid CPU in the list\n");
626070fdea1SSrinivas Pandruvada }
627070fdea1SSrinivas Pandruvada 
6283fb4f7cdSSrinivas Pandruvada #define BITMASK_SIZE 32
set_max_cpu_num(void)6293fb4f7cdSSrinivas Pandruvada static void set_max_cpu_num(void)
6303fb4f7cdSSrinivas Pandruvada {
6313fb4f7cdSSrinivas Pandruvada 	FILE *filep;
6323fb4f7cdSSrinivas Pandruvada 	unsigned long dummy;
633864dc09eSSrinivas Pandruvada 	int i;
6343fb4f7cdSSrinivas Pandruvada 
6353fb4f7cdSSrinivas Pandruvada 	topo_max_cpus = 0;
636864dc09eSSrinivas Pandruvada 	for (i = 0; i < 256; ++i) {
637864dc09eSSrinivas Pandruvada 		char path[256];
638864dc09eSSrinivas Pandruvada 
639864dc09eSSrinivas Pandruvada 		snprintf(path, sizeof(path),
640864dc09eSSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", i);
641864dc09eSSrinivas Pandruvada 		filep = fopen(path, "r");
642864dc09eSSrinivas Pandruvada 		if (filep)
643864dc09eSSrinivas Pandruvada 			break;
644864dc09eSSrinivas Pandruvada 	}
645864dc09eSSrinivas Pandruvada 
646864dc09eSSrinivas Pandruvada 	if (!filep) {
647864dc09eSSrinivas Pandruvada 		fprintf(stderr, "Can't get max cpu number\n");
648864dc09eSSrinivas Pandruvada 		exit(0);
649864dc09eSSrinivas Pandruvada 	}
650864dc09eSSrinivas Pandruvada 
6513fb4f7cdSSrinivas Pandruvada 	while (fscanf(filep, "%lx,", &dummy) == 1)
6523fb4f7cdSSrinivas Pandruvada 		topo_max_cpus += BITMASK_SIZE;
6533fb4f7cdSSrinivas Pandruvada 	fclose(filep);
6543fb4f7cdSSrinivas Pandruvada 
6553fb4f7cdSSrinivas Pandruvada 	debug_printf("max cpus %d\n", topo_max_cpus);
6563fb4f7cdSSrinivas Pandruvada }
6573fb4f7cdSSrinivas Pandruvada 
alloc_cpu_set(cpu_set_t ** cpu_set)6583fb4f7cdSSrinivas Pandruvada size_t alloc_cpu_set(cpu_set_t **cpu_set)
6593fb4f7cdSSrinivas Pandruvada {
6603fb4f7cdSSrinivas Pandruvada 	cpu_set_t *_cpu_set;
6613fb4f7cdSSrinivas Pandruvada 	size_t size;
6623fb4f7cdSSrinivas Pandruvada 
6633fb4f7cdSSrinivas Pandruvada 	_cpu_set = CPU_ALLOC((topo_max_cpus + 1));
6643fb4f7cdSSrinivas Pandruvada 	if (_cpu_set == NULL)
6653fb4f7cdSSrinivas Pandruvada 		err(3, "CPU_ALLOC");
6663fb4f7cdSSrinivas Pandruvada 	size = CPU_ALLOC_SIZE((topo_max_cpus + 1));
6673fb4f7cdSSrinivas Pandruvada 	CPU_ZERO_S(size, _cpu_set);
6683fb4f7cdSSrinivas Pandruvada 
6693fb4f7cdSSrinivas Pandruvada 	*cpu_set = _cpu_set;
6703fb4f7cdSSrinivas Pandruvada 	return size;
6713fb4f7cdSSrinivas Pandruvada }
6723fb4f7cdSSrinivas Pandruvada 
free_cpu_set(cpu_set_t * cpu_set)6733fb4f7cdSSrinivas Pandruvada void free_cpu_set(cpu_set_t *cpu_set)
6743fb4f7cdSSrinivas Pandruvada {
6753fb4f7cdSSrinivas Pandruvada 	CPU_FREE(cpu_set);
6763fb4f7cdSSrinivas Pandruvada }
6773fb4f7cdSSrinivas Pandruvada 
678b4edf385SZhang Rui static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE];
6793fb4f7cdSSrinivas Pandruvada 
get_max_punit_core_id(struct isst_id * id)68030e0600eSZhang Rui int get_max_punit_core_id(struct isst_id *id)
681de7f9d3dSSrinivas Pandruvada {
6827566616fSJonathan Doman 	int max_id = 0;
683de7f9d3dSSrinivas Pandruvada 	int i;
684de7f9d3dSSrinivas Pandruvada 
6857566616fSJonathan Doman 	for (i = 0; i < topo_max_cpus; ++i)
6867566616fSJonathan Doman 	{
6877566616fSJonathan Doman 		if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
6887566616fSJonathan Doman 			continue;
6897566616fSJonathan Doman 
69000bb07dbSZhang Rui 		if (is_cpu_in_power_domain(i, id) &&
6917566616fSJonathan Doman 		    cpu_map[i].punit_cpu_core > max_id)
6927566616fSJonathan Doman 			max_id = cpu_map[i].punit_cpu_core;
693de7f9d3dSSrinivas Pandruvada 	}
694de7f9d3dSSrinivas Pandruvada 
6957566616fSJonathan Doman 	return max_id;
696de7f9d3dSSrinivas Pandruvada }
697de7f9d3dSSrinivas Pandruvada 
get_cpu_count(struct isst_id * id)69830e0600eSZhang Rui int get_cpu_count(struct isst_id *id)
6993fb4f7cdSSrinivas Pandruvada {
700b4edf385SZhang Rui 	if (id->pkg < 0 || id->die < 0 || id->punit < 0)
7013fb4f7cdSSrinivas Pandruvada 		return 0;
7023ba6a275SZhang Rui 
703b4edf385SZhang Rui 	return cpu_cnt[id->pkg][id->die][id->punit];
7043fb4f7cdSSrinivas Pandruvada }
7053fb4f7cdSSrinivas Pandruvada 
update_punit_cpu_info(__u32 physical_cpu,struct _cpu_map * cpu_map)706a0ca5a09SSrinivas Pandruvada static void update_punit_cpu_info(__u32 physical_cpu, struct _cpu_map *cpu_map)
707a0ca5a09SSrinivas Pandruvada {
708a0ca5a09SSrinivas Pandruvada 	if (api_version() > 1) {
709a0ca5a09SSrinivas Pandruvada 		/*
710a0ca5a09SSrinivas Pandruvada 		 * MSR 0x54 format
711a0ca5a09SSrinivas Pandruvada 		 *	[15:11] PM_DOMAIN_ID
712a0ca5a09SSrinivas Pandruvada 		 *	[10:3] MODULE_ID (aka IDI_AGENT_ID)
713a0ca5a09SSrinivas Pandruvada 		 *	[2:0] LP_ID (We don't care about these bits we only
714a0ca5a09SSrinivas Pandruvada 		 *		care die and core id
715a0ca5a09SSrinivas Pandruvada 		 *	For Atom:
716a0ca5a09SSrinivas Pandruvada 		 *	[2] Always 0
717a0ca5a09SSrinivas Pandruvada 		 *	[1:0] core ID within module
718a0ca5a09SSrinivas Pandruvada 		 *	For Core
719a0ca5a09SSrinivas Pandruvada 		 *	[2:1] Always 0
720a0ca5a09SSrinivas Pandruvada 		 *	[0] thread ID
721a0ca5a09SSrinivas Pandruvada 		 */
722a0ca5a09SSrinivas Pandruvada 		cpu_map->punit_id = (physical_cpu >> 11) & 0x1f;
723a0ca5a09SSrinivas Pandruvada 		cpu_map->punit_cpu_core = (physical_cpu >> 3) & 0xff;
724a0ca5a09SSrinivas Pandruvada 		cpu_map->punit_cpu = physical_cpu & 0x7ff;
725a0ca5a09SSrinivas Pandruvada 	} else {
726a0ca5a09SSrinivas Pandruvada 		int punit_id;
727a0ca5a09SSrinivas Pandruvada 
728a0ca5a09SSrinivas Pandruvada 		/*
729a0ca5a09SSrinivas Pandruvada 		 * MSR 0x53 format
730a0ca5a09SSrinivas Pandruvada 		 * Format
731a0ca5a09SSrinivas Pandruvada 		 *      Bit 0 – thread ID
732a0ca5a09SSrinivas Pandruvada 		 *      Bit 8:1 – core ID
733a0ca5a09SSrinivas Pandruvada 		 *      Bit 13:9 – punit ID
734a0ca5a09SSrinivas Pandruvada 		 */
735a0ca5a09SSrinivas Pandruvada 		cpu_map->punit_cpu = physical_cpu & 0x1ff;
736a0ca5a09SSrinivas Pandruvada 		cpu_map->punit_cpu_core = (cpu_map->punit_cpu >> 1); // shift to get core id
737a0ca5a09SSrinivas Pandruvada 		punit_id = (physical_cpu >> 9) & 0x1f;
738a0ca5a09SSrinivas Pandruvada 
739a0ca5a09SSrinivas Pandruvada 		if (punit_id >= MAX_PUNIT_PER_DIE)
740a0ca5a09SSrinivas Pandruvada 			punit_id = 0;
741a0ca5a09SSrinivas Pandruvada 
742a0ca5a09SSrinivas Pandruvada 		cpu_map->punit_id = punit_id;
743a0ca5a09SSrinivas Pandruvada 	}
744a0ca5a09SSrinivas Pandruvada }
745a0ca5a09SSrinivas Pandruvada 
create_cpu_map(void)7463fb4f7cdSSrinivas Pandruvada static void create_cpu_map(void)
7473fb4f7cdSSrinivas Pandruvada {
7483fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
749921604b4SZhang Rui 	size_t size;
750921604b4SZhang Rui 	DIR *dir;
7513fb4f7cdSSrinivas Pandruvada 	int i, fd = 0;
7523fb4f7cdSSrinivas Pandruvada 	struct isst_if_cpu_maps map;
7533fb4f7cdSSrinivas Pandruvada 
754ca56725dSZhang Rui 	/* Use calloc to make sure the memory is initialized to Zero */
755ca56725dSZhang Rui 	cpu_map = calloc(topo_max_cpus, sizeof(*cpu_map));
7563fb4f7cdSSrinivas Pandruvada 	if (!cpu_map)
7573fb4f7cdSSrinivas Pandruvada 		err(3, "cpumap");
7583fb4f7cdSSrinivas Pandruvada 
7593fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
760ca56725dSZhang Rui 	if (fd < 0 && !is_clx_n_platform())
7613fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
7623fb4f7cdSSrinivas Pandruvada 
763921604b4SZhang Rui 	size = alloc_cpu_set(&present_cpumask);
764921604b4SZhang Rui 	present_cpumask_size = size;
765921604b4SZhang Rui 
7663fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
767921604b4SZhang Rui 		char buffer[256];
768e157c847SZhang Rui 		int pkg_id, die_id, core_id, punit_id;
769921604b4SZhang Rui 
770921604b4SZhang Rui 		/* check if CPU is online */
771921604b4SZhang Rui 		snprintf(buffer, sizeof(buffer),
772921604b4SZhang Rui 			 "/sys/devices/system/cpu/cpu%d", i);
773921604b4SZhang Rui 		dir = opendir(buffer);
774921604b4SZhang Rui 		if (!dir)
775921604b4SZhang Rui 			continue;
776921604b4SZhang Rui 		closedir(dir);
777921604b4SZhang Rui 
778921604b4SZhang Rui 		CPU_SET_S(i, size, present_cpumask);
779921604b4SZhang Rui 
780921604b4SZhang Rui 		pkg_id = get_physical_package_id(i);
781921604b4SZhang Rui 		die_id = get_physical_die_id(i);
782921604b4SZhang Rui 		core_id = get_physical_core_id(i);
783921604b4SZhang Rui 
784921604b4SZhang Rui 		if (pkg_id < 0 || die_id < 0 || core_id < 0)
7853fb4f7cdSSrinivas Pandruvada 			continue;
7863fb4f7cdSSrinivas Pandruvada 
787921604b4SZhang Rui 		cpu_map[i].pkg_id = pkg_id;
788921604b4SZhang Rui 		cpu_map[i].die_id = die_id;
789921604b4SZhang Rui 		cpu_map[i].core_id = core_id;
790ca56725dSZhang Rui 
791921604b4SZhang Rui 
792e157c847SZhang Rui 		punit_id = 0;
793e157c847SZhang Rui 
794e157c847SZhang Rui 		if (fd >= 0) {
7953fb4f7cdSSrinivas Pandruvada 			map.cmd_count = 1;
7963fb4f7cdSSrinivas Pandruvada 			map.cpu_map[0].logical_cpu = i;
7973fb4f7cdSSrinivas Pandruvada 			debug_printf(" map logical_cpu:%d\n",
7983fb4f7cdSSrinivas Pandruvada 				     map.cpu_map[0].logical_cpu);
7993fb4f7cdSSrinivas Pandruvada 			if (ioctl(fd, ISST_IF_GET_PHY_ID, &map) == -1) {
8003fb4f7cdSSrinivas Pandruvada 				perror("ISST_IF_GET_PHY_ID");
8013fb4f7cdSSrinivas Pandruvada 				fprintf(outf, "Error: map logical_cpu:%d\n",
8023fb4f7cdSSrinivas Pandruvada 					map.cpu_map[0].logical_cpu);
803e157c847SZhang Rui 			} else {
804a0ca5a09SSrinivas Pandruvada 				update_punit_cpu_info(map.cpu_map[0].physical_cpu, &cpu_map[i]);
8057a4ab2f4SSrinivas Pandruvada 				punit_id = cpu_map[i].punit_id;
806e157c847SZhang Rui 			}
807e157c847SZhang Rui 		}
808e157c847SZhang Rui 		cpu_map[i].initialized = 1;
809e157c847SZhang Rui 
810b4edf385SZhang Rui 		cpu_cnt[pkg_id][die_id][punit_id]++;
8113fb4f7cdSSrinivas Pandruvada 
812f9264471SSrinivas Pandruvada 		if (max_die_id < die_id)
813f9264471SSrinivas Pandruvada 			max_die_id = die_id;
814f9264471SSrinivas Pandruvada 
815f9264471SSrinivas Pandruvada 		if (max_punit_id < cpu_map[i].punit_id)
816f9264471SSrinivas Pandruvada 			max_punit_id = cpu_map[i].punit_id;
817f9264471SSrinivas Pandruvada 
8183fb4f7cdSSrinivas Pandruvada 		debug_printf(
819e157c847SZhang Rui 			"map logical_cpu:%d core: %d die:%d pkg:%d punit:%d punit_cpu:%d punit_core:%d\n",
8203fb4f7cdSSrinivas Pandruvada 			i, cpu_map[i].core_id, cpu_map[i].die_id,
821e157c847SZhang Rui 			cpu_map[i].pkg_id, cpu_map[i].punit_id,
822e157c847SZhang Rui 			cpu_map[i].punit_cpu, cpu_map[i].punit_cpu_core);
8233fb4f7cdSSrinivas Pandruvada 	}
824ca56725dSZhang Rui 	if (fd >= 0)
8253fb4f7cdSSrinivas Pandruvada 		close(fd);
826921604b4SZhang Rui 
827921604b4SZhang Rui 	size = alloc_cpu_set(&target_cpumask);
828921604b4SZhang Rui 	target_cpumask_size = size;
829921604b4SZhang Rui 	for (i = 0; i < max_target_cpus; ++i) {
830921604b4SZhang Rui 		if (!CPU_ISSET_S(target_cpus[i], present_cpumask_size,
831921604b4SZhang Rui 				 present_cpumask))
832921604b4SZhang Rui 			continue;
833921604b4SZhang Rui 
834921604b4SZhang Rui 		CPU_SET_S(target_cpus[i], size, target_cpumask);
835921604b4SZhang Rui 	}
8363fb4f7cdSSrinivas Pandruvada }
8373fb4f7cdSSrinivas Pandruvada 
set_cpu_mask_from_punit_coremask(struct isst_id * id,unsigned long long core_mask,size_t core_cpumask_size,cpu_set_t * core_cpumask,int * cpu_cnt)838850337ecSZhang Rui void set_cpu_mask_from_punit_coremask(struct isst_id *id, unsigned long long core_mask,
8393fb4f7cdSSrinivas Pandruvada 				      size_t core_cpumask_size,
8403fb4f7cdSSrinivas Pandruvada 				      cpu_set_t *core_cpumask, int *cpu_cnt)
8413fb4f7cdSSrinivas Pandruvada {
8423fb4f7cdSSrinivas Pandruvada 	int i, cnt = 0;
8433fb4f7cdSSrinivas Pandruvada 
844d0e12c46SZhang Rui 	if (id->cpu < 0)
845d0e12c46SZhang Rui 		return;
846d0e12c46SZhang Rui 
8473fb4f7cdSSrinivas Pandruvada 	*cpu_cnt = 0;
8483fb4f7cdSSrinivas Pandruvada 
8493fb4f7cdSSrinivas Pandruvada 	for (i = 0; i < 64; ++i) {
850873e391fSSrinivas Pandruvada 		if (core_mask & BIT_ULL(i)) {
8513fb4f7cdSSrinivas Pandruvada 			int j;
8523fb4f7cdSSrinivas Pandruvada 
8533fb4f7cdSSrinivas Pandruvada 			for (j = 0; j < topo_max_cpus; ++j) {
85444460efeSYouquan Song 				if (!CPU_ISSET_S(j, present_cpumask_size, present_cpumask))
85544460efeSYouquan Song 					continue;
85644460efeSYouquan Song 
85700bb07dbSZhang Rui 				if (is_cpu_in_power_domain(j, id) &&
8583fb4f7cdSSrinivas Pandruvada 				    cpu_map[j].punit_cpu_core == i) {
8593fb4f7cdSSrinivas Pandruvada 					CPU_SET_S(j, core_cpumask_size,
8603fb4f7cdSSrinivas Pandruvada 						  core_cpumask);
8613fb4f7cdSSrinivas Pandruvada 					++cnt;
8623fb4f7cdSSrinivas Pandruvada 				}
8633fb4f7cdSSrinivas Pandruvada 			}
8643fb4f7cdSSrinivas Pandruvada 		}
8653fb4f7cdSSrinivas Pandruvada 	}
8663fb4f7cdSSrinivas Pandruvada 
8673fb4f7cdSSrinivas Pandruvada 	*cpu_cnt = cnt;
8683fb4f7cdSSrinivas Pandruvada }
8693fb4f7cdSSrinivas Pandruvada 
find_phy_core_num(int logical_cpu)8703fb4f7cdSSrinivas Pandruvada int find_phy_core_num(int logical_cpu)
8713fb4f7cdSSrinivas Pandruvada {
8723fb4f7cdSSrinivas Pandruvada 	if (logical_cpu < topo_max_cpus)
8733fb4f7cdSSrinivas Pandruvada 		return cpu_map[logical_cpu].punit_cpu_core;
8743fb4f7cdSSrinivas Pandruvada 
8753fb4f7cdSSrinivas Pandruvada 	return -EINVAL;
8763fb4f7cdSSrinivas Pandruvada }
8773fb4f7cdSSrinivas Pandruvada 
use_cgroupv2(void)878997074dfSSrinivas Pandruvada int use_cgroupv2(void)
879997074dfSSrinivas Pandruvada {
880997074dfSSrinivas Pandruvada 	return cgroupv2;
881997074dfSSrinivas Pandruvada }
8823fb4f7cdSSrinivas Pandruvada 
enable_cpuset_controller(void)883997074dfSSrinivas Pandruvada int enable_cpuset_controller(void)
884997074dfSSrinivas Pandruvada {
885997074dfSSrinivas Pandruvada 	int fd, ret;
886997074dfSSrinivas Pandruvada 
887997074dfSSrinivas Pandruvada 	fd = open("/sys/fs/cgroup/cgroup.subtree_control", O_RDWR, 0);
888997074dfSSrinivas Pandruvada 	if (fd < 0) {
889997074dfSSrinivas Pandruvada 		debug_printf("Can't activate cpuset controller\n");
890997074dfSSrinivas Pandruvada 		debug_printf("Either you are not root user or CGroup v2 is not supported\n");
891997074dfSSrinivas Pandruvada 		return fd;
892997074dfSSrinivas Pandruvada 	}
893997074dfSSrinivas Pandruvada 
894997074dfSSrinivas Pandruvada 	ret = write(fd, " +cpuset", strlen(" +cpuset"));
895997074dfSSrinivas Pandruvada 	close(fd);
896997074dfSSrinivas Pandruvada 
897997074dfSSrinivas Pandruvada 	if (ret == -1) {
898997074dfSSrinivas Pandruvada 		debug_printf("Can't activate cpuset controller: Write failed\n");
899997074dfSSrinivas Pandruvada 		return ret;
900997074dfSSrinivas Pandruvada 	}
901997074dfSSrinivas Pandruvada 
902997074dfSSrinivas Pandruvada 	return 0;
903997074dfSSrinivas Pandruvada }
904997074dfSSrinivas Pandruvada 
isolate_cpus(struct isst_id * id,int mask_size,cpu_set_t * cpu_mask,int level,int cpu_0_only)9053bc0f20aSSrinivas Pandruvada int isolate_cpus(struct isst_id *id, int mask_size, cpu_set_t *cpu_mask, int level, int cpu_0_only)
906997074dfSSrinivas Pandruvada {
907997074dfSSrinivas Pandruvada 	int i, first, curr_index, index, ret, fd;
908997074dfSSrinivas Pandruvada 	static char str[512], dir_name[64];
909997074dfSSrinivas Pandruvada 	static char cpuset_cpus[128];
910997074dfSSrinivas Pandruvada 	int str_len = sizeof(str);
911997074dfSSrinivas Pandruvada 	DIR *dir;
912997074dfSSrinivas Pandruvada 
913997074dfSSrinivas Pandruvada 	snprintf(dir_name, sizeof(dir_name), "/sys/fs/cgroup/%d-%d-%d", id->pkg, id->die, id->punit);
914997074dfSSrinivas Pandruvada 	dir = opendir(dir_name);
915997074dfSSrinivas Pandruvada 	if (!dir) {
916997074dfSSrinivas Pandruvada 		ret = mkdir(dir_name, 0744);
917997074dfSSrinivas Pandruvada 		if (ret) {
918997074dfSSrinivas Pandruvada 			debug_printf("Can't create dir:%s errno:%d\n", dir_name, errno);
919997074dfSSrinivas Pandruvada 			return ret;
920997074dfSSrinivas Pandruvada 		}
921997074dfSSrinivas Pandruvada 	}
922997074dfSSrinivas Pandruvada 	closedir(dir);
923997074dfSSrinivas Pandruvada 
924997074dfSSrinivas Pandruvada 	if (!level) {
925997074dfSSrinivas Pandruvada 		sprintf(cpuset_cpus, "%s/cpuset.cpus.partition", dir_name);
926997074dfSSrinivas Pandruvada 
927997074dfSSrinivas Pandruvada 		fd = open(cpuset_cpus, O_RDWR, 0);
928997074dfSSrinivas Pandruvada 		if (fd < 0) {
929997074dfSSrinivas Pandruvada 			return fd;
930997074dfSSrinivas Pandruvada 		}
931997074dfSSrinivas Pandruvada 
932997074dfSSrinivas Pandruvada 		ret = write(fd, "member", strlen("member"));
933997074dfSSrinivas Pandruvada 		if (ret == -1) {
934997074dfSSrinivas Pandruvada 			printf("Can't update to member\n");
935997074dfSSrinivas Pandruvada 			return ret;
936997074dfSSrinivas Pandruvada 		}
937997074dfSSrinivas Pandruvada 
938997074dfSSrinivas Pandruvada 		return 0;
939997074dfSSrinivas Pandruvada 	}
940997074dfSSrinivas Pandruvada 
941997074dfSSrinivas Pandruvada 	if (!CPU_COUNT_S(mask_size, cpu_mask)) {
942997074dfSSrinivas Pandruvada 		return -1;
943997074dfSSrinivas Pandruvada 	}
944997074dfSSrinivas Pandruvada 
945997074dfSSrinivas Pandruvada 	curr_index = 0;
946997074dfSSrinivas Pandruvada 	first = 1;
947997074dfSSrinivas Pandruvada 	str[0] = '\0';
9483bc0f20aSSrinivas Pandruvada 
9493bc0f20aSSrinivas Pandruvada 	if (cpu_0_only) {
9503bc0f20aSSrinivas Pandruvada 		snprintf(str, str_len, "0");
9513bc0f20aSSrinivas Pandruvada 		goto create_partition;
9523bc0f20aSSrinivas Pandruvada 	}
9533bc0f20aSSrinivas Pandruvada 
954997074dfSSrinivas Pandruvada 	for (i = 0; i < get_topo_max_cpus(); ++i) {
955997074dfSSrinivas Pandruvada 		if (!is_cpu_in_power_domain(i, id))
956997074dfSSrinivas Pandruvada 			continue;
957997074dfSSrinivas Pandruvada 
958997074dfSSrinivas Pandruvada 		if (CPU_ISSET_S(i, mask_size, cpu_mask))
959997074dfSSrinivas Pandruvada 			continue;
960997074dfSSrinivas Pandruvada 
961997074dfSSrinivas Pandruvada 		if (!first) {
962997074dfSSrinivas Pandruvada 			index = snprintf(&str[curr_index],
963997074dfSSrinivas Pandruvada 					 str_len - curr_index, ",");
964997074dfSSrinivas Pandruvada 			curr_index += index;
965997074dfSSrinivas Pandruvada 			if (curr_index >= str_len)
966997074dfSSrinivas Pandruvada 				break;
967997074dfSSrinivas Pandruvada 		}
968997074dfSSrinivas Pandruvada 		index = snprintf(&str[curr_index], str_len - curr_index, "%d",
969997074dfSSrinivas Pandruvada 				 i);
970997074dfSSrinivas Pandruvada 		curr_index += index;
971997074dfSSrinivas Pandruvada 		if (curr_index >= str_len)
972997074dfSSrinivas Pandruvada 			break;
973997074dfSSrinivas Pandruvada 		first = 0;
974997074dfSSrinivas Pandruvada 	}
975997074dfSSrinivas Pandruvada 
9763bc0f20aSSrinivas Pandruvada create_partition:
977997074dfSSrinivas Pandruvada 	debug_printf("isolated CPUs list: package:%d curr_index:%d [%s]\n", id->pkg, curr_index ,str);
978997074dfSSrinivas Pandruvada 
979997074dfSSrinivas Pandruvada 	snprintf(cpuset_cpus, sizeof(cpuset_cpus), "%s/cpuset.cpus", dir_name);
980997074dfSSrinivas Pandruvada 
981997074dfSSrinivas Pandruvada 	fd = open(cpuset_cpus, O_RDWR, 0);
982997074dfSSrinivas Pandruvada 	if (fd < 0) {
983997074dfSSrinivas Pandruvada 		return fd;
984997074dfSSrinivas Pandruvada 	}
985997074dfSSrinivas Pandruvada 
986997074dfSSrinivas Pandruvada 	ret = write(fd, str, strlen(str));
987997074dfSSrinivas Pandruvada 	close(fd);
988997074dfSSrinivas Pandruvada 
989997074dfSSrinivas Pandruvada 	if (ret == -1) {
990997074dfSSrinivas Pandruvada 		debug_printf("Can't activate cpuset controller: Write failed\n");
991997074dfSSrinivas Pandruvada 		return ret;
992997074dfSSrinivas Pandruvada 	}
993997074dfSSrinivas Pandruvada 
994997074dfSSrinivas Pandruvada 	snprintf(cpuset_cpus, sizeof(cpuset_cpus), "%s/cpuset.cpus.partition", dir_name);
995997074dfSSrinivas Pandruvada 
996997074dfSSrinivas Pandruvada 	fd = open(cpuset_cpus, O_RDWR, 0);
997997074dfSSrinivas Pandruvada 	if (fd < 0) {
998997074dfSSrinivas Pandruvada 		return fd;
999997074dfSSrinivas Pandruvada 	}
1000997074dfSSrinivas Pandruvada 
1001997074dfSSrinivas Pandruvada 	ret = write(fd, "isolated", strlen("isolated"));
1002997074dfSSrinivas Pandruvada 	if (ret == -1) {
1003997074dfSSrinivas Pandruvada 		debug_printf("Can't update to isolated\n");
1004997074dfSSrinivas Pandruvada 		ret = write(fd, "root", strlen("root"));
1005997074dfSSrinivas Pandruvada 		if (ret == -1)
1006997074dfSSrinivas Pandruvada 			debug_printf("Can't update to root\n");
1007997074dfSSrinivas Pandruvada 	}
1008997074dfSSrinivas Pandruvada 
1009997074dfSSrinivas Pandruvada 	close(fd);
1010997074dfSSrinivas Pandruvada 
1011997074dfSSrinivas Pandruvada 	if (ret < 0)
1012997074dfSSrinivas Pandruvada 		return ret;
1013997074dfSSrinivas Pandruvada 
1014997074dfSSrinivas Pandruvada 	return 0;
1015997074dfSSrinivas Pandruvada }
10163fb4f7cdSSrinivas Pandruvada 
cpu_0_workaround(int isolate)10173bc0f20aSSrinivas Pandruvada static int cpu_0_workaround(int isolate)
10183bc0f20aSSrinivas Pandruvada {
10193bc0f20aSSrinivas Pandruvada 	int fd, fd1, len, ret;
10203bc0f20aSSrinivas Pandruvada 	cpu_set_t cpu_mask;
10213bc0f20aSSrinivas Pandruvada 	struct isst_id id;
10223bc0f20aSSrinivas Pandruvada 	char str[2];
10233bc0f20aSSrinivas Pandruvada 
10243bc0f20aSSrinivas Pandruvada 	debug_printf("isolate CPU 0 state: %d\n", isolate);
10253bc0f20aSSrinivas Pandruvada 
10263bc0f20aSSrinivas Pandruvada 	if (isolate)
10273bc0f20aSSrinivas Pandruvada 		goto isolate;
10283bc0f20aSSrinivas Pandruvada 
10293bc0f20aSSrinivas Pandruvada 	/* First check if CPU 0 was isolated to remove isolation. */
10303bc0f20aSSrinivas Pandruvada 
10313bc0f20aSSrinivas Pandruvada 	/* If the cpuset.cpus doesn't exist, that means that none of the CPUs are isolated*/
10323bc0f20aSSrinivas Pandruvada 	fd = open("/sys/fs/cgroup/0-0-0/cpuset.cpus", O_RDONLY, 0);
10333bc0f20aSSrinivas Pandruvada 	if (fd < 0)
10343bc0f20aSSrinivas Pandruvada 		return 0;
10353bc0f20aSSrinivas Pandruvada 
10363bc0f20aSSrinivas Pandruvada 	len = read(fd, str, sizeof(str));
10373bc0f20aSSrinivas Pandruvada 	/* Error check, but unlikely to fail. If fails that means that not isolated */
10383bc0f20aSSrinivas Pandruvada 	if (len == -1)
10393bc0f20aSSrinivas Pandruvada 		return 0;
10403bc0f20aSSrinivas Pandruvada 
10413bc0f20aSSrinivas Pandruvada 
10423bc0f20aSSrinivas Pandruvada 	/* Is CPU 0 is in isolate list, the display is sorted so first element will be CPU 0*/
10433bc0f20aSSrinivas Pandruvada 	if (str[0] != '0') {
10443bc0f20aSSrinivas Pandruvada 		close(fd);
10453bc0f20aSSrinivas Pandruvada 		return 0;
10463bc0f20aSSrinivas Pandruvada 	}
10473bc0f20aSSrinivas Pandruvada 
10483bc0f20aSSrinivas Pandruvada 	fd1 = open("/sys/fs/cgroup/0-0-0/cpuset.cpus.partition", O_RDONLY, 0);
10493bc0f20aSSrinivas Pandruvada 	/* Unlikely that, this attribute is not present, but handle error */
10503bc0f20aSSrinivas Pandruvada 	if (fd1 < 0) {
10513bc0f20aSSrinivas Pandruvada 		close(fd);
10523bc0f20aSSrinivas Pandruvada 		return 0;
10533bc0f20aSSrinivas Pandruvada 	}
10543bc0f20aSSrinivas Pandruvada 
10553bc0f20aSSrinivas Pandruvada 	/* Is CPU 0 already changed partition to "member" */
10563bc0f20aSSrinivas Pandruvada 	len = read(fd1, str, sizeof(str));
10573bc0f20aSSrinivas Pandruvada 	if (len != -1 && str[0] == 'm') {
10583bc0f20aSSrinivas Pandruvada 		close(fd1);
10593bc0f20aSSrinivas Pandruvada 		close(fd);
10603bc0f20aSSrinivas Pandruvada 		return 0;
10613bc0f20aSSrinivas Pandruvada 	}
10623bc0f20aSSrinivas Pandruvada 
10633bc0f20aSSrinivas Pandruvada 	close(fd1);
10643bc0f20aSSrinivas Pandruvada 	close(fd);
10653bc0f20aSSrinivas Pandruvada 
10663bc0f20aSSrinivas Pandruvada 	debug_printf("CPU 0 was isolated before, so remove isolation\n");
10673bc0f20aSSrinivas Pandruvada 
10683bc0f20aSSrinivas Pandruvada isolate:
10693bc0f20aSSrinivas Pandruvada 	ret = enable_cpuset_controller();
10703bc0f20aSSrinivas Pandruvada 	if (ret)
10713bc0f20aSSrinivas Pandruvada 		goto isolate_fail;
10723bc0f20aSSrinivas Pandruvada 
10733bc0f20aSSrinivas Pandruvada 	CPU_ZERO(&cpu_mask);
10743bc0f20aSSrinivas Pandruvada 	memset(&id, 0, sizeof(struct isst_id));
10753bc0f20aSSrinivas Pandruvada 	CPU_SET(0, &cpu_mask);
10763bc0f20aSSrinivas Pandruvada 
10773bc0f20aSSrinivas Pandruvada 	ret = isolate_cpus(&id, sizeof(cpu_mask), &cpu_mask, isolate, 1);
10783bc0f20aSSrinivas Pandruvada isolate_fail:
10793bc0f20aSSrinivas Pandruvada 	if (ret)
10803bc0f20aSSrinivas Pandruvada 		fprintf(stderr, "Can't isolate CPU 0\n");
10813bc0f20aSSrinivas Pandruvada 
10823bc0f20aSSrinivas Pandruvada 	return ret;
10833bc0f20aSSrinivas Pandruvada }
10843bc0f20aSSrinivas Pandruvada 
isst_fill_platform_info(void)10853fb4f7cdSSrinivas Pandruvada static int isst_fill_platform_info(void)
10863fb4f7cdSSrinivas Pandruvada {
10873fb4f7cdSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
10883fb4f7cdSSrinivas Pandruvada 	int fd;
10893fb4f7cdSSrinivas Pandruvada 
109005aab5b8SZhang Rui 	if (is_clx_n_platform()) {
109105aab5b8SZhang Rui 		isst_platform_info.api_version = 1;
1092d0d1a603SZhang Rui 		goto set_platform_ops;
109305aab5b8SZhang Rui 	}
1094e9f79348SZhang Rui 
10953fb4f7cdSSrinivas Pandruvada 	fd = open(pathname, O_RDWR);
10963fb4f7cdSSrinivas Pandruvada 	if (fd < 0)
10973fb4f7cdSSrinivas Pandruvada 		err(-1, "%s open failed", pathname);
10983fb4f7cdSSrinivas Pandruvada 
10993fb4f7cdSSrinivas Pandruvada 	if (ioctl(fd, ISST_IF_GET_PLATFORM_INFO, &isst_platform_info) == -1) {
11003fb4f7cdSSrinivas Pandruvada 		perror("ISST_IF_GET_PLATFORM_INFO");
11013fb4f7cdSSrinivas Pandruvada 		close(fd);
11023fb4f7cdSSrinivas Pandruvada 		return -1;
11033fb4f7cdSSrinivas Pandruvada 	}
11043fb4f7cdSSrinivas Pandruvada 
11053fb4f7cdSSrinivas Pandruvada 	close(fd);
11063fb4f7cdSSrinivas Pandruvada 
11073bc3d30cSPrarit Bhargava 	if (isst_platform_info.api_version > supported_api_ver) {
11083bc3d30cSPrarit Bhargava 		printf("Incompatible API versions; Upgrade of tool is required\n");
11093bc3d30cSPrarit Bhargava 		return -1;
11103bc3d30cSPrarit Bhargava 	}
1111d0d1a603SZhang Rui 
1112d0d1a603SZhang Rui set_platform_ops:
111305aab5b8SZhang Rui 	if (isst_set_platform_ops(isst_platform_info.api_version)) {
1114d0d1a603SZhang Rui 		fprintf(stderr, "Failed to set platform callbacks\n");
1115d0d1a603SZhang Rui 		exit(0);
1116d0d1a603SZhang Rui 	}
11173fb4f7cdSSrinivas Pandruvada 	return 0;
11183fb4f7cdSSrinivas Pandruvada }
11193fb4f7cdSSrinivas Pandruvada 
get_isst_status(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1120ad7e17fcSZhang Rui void get_isst_status(struct isst_id *id, void *arg1, void *arg2, void *arg3, void *arg4)
11211ba148aeSSrinivas Pandruvada {
11221ba148aeSSrinivas Pandruvada 	struct isst_pkg_ctdp pkg_dev;
1123ad7e17fcSZhang Rui 	struct isst_id *tid = (struct isst_id *)arg2;
1124ad7e17fcSZhang Rui 	int *mask = (int *)arg3;
1125ad7e17fcSZhang Rui 	int *max_level = (int *)arg4;
1126ad7e17fcSZhang Rui 	int j, ret;
11271ba148aeSSrinivas Pandruvada 
1128ad7e17fcSZhang Rui 	/* Only check the first cpu power domain */
1129ad7e17fcSZhang Rui 	if (id->cpu < 0 || tid->cpu >= 0)
11301ba148aeSSrinivas Pandruvada 		return;
11311ba148aeSSrinivas Pandruvada 
1132ad7e17fcSZhang Rui 	ret = isst_get_ctdp_levels(id, &pkg_dev);
11331ba148aeSSrinivas Pandruvada 	if (ret)
11341ba148aeSSrinivas Pandruvada 		return;
11351ba148aeSSrinivas Pandruvada 
1136ad7e17fcSZhang Rui 	if (pkg_dev.enabled)
1137ad7e17fcSZhang Rui 		*mask |= BIT(0);
1138ad7e17fcSZhang Rui 
1139ad7e17fcSZhang Rui 	if (pkg_dev.locked)
1140ad7e17fcSZhang Rui 		*mask |= BIT(1);
1141ad7e17fcSZhang Rui 
1142ad7e17fcSZhang Rui 	if (*max_level < pkg_dev.levels)
1143ad7e17fcSZhang Rui 		*max_level = pkg_dev.levels;
1144ad7e17fcSZhang Rui 
1145ad7e17fcSZhang Rui 	for (j = 0; j <= pkg_dev.levels; ++j) {
1146ad7e17fcSZhang Rui 		struct isst_pkg_ctdp_level_info ctdp_level;
1147ad7e17fcSZhang Rui 
1148ad7e17fcSZhang Rui 		ret = isst_get_ctdp_control(id, j, &ctdp_level);
1149ad7e17fcSZhang Rui 		if (ret)
1150ad7e17fcSZhang Rui 			continue;
1151ad7e17fcSZhang Rui 
1152ad7e17fcSZhang Rui 		if (ctdp_level.fact_support)
1153ad7e17fcSZhang Rui 			*mask |= BIT(2);
1154ad7e17fcSZhang Rui 
1155ad7e17fcSZhang Rui 		if (ctdp_level.pbf_support)
1156ad7e17fcSZhang Rui 			*mask |= BIT(3);
1157ad7e17fcSZhang Rui 	}
1158ad7e17fcSZhang Rui 
1159ad7e17fcSZhang Rui 	tid->cpu = id->cpu;
1160ad7e17fcSZhang Rui 	tid->pkg = id->pkg;
1161ad7e17fcSZhang Rui 	tid->die = id->die;
1162ad7e17fcSZhang Rui 	tid->punit = id->punit;
1163ad7e17fcSZhang Rui }
1164ad7e17fcSZhang Rui 
isst_print_extended_platform_info(void)1165ad7e17fcSZhang Rui static void isst_print_extended_platform_info(void)
1166ad7e17fcSZhang Rui {
1167ad7e17fcSZhang Rui 	int cp_state, cp_cap;
1168ad7e17fcSZhang Rui 	struct isst_id id;
1169ad7e17fcSZhang Rui 	int mask = 0, max_level = 0;
1170ad7e17fcSZhang Rui 
1171ad7e17fcSZhang Rui 	id.cpu = -1;
1172ad7e17fcSZhang Rui 	for_each_online_power_domain_in_set(get_isst_status, NULL, &id, &mask, &max_level);
1173ad7e17fcSZhang Rui 
1174ad7e17fcSZhang Rui 	if (mask & BIT(0)) {
11751ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is supported\n");
11761ba148aeSSrinivas Pandruvada 	} else {
11771ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-PP (feature perf-profile) is not supported\n");
11781ba148aeSSrinivas Pandruvada 		fprintf(outf, "Only performance level 0 (base level) is present\n");
11791ba148aeSSrinivas Pandruvada 	}
11801ba148aeSSrinivas Pandruvada 
1181ad7e17fcSZhang Rui 	if (mask & BIT(1))
11821ba148aeSSrinivas Pandruvada 		fprintf(outf, "TDP level change control is locked\n");
11831ba148aeSSrinivas Pandruvada 	else
1184ad7e17fcSZhang Rui 		fprintf(outf, "TDP level change control is unlocked, max level: %d\n", max_level);
11851ba148aeSSrinivas Pandruvada 
1186ad7e17fcSZhang Rui 	if (mask & BIT(2))
11871ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is supported\n");
11881ba148aeSSrinivas Pandruvada 	else
11891ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-TF (feature turbo-freq) is not supported\n");
11901ba148aeSSrinivas Pandruvada 
1191ad7e17fcSZhang Rui 	if (mask & BIT(3))
11921ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-BF (feature base-freq) is supported\n");
11931ba148aeSSrinivas Pandruvada 	else
11941ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-BF (feature base-freq) is not supported\n");
11951ba148aeSSrinivas Pandruvada 
1196ad7e17fcSZhang Rui 	if (isst_read_pm_config(&id, &cp_state, &cp_cap)) {
1197b84733a1SSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-CP (feature core-power) status is unknown\n");
1198b84733a1SSrinivas Pandruvada 		return;
1199b84733a1SSrinivas Pandruvada 	}
1200ad7e17fcSZhang Rui 
12011ba148aeSSrinivas Pandruvada 	if (cp_cap)
12021ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-CP (feature core-power) is supported\n");
12031ba148aeSSrinivas Pandruvada 	else
12041ba148aeSSrinivas Pandruvada 		fprintf(outf, "Intel(R) SST-CP (feature core-power) is not supported\n");
12051ba148aeSSrinivas Pandruvada }
12061ba148aeSSrinivas Pandruvada 
isst_print_platform_information(void)12073fb4f7cdSSrinivas Pandruvada static void isst_print_platform_information(void)
12083fb4f7cdSSrinivas Pandruvada {
12091ba148aeSSrinivas Pandruvada 	if (is_clx_n_platform()) {
12101ba148aeSSrinivas Pandruvada 		fprintf(stderr, "\nThis option in not supported on this platform\n");
12111ba148aeSSrinivas Pandruvada 		exit(0);
12121ba148aeSSrinivas Pandruvada 	}
12131ba148aeSSrinivas Pandruvada 
1214ca56725dSZhang Rui 	/* Early initialization to create working cpu_map */
1215ca56725dSZhang Rui 	set_max_cpu_num();
1216ca56725dSZhang Rui 	create_cpu_map();
1217ca56725dSZhang Rui 
12183fb4f7cdSSrinivas Pandruvada 	fprintf(outf, "Platform: API version : %d\n",
1219e9f79348SZhang Rui 		isst_platform_info.api_version);
12203fb4f7cdSSrinivas Pandruvada 	fprintf(outf, "Platform: Driver version : %d\n",
1221e9f79348SZhang Rui 		isst_platform_info.driver_version);
12223fb4f7cdSSrinivas Pandruvada 	fprintf(outf, "Platform: mbox supported : %d\n",
1223e9f79348SZhang Rui 		isst_platform_info.mbox_supported);
12243fb4f7cdSSrinivas Pandruvada 	fprintf(outf, "Platform: mmio supported : %d\n",
1225e9f79348SZhang Rui 		isst_platform_info.mmio_supported);
12261ba148aeSSrinivas Pandruvada 	isst_print_extended_platform_info();
12273fb4f7cdSSrinivas Pandruvada 
12283fb4f7cdSSrinivas Pandruvada 	exit(0);
12293fb4f7cdSSrinivas Pandruvada }
12303fb4f7cdSSrinivas Pandruvada 
12313d1a8579SSrinivas Pandruvada static char *local_str0, *local_str1;
exec_on_get_ctdp_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1232850337ecSZhang Rui static void exec_on_get_ctdp_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
12333fb4f7cdSSrinivas Pandruvada 				 void *arg4)
12343fb4f7cdSSrinivas Pandruvada {
1235850337ecSZhang Rui 	int (*fn_ptr)(struct isst_id *id, void *arg);
12363fb4f7cdSSrinivas Pandruvada 	int ret;
12373fb4f7cdSSrinivas Pandruvada 
12383fb4f7cdSSrinivas Pandruvada 	fn_ptr = arg1;
1239850337ecSZhang Rui 	ret = fn_ptr(id, arg2);
12403fb4f7cdSSrinivas Pandruvada 	if (ret)
12413d1a8579SSrinivas Pandruvada 		isst_display_error_info_message(1, "get_tdp_* failed", 0, 0);
12423fb4f7cdSSrinivas Pandruvada 	else
1243850337ecSZhang Rui 		isst_ctdp_display_core_info(id, outf, arg3,
12443d1a8579SSrinivas Pandruvada 					    *(unsigned int *)arg4,
12453d1a8579SSrinivas Pandruvada 					    local_str0, local_str1);
12463fb4f7cdSSrinivas Pandruvada }
12473fb4f7cdSSrinivas Pandruvada 
12483d1a8579SSrinivas Pandruvada #define _get_tdp_level(desc, suffix, object, help, str0, str1)			\
1249ce1326a2SPrarit Bhargava 	static void get_tdp_##object(int arg)                                    \
12503fb4f7cdSSrinivas Pandruvada 	{                                                                         \
12513fb4f7cdSSrinivas Pandruvada 		struct isst_pkg_ctdp ctdp;                                        \
12523fb4f7cdSSrinivas Pandruvada \
12533fb4f7cdSSrinivas Pandruvada 		if (cmd_help) {                                                   \
12543fb4f7cdSSrinivas Pandruvada 			fprintf(stderr,                                           \
12553fb4f7cdSSrinivas Pandruvada 				"Print %s [No command arguments are required]\n", \
12563fb4f7cdSSrinivas Pandruvada 				help);                                            \
12573fb4f7cdSSrinivas Pandruvada 			exit(0);                                                  \
12583fb4f7cdSSrinivas Pandruvada 		}                                                                 \
12593d1a8579SSrinivas Pandruvada 		local_str0 = str0;						  \
12603d1a8579SSrinivas Pandruvada 		local_str1 = str1;						  \
12613fb4f7cdSSrinivas Pandruvada 		isst_ctdp_display_information_start(outf);                        \
12623fb4f7cdSSrinivas Pandruvada 		if (max_target_cpus)                                              \
12633fb4f7cdSSrinivas Pandruvada 			for_each_online_target_cpu_in_set(                        \
12643fb4f7cdSSrinivas Pandruvada 				exec_on_get_ctdp_cpu, isst_get_ctdp_##suffix,     \
12653fb4f7cdSSrinivas Pandruvada 				&ctdp, desc, &ctdp.object);                       \
12663fb4f7cdSSrinivas Pandruvada 		else                                                              \
1267c77a8d4aSZhang Rui 			for_each_online_power_domain_in_set(exec_on_get_ctdp_cpu,      \
12683fb4f7cdSSrinivas Pandruvada 						       isst_get_ctdp_##suffix,    \
12693fb4f7cdSSrinivas Pandruvada 						       &ctdp, desc,               \
12703fb4f7cdSSrinivas Pandruvada 						       &ctdp.object);             \
12713fb4f7cdSSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);                          \
12723fb4f7cdSSrinivas Pandruvada 	}
12733fb4f7cdSSrinivas Pandruvada 
12743d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-levels", levels, levels, "Max TDP level", NULL, NULL);
12753d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-version", levels, version, "TDP version", NULL, NULL);
12763d1a8579SSrinivas Pandruvada _get_tdp_level("get-config-enabled", levels, enabled, "perf-profile enable status", "disabled", "enabled");
12773fb4f7cdSSrinivas Pandruvada _get_tdp_level("get-config-current_level", levels, current_level,
12783d1a8579SSrinivas Pandruvada 	       "Current TDP Level", NULL, NULL);
12793d1a8579SSrinivas Pandruvada _get_tdp_level("get-lock-status", levels, locked, "TDP lock status", "unlocked", "locked");
12803fb4f7cdSSrinivas Pandruvada 
1281062e4aacSPrarit Bhargava struct isst_pkg_ctdp clx_n_pkg_dev;
1282062e4aacSPrarit Bhargava 
clx_n_get_base_ratio(void)1283062e4aacSPrarit Bhargava static int clx_n_get_base_ratio(void)
1284062e4aacSPrarit Bhargava {
1285062e4aacSPrarit Bhargava 	FILE *fp;
1286062e4aacSPrarit Bhargava 	char *begin, *end, *line = NULL;
1287062e4aacSPrarit Bhargava 	char number[5];
1288062e4aacSPrarit Bhargava 	float value = 0;
1289062e4aacSPrarit Bhargava 	size_t n = 0;
1290062e4aacSPrarit Bhargava 
1291062e4aacSPrarit Bhargava 	fp = fopen("/proc/cpuinfo", "r");
1292062e4aacSPrarit Bhargava 	if (!fp)
1293062e4aacSPrarit Bhargava 		err(-1, "cannot open /proc/cpuinfo\n");
1294062e4aacSPrarit Bhargava 
1295062e4aacSPrarit Bhargava 	while (getline(&line, &n, fp) > 0) {
1296062e4aacSPrarit Bhargava 		if (strstr(line, "model name")) {
1297062e4aacSPrarit Bhargava 			/* this is true for CascadeLake-N */
1298062e4aacSPrarit Bhargava 			begin = strstr(line, "@ ") + 2;
1299062e4aacSPrarit Bhargava 			end = strstr(line, "GHz");
1300062e4aacSPrarit Bhargava 			strncpy(number, begin, end - begin);
1301062e4aacSPrarit Bhargava 			value = atof(number) * 10;
1302062e4aacSPrarit Bhargava 			break;
1303062e4aacSPrarit Bhargava 		}
1304062e4aacSPrarit Bhargava 	}
1305062e4aacSPrarit Bhargava 	free(line);
1306062e4aacSPrarit Bhargava 	fclose(fp);
1307062e4aacSPrarit Bhargava 
1308062e4aacSPrarit Bhargava 	return (int)(value);
1309062e4aacSPrarit Bhargava }
1310062e4aacSPrarit Bhargava 
clx_n_config(struct isst_id * id)1311850337ecSZhang Rui static int clx_n_config(struct isst_id *id)
1312062e4aacSPrarit Bhargava {
131356d64692SZhang Rui 	int i, ret;
1314062e4aacSPrarit Bhargava 	unsigned long cpu_bf;
1315062e4aacSPrarit Bhargava 	struct isst_pkg_ctdp_level_info *ctdp_level;
1316062e4aacSPrarit Bhargava 	struct isst_pbf_info *pbf_info;
1317062e4aacSPrarit Bhargava 
1318062e4aacSPrarit Bhargava 	ctdp_level = &clx_n_pkg_dev.ctdp_level[0];
1319062e4aacSPrarit Bhargava 	pbf_info = &ctdp_level->pbf_info;
1320062e4aacSPrarit Bhargava 	ctdp_level->core_cpumask_size =
1321062e4aacSPrarit Bhargava 			alloc_cpu_set(&ctdp_level->core_cpumask);
1322062e4aacSPrarit Bhargava 
1323062e4aacSPrarit Bhargava 	/* find the frequency base ratio */
1324062e4aacSPrarit Bhargava 	ctdp_level->tdp_ratio = clx_n_get_base_ratio();
1325062e4aacSPrarit Bhargava 	if (ctdp_level->tdp_ratio == 0) {
1326062e4aacSPrarit Bhargava 		debug_printf("CLX: cn base ratio is zero\n");
1327062e4aacSPrarit Bhargava 		ret = -1;
1328062e4aacSPrarit Bhargava 		goto error_ret;
1329062e4aacSPrarit Bhargava 	}
1330062e4aacSPrarit Bhargava 
1331062e4aacSPrarit Bhargava 	/* find the high and low priority frequencies */
1332062e4aacSPrarit Bhargava 	pbf_info->p1_high = 0;
1333062e4aacSPrarit Bhargava 	pbf_info->p1_low = ~0;
1334062e4aacSPrarit Bhargava 
1335062e4aacSPrarit Bhargava 	for (i = 0; i < topo_max_cpus; i++) {
1336062e4aacSPrarit Bhargava 		if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
1337062e4aacSPrarit Bhargava 			continue;
1338062e4aacSPrarit Bhargava 
133900bb07dbSZhang Rui 		if (!is_cpu_in_power_domain(i, id))
1340062e4aacSPrarit Bhargava 			continue;
1341062e4aacSPrarit Bhargava 
1342062e4aacSPrarit Bhargava 		CPU_SET_S(i, ctdp_level->core_cpumask_size,
1343062e4aacSPrarit Bhargava 			  ctdp_level->core_cpumask);
1344062e4aacSPrarit Bhargava 
1345062e4aacSPrarit Bhargava 		cpu_bf = parse_int_file(1,
1346062e4aacSPrarit Bhargava 			"/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency",
1347062e4aacSPrarit Bhargava 					i);
1348062e4aacSPrarit Bhargava 		if (cpu_bf > pbf_info->p1_high)
1349062e4aacSPrarit Bhargava 			pbf_info->p1_high = cpu_bf;
1350062e4aacSPrarit Bhargava 		if (cpu_bf < pbf_info->p1_low)
1351062e4aacSPrarit Bhargava 			pbf_info->p1_low = cpu_bf;
1352062e4aacSPrarit Bhargava 	}
1353062e4aacSPrarit Bhargava 
1354062e4aacSPrarit Bhargava 	if (pbf_info->p1_high == ~0UL) {
1355062e4aacSPrarit Bhargava 		debug_printf("CLX: maximum base frequency not set\n");
1356062e4aacSPrarit Bhargava 		ret = -1;
1357062e4aacSPrarit Bhargava 		goto error_ret;
1358062e4aacSPrarit Bhargava 	}
1359062e4aacSPrarit Bhargava 
1360062e4aacSPrarit Bhargava 	if (pbf_info->p1_low == 0) {
1361062e4aacSPrarit Bhargava 		debug_printf("CLX: minimum base frequency not set\n");
1362062e4aacSPrarit Bhargava 		ret = -1;
1363062e4aacSPrarit Bhargava 		goto error_ret;
1364062e4aacSPrarit Bhargava 	}
1365062e4aacSPrarit Bhargava 
1366062e4aacSPrarit Bhargava 	/* convert frequencies back to ratios */
136791d92814SSrinivas Pandruvada 	pbf_info->p1_high = pbf_info->p1_high / 100000;
136891d92814SSrinivas Pandruvada 	pbf_info->p1_low = pbf_info->p1_low / 100000;
1369062e4aacSPrarit Bhargava 
1370062e4aacSPrarit Bhargava 	/* create high priority cpu mask */
1371062e4aacSPrarit Bhargava 	pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
1372062e4aacSPrarit Bhargava 	for (i = 0; i < topo_max_cpus; i++) {
1373062e4aacSPrarit Bhargava 		if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
1374062e4aacSPrarit Bhargava 			continue;
1375062e4aacSPrarit Bhargava 
137600bb07dbSZhang Rui 		if (!is_cpu_in_power_domain(i, id))
1377062e4aacSPrarit Bhargava 			continue;
1378062e4aacSPrarit Bhargava 
1379062e4aacSPrarit Bhargava 		cpu_bf = parse_int_file(1,
1380062e4aacSPrarit Bhargava 			"/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency",
1381062e4aacSPrarit Bhargava 					i);
138291d92814SSrinivas Pandruvada 		cpu_bf = cpu_bf / 100000;
1383062e4aacSPrarit Bhargava 		if (cpu_bf == pbf_info->p1_high)
1384062e4aacSPrarit Bhargava 			CPU_SET_S(i, pbf_info->core_cpumask_size,
1385062e4aacSPrarit Bhargava 				  pbf_info->core_cpumask);
1386062e4aacSPrarit Bhargava 	}
1387062e4aacSPrarit Bhargava 
1388062e4aacSPrarit Bhargava 	/* extra ctdp & pbf struct parameters */
1389062e4aacSPrarit Bhargava 	ctdp_level->processed = 1;
1390062e4aacSPrarit Bhargava 	ctdp_level->pbf_support = 1; /* PBF is always supported and enabled */
1391062e4aacSPrarit Bhargava 	ctdp_level->pbf_enabled = 1;
1392062e4aacSPrarit Bhargava 	ctdp_level->fact_support = 0; /* FACT is never supported */
1393062e4aacSPrarit Bhargava 	ctdp_level->fact_enabled = 0;
1394062e4aacSPrarit Bhargava 
1395062e4aacSPrarit Bhargava 	return 0;
1396062e4aacSPrarit Bhargava 
1397062e4aacSPrarit Bhargava error_ret:
1398062e4aacSPrarit Bhargava 	free_cpu_set(ctdp_level->core_cpumask);
1399062e4aacSPrarit Bhargava 	return ret;
1400062e4aacSPrarit Bhargava }
1401062e4aacSPrarit Bhargava 
dump_clx_n_config_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1402850337ecSZhang Rui static void dump_clx_n_config_for_cpu(struct isst_id *id, void *arg1, void *arg2,
1403062e4aacSPrarit Bhargava 				   void *arg3, void *arg4)
1404062e4aacSPrarit Bhargava {
1405062e4aacSPrarit Bhargava 	int ret;
1406062e4aacSPrarit Bhargava 
1407ac9d05eaSSrinivas Pandruvada 	if (tdp_level != 0xff && tdp_level != 0) {
1408ac9d05eaSSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid level", 1, tdp_level);
1409ac9d05eaSSrinivas Pandruvada 		exit(0);
1410ac9d05eaSSrinivas Pandruvada 	}
1411ac9d05eaSSrinivas Pandruvada 
1412850337ecSZhang Rui 	ret = clx_n_config(id);
1413062e4aacSPrarit Bhargava 	if (ret) {
14147fc9fefdSSrinivas Pandruvada 		debug_printf("clx_n_config failed");
1415062e4aacSPrarit Bhargava 	} else {
1416062e4aacSPrarit Bhargava 		struct isst_pkg_ctdp_level_info *ctdp_level;
1417062e4aacSPrarit Bhargava 		struct isst_pbf_info *pbf_info;
1418062e4aacSPrarit Bhargava 
1419062e4aacSPrarit Bhargava 		ctdp_level = &clx_n_pkg_dev.ctdp_level[0];
1420062e4aacSPrarit Bhargava 		pbf_info = &ctdp_level->pbf_info;
142128c59ae6SPrarit Bhargava 		clx_n_pkg_dev.processed = 1;
1422850337ecSZhang Rui 		isst_ctdp_display_information(id, outf, tdp_level, &clx_n_pkg_dev);
1423062e4aacSPrarit Bhargava 		free_cpu_set(ctdp_level->core_cpumask);
1424062e4aacSPrarit Bhargava 		free_cpu_set(pbf_info->core_cpumask);
1425062e4aacSPrarit Bhargava 	}
1426062e4aacSPrarit Bhargava }
1427062e4aacSPrarit Bhargava 
dump_isst_config_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1428850337ecSZhang Rui static void dump_isst_config_for_cpu(struct isst_id *id, void *arg1, void *arg2,
14293fb4f7cdSSrinivas Pandruvada 				     void *arg3, void *arg4)
14303fb4f7cdSSrinivas Pandruvada {
14313fb4f7cdSSrinivas Pandruvada 	struct isst_pkg_ctdp pkg_dev;
14323fb4f7cdSSrinivas Pandruvada 	int ret;
14333fb4f7cdSSrinivas Pandruvada 
14343fb4f7cdSSrinivas Pandruvada 	memset(&pkg_dev, 0, sizeof(pkg_dev));
1435850337ecSZhang Rui 	ret = isst_get_process_ctdp(id, tdp_level, &pkg_dev);
14363fb4f7cdSSrinivas Pandruvada 	if (ret) {
1437850337ecSZhang Rui 		isst_display_error_info_message(1, "Failed to get perf-profile info on cpu", 1, id->cpu);
1438ac9d05eaSSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);
1439ac9d05eaSSrinivas Pandruvada 		exit(1);
14403fb4f7cdSSrinivas Pandruvada 	} else {
1441850337ecSZhang Rui 		isst_ctdp_display_information(id, outf, tdp_level, &pkg_dev);
1442850337ecSZhang Rui 		isst_get_process_ctdp_complete(id, &pkg_dev);
14433fb4f7cdSSrinivas Pandruvada 	}
14443fb4f7cdSSrinivas Pandruvada }
14453fb4f7cdSSrinivas Pandruvada 
dump_isst_config(int arg)1446ce1326a2SPrarit Bhargava static void dump_isst_config(int arg)
14473fb4f7cdSSrinivas Pandruvada {
1448062e4aacSPrarit Bhargava 	void *fn;
1449062e4aacSPrarit Bhargava 
14503fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
14513fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
14523fb4f7cdSSrinivas Pandruvada 			"Print Intel(R) Speed Select Technology Performance profile configuration\n");
14533fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
14543fb4f7cdSSrinivas Pandruvada 			"including base frequency and turbo frequency configurations\n");
14553fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Optional: -l|--level : Specify tdp level\n");
14563fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
14573fb4f7cdSSrinivas Pandruvada 			"\tIf no arguments, dump information for all TDP levels\n");
14583fb4f7cdSSrinivas Pandruvada 		exit(0);
14593fb4f7cdSSrinivas Pandruvada 	}
14603fb4f7cdSSrinivas Pandruvada 
1461062e4aacSPrarit Bhargava 	if (!is_clx_n_platform())
1462062e4aacSPrarit Bhargava 		fn = dump_isst_config_for_cpu;
1463062e4aacSPrarit Bhargava 	else
1464062e4aacSPrarit Bhargava 		fn = dump_clx_n_config_for_cpu;
1465062e4aacSPrarit Bhargava 
14663fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
14673fb4f7cdSSrinivas Pandruvada 
14683fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
1469062e4aacSPrarit Bhargava 		for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL);
14703fb4f7cdSSrinivas Pandruvada 	else
1471c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(fn, NULL, NULL, NULL, NULL);
14723fb4f7cdSSrinivas Pandruvada 
14733fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
14743fb4f7cdSSrinivas Pandruvada }
14753fb4f7cdSSrinivas Pandruvada 
1476f981dc17SSrinivas Pandruvada static void adjust_scaling_max_from_base_freq(int cpu);
1477f981dc17SSrinivas Pandruvada 
set_tdp_level_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1478850337ecSZhang Rui static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
14793fb4f7cdSSrinivas Pandruvada 				  void *arg4)
14803fb4f7cdSSrinivas Pandruvada {
148114f0cf6cSZhang Rui 	struct isst_pkg_ctdp pkg_dev;
14823fb4f7cdSSrinivas Pandruvada 	int ret;
14833fb4f7cdSSrinivas Pandruvada 
148414f0cf6cSZhang Rui 	ret = isst_get_ctdp_levels(id, &pkg_dev);
148514f0cf6cSZhang Rui 	if (ret) {
148614f0cf6cSZhang Rui 		isst_display_error_info_message(1, "Get TDP level failed", 0, 0);
148714f0cf6cSZhang Rui 		isst_ctdp_display_information_end(outf);
148814f0cf6cSZhang Rui 		exit(1);
148914f0cf6cSZhang Rui 	}
149014f0cf6cSZhang Rui 
149114f0cf6cSZhang Rui 	if (pkg_dev.current_level == tdp_level) {
149214f0cf6cSZhang Rui 		debug_printf("TDP level already set. Skipped\n");
149314f0cf6cSZhang Rui 		goto display_result;
149414f0cf6cSZhang Rui 	}
149514f0cf6cSZhang Rui 
1496850337ecSZhang Rui 	ret = isst_set_tdp_level(id, tdp_level);
1497ac9d05eaSSrinivas Pandruvada 	if (ret) {
1498ac9d05eaSSrinivas Pandruvada 		isst_display_error_info_message(1, "Set TDP level failed", 0, 0);
1499ac9d05eaSSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);
1500ac9d05eaSSrinivas Pandruvada 		exit(1);
150114f0cf6cSZhang Rui 	}
150214f0cf6cSZhang Rui 
150314f0cf6cSZhang Rui display_result:
150414f0cf6cSZhang Rui 	isst_display_result(id, outf, "perf-profile", "set_tdp_level", ret);
1505d0e12c46SZhang Rui 	if (force_online_offline && id->cpu >= 0) {
15063c64c81aSSrinivas Pandruvada 		struct isst_pkg_ctdp_level_info ctdp_level;
15073c64c81aSSrinivas Pandruvada 
1508f981dc17SSrinivas Pandruvada 		/* Wait for updated base frequencies */
1509f981dc17SSrinivas Pandruvada 		usleep(2000);
1510f981dc17SSrinivas Pandruvada 
15112612ae59SSrinivas Pandruvada 		/* Adjusting uncore freq */
151273452cccSZhang Rui 		isst_adjust_uncore_freq(id, tdp_level, &ctdp_level);
15132612ae59SSrinivas Pandruvada 
15143c64c81aSSrinivas Pandruvada 		fprintf(stderr, "Option is set to online/offline\n");
15153c64c81aSSrinivas Pandruvada 		ctdp_level.core_cpumask_size =
15163c64c81aSSrinivas Pandruvada 			alloc_cpu_set(&ctdp_level.core_cpumask);
1517850337ecSZhang Rui 		ret = isst_get_coremask_info(id, tdp_level, &ctdp_level);
15186374de84SSrinivas Pandruvada 		if (ret) {
15196374de84SSrinivas Pandruvada 			isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0);
152057797f19SSrinivas Pandruvada 			goto free_mask;
15216374de84SSrinivas Pandruvada 		}
1522997074dfSSrinivas Pandruvada 
1523997074dfSSrinivas Pandruvada 		if (use_cgroupv2()) {
1524997074dfSSrinivas Pandruvada 			int ret;
1525997074dfSSrinivas Pandruvada 
1526997074dfSSrinivas Pandruvada 			fprintf(stderr, "Using cgroup v2 in lieu of online/offline\n");
1527997074dfSSrinivas Pandruvada 			ret = enable_cpuset_controller();
1528997074dfSSrinivas Pandruvada 			if (ret)
1529997074dfSSrinivas Pandruvada 				goto use_offline;
1530997074dfSSrinivas Pandruvada 
15313bc0f20aSSrinivas Pandruvada 			ret = isolate_cpus(id, ctdp_level.core_cpumask_size,
15323bc0f20aSSrinivas Pandruvada 					   ctdp_level.core_cpumask, tdp_level, 0);
1533997074dfSSrinivas Pandruvada 			if (ret)
1534997074dfSSrinivas Pandruvada 				goto use_offline;
1535997074dfSSrinivas Pandruvada 
1536997074dfSSrinivas Pandruvada 			goto free_mask;
1537997074dfSSrinivas Pandruvada 		}
1538997074dfSSrinivas Pandruvada 
1539997074dfSSrinivas Pandruvada use_offline:
15403c64c81aSSrinivas Pandruvada 		if (ctdp_level.cpu_count) {
15413c64c81aSSrinivas Pandruvada 			int i, max_cpus = get_topo_max_cpus();
15423c64c81aSSrinivas Pandruvada 			for (i = 0; i < max_cpus; ++i) {
154300bb07dbSZhang Rui 				if (!is_cpu_in_power_domain(i, id))
15443c64c81aSSrinivas Pandruvada 					continue;
15453c64c81aSSrinivas Pandruvada 				if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) {
15463c64c81aSSrinivas Pandruvada 					fprintf(stderr, "online cpu %d\n", i);
15473c64c81aSSrinivas Pandruvada 					set_cpu_online_offline(i, 1);
1548f981dc17SSrinivas Pandruvada 					adjust_scaling_max_from_base_freq(i);
15493c64c81aSSrinivas Pandruvada 				} else {
15503c64c81aSSrinivas Pandruvada 					fprintf(stderr, "offline cpu %d\n", i);
15513c64c81aSSrinivas Pandruvada 					set_cpu_online_offline(i, 0);
15523c64c81aSSrinivas Pandruvada 				}
15533c64c81aSSrinivas Pandruvada 			}
15543c64c81aSSrinivas Pandruvada 		}
155557797f19SSrinivas Pandruvada free_mask:
155657797f19SSrinivas Pandruvada 		free_cpu_set(ctdp_level.core_cpumask);
15573c64c81aSSrinivas Pandruvada 	}
15583c64c81aSSrinivas Pandruvada }
15593fb4f7cdSSrinivas Pandruvada 
set_tdp_level(int arg)1560ce1326a2SPrarit Bhargava static void set_tdp_level(int arg)
15613fb4f7cdSSrinivas Pandruvada {
15623fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
15633fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Set Config TDP level\n");
15643fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
15653fb4f7cdSSrinivas Pandruvada 			"\t Arguments: -l|--level : Specify tdp level\n");
15663c64c81aSSrinivas Pandruvada 		fprintf(stderr,
15673c64c81aSSrinivas Pandruvada 			"\t Optional Arguments: -o | online : online/offline for the tdp level\n");
1568ac9d05eaSSrinivas Pandruvada 		fprintf(stderr,
1569ac9d05eaSSrinivas Pandruvada 			"\t  online/offline operation has limitations, refer to Linux hotplug documentation\n");
15703fb4f7cdSSrinivas Pandruvada 		exit(0);
15713fb4f7cdSSrinivas Pandruvada 	}
15723fb4f7cdSSrinivas Pandruvada 
15733fb4f7cdSSrinivas Pandruvada 	if (tdp_level == 0xff) {
1574ac9d05eaSSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0);
15753fb4f7cdSSrinivas Pandruvada 		exit(1);
15763fb4f7cdSSrinivas Pandruvada 	}
15773fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
15783fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
15793fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_tdp_level_for_cpu, NULL,
15803fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
15813fb4f7cdSSrinivas Pandruvada 	else
1582c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(set_tdp_level_for_cpu, NULL,
15833fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
15843fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
15853fb4f7cdSSrinivas Pandruvada }
15863fb4f7cdSSrinivas Pandruvada 
clx_n_dump_pbf_config_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1587850337ecSZhang Rui static void clx_n_dump_pbf_config_for_cpu(struct isst_id *id, void *arg1, void *arg2,
15881aa7177cSPrarit Bhargava 				       void *arg3, void *arg4)
15891aa7177cSPrarit Bhargava {
15901aa7177cSPrarit Bhargava 	int ret;
15911aa7177cSPrarit Bhargava 
1592850337ecSZhang Rui 	ret = clx_n_config(id);
15931aa7177cSPrarit Bhargava 	if (ret) {
159439bae0fcSSrinivas Pandruvada 		isst_display_error_info_message(1, "clx_n_config failed", 0, 0);
15951aa7177cSPrarit Bhargava 	} else {
15961aa7177cSPrarit Bhargava 		struct isst_pkg_ctdp_level_info *ctdp_level;
15971aa7177cSPrarit Bhargava 		struct isst_pbf_info *pbf_info;
15981aa7177cSPrarit Bhargava 
15991aa7177cSPrarit Bhargava 		ctdp_level = &clx_n_pkg_dev.ctdp_level[0];
16001aa7177cSPrarit Bhargava 		pbf_info = &ctdp_level->pbf_info;
1601850337ecSZhang Rui 		isst_pbf_display_information(id, outf, tdp_level, pbf_info);
16021aa7177cSPrarit Bhargava 		free_cpu_set(ctdp_level->core_cpumask);
16031aa7177cSPrarit Bhargava 		free_cpu_set(pbf_info->core_cpumask);
16041aa7177cSPrarit Bhargava 	}
16051aa7177cSPrarit Bhargava }
16061aa7177cSPrarit Bhargava 
dump_pbf_config_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1607850337ecSZhang Rui static void dump_pbf_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
16083fb4f7cdSSrinivas Pandruvada 				    void *arg4)
16093fb4f7cdSSrinivas Pandruvada {
16103fb4f7cdSSrinivas Pandruvada 	struct isst_pbf_info pbf_info;
16113fb4f7cdSSrinivas Pandruvada 	int ret;
16123fb4f7cdSSrinivas Pandruvada 
1613850337ecSZhang Rui 	ret = isst_get_pbf_info(id, tdp_level, &pbf_info);
16143fb4f7cdSSrinivas Pandruvada 	if (ret) {
161539bae0fcSSrinivas Pandruvada 		isst_display_error_info_message(1, "Failed to get base-freq info at this level", 1, tdp_level);
161639bae0fcSSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);
161739bae0fcSSrinivas Pandruvada 		exit(1);
16183fb4f7cdSSrinivas Pandruvada 	} else {
1619850337ecSZhang Rui 		isst_pbf_display_information(id, outf, tdp_level, &pbf_info);
162005ece691SZhang Rui 		free_cpu_set(pbf_info.core_cpumask);
16213fb4f7cdSSrinivas Pandruvada 	}
16223fb4f7cdSSrinivas Pandruvada }
16233fb4f7cdSSrinivas Pandruvada 
dump_pbf_config(int arg)1624ce1326a2SPrarit Bhargava static void dump_pbf_config(int arg)
16253fb4f7cdSSrinivas Pandruvada {
16261aa7177cSPrarit Bhargava 	void *fn;
16271aa7177cSPrarit Bhargava 
16283fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
16293fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
16303fb4f7cdSSrinivas Pandruvada 			"Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n");
16313fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
16323fb4f7cdSSrinivas Pandruvada 			"\tArguments: -l|--level : Specify tdp level\n");
16333fb4f7cdSSrinivas Pandruvada 		exit(0);
16343fb4f7cdSSrinivas Pandruvada 	}
16353fb4f7cdSSrinivas Pandruvada 
16363fb4f7cdSSrinivas Pandruvada 	if (tdp_level == 0xff) {
163739bae0fcSSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid command: specify tdp_level", 0, 0);
16383fb4f7cdSSrinivas Pandruvada 		exit(1);
16393fb4f7cdSSrinivas Pandruvada 	}
16403fb4f7cdSSrinivas Pandruvada 
16411aa7177cSPrarit Bhargava 	if (!is_clx_n_platform())
16421aa7177cSPrarit Bhargava 		fn = dump_pbf_config_for_cpu;
16433fb4f7cdSSrinivas Pandruvada 	else
16441aa7177cSPrarit Bhargava 		fn = clx_n_dump_pbf_config_for_cpu;
16451aa7177cSPrarit Bhargava 
16461aa7177cSPrarit Bhargava 	isst_ctdp_display_information_start(outf);
16471aa7177cSPrarit Bhargava 
16481aa7177cSPrarit Bhargava 	if (max_target_cpus)
16491aa7177cSPrarit Bhargava 		for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL);
16501aa7177cSPrarit Bhargava 	else
1651c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(fn, NULL, NULL, NULL, NULL);
16521aa7177cSPrarit Bhargava 
16533fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
16543fb4f7cdSSrinivas Pandruvada }
16553fb4f7cdSSrinivas Pandruvada 
set_clos_param(struct isst_id * id,int clos,int epp,int wt,int min,int max)1656850337ecSZhang Rui static int set_clos_param(struct isst_id *id, int clos, int epp, int wt, int min, int max)
1657354bd06fSSrinivas Pandruvada {
1658354bd06fSSrinivas Pandruvada 	struct isst_clos_config clos_config;
1659354bd06fSSrinivas Pandruvada 	int ret;
1660354bd06fSSrinivas Pandruvada 
1661850337ecSZhang Rui 	ret = isst_pm_get_clos(id, clos, &clos_config);
1662354bd06fSSrinivas Pandruvada 	if (ret) {
1663fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0);
1664354bd06fSSrinivas Pandruvada 		return ret;
1665354bd06fSSrinivas Pandruvada 	}
1666354bd06fSSrinivas Pandruvada 	clos_config.clos_min = min;
1667354bd06fSSrinivas Pandruvada 	clos_config.clos_max = max;
1668354bd06fSSrinivas Pandruvada 	clos_config.epp = epp;
1669354bd06fSSrinivas Pandruvada 	clos_config.clos_prop_prio = wt;
1670850337ecSZhang Rui 	ret = isst_set_clos(id, clos, &clos_config);
1671354bd06fSSrinivas Pandruvada 	if (ret) {
1672fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "isst_set_clos failed", 0, 0);
1673354bd06fSSrinivas Pandruvada 		return ret;
1674354bd06fSSrinivas Pandruvada 	}
1675354bd06fSSrinivas Pandruvada 
1676354bd06fSSrinivas Pandruvada 	return 0;
1677354bd06fSSrinivas Pandruvada }
1678354bd06fSSrinivas Pandruvada 
set_cpufreq_scaling_min_max(int cpu,int max,int freq)1679a9b2f8e2SSrinivas Pandruvada static int set_cpufreq_scaling_min_max(int cpu, int max, int freq)
1680a9b2f8e2SSrinivas Pandruvada {
1681a9b2f8e2SSrinivas Pandruvada 	char buffer[128], freq_str[16];
1682a9b2f8e2SSrinivas Pandruvada 	int fd, ret, len;
1683a9b2f8e2SSrinivas Pandruvada 
1684a9b2f8e2SSrinivas Pandruvada 	if (max)
1685a9b2f8e2SSrinivas Pandruvada 		snprintf(buffer, sizeof(buffer),
1686a9b2f8e2SSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu);
1687a9b2f8e2SSrinivas Pandruvada 	else
1688a9b2f8e2SSrinivas Pandruvada 		snprintf(buffer, sizeof(buffer),
1689a9b2f8e2SSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu);
1690a9b2f8e2SSrinivas Pandruvada 
1691a9b2f8e2SSrinivas Pandruvada 	fd = open(buffer, O_WRONLY);
1692a9b2f8e2SSrinivas Pandruvada 	if (fd < 0)
1693a9b2f8e2SSrinivas Pandruvada 		return fd;
1694a9b2f8e2SSrinivas Pandruvada 
1695a9b2f8e2SSrinivas Pandruvada 	snprintf(freq_str, sizeof(freq_str), "%d", freq);
1696a9b2f8e2SSrinivas Pandruvada 	len = strlen(freq_str);
1697a9b2f8e2SSrinivas Pandruvada 	ret = write(fd, freq_str, len);
1698a9b2f8e2SSrinivas Pandruvada 	if (ret == -1) {
1699a9b2f8e2SSrinivas Pandruvada 		close(fd);
1700a9b2f8e2SSrinivas Pandruvada 		return ret;
1701a9b2f8e2SSrinivas Pandruvada 	}
1702a9b2f8e2SSrinivas Pandruvada 	close(fd);
1703a9b2f8e2SSrinivas Pandruvada 
1704a9b2f8e2SSrinivas Pandruvada 	return 0;
1705a9b2f8e2SSrinivas Pandruvada }
1706a9b2f8e2SSrinivas Pandruvada 
no_turbo(void)1707f981dc17SSrinivas Pandruvada static int no_turbo(void)
1708f981dc17SSrinivas Pandruvada {
1709f981dc17SSrinivas Pandruvada 	return parse_int_file(0, "/sys/devices/system/cpu/intel_pstate/no_turbo");
1710f981dc17SSrinivas Pandruvada }
1711f981dc17SSrinivas Pandruvada 
adjust_scaling_max_from_base_freq(int cpu)1712f981dc17SSrinivas Pandruvada static void adjust_scaling_max_from_base_freq(int cpu)
1713f981dc17SSrinivas Pandruvada {
1714f981dc17SSrinivas Pandruvada 	int base_freq, scaling_max_freq;
1715f981dc17SSrinivas Pandruvada 
1716f981dc17SSrinivas Pandruvada 	scaling_max_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu);
1717f981dc17SSrinivas Pandruvada 	base_freq = get_cpufreq_base_freq(cpu);
1718f981dc17SSrinivas Pandruvada 	if (scaling_max_freq < base_freq || no_turbo())
1719f981dc17SSrinivas Pandruvada 		set_cpufreq_scaling_min_max(cpu, 1, base_freq);
1720f981dc17SSrinivas Pandruvada }
1721f981dc17SSrinivas Pandruvada 
adjust_scaling_min_from_base_freq(int cpu)1722bbaa2e95SSrinivas Pandruvada static void adjust_scaling_min_from_base_freq(int cpu)
1723bbaa2e95SSrinivas Pandruvada {
1724bbaa2e95SSrinivas Pandruvada 	int base_freq, scaling_min_freq;
1725bbaa2e95SSrinivas Pandruvada 
1726bbaa2e95SSrinivas Pandruvada 	scaling_min_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu);
1727bbaa2e95SSrinivas Pandruvada 	base_freq = get_cpufreq_base_freq(cpu);
1728bbaa2e95SSrinivas Pandruvada 	if (scaling_min_freq < base_freq)
1729bbaa2e95SSrinivas Pandruvada 		set_cpufreq_scaling_min_max(cpu, 0, base_freq);
1730bbaa2e95SSrinivas Pandruvada }
1731bbaa2e95SSrinivas Pandruvada 
set_clx_pbf_cpufreq_scaling_min_max(struct isst_id * id)1732850337ecSZhang Rui static int set_clx_pbf_cpufreq_scaling_min_max(struct isst_id *id)
1733a9b2f8e2SSrinivas Pandruvada {
1734a9b2f8e2SSrinivas Pandruvada 	struct isst_pkg_ctdp_level_info *ctdp_level;
1735a9b2f8e2SSrinivas Pandruvada 	struct isst_pbf_info *pbf_info;
173656d64692SZhang Rui 	int i, freq, freq_high, freq_low;
1737a9b2f8e2SSrinivas Pandruvada 	int ret;
1738a9b2f8e2SSrinivas Pandruvada 
1739850337ecSZhang Rui 	ret = clx_n_config(id);
1740a9b2f8e2SSrinivas Pandruvada 	if (ret) {
17417fc9fefdSSrinivas Pandruvada 		debug_printf("cpufreq_scaling_min_max failed for CLX");
1742a9b2f8e2SSrinivas Pandruvada 		return ret;
1743a9b2f8e2SSrinivas Pandruvada 	}
1744a9b2f8e2SSrinivas Pandruvada 
1745a9b2f8e2SSrinivas Pandruvada 	ctdp_level = &clx_n_pkg_dev.ctdp_level[0];
1746a9b2f8e2SSrinivas Pandruvada 	pbf_info = &ctdp_level->pbf_info;
1747a9b2f8e2SSrinivas Pandruvada 	freq_high = pbf_info->p1_high * 100000;
1748a9b2f8e2SSrinivas Pandruvada 	freq_low = pbf_info->p1_low * 100000;
1749a9b2f8e2SSrinivas Pandruvada 
1750a9b2f8e2SSrinivas Pandruvada 	for (i = 0; i < get_topo_max_cpus(); ++i) {
175100bb07dbSZhang Rui 		if (!is_cpu_in_power_domain(i, id))
1752a9b2f8e2SSrinivas Pandruvada 			continue;
1753a9b2f8e2SSrinivas Pandruvada 
1754a9b2f8e2SSrinivas Pandruvada 		if (CPU_ISSET_S(i, pbf_info->core_cpumask_size,
1755a9b2f8e2SSrinivas Pandruvada 				  pbf_info->core_cpumask))
1756a9b2f8e2SSrinivas Pandruvada 			freq = freq_high;
1757a9b2f8e2SSrinivas Pandruvada 		else
1758a9b2f8e2SSrinivas Pandruvada 			freq = freq_low;
1759a9b2f8e2SSrinivas Pandruvada 
1760a9b2f8e2SSrinivas Pandruvada 		set_cpufreq_scaling_min_max(i, 1, freq);
1761a9b2f8e2SSrinivas Pandruvada 		set_cpufreq_scaling_min_max(i, 0, freq);
1762a9b2f8e2SSrinivas Pandruvada 	}
1763a9b2f8e2SSrinivas Pandruvada 
1764a9b2f8e2SSrinivas Pandruvada 	return 0;
1765a9b2f8e2SSrinivas Pandruvada }
1766a9b2f8e2SSrinivas Pandruvada 
set_cpufreq_scaling_min_max_from_cpuinfo(int cpu,int cpuinfo_max,int scaling_max)1767a9b2f8e2SSrinivas Pandruvada static int set_cpufreq_scaling_min_max_from_cpuinfo(int cpu, int cpuinfo_max, int scaling_max)
1768354bd06fSSrinivas Pandruvada {
1769354bd06fSSrinivas Pandruvada 	char buffer[128], min_freq[16];
1770354bd06fSSrinivas Pandruvada 	int fd, ret, len;
1771354bd06fSSrinivas Pandruvada 
1772354bd06fSSrinivas Pandruvada 	if (!CPU_ISSET_S(cpu, present_cpumask_size, present_cpumask))
1773354bd06fSSrinivas Pandruvada 		return -1;
1774354bd06fSSrinivas Pandruvada 
1775a9b2f8e2SSrinivas Pandruvada 	if (cpuinfo_max)
1776354bd06fSSrinivas Pandruvada 		snprintf(buffer, sizeof(buffer),
1777354bd06fSSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu);
1778354bd06fSSrinivas Pandruvada 	else
1779354bd06fSSrinivas Pandruvada 		snprintf(buffer, sizeof(buffer),
1780354bd06fSSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_min_freq", cpu);
1781354bd06fSSrinivas Pandruvada 
1782354bd06fSSrinivas Pandruvada 	fd = open(buffer, O_RDONLY);
1783354bd06fSSrinivas Pandruvada 	if (fd < 0)
1784354bd06fSSrinivas Pandruvada 		return fd;
1785354bd06fSSrinivas Pandruvada 
1786354bd06fSSrinivas Pandruvada 	len = read(fd, min_freq, sizeof(min_freq));
1787354bd06fSSrinivas Pandruvada 	close(fd);
1788354bd06fSSrinivas Pandruvada 
1789354bd06fSSrinivas Pandruvada 	if (len < 0)
1790354bd06fSSrinivas Pandruvada 		return len;
1791354bd06fSSrinivas Pandruvada 
1792a9b2f8e2SSrinivas Pandruvada 	if (scaling_max)
1793a9b2f8e2SSrinivas Pandruvada 		snprintf(buffer, sizeof(buffer),
1794a9b2f8e2SSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu);
1795a9b2f8e2SSrinivas Pandruvada 	else
1796354bd06fSSrinivas Pandruvada 		snprintf(buffer, sizeof(buffer),
1797354bd06fSSrinivas Pandruvada 			 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu);
1798354bd06fSSrinivas Pandruvada 
1799354bd06fSSrinivas Pandruvada 	fd = open(buffer, O_WRONLY);
1800354bd06fSSrinivas Pandruvada 	if (fd < 0)
1801354bd06fSSrinivas Pandruvada 		return fd;
1802354bd06fSSrinivas Pandruvada 
1803689dfc9eSZhang Rui 	min_freq[15] = '\0';
1804354bd06fSSrinivas Pandruvada 	len = strlen(min_freq);
1805354bd06fSSrinivas Pandruvada 	ret = write(fd, min_freq, len);
1806354bd06fSSrinivas Pandruvada 	if (ret == -1) {
1807354bd06fSSrinivas Pandruvada 		close(fd);
1808354bd06fSSrinivas Pandruvada 		return ret;
1809354bd06fSSrinivas Pandruvada 	}
1810354bd06fSSrinivas Pandruvada 	close(fd);
1811354bd06fSSrinivas Pandruvada 
1812354bd06fSSrinivas Pandruvada 	return 0;
1813354bd06fSSrinivas Pandruvada }
1814354bd06fSSrinivas Pandruvada 
set_scaling_min_to_cpuinfo_max(struct isst_id * id)1815850337ecSZhang Rui static void set_scaling_min_to_cpuinfo_max(struct isst_id *id)
1816354bd06fSSrinivas Pandruvada {
181756d64692SZhang Rui 	int i;
1818354bd06fSSrinivas Pandruvada 
1819d0e12c46SZhang Rui 	if (id->cpu < 0)
1820d0e12c46SZhang Rui 		return;
1821d0e12c46SZhang Rui 
1822354bd06fSSrinivas Pandruvada 	for (i = 0; i < get_topo_max_cpus(); ++i) {
182300bb07dbSZhang Rui 		if (!is_cpu_in_power_domain(i, id))
1824354bd06fSSrinivas Pandruvada 			continue;
1825354bd06fSSrinivas Pandruvada 
1826cf3b8e8fSSrinivas Pandruvada 		if (is_cpu_online(i) != 1)
1827cf3b8e8fSSrinivas Pandruvada 			continue;
1828cf3b8e8fSSrinivas Pandruvada 
18299734213eSSrinivas Pandruvada 		adjust_scaling_max_from_base_freq(i);
1830a9b2f8e2SSrinivas Pandruvada 		set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0);
1831bbaa2e95SSrinivas Pandruvada 		adjust_scaling_min_from_base_freq(i);
1832354bd06fSSrinivas Pandruvada 	}
1833354bd06fSSrinivas Pandruvada }
1834354bd06fSSrinivas Pandruvada 
set_scaling_min_to_cpuinfo_min(struct isst_id * id)1835850337ecSZhang Rui static void set_scaling_min_to_cpuinfo_min(struct isst_id *id)
1836354bd06fSSrinivas Pandruvada {
183756d64692SZhang Rui 	int i;
1838354bd06fSSrinivas Pandruvada 
1839d0e12c46SZhang Rui 	if (id->cpu < 0)
1840d0e12c46SZhang Rui 		return;
1841d0e12c46SZhang Rui 
1842354bd06fSSrinivas Pandruvada 	for (i = 0; i < get_topo_max_cpus(); ++i) {
184300bb07dbSZhang Rui 		if (!is_cpu_in_power_domain(i, id))
1844354bd06fSSrinivas Pandruvada 			continue;
1845354bd06fSSrinivas Pandruvada 
1846cf3b8e8fSSrinivas Pandruvada 		if (is_cpu_online(i) != 1)
1847cf3b8e8fSSrinivas Pandruvada 			continue;
1848cf3b8e8fSSrinivas Pandruvada 
18499734213eSSrinivas Pandruvada 		adjust_scaling_max_from_base_freq(i);
1850a9b2f8e2SSrinivas Pandruvada 		set_cpufreq_scaling_min_max_from_cpuinfo(i, 0, 0);
1851a9b2f8e2SSrinivas Pandruvada 	}
1852a9b2f8e2SSrinivas Pandruvada }
1853a9b2f8e2SSrinivas Pandruvada 
set_scaling_max_to_cpuinfo_max(struct isst_id * id)1854850337ecSZhang Rui static void set_scaling_max_to_cpuinfo_max(struct isst_id *id)
1855a9b2f8e2SSrinivas Pandruvada {
185656d64692SZhang Rui 	int i;
1857a9b2f8e2SSrinivas Pandruvada 
1858a9b2f8e2SSrinivas Pandruvada 	for (i = 0; i < get_topo_max_cpus(); ++i) {
185900bb07dbSZhang Rui 		if (!is_cpu_in_power_domain(i, id))
1860a9b2f8e2SSrinivas Pandruvada 			continue;
1861a9b2f8e2SSrinivas Pandruvada 
1862a9b2f8e2SSrinivas Pandruvada 		set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 1);
1863354bd06fSSrinivas Pandruvada 	}
1864354bd06fSSrinivas Pandruvada }
1865354bd06fSSrinivas Pandruvada 
set_core_priority_and_min(struct isst_id * id,int mask_size,cpu_set_t * cpu_mask,int min_high,int min_low)1866850337ecSZhang Rui static int set_core_priority_and_min(struct isst_id *id, int mask_size,
1867354bd06fSSrinivas Pandruvada 				     cpu_set_t *cpu_mask, int min_high,
1868354bd06fSSrinivas Pandruvada 				     int min_low)
1869354bd06fSSrinivas Pandruvada {
187056d64692SZhang Rui 	int ret, i;
1871354bd06fSSrinivas Pandruvada 
1872354bd06fSSrinivas Pandruvada 	if (!CPU_COUNT_S(mask_size, cpu_mask))
1873354bd06fSSrinivas Pandruvada 		return -1;
1874354bd06fSSrinivas Pandruvada 
1875850337ecSZhang Rui 	ret = set_clos_param(id, 0, 0, 0, min_high, 0xff);
1876354bd06fSSrinivas Pandruvada 	if (ret)
1877354bd06fSSrinivas Pandruvada 		return ret;
1878354bd06fSSrinivas Pandruvada 
1879850337ecSZhang Rui 	ret = set_clos_param(id, 1, 15, 15, min_low, 0xff);
1880354bd06fSSrinivas Pandruvada 	if (ret)
1881354bd06fSSrinivas Pandruvada 		return ret;
1882354bd06fSSrinivas Pandruvada 
1883850337ecSZhang Rui 	ret = set_clos_param(id, 2, 15, 15, min_low, 0xff);
1884354bd06fSSrinivas Pandruvada 	if (ret)
1885354bd06fSSrinivas Pandruvada 		return ret;
1886354bd06fSSrinivas Pandruvada 
1887850337ecSZhang Rui 	ret = set_clos_param(id, 3, 15, 15, min_low, 0xff);
1888354bd06fSSrinivas Pandruvada 	if (ret)
1889354bd06fSSrinivas Pandruvada 		return ret;
1890354bd06fSSrinivas Pandruvada 
1891354bd06fSSrinivas Pandruvada 	for (i = 0; i < get_topo_max_cpus(); ++i) {
1892354bd06fSSrinivas Pandruvada 		int clos;
1893850337ecSZhang Rui 		struct isst_id tid;
1894354bd06fSSrinivas Pandruvada 
189500bb07dbSZhang Rui 		if (!is_cpu_in_power_domain(i, id))
1896354bd06fSSrinivas Pandruvada 			continue;
1897354bd06fSSrinivas Pandruvada 
1898354bd06fSSrinivas Pandruvada 		if (CPU_ISSET_S(i, mask_size, cpu_mask))
1899354bd06fSSrinivas Pandruvada 			clos = 0;
1900354bd06fSSrinivas Pandruvada 		else
1901354bd06fSSrinivas Pandruvada 			clos = 3;
1902354bd06fSSrinivas Pandruvada 
1903354bd06fSSrinivas Pandruvada 		debug_printf("Associate cpu: %d clos: %d\n", i, clos);
1904850337ecSZhang Rui 		set_isst_id(&tid, i);
1905850337ecSZhang Rui 		ret = isst_clos_associate(&tid, clos);
1906354bd06fSSrinivas Pandruvada 		if (ret) {
1907fe6fb216SSrinivas Pandruvada 			isst_display_error_info_message(1, "isst_clos_associate failed", 0, 0);
1908354bd06fSSrinivas Pandruvada 			return ret;
1909354bd06fSSrinivas Pandruvada 		}
1910354bd06fSSrinivas Pandruvada 	}
1911354bd06fSSrinivas Pandruvada 
1912354bd06fSSrinivas Pandruvada 	return 0;
1913354bd06fSSrinivas Pandruvada }
1914354bd06fSSrinivas Pandruvada 
set_pbf_core_power(struct isst_id * id)1915850337ecSZhang Rui static int set_pbf_core_power(struct isst_id *id)
1916354bd06fSSrinivas Pandruvada {
1917354bd06fSSrinivas Pandruvada 	struct isst_pbf_info pbf_info;
1918354bd06fSSrinivas Pandruvada 	struct isst_pkg_ctdp pkg_dev;
1919354bd06fSSrinivas Pandruvada 	int ret;
1920354bd06fSSrinivas Pandruvada 
1921d0e12c46SZhang Rui 	if (id->cpu < 0)
1922d0e12c46SZhang Rui 		return 0;
1923d0e12c46SZhang Rui 
1924850337ecSZhang Rui 	ret = isst_get_ctdp_levels(id, &pkg_dev);
1925354bd06fSSrinivas Pandruvada 	if (ret) {
1926fe6fb216SSrinivas Pandruvada 		debug_printf("isst_get_ctdp_levels failed");
1927354bd06fSSrinivas Pandruvada 		return ret;
1928354bd06fSSrinivas Pandruvada 	}
1929354bd06fSSrinivas Pandruvada 	debug_printf("Current_level: %d\n", pkg_dev.current_level);
1930354bd06fSSrinivas Pandruvada 
1931850337ecSZhang Rui 	ret = isst_get_pbf_info(id, pkg_dev.current_level, &pbf_info);
1932354bd06fSSrinivas Pandruvada 	if (ret) {
1933fe6fb216SSrinivas Pandruvada 		debug_printf("isst_get_pbf_info failed");
1934354bd06fSSrinivas Pandruvada 		return ret;
1935354bd06fSSrinivas Pandruvada 	}
1936354bd06fSSrinivas Pandruvada 	debug_printf("p1_high: %d p1_low: %d\n", pbf_info.p1_high,
1937354bd06fSSrinivas Pandruvada 		     pbf_info.p1_low);
1938354bd06fSSrinivas Pandruvada 
1939850337ecSZhang Rui 	ret = set_core_priority_and_min(id, pbf_info.core_cpumask_size,
1940354bd06fSSrinivas Pandruvada 					pbf_info.core_cpumask,
1941354bd06fSSrinivas Pandruvada 					pbf_info.p1_high, pbf_info.p1_low);
1942354bd06fSSrinivas Pandruvada 	if (ret) {
1943fe6fb216SSrinivas Pandruvada 		debug_printf("set_core_priority_and_min failed");
1944354bd06fSSrinivas Pandruvada 		return ret;
1945354bd06fSSrinivas Pandruvada 	}
1946354bd06fSSrinivas Pandruvada 
1947850337ecSZhang Rui 	ret = isst_pm_qos_config(id, 1, 1);
1948354bd06fSSrinivas Pandruvada 	if (ret) {
1949fe6fb216SSrinivas Pandruvada 		debug_printf("isst_pm_qos_config failed");
1950354bd06fSSrinivas Pandruvada 		return ret;
1951354bd06fSSrinivas Pandruvada 	}
1952354bd06fSSrinivas Pandruvada 
1953354bd06fSSrinivas Pandruvada 	return 0;
1954354bd06fSSrinivas Pandruvada }
1955354bd06fSSrinivas Pandruvada 
set_pbf_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)1956850337ecSZhang Rui static void set_pbf_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
19573fb4f7cdSSrinivas Pandruvada 			    void *arg4)
19583fb4f7cdSSrinivas Pandruvada {
19593d904f06SSrinivas Pandruvada 	struct isst_pkg_ctdp_level_info ctdp_level;
19603d904f06SSrinivas Pandruvada 	struct isst_pkg_ctdp pkg_dev;
19613fb4f7cdSSrinivas Pandruvada 	int ret;
19623fb4f7cdSSrinivas Pandruvada 	int status = *(int *)arg4;
19633fb4f7cdSSrinivas Pandruvada 
19641aa7177cSPrarit Bhargava 	if (is_clx_n_platform()) {
19651aa7177cSPrarit Bhargava 		ret = 0;
19667fc9fefdSSrinivas Pandruvada 		if (status) {
1967850337ecSZhang Rui 			set_clx_pbf_cpufreq_scaling_min_max(id);
1968a9b2f8e2SSrinivas Pandruvada 
1969a9b2f8e2SSrinivas Pandruvada 		} else {
1970850337ecSZhang Rui 			set_scaling_max_to_cpuinfo_max(id);
1971850337ecSZhang Rui 			set_scaling_min_to_cpuinfo_min(id);
1972a9b2f8e2SSrinivas Pandruvada 		}
19731aa7177cSPrarit Bhargava 		goto disp_result;
19741aa7177cSPrarit Bhargava 	}
19751aa7177cSPrarit Bhargava 
1976850337ecSZhang Rui 	ret = isst_get_ctdp_levels(id, &pkg_dev);
19773d904f06SSrinivas Pandruvada 	if (ret) {
19783d904f06SSrinivas Pandruvada 		isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
19793d904f06SSrinivas Pandruvada 		goto disp_result;
19803d904f06SSrinivas Pandruvada 	}
19813d904f06SSrinivas Pandruvada 
1982850337ecSZhang Rui 	ret = isst_get_ctdp_control(id, pkg_dev.current_level, &ctdp_level);
19833d904f06SSrinivas Pandruvada 	if (ret) {
19843d904f06SSrinivas Pandruvada 		isst_display_error_info_message(1, "Failed to get current level", 0, 0);
19853d904f06SSrinivas Pandruvada 		goto disp_result;
19863d904f06SSrinivas Pandruvada 	}
19873d904f06SSrinivas Pandruvada 
19883d904f06SSrinivas Pandruvada 	if (!ctdp_level.pbf_support) {
19893d904f06SSrinivas Pandruvada 		isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, pkg_dev.current_level);
19903d904f06SSrinivas Pandruvada 		ret = -1;
19913d904f06SSrinivas Pandruvada 		goto disp_result;
19923d904f06SSrinivas Pandruvada 	}
19933d904f06SSrinivas Pandruvada 
1994097a5222SSrinivas Pandruvada 	if (auto_mode && status) {
1995850337ecSZhang Rui 		ret = set_pbf_core_power(id);
1996354bd06fSSrinivas Pandruvada 		if (ret)
1997354bd06fSSrinivas Pandruvada 			goto disp_result;
1998354bd06fSSrinivas Pandruvada 	}
1999354bd06fSSrinivas Pandruvada 
2000850337ecSZhang Rui 	ret = isst_set_pbf_fact_status(id, 1, status);
20013fb4f7cdSSrinivas Pandruvada 	if (ret) {
200239bae0fcSSrinivas Pandruvada 		debug_printf("isst_set_pbf_fact_status failed");
2003354bd06fSSrinivas Pandruvada 		if (auto_mode)
2004850337ecSZhang Rui 			isst_pm_qos_config(id, 0, 0);
20053fb4f7cdSSrinivas Pandruvada 	} else {
2006354bd06fSSrinivas Pandruvada 		if (auto_mode) {
2007354bd06fSSrinivas Pandruvada 			if (status)
2008850337ecSZhang Rui 				set_scaling_min_to_cpuinfo_max(id);
2009354bd06fSSrinivas Pandruvada 			else
2010850337ecSZhang Rui 				set_scaling_min_to_cpuinfo_min(id);
2011354bd06fSSrinivas Pandruvada 		}
2012354bd06fSSrinivas Pandruvada 	}
2013354bd06fSSrinivas Pandruvada 
2014097a5222SSrinivas Pandruvada 	if (auto_mode && !status)
2015850337ecSZhang Rui 		isst_pm_qos_config(id, 0, 1);
2016097a5222SSrinivas Pandruvada 
2017354bd06fSSrinivas Pandruvada disp_result:
20183fb4f7cdSSrinivas Pandruvada 	if (status)
2019850337ecSZhang Rui 		isst_display_result(id, outf, "base-freq", "enable",
20203fb4f7cdSSrinivas Pandruvada 				    ret);
20213fb4f7cdSSrinivas Pandruvada 	else
2022850337ecSZhang Rui 		isst_display_result(id, outf, "base-freq", "disable",
20233fb4f7cdSSrinivas Pandruvada 				    ret);
20243fb4f7cdSSrinivas Pandruvada }
20253fb4f7cdSSrinivas Pandruvada 
set_pbf_enable(int arg)2026ce1326a2SPrarit Bhargava static void set_pbf_enable(int arg)
20273fb4f7cdSSrinivas Pandruvada {
2028ce1326a2SPrarit Bhargava 	int enable = arg;
20293fb4f7cdSSrinivas Pandruvada 
20303fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
2031ce1326a2SPrarit Bhargava 		if (enable) {
20323fb4f7cdSSrinivas Pandruvada 			fprintf(stderr,
2033354bd06fSSrinivas Pandruvada 				"Enable Intel Speed Select Technology base frequency feature\n");
203439bae0fcSSrinivas Pandruvada 			if (is_clx_n_platform()) {
203539bae0fcSSrinivas Pandruvada 				fprintf(stderr,
203639bae0fcSSrinivas Pandruvada 					"\tOn this platform this command doesn't enable feature in the hardware.\n");
203739bae0fcSSrinivas Pandruvada 				fprintf(stderr,
203839bae0fcSSrinivas Pandruvada 					"\tIt updates the cpufreq scaling_min_freq to match cpufreq base_frequency.\n");
203939bae0fcSSrinivas Pandruvada 				exit(0);
204039bae0fcSSrinivas Pandruvada 
204139bae0fcSSrinivas Pandruvada 			}
2042354bd06fSSrinivas Pandruvada 			fprintf(stderr,
2043354bd06fSSrinivas Pandruvada 				"\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n");
2044ce1326a2SPrarit Bhargava 		} else {
2045354bd06fSSrinivas Pandruvada 
204639bae0fcSSrinivas Pandruvada 			if (is_clx_n_platform()) {
204739bae0fcSSrinivas Pandruvada 				fprintf(stderr,
204839bae0fcSSrinivas Pandruvada 					"\tOn this platform this command doesn't disable feature in the hardware.\n");
204939bae0fcSSrinivas Pandruvada 				fprintf(stderr,
205039bae0fcSSrinivas Pandruvada 					"\tIt updates the cpufreq scaling_min_freq to match cpuinfo_min_freq\n");
205139bae0fcSSrinivas Pandruvada 				exit(0);
205239bae0fcSSrinivas Pandruvada 			}
20533fb4f7cdSSrinivas Pandruvada 			fprintf(stderr,
2054354bd06fSSrinivas Pandruvada 				"Disable Intel Speed Select Technology base frequency feature\n");
2055354bd06fSSrinivas Pandruvada 			fprintf(stderr,
2056354bd06fSSrinivas Pandruvada 				"\tOptional Arguments: -a|--auto : Also disable core-power associations\n");
2057ce1326a2SPrarit Bhargava 		}
20583fb4f7cdSSrinivas Pandruvada 		exit(0);
20593fb4f7cdSSrinivas Pandruvada 	}
20603fb4f7cdSSrinivas Pandruvada 
20613fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
20623fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
20633fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL,
2064ce1326a2SPrarit Bhargava 						  NULL, &enable);
20653fb4f7cdSSrinivas Pandruvada 	else
2066c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(set_pbf_for_cpu, NULL, NULL,
2067ce1326a2SPrarit Bhargava 					       NULL, &enable);
20683fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
20693fb4f7cdSSrinivas Pandruvada }
20703fb4f7cdSSrinivas Pandruvada 
dump_fact_config_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2071850337ecSZhang Rui static void dump_fact_config_for_cpu(struct isst_id *id, void *arg1, void *arg2,
20723fb4f7cdSSrinivas Pandruvada 				     void *arg3, void *arg4)
20733fb4f7cdSSrinivas Pandruvada {
20743fb4f7cdSSrinivas Pandruvada 	struct isst_fact_info fact_info;
20753fb4f7cdSSrinivas Pandruvada 	int ret;
20763fb4f7cdSSrinivas Pandruvada 
207755d5639bSSrinivas Pandruvada 	memset(&fact_info, 0, sizeof(fact_info));
2078850337ecSZhang Rui 	ret = isst_get_fact_info(id, tdp_level, fact_bucket, &fact_info);
2079a9fd6ae7SSrinivas Pandruvada 	if (ret) {
2080a9fd6ae7SSrinivas Pandruvada 		isst_display_error_info_message(1, "Failed to get turbo-freq info at this level", 1, tdp_level);
2081a9fd6ae7SSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);
2082a9fd6ae7SSrinivas Pandruvada 		exit(1);
2083a9fd6ae7SSrinivas Pandruvada 	} else {
2084850337ecSZhang Rui 		isst_fact_display_information(id, outf, tdp_level, fact_bucket,
20853fb4f7cdSSrinivas Pandruvada 					      fact_avx, &fact_info);
20863fb4f7cdSSrinivas Pandruvada 	}
2087a9fd6ae7SSrinivas Pandruvada }
20883fb4f7cdSSrinivas Pandruvada 
dump_fact_config(int arg)2089ce1326a2SPrarit Bhargava static void dump_fact_config(int arg)
20903fb4f7cdSSrinivas Pandruvada {
20913fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
20923fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
20933fb4f7cdSSrinivas Pandruvada 			"Print complete Intel Speed Select Technology turbo frequency configuration for a TDP level. Other arguments are optional.\n");
20943fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
20953fb4f7cdSSrinivas Pandruvada 			"\tArguments: -l|--level : Specify tdp level\n");
20963fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
20973fb4f7cdSSrinivas Pandruvada 			"\tArguments: -b|--bucket : Bucket index to dump\n");
20983fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
20993fb4f7cdSSrinivas Pandruvada 			"\tArguments: -r|--trl-type : Specify trl type: sse|avx2|avx512\n");
21003fb4f7cdSSrinivas Pandruvada 		exit(0);
21013fb4f7cdSSrinivas Pandruvada 	}
21023fb4f7cdSSrinivas Pandruvada 
21033fb4f7cdSSrinivas Pandruvada 	if (tdp_level == 0xff) {
2104a9fd6ae7SSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid command: specify tdp_level\n", 0, 0);
21053fb4f7cdSSrinivas Pandruvada 		exit(1);
21063fb4f7cdSSrinivas Pandruvada 	}
21073fb4f7cdSSrinivas Pandruvada 
21083fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
21093fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
21103fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(dump_fact_config_for_cpu,
21113fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL, NULL);
21123fb4f7cdSSrinivas Pandruvada 	else
2113c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(dump_fact_config_for_cpu, NULL,
21143fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
21153fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
21163fb4f7cdSSrinivas Pandruvada }
21173fb4f7cdSSrinivas Pandruvada 
set_fact_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2118850337ecSZhang Rui static void set_fact_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
21193fb4f7cdSSrinivas Pandruvada 			     void *arg4)
21203fb4f7cdSSrinivas Pandruvada {
21213d904f06SSrinivas Pandruvada 	struct isst_pkg_ctdp_level_info ctdp_level;
21223d904f06SSrinivas Pandruvada 	struct isst_pkg_ctdp pkg_dev;
21233fb4f7cdSSrinivas Pandruvada 	int ret;
21243fb4f7cdSSrinivas Pandruvada 	int status = *(int *)arg4;
21253fb4f7cdSSrinivas Pandruvada 
21262da6391dSSrinivas Pandruvada 	if (status && no_turbo()) {
21272da6391dSSrinivas Pandruvada 		isst_display_error_info_message(1, "Turbo mode is disabled", 0, 0);
21282da6391dSSrinivas Pandruvada 		ret = -1;
21292da6391dSSrinivas Pandruvada 		goto disp_results;
21302da6391dSSrinivas Pandruvada 	}
21312da6391dSSrinivas Pandruvada 
2132850337ecSZhang Rui 	ret = isst_get_ctdp_levels(id, &pkg_dev);
21333d904f06SSrinivas Pandruvada 	if (ret) {
21343d904f06SSrinivas Pandruvada 		isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
21353d904f06SSrinivas Pandruvada 		goto disp_results;
21363d904f06SSrinivas Pandruvada 	}
21373d904f06SSrinivas Pandruvada 
2138850337ecSZhang Rui 	ret = isst_get_ctdp_control(id, pkg_dev.current_level, &ctdp_level);
21393d904f06SSrinivas Pandruvada 	if (ret) {
21403d904f06SSrinivas Pandruvada 		isst_display_error_info_message(1, "Failed to get current level", 0, 0);
21413d904f06SSrinivas Pandruvada 		goto disp_results;
21423d904f06SSrinivas Pandruvada 	}
21433d904f06SSrinivas Pandruvada 
21443d904f06SSrinivas Pandruvada 	if (!ctdp_level.fact_support) {
21453d904f06SSrinivas Pandruvada 		isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, pkg_dev.current_level);
21463d904f06SSrinivas Pandruvada 		ret = -1;
21473d904f06SSrinivas Pandruvada 		goto disp_results;
21483d904f06SSrinivas Pandruvada 	}
21493d904f06SSrinivas Pandruvada 
21507983ed6fSSrinivas Pandruvada 	if (status) {
2151850337ecSZhang Rui 		ret = isst_pm_qos_config(id, 1, 1);
21523fb4f7cdSSrinivas Pandruvada 		if (ret)
2153a6a82f9bSSrinivas Pandruvada 			goto disp_results;
2154a6a82f9bSSrinivas Pandruvada 	}
2155a6a82f9bSSrinivas Pandruvada 
2156850337ecSZhang Rui 	ret = isst_set_pbf_fact_status(id, 0, status);
2157a6a82f9bSSrinivas Pandruvada 	if (ret) {
2158a9fd6ae7SSrinivas Pandruvada 		debug_printf("isst_set_pbf_fact_status failed");
2159a6a82f9bSSrinivas Pandruvada 		if (auto_mode)
2160850337ecSZhang Rui 			isst_pm_qos_config(id, 0, 0);
2161a6a82f9bSSrinivas Pandruvada 
2162a6a82f9bSSrinivas Pandruvada 		goto disp_results;
2163a6a82f9bSSrinivas Pandruvada 	}
2164a6a82f9bSSrinivas Pandruvada 
2165a6a82f9bSSrinivas Pandruvada 	/* Set TRL */
21663fb4f7cdSSrinivas Pandruvada 	if (status) {
21673fb4f7cdSSrinivas Pandruvada 		struct isst_pkg_ctdp pkg_dev;
21683fb4f7cdSSrinivas Pandruvada 
2169850337ecSZhang Rui 		ret = isst_get_ctdp_levels(id, &pkg_dev);
2170d0e12c46SZhang Rui 		if (!ret && id->cpu >= 0)
2171850337ecSZhang Rui 			ret = isst_set_trl(id, fact_trl);
2172a6a82f9bSSrinivas Pandruvada 		if (ret && auto_mode)
2173850337ecSZhang Rui 			isst_pm_qos_config(id, 0, 0);
2174097a5222SSrinivas Pandruvada 	} else {
2175097a5222SSrinivas Pandruvada 		if (auto_mode)
2176850337ecSZhang Rui 			isst_pm_qos_config(id, 0, 0);
2177a6a82f9bSSrinivas Pandruvada 	}
2178a6a82f9bSSrinivas Pandruvada 
2179a6a82f9bSSrinivas Pandruvada disp_results:
2180a6a82f9bSSrinivas Pandruvada 	if (status) {
2181850337ecSZhang Rui 		isst_display_result(id, outf, "turbo-freq", "enable", ret);
218214a8aa49SSrinivas Pandruvada 		if (ret)
218314a8aa49SSrinivas Pandruvada 			fact_enable_fail = ret;
21843fb4f7cdSSrinivas Pandruvada 	} else {
21853fb4f7cdSSrinivas Pandruvada 		/* Since we modified TRL during Fact enable, restore it */
2186850337ecSZhang Rui 		isst_set_trl_from_current_tdp(id, fact_trl);
2187850337ecSZhang Rui 		isst_display_result(id, outf, "turbo-freq", "disable", ret);
21883fb4f7cdSSrinivas Pandruvada 	}
21893fb4f7cdSSrinivas Pandruvada }
21903fb4f7cdSSrinivas Pandruvada 
set_fact_enable(int arg)2191ce1326a2SPrarit Bhargava static void set_fact_enable(int arg)
21923fb4f7cdSSrinivas Pandruvada {
2193ce1326a2SPrarit Bhargava 	int i, ret, enable = arg;
2194850337ecSZhang Rui 	struct isst_id id;
21953fb4f7cdSSrinivas Pandruvada 
21963fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
2197ce1326a2SPrarit Bhargava 		if (enable) {
21983fb4f7cdSSrinivas Pandruvada 			fprintf(stderr,
21993fb4f7cdSSrinivas Pandruvada 				"Enable Intel Speed Select Technology Turbo frequency feature\n");
22003fb4f7cdSSrinivas Pandruvada 			fprintf(stderr,
22013076db34SSrinivas Pandruvada 				"Optional: -t|--trl : Specify turbo ratio limit in hex starting with 0x\n");
2202a6a82f9bSSrinivas Pandruvada 			fprintf(stderr,
2203a6a82f9bSSrinivas Pandruvada 				"\tOptional Arguments: -a|--auto : Designate specified target CPUs with");
2204ce1326a2SPrarit Bhargava 			fprintf(stderr,
2205ce1326a2SPrarit Bhargava 				"-C|--cpu option as as high priority using core-power feature\n");
2206ce1326a2SPrarit Bhargava 		} else {
2207ce1326a2SPrarit Bhargava 			fprintf(stderr,
2208ce1326a2SPrarit Bhargava 				"Disable Intel Speed Select Technology turbo frequency feature\n");
2209ce1326a2SPrarit Bhargava 			fprintf(stderr,
22103076db34SSrinivas Pandruvada 				"Optional: -t|--trl : Specify turbo ratio limit in hex starting with 0x\n");
2211ce1326a2SPrarit Bhargava 			fprintf(stderr,
2212ce1326a2SPrarit Bhargava 				"\tOptional Arguments: -a|--auto : Also disable core-power associations\n");
2213ce1326a2SPrarit Bhargava 		}
22143fb4f7cdSSrinivas Pandruvada 		exit(0);
22153fb4f7cdSSrinivas Pandruvada 	}
22163fb4f7cdSSrinivas Pandruvada 
22173fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
22183fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
22193fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL,
2220ce1326a2SPrarit Bhargava 						  NULL, &enable);
22213fb4f7cdSSrinivas Pandruvada 	else
2222c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(set_fact_for_cpu, NULL, NULL,
2223ce1326a2SPrarit Bhargava 					       NULL, &enable);
2224a6a82f9bSSrinivas Pandruvada 
222514a8aa49SSrinivas Pandruvada 	if (!fact_enable_fail && enable && auto_mode) {
2226a6a82f9bSSrinivas Pandruvada 		/*
2227a6a82f9bSSrinivas Pandruvada 		 * When we adjust CLOS param, we have to set for siblings also.
2228a6a82f9bSSrinivas Pandruvada 		 * So for the each user specified CPU, also add the sibling
2229a6a82f9bSSrinivas Pandruvada 		 * in the present_cpu_mask.
2230a6a82f9bSSrinivas Pandruvada 		 */
2231a6a82f9bSSrinivas Pandruvada 		for (i = 0; i < get_topo_max_cpus(); ++i) {
2232a6a82f9bSSrinivas Pandruvada 			char buffer[128], sibling_list[128], *cpu_str;
2233a6a82f9bSSrinivas Pandruvada 			int fd, len;
2234a6a82f9bSSrinivas Pandruvada 
2235a6a82f9bSSrinivas Pandruvada 			if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask))
2236a6a82f9bSSrinivas Pandruvada 				continue;
2237a6a82f9bSSrinivas Pandruvada 
2238a6a82f9bSSrinivas Pandruvada 			snprintf(buffer, sizeof(buffer),
2239a6a82f9bSSrinivas Pandruvada 				 "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i);
2240a6a82f9bSSrinivas Pandruvada 
2241a6a82f9bSSrinivas Pandruvada 			fd = open(buffer, O_RDONLY);
2242a6a82f9bSSrinivas Pandruvada 			if (fd < 0)
2243a6a82f9bSSrinivas Pandruvada 				continue;
2244a6a82f9bSSrinivas Pandruvada 
2245a6a82f9bSSrinivas Pandruvada 			len = read(fd, sibling_list, sizeof(sibling_list));
2246a6a82f9bSSrinivas Pandruvada 			close(fd);
2247a6a82f9bSSrinivas Pandruvada 
2248a6a82f9bSSrinivas Pandruvada 			if (len < 0)
2249a6a82f9bSSrinivas Pandruvada 				continue;
2250a6a82f9bSSrinivas Pandruvada 
2251689dfc9eSZhang Rui 			sibling_list[127] = '\0';
2252a6a82f9bSSrinivas Pandruvada 			cpu_str = strtok(sibling_list, ",");
2253a6a82f9bSSrinivas Pandruvada 			while (cpu_str != NULL) {
2254a6a82f9bSSrinivas Pandruvada 				int cpu;
2255a6a82f9bSSrinivas Pandruvada 
2256a6a82f9bSSrinivas Pandruvada 				sscanf(cpu_str, "%d", &cpu);
2257a6a82f9bSSrinivas Pandruvada 				CPU_SET_S(cpu, target_cpumask_size, target_cpumask);
2258a6a82f9bSSrinivas Pandruvada 				cpu_str = strtok(NULL, ",");
2259a6a82f9bSSrinivas Pandruvada 			}
2260a6a82f9bSSrinivas Pandruvada 		}
2261a6a82f9bSSrinivas Pandruvada 
2262a6a82f9bSSrinivas Pandruvada 		for (i = 0; i < get_topo_max_cpus(); ++i) {
2263a6a82f9bSSrinivas Pandruvada 			int clos;
2264a6a82f9bSSrinivas Pandruvada 
2265a6a82f9bSSrinivas Pandruvada 			if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask))
2266a6a82f9bSSrinivas Pandruvada 				continue;
2267a6a82f9bSSrinivas Pandruvada 
22686ed9e363SSrinivas Pandruvada 			if (is_cpu_online(i) != 1)
22696ed9e363SSrinivas Pandruvada 				continue;
22706ed9e363SSrinivas Pandruvada 
2271850337ecSZhang Rui 			set_isst_id(&id, i);
2272850337ecSZhang Rui 			ret = set_clos_param(&id, 0, 0, 0, 0, 0xff);
2273a6a82f9bSSrinivas Pandruvada 			if (ret)
2274a6a82f9bSSrinivas Pandruvada 				goto error_disp;
2275a6a82f9bSSrinivas Pandruvada 
2276850337ecSZhang Rui 			ret = set_clos_param(&id, 1, 15, 15, 0, 0xff);
2277a6a82f9bSSrinivas Pandruvada 			if (ret)
2278a6a82f9bSSrinivas Pandruvada 				goto error_disp;
2279a6a82f9bSSrinivas Pandruvada 
2280850337ecSZhang Rui 			ret = set_clos_param(&id, 2, 15, 15, 0, 0xff);
2281a6a82f9bSSrinivas Pandruvada 			if (ret)
2282a6a82f9bSSrinivas Pandruvada 				goto error_disp;
2283a6a82f9bSSrinivas Pandruvada 
2284850337ecSZhang Rui 			ret = set_clos_param(&id, 3, 15, 15, 0, 0xff);
2285a6a82f9bSSrinivas Pandruvada 			if (ret)
2286a6a82f9bSSrinivas Pandruvada 				goto error_disp;
2287a6a82f9bSSrinivas Pandruvada 
2288a6a82f9bSSrinivas Pandruvada 			if (CPU_ISSET_S(i, target_cpumask_size, target_cpumask))
2289a6a82f9bSSrinivas Pandruvada 				clos = 0;
2290a6a82f9bSSrinivas Pandruvada 			else
2291a6a82f9bSSrinivas Pandruvada 				clos = 3;
2292a6a82f9bSSrinivas Pandruvada 
2293a6a82f9bSSrinivas Pandruvada 			debug_printf("Associate cpu: %d clos: %d\n", i, clos);
2294850337ecSZhang Rui 			ret = isst_clos_associate(&id, clos);
2295a6a82f9bSSrinivas Pandruvada 			if (ret)
2296a6a82f9bSSrinivas Pandruvada 				goto error_disp;
2297a6a82f9bSSrinivas Pandruvada 		}
2298850337ecSZhang Rui 		set_isst_id(&id, -1);
2299850337ecSZhang Rui 		isst_display_result(&id, outf, "turbo-freq --auto", "enable", 0);
2300a6a82f9bSSrinivas Pandruvada 	}
2301a6a82f9bSSrinivas Pandruvada 
2302fcf12783SSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
2303fcf12783SSrinivas Pandruvada 
2304a6a82f9bSSrinivas Pandruvada 	return;
2305a6a82f9bSSrinivas Pandruvada 
2306a6a82f9bSSrinivas Pandruvada error_disp:
2307850337ecSZhang Rui 	isst_display_result(&id, outf, "turbo-freq --auto", "enable", ret);
2308fcf12783SSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
2309a6a82f9bSSrinivas Pandruvada 
23103fb4f7cdSSrinivas Pandruvada }
23113fb4f7cdSSrinivas Pandruvada 
enable_clos_qos_config(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2312850337ecSZhang Rui static void enable_clos_qos_config(struct isst_id *id, void *arg1, void *arg2, void *arg3,
23133fb4f7cdSSrinivas Pandruvada 				   void *arg4)
23143fb4f7cdSSrinivas Pandruvada {
23153fb4f7cdSSrinivas Pandruvada 	int ret;
23163fb4f7cdSSrinivas Pandruvada 	int status = *(int *)arg4;
2317da4c1b9eSSrinivas Pandruvada 	int cp_state, cp_cap;
2318da4c1b9eSSrinivas Pandruvada 
2319da4c1b9eSSrinivas Pandruvada 	if (!isst_read_pm_config(id, &cp_state, &cp_cap)) {
2320da4c1b9eSSrinivas Pandruvada 		if (!cp_cap) {
2321da4c1b9eSSrinivas Pandruvada 			isst_display_error_info_message(1, "core-power not supported", 0, 0);
2322da4c1b9eSSrinivas Pandruvada 			return;
2323da4c1b9eSSrinivas Pandruvada 		}
2324da4c1b9eSSrinivas Pandruvada 	}
23253fb4f7cdSSrinivas Pandruvada 
2326fe6fb216SSrinivas Pandruvada 	if (is_skx_based_platform())
2327fe6fb216SSrinivas Pandruvada 		clos_priority_type = 1;
2328fe6fb216SSrinivas Pandruvada 
2329850337ecSZhang Rui 	ret = isst_pm_qos_config(id, status, clos_priority_type);
2330a6a82f9bSSrinivas Pandruvada 	if (ret)
2331fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "isst_pm_qos_config failed", 0, 0);
2332a6a82f9bSSrinivas Pandruvada 
23333fb4f7cdSSrinivas Pandruvada 	if (status)
2334850337ecSZhang Rui 		isst_display_result(id, outf, "core-power", "enable",
23353fb4f7cdSSrinivas Pandruvada 				    ret);
23363fb4f7cdSSrinivas Pandruvada 	else
2337850337ecSZhang Rui 		isst_display_result(id, outf, "core-power", "disable",
23383fb4f7cdSSrinivas Pandruvada 				    ret);
23393fb4f7cdSSrinivas Pandruvada }
23403fb4f7cdSSrinivas Pandruvada 
set_clos_enable(int arg)2341ce1326a2SPrarit Bhargava static void set_clos_enable(int arg)
23423fb4f7cdSSrinivas Pandruvada {
2343ce1326a2SPrarit Bhargava 	int enable = arg;
23443fb4f7cdSSrinivas Pandruvada 
23453fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
2346ce1326a2SPrarit Bhargava 		if (enable) {
2347ce1326a2SPrarit Bhargava 			fprintf(stderr,
2348ce1326a2SPrarit Bhargava 				"Enable core-power for a package/die\n");
2349fe6fb216SSrinivas Pandruvada 			if (!is_skx_based_platform()) {
23503fb4f7cdSSrinivas Pandruvada 				fprintf(stderr,
23513fb4f7cdSSrinivas Pandruvada 					"\tClos Enable: Specify priority type with [--priority|-p]\n");
23523fb4f7cdSSrinivas Pandruvada 				fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n");
2353fe6fb216SSrinivas Pandruvada 			}
2354ce1326a2SPrarit Bhargava 		} else {
2355ce1326a2SPrarit Bhargava 			fprintf(stderr,
2356ce1326a2SPrarit Bhargava 				"Disable core-power: [No command arguments are required]\n");
2357ce1326a2SPrarit Bhargava 		}
23583fb4f7cdSSrinivas Pandruvada 		exit(0);
23593fb4f7cdSSrinivas Pandruvada 	}
23603fb4f7cdSSrinivas Pandruvada 
2361ce1326a2SPrarit Bhargava 	if (enable && cpufreq_sysfs_present()) {
23623fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
23633fb4f7cdSSrinivas Pandruvada 			"cpufreq subsystem and core-power enable will interfere with each other!\n");
23643fb4f7cdSSrinivas Pandruvada 	}
23653fb4f7cdSSrinivas Pandruvada 
23663fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
23673fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
23683fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL,
2369ce1326a2SPrarit Bhargava 						  NULL, NULL, &enable);
23703fb4f7cdSSrinivas Pandruvada 	else
2371c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(enable_clos_qos_config, NULL,
2372ce1326a2SPrarit Bhargava 					       NULL, NULL, &enable);
23733fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
23743fb4f7cdSSrinivas Pandruvada }
23753fb4f7cdSSrinivas Pandruvada 
dump_clos_config_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2376850337ecSZhang Rui static void dump_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2,
23773fb4f7cdSSrinivas Pandruvada 				     void *arg3, void *arg4)
23783fb4f7cdSSrinivas Pandruvada {
23793fb4f7cdSSrinivas Pandruvada 	struct isst_clos_config clos_config;
23803fb4f7cdSSrinivas Pandruvada 	int ret;
23813fb4f7cdSSrinivas Pandruvada 
2382850337ecSZhang Rui 	ret = isst_pm_get_clos(id, current_clos, &clos_config);
23833fb4f7cdSSrinivas Pandruvada 	if (ret)
2384fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0);
23853fb4f7cdSSrinivas Pandruvada 	else
2386850337ecSZhang Rui 		isst_clos_display_information(id, outf, current_clos,
23873fb4f7cdSSrinivas Pandruvada 					      &clos_config);
23883fb4f7cdSSrinivas Pandruvada }
23893fb4f7cdSSrinivas Pandruvada 
dump_clos_config(int arg)2390ce1326a2SPrarit Bhargava static void dump_clos_config(int arg)
23913fb4f7cdSSrinivas Pandruvada {
23923fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
23933fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
23943fb4f7cdSSrinivas Pandruvada 			"Print Intel Speed Select Technology core power configuration\n");
23953fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
23963fb4f7cdSSrinivas Pandruvada 			"\tArguments: [-c | --clos]: Specify clos id\n");
23973fb4f7cdSSrinivas Pandruvada 		exit(0);
23983fb4f7cdSSrinivas Pandruvada 	}
23993fb4f7cdSSrinivas Pandruvada 	if (current_clos < 0 || current_clos > 3) {
2400fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid clos id\n", 0, 0);
2401fe6fb216SSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);
24023fb4f7cdSSrinivas Pandruvada 		exit(0);
24033fb4f7cdSSrinivas Pandruvada 	}
24043fb4f7cdSSrinivas Pandruvada 
24053fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
24063fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
24073fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(dump_clos_config_for_cpu,
24083fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL, NULL);
24093fb4f7cdSSrinivas Pandruvada 	else
2410c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(dump_clos_config_for_cpu, NULL,
24113fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
24123fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
24133fb4f7cdSSrinivas Pandruvada }
24143fb4f7cdSSrinivas Pandruvada 
get_clos_info_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2415850337ecSZhang Rui static void get_clos_info_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
2416188afed9SSrinivas Pandruvada 				  void *arg4)
2417188afed9SSrinivas Pandruvada {
2418188afed9SSrinivas Pandruvada 	int enable, ret, prio_type;
2419188afed9SSrinivas Pandruvada 
2420850337ecSZhang Rui 	ret = isst_clos_get_clos_information(id, &enable, &prio_type);
2421188afed9SSrinivas Pandruvada 	if (ret)
2422fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "isst_clos_get_info failed", 0, 0);
2423143ad322SSrinivas Pandruvada 	else {
2424143ad322SSrinivas Pandruvada 		int cp_state, cp_cap;
2425143ad322SSrinivas Pandruvada 
2426850337ecSZhang Rui 		isst_read_pm_config(id, &cp_state, &cp_cap);
2427850337ecSZhang Rui 		isst_clos_display_clos_information(id, outf, enable, prio_type,
2428143ad322SSrinivas Pandruvada 						   cp_state, cp_cap);
2429143ad322SSrinivas Pandruvada 	}
2430188afed9SSrinivas Pandruvada }
2431188afed9SSrinivas Pandruvada 
dump_clos_info(int arg)2432ce1326a2SPrarit Bhargava static void dump_clos_info(int arg)
2433188afed9SSrinivas Pandruvada {
2434188afed9SSrinivas Pandruvada 	if (cmd_help) {
2435188afed9SSrinivas Pandruvada 		fprintf(stderr,
2436188afed9SSrinivas Pandruvada 			"Print Intel Speed Select Technology core power information\n");
2437f5205f49SSrinivas Pandruvada 		fprintf(stderr, "\t Optionally specify targeted cpu id with [--cpu|-c]\n");
2438188afed9SSrinivas Pandruvada 		exit(0);
2439188afed9SSrinivas Pandruvada 	}
2440188afed9SSrinivas Pandruvada 
2441188afed9SSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
2442f5205f49SSrinivas Pandruvada 	if (max_target_cpus)
2443188afed9SSrinivas Pandruvada 		for_each_online_target_cpu_in_set(get_clos_info_for_cpu, NULL,
2444188afed9SSrinivas Pandruvada 						  NULL, NULL, NULL);
2445f5205f49SSrinivas Pandruvada 	else
2446c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(get_clos_info_for_cpu, NULL,
2447f5205f49SSrinivas Pandruvada 					       NULL, NULL, NULL);
2448188afed9SSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
2449188afed9SSrinivas Pandruvada 
2450188afed9SSrinivas Pandruvada }
2451188afed9SSrinivas Pandruvada 
set_clos_config_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2452850337ecSZhang Rui static void set_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
24533fb4f7cdSSrinivas Pandruvada 				    void *arg4)
24543fb4f7cdSSrinivas Pandruvada {
24553fb4f7cdSSrinivas Pandruvada 	struct isst_clos_config clos_config;
24563fb4f7cdSSrinivas Pandruvada 	int ret;
24573fb4f7cdSSrinivas Pandruvada 
2458443bf104SZhang Rui 	if (id->cpu < 0)
2459443bf104SZhang Rui 		return;
2460443bf104SZhang Rui 
24613fb4f7cdSSrinivas Pandruvada 	clos_config.epp = clos_epp;
24623fb4f7cdSSrinivas Pandruvada 	clos_config.clos_prop_prio = clos_prop_prio;
24633fb4f7cdSSrinivas Pandruvada 	clos_config.clos_min = clos_min;
24643fb4f7cdSSrinivas Pandruvada 	clos_config.clos_max = clos_max;
24653fb4f7cdSSrinivas Pandruvada 	clos_config.clos_desired = clos_desired;
2466850337ecSZhang Rui 	ret = isst_set_clos(id, current_clos, &clos_config);
24673fb4f7cdSSrinivas Pandruvada 	if (ret)
2468fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "isst_set_clos failed", 0, 0);
24693fb4f7cdSSrinivas Pandruvada 	else
2470850337ecSZhang Rui 		isst_display_result(id, outf, "core-power", "config", ret);
24713fb4f7cdSSrinivas Pandruvada }
24723fb4f7cdSSrinivas Pandruvada 
set_clos_config(int arg)2473ce1326a2SPrarit Bhargava static void set_clos_config(int arg)
24743fb4f7cdSSrinivas Pandruvada {
24753fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
24763fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
24773fb4f7cdSSrinivas Pandruvada 			"Set core-power configuration for one of the four clos ids\n");
24783fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
24793fb4f7cdSSrinivas Pandruvada 			"\tSpecify targeted clos id with [--clos|-c]\n");
2480fe6fb216SSrinivas Pandruvada 		if (!is_skx_based_platform()) {
24813fb4f7cdSSrinivas Pandruvada 			fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n");
24823fb4f7cdSSrinivas Pandruvada 			fprintf(stderr,
24833fb4f7cdSSrinivas Pandruvada 				"\tSpecify clos Proportional Priority [--weight|-w]\n");
2484fe6fb216SSrinivas Pandruvada 		}
248540dee9ddSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify clos min in MHz with [--min|-n]\n");
248640dee9ddSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify clos max in MHz with [--max|-m]\n");
24873fb4f7cdSSrinivas Pandruvada 		exit(0);
24883fb4f7cdSSrinivas Pandruvada 	}
24893fb4f7cdSSrinivas Pandruvada 
24903fb4f7cdSSrinivas Pandruvada 	if (current_clos < 0 || current_clos > 3) {
2491fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid clos id\n", 0, 0);
24923fb4f7cdSSrinivas Pandruvada 		exit(0);
24933fb4f7cdSSrinivas Pandruvada 	}
2494fe6fb216SSrinivas Pandruvada 	if (!is_skx_based_platform() && (clos_epp < 0 || clos_epp > 0x0F)) {
2495fe6fb216SSrinivas Pandruvada 		fprintf(stderr, "clos epp is not specified or invalid, default: 0\n");
24963fb4f7cdSSrinivas Pandruvada 		clos_epp = 0;
24973fb4f7cdSSrinivas Pandruvada 	}
2498fe6fb216SSrinivas Pandruvada 	if (!is_skx_based_platform() && (clos_prop_prio < 0 || clos_prop_prio > 0x0F)) {
24993fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
2500fe6fb216SSrinivas Pandruvada 			"clos frequency weight is not specified or invalid, default: 0\n");
25013fb4f7cdSSrinivas Pandruvada 		clos_prop_prio = 0;
25023fb4f7cdSSrinivas Pandruvada 	}
25033fb4f7cdSSrinivas Pandruvada 	if (clos_min < 0) {
25043fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "clos min is not specified, default: 0\n");
25053fb4f7cdSSrinivas Pandruvada 		clos_min = 0;
25063fb4f7cdSSrinivas Pandruvada 	}
25073fb4f7cdSSrinivas Pandruvada 	if (clos_max < 0) {
2508fe6fb216SSrinivas Pandruvada 		fprintf(stderr, "clos max is not specified, default: Max frequency (ratio 0xff)\n");
25093fb4f7cdSSrinivas Pandruvada 		clos_max = 0xff;
25103fb4f7cdSSrinivas Pandruvada 	}
2511fe6fb216SSrinivas Pandruvada 	if (clos_desired) {
2512fe6fb216SSrinivas Pandruvada 		fprintf(stderr, "clos desired is not supported on this platform\n");
25133fb4f7cdSSrinivas Pandruvada 		clos_desired = 0x00;
25143fb4f7cdSSrinivas Pandruvada 	}
25153fb4f7cdSSrinivas Pandruvada 
25163fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
25173fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
25183fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_clos_config_for_cpu, NULL,
25193fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
25203fb4f7cdSSrinivas Pandruvada 	else
2521c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(set_clos_config_for_cpu, NULL,
25223fb4f7cdSSrinivas Pandruvada 					       NULL, NULL, NULL);
25233fb4f7cdSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
25243fb4f7cdSSrinivas Pandruvada }
25253fb4f7cdSSrinivas Pandruvada 
set_clos_assoc_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2526850337ecSZhang Rui static void set_clos_assoc_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
25273fb4f7cdSSrinivas Pandruvada 				   void *arg4)
25283fb4f7cdSSrinivas Pandruvada {
25293fb4f7cdSSrinivas Pandruvada 	int ret;
25303fb4f7cdSSrinivas Pandruvada 
2531850337ecSZhang Rui 	ret = isst_clos_associate(id, current_clos);
25323fb4f7cdSSrinivas Pandruvada 	if (ret)
2533fe6fb216SSrinivas Pandruvada 		debug_printf("isst_clos_associate failed");
25343fb4f7cdSSrinivas Pandruvada 	else
2535850337ecSZhang Rui 		isst_display_result(id, outf, "core-power", "assoc", ret);
25363fb4f7cdSSrinivas Pandruvada }
25373fb4f7cdSSrinivas Pandruvada 
set_clos_assoc(int arg)2538ce1326a2SPrarit Bhargava static void set_clos_assoc(int arg)
25393fb4f7cdSSrinivas Pandruvada {
25403fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
25413fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Associate a clos id to a CPU\n");
25423fb4f7cdSSrinivas Pandruvada 		fprintf(stderr,
25433fb4f7cdSSrinivas Pandruvada 			"\tSpecify targeted clos id with [--clos|-c]\n");
254468e2f109SSrinivas Pandruvada 		fprintf(stderr,
254568e2f109SSrinivas Pandruvada 			"\tFor example to associate clos 1 to CPU 0: issue\n");
254668e2f109SSrinivas Pandruvada 		fprintf(stderr,
254768e2f109SSrinivas Pandruvada 			"\tintel-speed-select --cpu 0 core-power assoc --clos 1\n");
25483fb4f7cdSSrinivas Pandruvada 		exit(0);
25493fb4f7cdSSrinivas Pandruvada 	}
25503fb4f7cdSSrinivas Pandruvada 
25513fb4f7cdSSrinivas Pandruvada 	if (current_clos < 0 || current_clos > 3) {
2552fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid clos id\n", 0, 0);
25533fb4f7cdSSrinivas Pandruvada 		exit(0);
25543fb4f7cdSSrinivas Pandruvada 	}
2555fcf12783SSrinivas Pandruvada 
2556fcf12783SSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
2557fcf12783SSrinivas Pandruvada 
25583fb4f7cdSSrinivas Pandruvada 	if (max_target_cpus)
25593fb4f7cdSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL,
25603fb4f7cdSSrinivas Pandruvada 						  NULL, NULL, NULL);
25613fb4f7cdSSrinivas Pandruvada 	else {
2562fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0);
25633fb4f7cdSSrinivas Pandruvada 	}
2564fcf12783SSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
25653fb4f7cdSSrinivas Pandruvada }
25663fb4f7cdSSrinivas Pandruvada 
get_clos_assoc_for_cpu(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2567850337ecSZhang Rui static void get_clos_assoc_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3,
25683fb4f7cdSSrinivas Pandruvada 				   void *arg4)
25693fb4f7cdSSrinivas Pandruvada {
25703fb4f7cdSSrinivas Pandruvada 	int clos, ret;
25713fb4f7cdSSrinivas Pandruvada 
2572850337ecSZhang Rui 	ret = isst_clos_get_assoc_status(id, &clos);
25733fb4f7cdSSrinivas Pandruvada 	if (ret)
2574fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "isst_clos_get_assoc_status failed", 0, 0);
25753fb4f7cdSSrinivas Pandruvada 	else
2576850337ecSZhang Rui 		isst_clos_display_assoc_information(id, outf, clos);
25773fb4f7cdSSrinivas Pandruvada }
25783fb4f7cdSSrinivas Pandruvada 
get_clos_assoc(int arg)2579ce1326a2SPrarit Bhargava static void get_clos_assoc(int arg)
25803fb4f7cdSSrinivas Pandruvada {
25813fb4f7cdSSrinivas Pandruvada 	if (cmd_help) {
25823fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Get associate clos id to a CPU\n");
25833fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "\tSpecify targeted cpu id with [--cpu|-c]\n");
25843fb4f7cdSSrinivas Pandruvada 		exit(0);
25853fb4f7cdSSrinivas Pandruvada 	}
2586e118fbe3SSrinivas Pandruvada 
2587e118fbe3SSrinivas Pandruvada 	if (!max_target_cpus) {
2588fe6fb216SSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0);
2589e118fbe3SSrinivas Pandruvada 		exit(0);
25903fb4f7cdSSrinivas Pandruvada 	}
2591e118fbe3SSrinivas Pandruvada 
2592e118fbe3SSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
2593e118fbe3SSrinivas Pandruvada 	for_each_online_target_cpu_in_set(get_clos_assoc_for_cpu, NULL,
2594e118fbe3SSrinivas Pandruvada 					  NULL, NULL, NULL);
2595e118fbe3SSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
25963fb4f7cdSSrinivas Pandruvada }
25973fb4f7cdSSrinivas Pandruvada 
set_turbo_mode_for_cpu(struct isst_id * id,int status)2598850337ecSZhang Rui static void set_turbo_mode_for_cpu(struct isst_id *id, int status)
2599006050a6SSrinivas Pandruvada {
2600006050a6SSrinivas Pandruvada 	int base_freq;
2601006050a6SSrinivas Pandruvada 
2602006050a6SSrinivas Pandruvada 	if (status) {
2603850337ecSZhang Rui 		base_freq = get_cpufreq_base_freq(id->cpu);
2604850337ecSZhang Rui 		set_cpufreq_scaling_min_max(id->cpu, 1, base_freq);
2605006050a6SSrinivas Pandruvada 	} else {
2606850337ecSZhang Rui 		set_scaling_max_to_cpuinfo_max(id);
2607006050a6SSrinivas Pandruvada 	}
2608006050a6SSrinivas Pandruvada 
2609006050a6SSrinivas Pandruvada 	if (status) {
2610850337ecSZhang Rui 		isst_display_result(id, outf, "turbo-mode", "disable", 0);
26117b00d101SSrinivas Pandruvada 	} else {
26127b00d101SSrinivas Pandruvada 		isst_display_result(id, outf, "turbo-mode", "enable", 0);
2613006050a6SSrinivas Pandruvada 	}
2614006050a6SSrinivas Pandruvada }
2615006050a6SSrinivas Pandruvada 
set_turbo_mode(int arg)2616006050a6SSrinivas Pandruvada static void set_turbo_mode(int arg)
2617006050a6SSrinivas Pandruvada {
26187b00d101SSrinivas Pandruvada 	int i, disable = arg;
2619850337ecSZhang Rui 	struct isst_id id;
2620006050a6SSrinivas Pandruvada 
2621006050a6SSrinivas Pandruvada 	if (cmd_help) {
26227b00d101SSrinivas Pandruvada 		if (disable)
2623006050a6SSrinivas Pandruvada 			fprintf(stderr, "Set turbo mode disable\n");
26247b00d101SSrinivas Pandruvada 		else
26257b00d101SSrinivas Pandruvada 			fprintf(stderr, "Set turbo mode enable\n");
2626006050a6SSrinivas Pandruvada 		exit(0);
2627006050a6SSrinivas Pandruvada 	}
2628006050a6SSrinivas Pandruvada 
2629006050a6SSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
2630006050a6SSrinivas Pandruvada 
2631006050a6SSrinivas Pandruvada 	for (i = 0; i < topo_max_cpus; ++i) {
2632006050a6SSrinivas Pandruvada 		int online;
2633006050a6SSrinivas Pandruvada 
2634006050a6SSrinivas Pandruvada 		if (i)
2635006050a6SSrinivas Pandruvada 			online = parse_int_file(
2636006050a6SSrinivas Pandruvada 				1, "/sys/devices/system/cpu/cpu%d/online", i);
2637006050a6SSrinivas Pandruvada 		else
2638006050a6SSrinivas Pandruvada 			online =
2639006050a6SSrinivas Pandruvada 				1; /* online entry for CPU 0 needs some special configs */
2640006050a6SSrinivas Pandruvada 
2641850337ecSZhang Rui 		if (online) {
2642850337ecSZhang Rui 			set_isst_id(&id, i);
26437b00d101SSrinivas Pandruvada 			set_turbo_mode_for_cpu(&id, disable);
2644850337ecSZhang Rui 		}
2645006050a6SSrinivas Pandruvada 
2646006050a6SSrinivas Pandruvada 	}
2647006050a6SSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
2648006050a6SSrinivas Pandruvada }
2649006050a6SSrinivas Pandruvada 
get_set_trl(struct isst_id * id,void * arg1,void * arg2,void * arg3,void * arg4)2650850337ecSZhang Rui static void get_set_trl(struct isst_id *id, void *arg1, void *arg2, void *arg3,
26512c7dc57eSSrinivas Pandruvada 			void *arg4)
26522c7dc57eSSrinivas Pandruvada {
26532c7dc57eSSrinivas Pandruvada 	unsigned long long trl;
26542c7dc57eSSrinivas Pandruvada 	int set = *(int *)arg4;
26552c7dc57eSSrinivas Pandruvada 	int ret;
26562c7dc57eSSrinivas Pandruvada 
26572fe8d2d7SSrinivas Pandruvada 	if (id->cpu < 0)
26582fe8d2d7SSrinivas Pandruvada 		return;
26592fe8d2d7SSrinivas Pandruvada 
26602c7dc57eSSrinivas Pandruvada 	if (set && !fact_trl) {
26612c7dc57eSSrinivas Pandruvada 		isst_display_error_info_message(1, "Invalid TRL. Specify with [-t|--trl]", 0, 0);
26622c7dc57eSSrinivas Pandruvada 		exit(0);
26632c7dc57eSSrinivas Pandruvada 	}
26642c7dc57eSSrinivas Pandruvada 
26652c7dc57eSSrinivas Pandruvada 	if (set) {
2666850337ecSZhang Rui 		ret = isst_set_trl(id, fact_trl);
2667850337ecSZhang Rui 		isst_display_result(id, outf, "turbo-mode", "set-trl", ret);
26682c7dc57eSSrinivas Pandruvada 		return;
26692c7dc57eSSrinivas Pandruvada 	}
26702c7dc57eSSrinivas Pandruvada 
2671850337ecSZhang Rui 	ret = isst_get_trl(id, &trl);
26722c7dc57eSSrinivas Pandruvada 	if (ret)
2673850337ecSZhang Rui 		isst_display_result(id, outf, "turbo-mode", "get-trl", ret);
26742c7dc57eSSrinivas Pandruvada 	else
2675850337ecSZhang Rui 		isst_trl_display_information(id, outf, trl);
26762c7dc57eSSrinivas Pandruvada }
26772c7dc57eSSrinivas Pandruvada 
process_trl(int arg)26782c7dc57eSSrinivas Pandruvada static void process_trl(int arg)
26792c7dc57eSSrinivas Pandruvada {
26802c7dc57eSSrinivas Pandruvada 	if (cmd_help) {
26812c7dc57eSSrinivas Pandruvada 		if (arg) {
26822c7dc57eSSrinivas Pandruvada 			fprintf(stderr, "Set TRL (turbo ratio limits)\n");
26833076db34SSrinivas Pandruvada 			fprintf(stderr, "\t t|--trl: Specify turbo ratio limit for setting TRL in hex starting with 0x\n");
26842c7dc57eSSrinivas Pandruvada 		} else {
26852c7dc57eSSrinivas Pandruvada 			fprintf(stderr, "Get TRL (turbo ratio limits)\n");
26862c7dc57eSSrinivas Pandruvada 		}
26872c7dc57eSSrinivas Pandruvada 		exit(0);
26882c7dc57eSSrinivas Pandruvada 	}
26892c7dc57eSSrinivas Pandruvada 
26902c7dc57eSSrinivas Pandruvada 	isst_ctdp_display_information_start(outf);
26912c7dc57eSSrinivas Pandruvada 	if (max_target_cpus)
26922c7dc57eSSrinivas Pandruvada 		for_each_online_target_cpu_in_set(get_set_trl, NULL,
26932c7dc57eSSrinivas Pandruvada 						  NULL, NULL, &arg);
26942c7dc57eSSrinivas Pandruvada 	else
2695c77a8d4aSZhang Rui 		for_each_online_power_domain_in_set(get_set_trl, NULL,
26962c7dc57eSSrinivas Pandruvada 					       NULL, NULL, &arg);
26972c7dc57eSSrinivas Pandruvada 	isst_ctdp_display_information_end(outf);
26982c7dc57eSSrinivas Pandruvada }
26992c7dc57eSSrinivas Pandruvada 
2700c829f0efSPrarit Bhargava static struct process_cmd_struct clx_n_cmds[] = {
2701062e4aacSPrarit Bhargava 	{ "perf-profile", "info", dump_isst_config, 0 },
27021aa7177cSPrarit Bhargava 	{ "base-freq", "info", dump_pbf_config, 0 },
27031aa7177cSPrarit Bhargava 	{ "base-freq", "enable", set_pbf_enable, 1 },
27041aa7177cSPrarit Bhargava 	{ "base-freq", "disable", set_pbf_enable, 0 },
2705c829f0efSPrarit Bhargava 	{ NULL, NULL, NULL, 0 }
2706c829f0efSPrarit Bhargava };
2707c829f0efSPrarit Bhargava 
27083fb4f7cdSSrinivas Pandruvada static struct process_cmd_struct isst_cmds[] = {
2709ce1326a2SPrarit Bhargava 	{ "perf-profile", "get-lock-status", get_tdp_locked, 0 },
2710ce1326a2SPrarit Bhargava 	{ "perf-profile", "get-config-levels", get_tdp_levels, 0 },
2711ce1326a2SPrarit Bhargava 	{ "perf-profile", "get-config-version", get_tdp_version, 0 },
2712ce1326a2SPrarit Bhargava 	{ "perf-profile", "get-config-enabled", get_tdp_enabled, 0 },
2713ce1326a2SPrarit Bhargava 	{ "perf-profile", "get-config-current-level", get_tdp_current_level,
2714ce1326a2SPrarit Bhargava 	 0 },
2715ce1326a2SPrarit Bhargava 	{ "perf-profile", "set-config-level", set_tdp_level, 0 },
2716ce1326a2SPrarit Bhargava 	{ "perf-profile", "info", dump_isst_config, 0 },
2717ce1326a2SPrarit Bhargava 	{ "base-freq", "info", dump_pbf_config, 0 },
2718ce1326a2SPrarit Bhargava 	{ "base-freq", "enable", set_pbf_enable, 1 },
2719ce1326a2SPrarit Bhargava 	{ "base-freq", "disable", set_pbf_enable, 0 },
2720ce1326a2SPrarit Bhargava 	{ "turbo-freq", "info", dump_fact_config, 0 },
2721ce1326a2SPrarit Bhargava 	{ "turbo-freq", "enable", set_fact_enable, 1 },
2722ce1326a2SPrarit Bhargava 	{ "turbo-freq", "disable", set_fact_enable, 0 },
2723ce1326a2SPrarit Bhargava 	{ "core-power", "info", dump_clos_info, 0 },
2724ce1326a2SPrarit Bhargava 	{ "core-power", "enable", set_clos_enable, 1 },
2725ce1326a2SPrarit Bhargava 	{ "core-power", "disable", set_clos_enable, 0 },
2726ce1326a2SPrarit Bhargava 	{ "core-power", "config", set_clos_config, 0 },
2727ce1326a2SPrarit Bhargava 	{ "core-power", "get-config", dump_clos_config, 0 },
2728ce1326a2SPrarit Bhargava 	{ "core-power", "assoc", set_clos_assoc, 0 },
2729ce1326a2SPrarit Bhargava 	{ "core-power", "get-assoc", get_clos_assoc, 0 },
2730006050a6SSrinivas Pandruvada 	{ "turbo-mode", "enable", set_turbo_mode, 0 },
2731006050a6SSrinivas Pandruvada 	{ "turbo-mode", "disable", set_turbo_mode, 1 },
27322c7dc57eSSrinivas Pandruvada 	{ "turbo-mode", "get-trl", process_trl, 0 },
27332c7dc57eSSrinivas Pandruvada 	{ "turbo-mode", "set-trl", process_trl, 1 },
27343fb4f7cdSSrinivas Pandruvada 	{ NULL, NULL, NULL }
27353fb4f7cdSSrinivas Pandruvada };
27363fb4f7cdSSrinivas Pandruvada 
27373fb4f7cdSSrinivas Pandruvada /*
27383fb4f7cdSSrinivas Pandruvada  * parse cpuset with following syntax
27393fb4f7cdSSrinivas Pandruvada  * 1,2,4..6,8-10 and set bits in cpu_subset
27403fb4f7cdSSrinivas Pandruvada  */
parse_cpu_command(char * optarg)27413fb4f7cdSSrinivas Pandruvada void parse_cpu_command(char *optarg)
27423fb4f7cdSSrinivas Pandruvada {
2743e67b6ed2SSrinivas Pandruvada 	unsigned int start, end, invalid_count;
27443fb4f7cdSSrinivas Pandruvada 	char *next;
27453fb4f7cdSSrinivas Pandruvada 
27463fb4f7cdSSrinivas Pandruvada 	next = optarg;
2747e67b6ed2SSrinivas Pandruvada 	invalid_count = 0;
27483fb4f7cdSSrinivas Pandruvada 
27493fb4f7cdSSrinivas Pandruvada 	while (next && *next) {
27503fb4f7cdSSrinivas Pandruvada 		if (*next == '-') /* no negative cpu numbers */
27513fb4f7cdSSrinivas Pandruvada 			goto error;
27523fb4f7cdSSrinivas Pandruvada 
27533fb4f7cdSSrinivas Pandruvada 		start = strtoul(next, &next, 10);
27543fb4f7cdSSrinivas Pandruvada 
27553fb4f7cdSSrinivas Pandruvada 		if (max_target_cpus < MAX_CPUS_IN_ONE_REQ)
27563fb4f7cdSSrinivas Pandruvada 			target_cpus[max_target_cpus++] = start;
2757e67b6ed2SSrinivas Pandruvada 		else
2758e67b6ed2SSrinivas Pandruvada 			invalid_count = 1;
27593fb4f7cdSSrinivas Pandruvada 
27603fb4f7cdSSrinivas Pandruvada 		if (*next == '\0')
27613fb4f7cdSSrinivas Pandruvada 			break;
27623fb4f7cdSSrinivas Pandruvada 
27633fb4f7cdSSrinivas Pandruvada 		if (*next == ',') {
27643fb4f7cdSSrinivas Pandruvada 			next += 1;
27653fb4f7cdSSrinivas Pandruvada 			continue;
27663fb4f7cdSSrinivas Pandruvada 		}
27673fb4f7cdSSrinivas Pandruvada 
27683fb4f7cdSSrinivas Pandruvada 		if (*next == '-') {
27693fb4f7cdSSrinivas Pandruvada 			next += 1; /* start range */
27703fb4f7cdSSrinivas Pandruvada 		} else if (*next == '.') {
27713fb4f7cdSSrinivas Pandruvada 			next += 1;
27723fb4f7cdSSrinivas Pandruvada 			if (*next == '.')
27733fb4f7cdSSrinivas Pandruvada 				next += 1; /* start range */
27743fb4f7cdSSrinivas Pandruvada 			else
27753fb4f7cdSSrinivas Pandruvada 				goto error;
27763fb4f7cdSSrinivas Pandruvada 		}
27773fb4f7cdSSrinivas Pandruvada 
27783fb4f7cdSSrinivas Pandruvada 		end = strtoul(next, &next, 10);
27793fb4f7cdSSrinivas Pandruvada 		if (end <= start)
27803fb4f7cdSSrinivas Pandruvada 			goto error;
27813fb4f7cdSSrinivas Pandruvada 
27823fb4f7cdSSrinivas Pandruvada 		while (++start <= end) {
27833fb4f7cdSSrinivas Pandruvada 			if (max_target_cpus < MAX_CPUS_IN_ONE_REQ)
27843fb4f7cdSSrinivas Pandruvada 				target_cpus[max_target_cpus++] = start;
2785e67b6ed2SSrinivas Pandruvada 			else
2786e67b6ed2SSrinivas Pandruvada 				invalid_count = 1;
27873fb4f7cdSSrinivas Pandruvada 		}
27883fb4f7cdSSrinivas Pandruvada 
27893fb4f7cdSSrinivas Pandruvada 		if (*next == ',')
27903fb4f7cdSSrinivas Pandruvada 			next += 1;
27913fb4f7cdSSrinivas Pandruvada 		else if (*next != '\0')
27923fb4f7cdSSrinivas Pandruvada 			goto error;
27933fb4f7cdSSrinivas Pandruvada 	}
27943fb4f7cdSSrinivas Pandruvada 
2795e67b6ed2SSrinivas Pandruvada 	if (invalid_count) {
2796e67b6ed2SSrinivas Pandruvada 		isst_ctdp_display_information_start(outf);
2797e67b6ed2SSrinivas Pandruvada 		isst_display_error_info_message(1, "Too many CPUs in one request: max is", 1, MAX_CPUS_IN_ONE_REQ - 1);
2798e67b6ed2SSrinivas Pandruvada 		isst_ctdp_display_information_end(outf);
2799e67b6ed2SSrinivas Pandruvada 		exit(-1);
2800e67b6ed2SSrinivas Pandruvada 	}
2801e67b6ed2SSrinivas Pandruvada 
28023fb4f7cdSSrinivas Pandruvada #ifdef DEBUG
28033fb4f7cdSSrinivas Pandruvada 	{
28043fb4f7cdSSrinivas Pandruvada 		int i;
28053fb4f7cdSSrinivas Pandruvada 
28063fb4f7cdSSrinivas Pandruvada 		for (i = 0; i < max_target_cpus; ++i)
28073fb4f7cdSSrinivas Pandruvada 			printf("cpu [%d] in arg\n", target_cpus[i]);
28083fb4f7cdSSrinivas Pandruvada 	}
28093fb4f7cdSSrinivas Pandruvada #endif
28103fb4f7cdSSrinivas Pandruvada 	return;
28113fb4f7cdSSrinivas Pandruvada 
28123fb4f7cdSSrinivas Pandruvada error:
28133fb4f7cdSSrinivas Pandruvada 	fprintf(stderr, "\"--cpu %s\" malformed\n", optarg);
28143fb4f7cdSSrinivas Pandruvada 	exit(-1);
28153fb4f7cdSSrinivas Pandruvada }
28163fb4f7cdSSrinivas Pandruvada 
check_optarg(char * option,int hex)281761f3d868SSrinivas Pandruvada static void check_optarg(char *option, int hex)
281861f3d868SSrinivas Pandruvada {
281961f3d868SSrinivas Pandruvada 	if (optarg) {
282061f3d868SSrinivas Pandruvada 		char *start = optarg;
282161f3d868SSrinivas Pandruvada 		int i;
282261f3d868SSrinivas Pandruvada 
282361f3d868SSrinivas Pandruvada 		if (hex && strlen(optarg) < 3) {
282461f3d868SSrinivas Pandruvada 			/* At least 0x plus one character must be present */
282561f3d868SSrinivas Pandruvada 			fprintf(stderr, "malformed arguments for:%s [%s]\n", option, optarg);
282661f3d868SSrinivas Pandruvada 			exit(0);
282761f3d868SSrinivas Pandruvada 		}
282861f3d868SSrinivas Pandruvada 
282961f3d868SSrinivas Pandruvada 		if (hex) {
283061f3d868SSrinivas Pandruvada 			if (optarg[0] != '0' || tolower(optarg[1]) != 'x') {
283161f3d868SSrinivas Pandruvada 				fprintf(stderr, "malformed arguments for:%s [%s]\n",
283261f3d868SSrinivas Pandruvada 					option, optarg);
283361f3d868SSrinivas Pandruvada 				exit(0);
283461f3d868SSrinivas Pandruvada 			}
283561f3d868SSrinivas Pandruvada 			start = &optarg[2];
283661f3d868SSrinivas Pandruvada 		}
283761f3d868SSrinivas Pandruvada 
283861f3d868SSrinivas Pandruvada 		for (i = 0; i < strlen(start); ++i) {
283961f3d868SSrinivas Pandruvada 			if (hex) {
284061f3d868SSrinivas Pandruvada 				if (!isxdigit(start[i])) {
284161f3d868SSrinivas Pandruvada 					fprintf(stderr, "malformed arguments for:%s [%s]\n",
284261f3d868SSrinivas Pandruvada 						option, optarg);
284361f3d868SSrinivas Pandruvada 					exit(0);
284461f3d868SSrinivas Pandruvada 				}
284561f3d868SSrinivas Pandruvada 			} else if (!isdigit(start[i])) {
284661f3d868SSrinivas Pandruvada 				fprintf(stderr, "malformed arguments for:%s [%s]\n",
284761f3d868SSrinivas Pandruvada 					option, optarg);
284861f3d868SSrinivas Pandruvada 				exit(0);
284961f3d868SSrinivas Pandruvada 			}
285061f3d868SSrinivas Pandruvada 		}
285161f3d868SSrinivas Pandruvada 	}
285261f3d868SSrinivas Pandruvada }
285361f3d868SSrinivas Pandruvada 
parse_cmd_args(int argc,int start,char ** argv)28543fb4f7cdSSrinivas Pandruvada static void parse_cmd_args(int argc, int start, char **argv)
28553fb4f7cdSSrinivas Pandruvada {
28563fb4f7cdSSrinivas Pandruvada 	int opt;
28573fb4f7cdSSrinivas Pandruvada 	int option_index;
28583fb4f7cdSSrinivas Pandruvada 
28593fb4f7cdSSrinivas Pandruvada 	static struct option long_options[] = {
28603fb4f7cdSSrinivas Pandruvada 		{ "bucket", required_argument, 0, 'b' },
28613fb4f7cdSSrinivas Pandruvada 		{ "level", required_argument, 0, 'l' },
28623c64c81aSSrinivas Pandruvada 		{ "online", required_argument, 0, 'o' },
28633fb4f7cdSSrinivas Pandruvada 		{ "trl-type", required_argument, 0, 'r' },
28643fb4f7cdSSrinivas Pandruvada 		{ "trl", required_argument, 0, 't' },
28653fb4f7cdSSrinivas Pandruvada 		{ "help", no_argument, 0, 'h' },
28663fb4f7cdSSrinivas Pandruvada 		{ "clos", required_argument, 0, 'c' },
28673fb4f7cdSSrinivas Pandruvada 		{ "desired", required_argument, 0, 'd' },
28683fb4f7cdSSrinivas Pandruvada 		{ "epp", required_argument, 0, 'e' },
28693fb4f7cdSSrinivas Pandruvada 		{ "min", required_argument, 0, 'n' },
28703fb4f7cdSSrinivas Pandruvada 		{ "max", required_argument, 0, 'm' },
28713fb4f7cdSSrinivas Pandruvada 		{ "priority", required_argument, 0, 'p' },
28723fb4f7cdSSrinivas Pandruvada 		{ "weight", required_argument, 0, 'w' },
2873354bd06fSSrinivas Pandruvada 		{ "auto", no_argument, 0, 'a' },
28743fb4f7cdSSrinivas Pandruvada 		{ 0, 0, 0, 0 }
28753fb4f7cdSSrinivas Pandruvada 	};
28763fb4f7cdSSrinivas Pandruvada 
28773fb4f7cdSSrinivas Pandruvada 	option_index = start;
28783fb4f7cdSSrinivas Pandruvada 
28793fb4f7cdSSrinivas Pandruvada 	optind = start + 1;
2880b86639e1SSrinivas Pandruvada 	while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:r:hoa",
28813fb4f7cdSSrinivas Pandruvada 				  long_options, &option_index)) != -1) {
28823fb4f7cdSSrinivas Pandruvada 		switch (opt) {
2883354bd06fSSrinivas Pandruvada 		case 'a':
2884354bd06fSSrinivas Pandruvada 			auto_mode = 1;
2885354bd06fSSrinivas Pandruvada 			break;
28863fb4f7cdSSrinivas Pandruvada 		case 'b':
288761f3d868SSrinivas Pandruvada 			check_optarg("bucket", 0);
28883fb4f7cdSSrinivas Pandruvada 			fact_bucket = atoi(optarg);
28893fb4f7cdSSrinivas Pandruvada 			break;
28903fb4f7cdSSrinivas Pandruvada 		case 'h':
28913fb4f7cdSSrinivas Pandruvada 			cmd_help = 1;
28923fb4f7cdSSrinivas Pandruvada 			break;
28933fb4f7cdSSrinivas Pandruvada 		case 'l':
289461f3d868SSrinivas Pandruvada 			check_optarg("level", 0);
28953fb4f7cdSSrinivas Pandruvada 			tdp_level = atoi(optarg);
28963fb4f7cdSSrinivas Pandruvada 			break;
28973c64c81aSSrinivas Pandruvada 		case 'o':
28983c64c81aSSrinivas Pandruvada 			force_online_offline = 1;
28993c64c81aSSrinivas Pandruvada 			break;
29003fb4f7cdSSrinivas Pandruvada 		case 't':
290161f3d868SSrinivas Pandruvada 			check_optarg("trl", 1);
29023fb4f7cdSSrinivas Pandruvada 			sscanf(optarg, "0x%llx", &fact_trl);
29033fb4f7cdSSrinivas Pandruvada 			break;
29043fb4f7cdSSrinivas Pandruvada 		case 'r':
29053fb4f7cdSSrinivas Pandruvada 			if (!strncmp(optarg, "sse", 3)) {
29063fb4f7cdSSrinivas Pandruvada 				fact_avx = 0x01;
29073fb4f7cdSSrinivas Pandruvada 			} else if (!strncmp(optarg, "avx2", 4)) {
29083fb4f7cdSSrinivas Pandruvada 				fact_avx = 0x02;
2909b86639e1SSrinivas Pandruvada 			} else if (!strncmp(optarg, "avx512", 6)) {
29103fb4f7cdSSrinivas Pandruvada 				fact_avx = 0x04;
29113fb4f7cdSSrinivas Pandruvada 			} else {
29123fb4f7cdSSrinivas Pandruvada 				fprintf(outf, "Invalid sse,avx options\n");
29133fb4f7cdSSrinivas Pandruvada 				exit(1);
29143fb4f7cdSSrinivas Pandruvada 			}
29153fb4f7cdSSrinivas Pandruvada 			break;
29163fb4f7cdSSrinivas Pandruvada 		/* CLOS related */
29173fb4f7cdSSrinivas Pandruvada 		case 'c':
291861f3d868SSrinivas Pandruvada 			check_optarg("clos", 0);
29193fb4f7cdSSrinivas Pandruvada 			current_clos = atoi(optarg);
29203fb4f7cdSSrinivas Pandruvada 			break;
29213fb4f7cdSSrinivas Pandruvada 		case 'd':
292261f3d868SSrinivas Pandruvada 			check_optarg("desired", 0);
29233fb4f7cdSSrinivas Pandruvada 			clos_desired = atoi(optarg);
292413b868f8SZhang Rui 			clos_desired /= isst_get_disp_freq_multiplier();
29253fb4f7cdSSrinivas Pandruvada 			break;
29263fb4f7cdSSrinivas Pandruvada 		case 'e':
292761f3d868SSrinivas Pandruvada 			check_optarg("epp", 0);
29283fb4f7cdSSrinivas Pandruvada 			clos_epp = atoi(optarg);
2929fe6fb216SSrinivas Pandruvada 			if (is_skx_based_platform()) {
2930fe6fb216SSrinivas Pandruvada 				isst_display_error_info_message(1, "epp can't be specified on this platform", 0, 0);
2931fe6fb216SSrinivas Pandruvada 				exit(0);
2932fe6fb216SSrinivas Pandruvada 			}
29333fb4f7cdSSrinivas Pandruvada 			break;
29343fb4f7cdSSrinivas Pandruvada 		case 'n':
293561f3d868SSrinivas Pandruvada 			check_optarg("min", 0);
29363fb4f7cdSSrinivas Pandruvada 			clos_min = atoi(optarg);
293713b868f8SZhang Rui 			clos_min /= isst_get_disp_freq_multiplier();
29383fb4f7cdSSrinivas Pandruvada 			break;
29393fb4f7cdSSrinivas Pandruvada 		case 'm':
294061f3d868SSrinivas Pandruvada 			check_optarg("max", 0);
29413fb4f7cdSSrinivas Pandruvada 			clos_max = atoi(optarg);
294213b868f8SZhang Rui 			clos_max /= isst_get_disp_freq_multiplier();
29433fb4f7cdSSrinivas Pandruvada 			break;
29443fb4f7cdSSrinivas Pandruvada 		case 'p':
294561f3d868SSrinivas Pandruvada 			check_optarg("priority", 0);
29463fb4f7cdSSrinivas Pandruvada 			clos_priority_type = atoi(optarg);
2947fe6fb216SSrinivas Pandruvada 			if (is_skx_based_platform() && !clos_priority_type) {
2948fe6fb216SSrinivas Pandruvada 				isst_display_error_info_message(1, "Invalid clos priority type: proportional for this platform", 0, 0);
2949fe6fb216SSrinivas Pandruvada 				exit(0);
2950fe6fb216SSrinivas Pandruvada 			}
29513fb4f7cdSSrinivas Pandruvada 			break;
29523fb4f7cdSSrinivas Pandruvada 		case 'w':
295361f3d868SSrinivas Pandruvada 			check_optarg("weight", 0);
29543fb4f7cdSSrinivas Pandruvada 			clos_prop_prio = atoi(optarg);
2955fe6fb216SSrinivas Pandruvada 			if (is_skx_based_platform()) {
2956fe6fb216SSrinivas Pandruvada 				isst_display_error_info_message(1, "weight can't be specified on this platform", 0, 0);
2957fe6fb216SSrinivas Pandruvada 				exit(0);
2958fe6fb216SSrinivas Pandruvada 			}
29593fb4f7cdSSrinivas Pandruvada 			break;
29603fb4f7cdSSrinivas Pandruvada 		default:
29614a960353SSrinivas Pandruvada 			printf("Unknown option: ignore\n");
29623fb4f7cdSSrinivas Pandruvada 		}
29633fb4f7cdSSrinivas Pandruvada 	}
29644a960353SSrinivas Pandruvada 
29654a960353SSrinivas Pandruvada 	if (argv[optind])
29664a960353SSrinivas Pandruvada 		printf("Garbage at the end of command: ignore\n");
29673fb4f7cdSSrinivas Pandruvada }
29683fb4f7cdSSrinivas Pandruvada 
isst_help(void)29693fb4f7cdSSrinivas Pandruvada static void isst_help(void)
29703fb4f7cdSSrinivas Pandruvada {
29713fb4f7cdSSrinivas Pandruvada 	printf("perf-profile:\tAn architectural mechanism that allows multiple optimized \n\
29723fb4f7cdSSrinivas Pandruvada 		performance profiles per system via static and/or dynamic\n\
29733fb4f7cdSSrinivas Pandruvada 		adjustment of core count, workload, Tjmax, and\n\
29743fb4f7cdSSrinivas Pandruvada 		TDP, etc.\n");
29753fb4f7cdSSrinivas Pandruvada 	printf("\nCommands : For feature=perf-profile\n");
29763fb4f7cdSSrinivas Pandruvada 	printf("\tinfo\n");
2977c829f0efSPrarit Bhargava 
2978c829f0efSPrarit Bhargava 	if (!is_clx_n_platform()) {
29793fb4f7cdSSrinivas Pandruvada 		printf("\tget-lock-status\n");
29803fb4f7cdSSrinivas Pandruvada 		printf("\tget-config-levels\n");
29813fb4f7cdSSrinivas Pandruvada 		printf("\tget-config-version\n");
29823fb4f7cdSSrinivas Pandruvada 		printf("\tget-config-enabled\n");
29833fb4f7cdSSrinivas Pandruvada 		printf("\tget-config-current-level\n");
29843fb4f7cdSSrinivas Pandruvada 		printf("\tset-config-level\n");
29853fb4f7cdSSrinivas Pandruvada 	}
2986c829f0efSPrarit Bhargava }
29873fb4f7cdSSrinivas Pandruvada 
pbf_help(void)29883fb4f7cdSSrinivas Pandruvada static void pbf_help(void)
29893fb4f7cdSSrinivas Pandruvada {
29903fb4f7cdSSrinivas Pandruvada 	printf("base-freq:\tEnables users to increase guaranteed base frequency\n\
29913fb4f7cdSSrinivas Pandruvada 		on certain cores (high priority cores) in exchange for lower\n\
29923fb4f7cdSSrinivas Pandruvada 		base frequency on remaining cores (low priority cores).\n");
29933fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : info\n");
29943fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : enable\n");
29953fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : disable\n");
29963fb4f7cdSSrinivas Pandruvada }
29973fb4f7cdSSrinivas Pandruvada 
fact_help(void)29983fb4f7cdSSrinivas Pandruvada static void fact_help(void)
29993fb4f7cdSSrinivas Pandruvada {
30003fb4f7cdSSrinivas Pandruvada 	printf("turbo-freq:\tEnables the ability to set different turbo ratio\n\
30013fb4f7cdSSrinivas Pandruvada 		limits to cores based on priority.\n");
30023fb4f7cdSSrinivas Pandruvada 	printf("\nCommand: For feature=turbo-freq\n");
30033fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : info\n");
30043fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : enable\n");
30053fb4f7cdSSrinivas Pandruvada 	printf("\tcommand : disable\n");
30063fb4f7cdSSrinivas Pandruvada }
30073fb4f7cdSSrinivas Pandruvada 
turbo_mode_help(void)3008006050a6SSrinivas Pandruvada static void turbo_mode_help(void)
3009006050a6SSrinivas Pandruvada {
30102c7dc57eSSrinivas Pandruvada 	printf("turbo-mode:\tEnables users to enable/disable turbo mode by adjusting frequency settings. Also allows to get and set turbo ratio limits (TRL).\n");
3011006050a6SSrinivas Pandruvada 	printf("\tcommand : enable\n");
3012006050a6SSrinivas Pandruvada 	printf("\tcommand : disable\n");
30132c7dc57eSSrinivas Pandruvada 	printf("\tcommand : get-trl\n");
30142c7dc57eSSrinivas Pandruvada 	printf("\tcommand : set-trl\n");
3015006050a6SSrinivas Pandruvada }
3016006050a6SSrinivas Pandruvada 
3017006050a6SSrinivas Pandruvada 
core_power_help(void)30183fb4f7cdSSrinivas Pandruvada static void core_power_help(void)
30193fb4f7cdSSrinivas Pandruvada {
30203fb4f7cdSSrinivas Pandruvada 	printf("core-power:\tInterface that allows user to define per core/tile\n\
30213fb4f7cdSSrinivas Pandruvada 		priority.\n");
30223fb4f7cdSSrinivas Pandruvada 	printf("\nCommands : For feature=core-power\n");
30233fb4f7cdSSrinivas Pandruvada 	printf("\tinfo\n");
30243fb4f7cdSSrinivas Pandruvada 	printf("\tenable\n");
30253fb4f7cdSSrinivas Pandruvada 	printf("\tdisable\n");
30263fb4f7cdSSrinivas Pandruvada 	printf("\tconfig\n");
3027188afed9SSrinivas Pandruvada 	printf("\tget-config\n");
30283fb4f7cdSSrinivas Pandruvada 	printf("\tassoc\n");
30293fb4f7cdSSrinivas Pandruvada 	printf("\tget-assoc\n");
30303fb4f7cdSSrinivas Pandruvada }
30313fb4f7cdSSrinivas Pandruvada 
30323fb4f7cdSSrinivas Pandruvada struct process_cmd_help_struct {
30333fb4f7cdSSrinivas Pandruvada 	char *feature;
30343fb4f7cdSSrinivas Pandruvada 	void (*process_fn)(void);
30353fb4f7cdSSrinivas Pandruvada };
30363fb4f7cdSSrinivas Pandruvada 
30373fb4f7cdSSrinivas Pandruvada static struct process_cmd_help_struct isst_help_cmds[] = {
30383fb4f7cdSSrinivas Pandruvada 	{ "perf-profile", isst_help },
30393fb4f7cdSSrinivas Pandruvada 	{ "base-freq", pbf_help },
30403fb4f7cdSSrinivas Pandruvada 	{ "turbo-freq", fact_help },
30413fb4f7cdSSrinivas Pandruvada 	{ "core-power", core_power_help },
3042006050a6SSrinivas Pandruvada 	{ "turbo-mode", turbo_mode_help },
30433fb4f7cdSSrinivas Pandruvada 	{ NULL, NULL }
30443fb4f7cdSSrinivas Pandruvada };
30453fb4f7cdSSrinivas Pandruvada 
3046c829f0efSPrarit Bhargava static struct process_cmd_help_struct clx_n_help_cmds[] = {
3047c829f0efSPrarit Bhargava 	{ "perf-profile", isst_help },
3048c829f0efSPrarit Bhargava 	{ "base-freq", pbf_help },
3049c829f0efSPrarit Bhargava 	{ NULL, NULL }
3050c829f0efSPrarit Bhargava };
3051c829f0efSPrarit Bhargava 
process_command(int argc,char ** argv,struct process_cmd_help_struct * help_cmds,struct process_cmd_struct * cmds)3052210369dcSPrarit Bhargava void process_command(int argc, char **argv,
3053210369dcSPrarit Bhargava 		     struct process_cmd_help_struct *help_cmds,
3054210369dcSPrarit Bhargava 		     struct process_cmd_struct *cmds)
30553fb4f7cdSSrinivas Pandruvada {
30563fb4f7cdSSrinivas Pandruvada 	int i = 0, matched = 0;
30573fb4f7cdSSrinivas Pandruvada 	char *feature = argv[optind];
30583fb4f7cdSSrinivas Pandruvada 	char *cmd = argv[optind + 1];
30593fb4f7cdSSrinivas Pandruvada 
30603fb4f7cdSSrinivas Pandruvada 	if (!feature || !cmd)
30613fb4f7cdSSrinivas Pandruvada 		return;
30623fb4f7cdSSrinivas Pandruvada 
30633fb4f7cdSSrinivas Pandruvada 	debug_printf("feature name [%s] command [%s]\n", feature, cmd);
30643fb4f7cdSSrinivas Pandruvada 	if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) {
3065210369dcSPrarit Bhargava 		while (help_cmds[i].feature) {
3066210369dcSPrarit Bhargava 			if (!strcmp(help_cmds[i].feature, feature)) {
3067210369dcSPrarit Bhargava 				help_cmds[i].process_fn();
30683fb4f7cdSSrinivas Pandruvada 				exit(0);
30693fb4f7cdSSrinivas Pandruvada 			}
30703fb4f7cdSSrinivas Pandruvada 			++i;
30713fb4f7cdSSrinivas Pandruvada 		}
30723fb4f7cdSSrinivas Pandruvada 	}
30733fb4f7cdSSrinivas Pandruvada 
30743fb4f7cdSSrinivas Pandruvada 	i = 0;
3075210369dcSPrarit Bhargava 	while (cmds[i].feature) {
3076210369dcSPrarit Bhargava 		if (!strcmp(cmds[i].feature, feature) &&
3077210369dcSPrarit Bhargava 		    !strcmp(cmds[i].command, cmd)) {
30783fb4f7cdSSrinivas Pandruvada 			parse_cmd_args(argc, optind + 1, argv);
3079210369dcSPrarit Bhargava 			cmds[i].process_fn(cmds[i].arg);
30803fb4f7cdSSrinivas Pandruvada 			matched = 1;
30813fb4f7cdSSrinivas Pandruvada 			break;
30823fb4f7cdSSrinivas Pandruvada 		}
30833fb4f7cdSSrinivas Pandruvada 		++i;
30843fb4f7cdSSrinivas Pandruvada 	}
30853fb4f7cdSSrinivas Pandruvada 
30863fb4f7cdSSrinivas Pandruvada 	if (!matched)
30873fb4f7cdSSrinivas Pandruvada 		fprintf(stderr, "Invalid command\n");
30883fb4f7cdSSrinivas Pandruvada }
30893fb4f7cdSSrinivas Pandruvada 
usage(void)30903fb4f7cdSSrinivas Pandruvada static void usage(void)
30913fb4f7cdSSrinivas Pandruvada {
3092addd116dSSrinivas Pandruvada 	if (is_clx_n_platform()) {
3093addd116dSSrinivas Pandruvada 		fprintf(stderr, "\nThere is limited support of Intel Speed Select features on this platform.\n");
3094addd116dSSrinivas Pandruvada 		fprintf(stderr, "Everything is pre-configured using BIOS options, this tool can't enable any feature in the hardware.\n\n");
3095addd116dSSrinivas Pandruvada 	}
3096addd116dSSrinivas Pandruvada 
30973fb4f7cdSSrinivas Pandruvada 	printf("\nUsage:\n");
30983fb4f7cdSSrinivas Pandruvada 	printf("intel-speed-select [OPTIONS] FEATURE COMMAND COMMAND_ARGUMENTS\n");
3099addd116dSSrinivas Pandruvada 	printf("\nUse this tool to enumerate and control the Intel Speed Select Technology features:\n");
3100addd116dSSrinivas Pandruvada 	if (is_clx_n_platform())
3101addd116dSSrinivas Pandruvada 		printf("\nFEATURE : [perf-profile|base-freq]\n");
3102addd116dSSrinivas Pandruvada 	else
3103006050a6SSrinivas Pandruvada 		printf("\nFEATURE : [perf-profile|base-freq|turbo-freq|core-power|turbo-mode]\n");
310443774c0dSPrarit Bhargava 	printf("\nFor help on each feature, use -h|--help\n");
31053fb4f7cdSSrinivas Pandruvada 	printf("\tFor example:  intel-speed-select perf-profile -h\n");
31063fb4f7cdSSrinivas Pandruvada 
31073fb4f7cdSSrinivas Pandruvada 	printf("\nFor additional help on each command for a feature, use --h|--help\n");
31083fb4f7cdSSrinivas Pandruvada 	printf("\tFor example:  intel-speed-select perf-profile get-lock-status -h\n");
31093fb4f7cdSSrinivas Pandruvada 	printf("\t\t This will print help for the command \"get-lock-status\" for the feature \"perf-profile\"\n");
31103fb4f7cdSSrinivas Pandruvada 
31113fb4f7cdSSrinivas Pandruvada 	printf("\nOPTIONS\n");
31123fb4f7cdSSrinivas Pandruvada 	printf("\t[-c|--cpu] : logical cpu number\n");
31133fb4f7cdSSrinivas Pandruvada 	printf("\t\tDefault: Die scoped for all dies in the system with multiple dies/package\n");
31143fb4f7cdSSrinivas Pandruvada 	printf("\t\t\t Or Package scoped for all Packages when each package contains one die\n");
31153fb4f7cdSSrinivas Pandruvada 	printf("\t[-d|--debug] : Debug mode\n");
3116addd116dSSrinivas Pandruvada 	printf("\t[-f|--format] : output format [json|text]. Default: text\n");
31173fb4f7cdSSrinivas Pandruvada 	printf("\t[-h|--help] : Print help\n");
31183fb4f7cdSSrinivas Pandruvada 	printf("\t[-i|--info] : Print platform information\n");
31190d3dfd75SSrinivas Pandruvada 	printf("\t[-a|--all-cpus-online] : Force online every CPU in the system\n");
31203fb4f7cdSSrinivas Pandruvada 	printf("\t[-o|--out] : Output file\n");
31213fb4f7cdSSrinivas Pandruvada 	printf("\t\t\tDefault : stderr\n");
3122a85a35fcSSrinivas Pandruvada 	printf("\t[-p|--pause] : Delay between two mail box commands in milliseconds\n");
312332279be7SSrinivas Pandruvada 	printf("\t[-r|--retry] : Retry count for mail box commands on failure, default 3\n");
31243fb4f7cdSSrinivas Pandruvada 	printf("\t[-v|--version] : Print version\n");
31257fd786dfSSrinivas Pandruvada 	printf("\t[-b|--oob : Start a daemon to process HFI events for perf profile change from Out of Band agent.\n");
31267fd786dfSSrinivas Pandruvada 	printf("\t[-n|--no-daemon : Don't run as daemon. By default --oob will turn on daemon mode\n");
31277fd786dfSSrinivas Pandruvada 	printf("\t[-w|--delay : Delay for reading config level state change in OOB poll mode.\n");
3128997074dfSSrinivas Pandruvada 	printf("\t[-g|--cgroupv2 : Try to use cgroup v2 CPU isolation instead of CPU online/offline.\n");
31293bc0f20aSSrinivas Pandruvada 	printf("\t[-u|--cpu0-workaround : Don't try to online/offline CPU0 instead use cgroup v2.\n");
31303fb4f7cdSSrinivas Pandruvada 	printf("\nResult format\n");
31313fb4f7cdSSrinivas Pandruvada 	printf("\tResult display uses a common format for each command:\n");
31323fb4f7cdSSrinivas Pandruvada 	printf("\tResults are formatted in text/JSON with\n");
31333fb4f7cdSSrinivas Pandruvada 	printf("\t\tPackage, Die, CPU, and command specific results.\n");
3134addd116dSSrinivas Pandruvada 
3135addd116dSSrinivas Pandruvada 	printf("\nExamples\n");
3136addd116dSSrinivas Pandruvada 	printf("\tTo get platform information:\n");
3137addd116dSSrinivas Pandruvada 	printf("\t\tintel-speed-select --info\n");
3138addd116dSSrinivas Pandruvada 	printf("\tTo get full perf-profile information dump:\n");
3139addd116dSSrinivas Pandruvada 	printf("\t\tintel-speed-select perf-profile info\n");
3140addd116dSSrinivas Pandruvada 	printf("\tTo get full base-freq information dump:\n");
3141addd116dSSrinivas Pandruvada 	printf("\t\tintel-speed-select base-freq info -l 0\n");
3142addd116dSSrinivas Pandruvada 	if (!is_clx_n_platform()) {
3143addd116dSSrinivas Pandruvada 		printf("\tTo get full turbo-freq information dump:\n");
3144addd116dSSrinivas Pandruvada 		printf("\t\tintel-speed-select turbo-freq info -l 0\n");
3145addd116dSSrinivas Pandruvada 	}
31463fb4f7cdSSrinivas Pandruvada 	exit(1);
31473fb4f7cdSSrinivas Pandruvada }
31483fb4f7cdSSrinivas Pandruvada 
print_version(void)31493fb4f7cdSSrinivas Pandruvada static void print_version(void)
31503fb4f7cdSSrinivas Pandruvada {
31513fb4f7cdSSrinivas Pandruvada 	fprintf(outf, "Version %s\n", version_str);
31523fb4f7cdSSrinivas Pandruvada 	exit(0);
31533fb4f7cdSSrinivas Pandruvada }
31543fb4f7cdSSrinivas Pandruvada 
cmdline(int argc,char ** argv)31553fb4f7cdSSrinivas Pandruvada static void cmdline(int argc, char **argv)
31563fb4f7cdSSrinivas Pandruvada {
3157f362cdccSSrinivas Pandruvada 	const char *pathname = "/dev/isst_interface";
3158a85a35fcSSrinivas Pandruvada 	char *ptr;
3159f362cdccSSrinivas Pandruvada 	FILE *fp;
31600d3dfd75SSrinivas Pandruvada 	int opt, force_cpus_online = 0;
31613fb4f7cdSSrinivas Pandruvada 	int option_index = 0;
31623bc3d30cSPrarit Bhargava 	int ret;
31637fd786dfSSrinivas Pandruvada 	int oob_mode = 0;
31647fd786dfSSrinivas Pandruvada 	int poll_interval = -1;
31657fd786dfSSrinivas Pandruvada 	int no_daemon = 0;
31662042c0abSZhang Rui 	int mbox_delay = 0, mbox_retries = 3;
31673fb4f7cdSSrinivas Pandruvada 
31683fb4f7cdSSrinivas Pandruvada 	static struct option long_options[] = {
31690d3dfd75SSrinivas Pandruvada 		{ "all-cpus-online", no_argument, 0, 'a' },
31703fb4f7cdSSrinivas Pandruvada 		{ "cpu", required_argument, 0, 'c' },
31713fb4f7cdSSrinivas Pandruvada 		{ "debug", no_argument, 0, 'd' },
31723fb4f7cdSSrinivas Pandruvada 		{ "format", required_argument, 0, 'f' },
31733fb4f7cdSSrinivas Pandruvada 		{ "help", no_argument, 0, 'h' },
31743fb4f7cdSSrinivas Pandruvada 		{ "info", no_argument, 0, 'i' },
3175a85a35fcSSrinivas Pandruvada 		{ "pause", required_argument, 0, 'p' },
31763fb4f7cdSSrinivas Pandruvada 		{ "out", required_argument, 0, 'o' },
317732279be7SSrinivas Pandruvada 		{ "retry", required_argument, 0, 'r' },
31783fb4f7cdSSrinivas Pandruvada 		{ "version", no_argument, 0, 'v' },
31797fd786dfSSrinivas Pandruvada 		{ "oob", no_argument, 0, 'b' },
31807fd786dfSSrinivas Pandruvada 		{ "no-daemon", no_argument, 0, 'n' },
31817fd786dfSSrinivas Pandruvada 		{ "poll-interval", required_argument, 0, 'w' },
3182997074dfSSrinivas Pandruvada 		{ "cgroupv2", required_argument, 0, 'g' },
31833bc0f20aSSrinivas Pandruvada 		{ "cpu0-workaround", required_argument, 0, 'u' },
31843fb4f7cdSSrinivas Pandruvada 		{ 0, 0, 0, 0 }
31853fb4f7cdSSrinivas Pandruvada 	};
31863fb4f7cdSSrinivas Pandruvada 
3187f362cdccSSrinivas Pandruvada 	if (geteuid() != 0) {
3188f362cdccSSrinivas Pandruvada 		fprintf(stderr, "Must run as root\n");
3189f362cdccSSrinivas Pandruvada 		exit(0);
3190f362cdccSSrinivas Pandruvada 	}
3191f362cdccSSrinivas Pandruvada 
3192f362cdccSSrinivas Pandruvada 	ret = update_cpu_model();
3193f362cdccSSrinivas Pandruvada 	if (ret)
3194f362cdccSSrinivas Pandruvada 		err(-1, "Invalid CPU model (%d)\n", cpu_model);
3195f362cdccSSrinivas Pandruvada 	printf("Intel(R) Speed Select Technology\n");
3196f362cdccSSrinivas Pandruvada 	printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model);
3197f362cdccSSrinivas Pandruvada 
3198f362cdccSSrinivas Pandruvada 	if (!is_clx_n_platform()) {
3199f362cdccSSrinivas Pandruvada 		fp = fopen(pathname, "rb");
3200f362cdccSSrinivas Pandruvada 		if (!fp) {
3201f362cdccSSrinivas Pandruvada 			fprintf(stderr, "Intel speed select drivers are not loaded on this system.\n");
3202f362cdccSSrinivas Pandruvada 			fprintf(stderr, "Verify that kernel config includes CONFIG_INTEL_SPEED_SELECT_INTERFACE.\n");
3203f362cdccSSrinivas Pandruvada 			fprintf(stderr, "If the config is included then this is not a supported platform.\n");
3204f362cdccSSrinivas Pandruvada 			exit(0);
3205f362cdccSSrinivas Pandruvada 		}
3206f362cdccSSrinivas Pandruvada 		fclose(fp);
3207f362cdccSSrinivas Pandruvada 	}
3208f362cdccSSrinivas Pandruvada 
3209e9f79348SZhang Rui 	ret = isst_fill_platform_info();
3210e9f79348SZhang Rui 	if (ret)
3211e9f79348SZhang Rui 		goto out;
3212e9f79348SZhang Rui 
32133fb4f7cdSSrinivas Pandruvada 	progname = argv[0];
32143bc0f20aSSrinivas Pandruvada 	while ((opt = getopt_long_only(argc, argv, "+c:df:hio:vabw:ngu", long_options,
32153fb4f7cdSSrinivas Pandruvada 				       &option_index)) != -1) {
32163fb4f7cdSSrinivas Pandruvada 		switch (opt) {
32170d3dfd75SSrinivas Pandruvada 		case 'a':
32180d3dfd75SSrinivas Pandruvada 			force_cpus_online = 1;
32190d3dfd75SSrinivas Pandruvada 			break;
32203fb4f7cdSSrinivas Pandruvada 		case 'c':
32213fb4f7cdSSrinivas Pandruvada 			parse_cpu_command(optarg);
32223fb4f7cdSSrinivas Pandruvada 			break;
32233fb4f7cdSSrinivas Pandruvada 		case 'd':
32243fb4f7cdSSrinivas Pandruvada 			debug_flag = 1;
32253fb4f7cdSSrinivas Pandruvada 			printf("Debug Mode ON\n");
32263fb4f7cdSSrinivas Pandruvada 			break;
32273fb4f7cdSSrinivas Pandruvada 		case 'f':
32283fb4f7cdSSrinivas Pandruvada 			if (!strncmp(optarg, "json", 4))
32293fb4f7cdSSrinivas Pandruvada 				out_format_json = 1;
32303fb4f7cdSSrinivas Pandruvada 			break;
32313fb4f7cdSSrinivas Pandruvada 		case 'h':
32323fb4f7cdSSrinivas Pandruvada 			usage();
32333fb4f7cdSSrinivas Pandruvada 			break;
32343fb4f7cdSSrinivas Pandruvada 		case 'i':
32353fb4f7cdSSrinivas Pandruvada 			isst_print_platform_information();
32363fb4f7cdSSrinivas Pandruvada 			break;
32373fb4f7cdSSrinivas Pandruvada 		case 'o':
32383fb4f7cdSSrinivas Pandruvada 			if (outf)
32393fb4f7cdSSrinivas Pandruvada 				fclose(outf);
32403fb4f7cdSSrinivas Pandruvada 			outf = fopen_or_exit(optarg, "w");
32413fb4f7cdSSrinivas Pandruvada 			break;
3242a85a35fcSSrinivas Pandruvada 		case 'p':
3243a85a35fcSSrinivas Pandruvada 			ret = strtol(optarg, &ptr, 10);
3244a85a35fcSSrinivas Pandruvada 			if (!ret)
3245a85a35fcSSrinivas Pandruvada 				fprintf(stderr, "Invalid pause interval, ignore\n");
3246a85a35fcSSrinivas Pandruvada 			else
3247a85a35fcSSrinivas Pandruvada 				mbox_delay = ret;
3248a85a35fcSSrinivas Pandruvada 			break;
324932279be7SSrinivas Pandruvada 		case 'r':
325032279be7SSrinivas Pandruvada 			ret = strtol(optarg, &ptr, 10);
325132279be7SSrinivas Pandruvada 			if (!ret)
325232279be7SSrinivas Pandruvada 				fprintf(stderr, "Invalid retry count, ignore\n");
325332279be7SSrinivas Pandruvada 			else
325432279be7SSrinivas Pandruvada 				mbox_retries = ret;
325532279be7SSrinivas Pandruvada 			break;
32563fb4f7cdSSrinivas Pandruvada 		case 'v':
32573fb4f7cdSSrinivas Pandruvada 			print_version();
32583fb4f7cdSSrinivas Pandruvada 			break;
32597fd786dfSSrinivas Pandruvada 		case 'b':
32607fd786dfSSrinivas Pandruvada 			oob_mode = 1;
32617fd786dfSSrinivas Pandruvada 			break;
32627fd786dfSSrinivas Pandruvada 		case 'n':
32637fd786dfSSrinivas Pandruvada 			no_daemon = 1;
32647fd786dfSSrinivas Pandruvada 			break;
32657fd786dfSSrinivas Pandruvada 		case 'w':
32667fd786dfSSrinivas Pandruvada 			ret = strtol(optarg, &ptr, 10);
32677fd786dfSSrinivas Pandruvada 			if (!ret) {
32687fd786dfSSrinivas Pandruvada 				fprintf(stderr, "Invalid poll interval count\n");
32697fd786dfSSrinivas Pandruvada 				exit(0);
32707fd786dfSSrinivas Pandruvada 			}
32717fd786dfSSrinivas Pandruvada 			poll_interval = ret;
32727fd786dfSSrinivas Pandruvada 			break;
3273997074dfSSrinivas Pandruvada 		case 'g':
3274997074dfSSrinivas Pandruvada 			cgroupv2 = 1;
3275997074dfSSrinivas Pandruvada 			break;
32763bc0f20aSSrinivas Pandruvada 		case 'u':
32773bc0f20aSSrinivas Pandruvada 			cpu_0_cgroupv2 = 1;
32783bc0f20aSSrinivas Pandruvada 			break;
32793fb4f7cdSSrinivas Pandruvada 		default:
32803fb4f7cdSSrinivas Pandruvada 			usage();
32813fb4f7cdSSrinivas Pandruvada 		}
32823fb4f7cdSSrinivas Pandruvada 	}
32833fb4f7cdSSrinivas Pandruvada 
32847fd786dfSSrinivas Pandruvada 	if (optind > (argc - 2) && !oob_mode) {
3285addd116dSSrinivas Pandruvada 		usage();
32863fb4f7cdSSrinivas Pandruvada 		exit(0);
32873fb4f7cdSSrinivas Pandruvada 	}
32882042c0abSZhang Rui 
32892042c0abSZhang Rui 	isst_update_platform_param(ISST_PARAM_MBOX_DELAY, mbox_delay);
32902042c0abSZhang Rui 	isst_update_platform_param(ISST_PARAM_MBOX_RETRIES, mbox_retries);
32912042c0abSZhang Rui 
32923fb4f7cdSSrinivas Pandruvada 	set_max_cpu_num();
32930d3dfd75SSrinivas Pandruvada 	if (force_cpus_online)
32940d3dfd75SSrinivas Pandruvada 		force_all_cpus_online();
3295fb186158SSrinivas Pandruvada 	store_cpu_topology();
3296ca56725dSZhang Rui 	create_cpu_map();
3297c829f0efSPrarit Bhargava 
32987fd786dfSSrinivas Pandruvada 	if (oob_mode) {
32997fd786dfSSrinivas Pandruvada 		if (debug_flag)
33007fd786dfSSrinivas Pandruvada 			fprintf(stderr, "OOB mode is enabled in debug mode\n");
33017fd786dfSSrinivas Pandruvada 
33027fd786dfSSrinivas Pandruvada 		ret = isst_daemon(debug_flag, poll_interval, no_daemon);
33037fd786dfSSrinivas Pandruvada 		if (ret)
33047fd786dfSSrinivas Pandruvada 			fprintf(stderr, "OOB mode enable failed\n");
33057fd786dfSSrinivas Pandruvada 		goto out;
33067fd786dfSSrinivas Pandruvada 	}
33077fd786dfSSrinivas Pandruvada 
3308c829f0efSPrarit Bhargava 	if (!is_clx_n_platform()) {
3309210369dcSPrarit Bhargava 		process_command(argc, argv, isst_help_cmds, isst_cmds);
3310c829f0efSPrarit Bhargava 	} else {
3311c829f0efSPrarit Bhargava 		process_command(argc, argv, clx_n_help_cmds, clx_n_cmds);
3312c829f0efSPrarit Bhargava 	}
33133bc3d30cSPrarit Bhargava out:
33143bc3d30cSPrarit Bhargava 	free_cpu_set(present_cpumask);
33153bc3d30cSPrarit Bhargava 	free_cpu_set(target_cpumask);
33163fb4f7cdSSrinivas Pandruvada }
33173fb4f7cdSSrinivas Pandruvada 
main(int argc,char ** argv)33183fb4f7cdSSrinivas Pandruvada int main(int argc, char **argv)
33193fb4f7cdSSrinivas Pandruvada {
33203fb4f7cdSSrinivas Pandruvada 	outf = stderr;
33213fb4f7cdSSrinivas Pandruvada 	cmdline(argc, argv);
33223fb4f7cdSSrinivas Pandruvada 	return 0;
33233fb4f7cdSSrinivas Pandruvada }
3324