1 /*
2  * x86_energy_perf_policy -- set the energy versus performance
3  * policy preference bias on recent X86 processors.
4  */
5 /*
6  * Copyright (c) 2010 - 2017 Intel Corporation.
7  * Len Brown <len.brown@intel.com>
8  *
9  * This program is released under GPL v2
10  */
11 
12 #define _GNU_SOURCE
13 #include MSRHEADER
14 #include <stdio.h>
15 #include <unistd.h>
16 #include <sys/types.h>
17 #include <sched.h>
18 #include <sys/stat.h>
19 #include <sys/resource.h>
20 #include <getopt.h>
21 #include <err.h>
22 #include <fcntl.h>
23 #include <signal.h>
24 #include <sys/time.h>
25 #include <limits.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <cpuid.h>
29 #include <errno.h>
30 
31 #define	OPTARG_NORMAL			(INT_MAX - 1)
32 #define	OPTARG_POWER			(INT_MAX - 2)
33 #define	OPTARG_BALANCE_POWER		(INT_MAX - 3)
34 #define	OPTARG_BALANCE_PERFORMANCE	(INT_MAX - 4)
35 #define	OPTARG_PERFORMANCE		(INT_MAX - 5)
36 
37 struct msr_hwp_cap {
38 	unsigned char highest;
39 	unsigned char guaranteed;
40 	unsigned char efficient;
41 	unsigned char lowest;
42 };
43 
44 struct msr_hwp_request {
45 	unsigned char hwp_min;
46 	unsigned char hwp_max;
47 	unsigned char hwp_desired;
48 	unsigned char hwp_epp;
49 	unsigned int hwp_window;
50 	unsigned char hwp_use_pkg;
51 } req_update;
52 
53 unsigned int debug;
54 unsigned int verbose;
55 unsigned int force;
56 char *progname;
57 int base_cpu;
58 unsigned char update_epb;
59 unsigned long long new_epb;
60 unsigned char turbo_is_enabled;
61 unsigned char update_turbo;
62 unsigned char turbo_update_value;
63 unsigned char update_hwp_epp;
64 unsigned char update_hwp_min;
65 unsigned char update_hwp_max;
66 unsigned char update_hwp_desired;
67 unsigned char update_hwp_window;
68 unsigned char update_hwp_use_pkg;
69 unsigned char update_hwp_enable;
70 #define hwp_update_enabled() (update_hwp_enable | update_hwp_epp | update_hwp_max | update_hwp_min | update_hwp_desired | update_hwp_window | update_hwp_use_pkg)
71 int max_cpu_num;
72 int max_pkg_num;
73 #define MAX_PACKAGES 64
74 unsigned int first_cpu_in_pkg[MAX_PACKAGES];
75 unsigned long long pkg_present_set;
76 unsigned long long pkg_selected_set;
77 cpu_set_t *cpu_present_set;
78 cpu_set_t *cpu_selected_set;
79 int genuine_intel;
80 
81 size_t cpu_setsize;
82 
83 char *proc_stat = "/proc/stat";
84 
85 unsigned int has_epb;	/* MSR_IA32_ENERGY_PERF_BIAS */
86 unsigned int has_hwp;	/* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
87 			/* IA32_HWP_REQUEST, IA32_HWP_STATUS */
88 unsigned int has_hwp_notify;		/* IA32_HWP_INTERRUPT */
89 unsigned int has_hwp_activity_window;	/* IA32_HWP_REQUEST[bits 41:32] */
90 unsigned int has_hwp_epp;	/* IA32_HWP_REQUEST[bits 31:24] */
91 unsigned int has_hwp_request_pkg;	/* IA32_HWP_REQUEST_PKG */
92 
93 unsigned int bdx_highest_ratio;
94 
95 /*
96  * maintain compatibility with original implementation, but don't document it:
97  */
98 void usage(void)
99 {
100 	fprintf(stderr, "%s [options] [scope][field value]\n", progname);
101 	fprintf(stderr, "scope: --cpu cpu-list [--hwp-use-pkg #] | --pkg pkg-list\n");
102 	fprintf(stderr, "field: --all | --epb | --hwp-epp | --hwp-min | --hwp-max | --hwp-desired\n");
103 	fprintf(stderr, "other: --hwp-enable | --turbo-enable (0 | 1) | --help | --force\n");
104 	fprintf(stderr,
105 		"value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
106 	fprintf(stderr, "--hwp-window usec\n");
107 
108 	fprintf(stderr, "Specify only Energy Performance BIAS (legacy usage):\n");
109 	fprintf(stderr, "%s: [-c cpu] [-v] (-r | policy-value )\n", progname);
110 
111 	exit(1);
112 }
113 
114 /*
115  * If bdx_highest_ratio is set,
116  * then we must translate between MSR format and simple ratio
117  * used on the cmdline.
118  */
119 int ratio_2_msr_perf(int ratio)
120 {
121 	int msr_perf;
122 
123 	if (!bdx_highest_ratio)
124 		return ratio;
125 
126 	msr_perf = ratio * 255 / bdx_highest_ratio;
127 
128 	if (debug)
129 		fprintf(stderr, "%d = ratio_to_msr_perf(%d)\n", msr_perf, ratio);
130 
131 	return msr_perf;
132 }
133 int msr_perf_2_ratio(int msr_perf)
134 {
135 	int ratio;
136 	double d;
137 
138 	if (!bdx_highest_ratio)
139 		return msr_perf;
140 
141 	d = (double)msr_perf * (double) bdx_highest_ratio / 255.0;
142 	d = d + 0.5;	/* round */
143 	ratio = (int)d;
144 
145 	if (debug)
146 		fprintf(stderr, "%d = msr_perf_ratio(%d) {%f}\n", ratio, msr_perf, d);
147 
148 	return ratio;
149 }
150 int parse_cmdline_epb(int i)
151 {
152 	if (!has_epb)
153 		errx(1, "EPB not enabled on this platform");
154 
155 	update_epb = 1;
156 
157 	switch (i) {
158 	case OPTARG_POWER:
159 		return ENERGY_PERF_BIAS_POWERSAVE;
160 	case OPTARG_BALANCE_POWER:
161 		return ENERGY_PERF_BIAS_BALANCE_POWERSAVE;
162 	case OPTARG_NORMAL:
163 		return ENERGY_PERF_BIAS_NORMAL;
164 	case OPTARG_BALANCE_PERFORMANCE:
165 		return ENERGY_PERF_BIAS_BALANCE_PERFORMANCE;
166 	case OPTARG_PERFORMANCE:
167 		return ENERGY_PERF_BIAS_PERFORMANCE;
168 	}
169 	if (i < 0 || i > ENERGY_PERF_BIAS_POWERSAVE)
170 		errx(1, "--epb must be from 0 to 15");
171 	return i;
172 }
173 
174 #define HWP_CAP_LOWEST 0
175 #define HWP_CAP_HIGHEST 255
176 
177 /*
178  * "performance" changes hwp_min to cap.highest
179  * All others leave it at cap.lowest
180  */
181 int parse_cmdline_hwp_min(int i)
182 {
183 	update_hwp_min = 1;
184 
185 	switch (i) {
186 	case OPTARG_POWER:
187 	case OPTARG_BALANCE_POWER:
188 	case OPTARG_NORMAL:
189 	case OPTARG_BALANCE_PERFORMANCE:
190 		return HWP_CAP_LOWEST;
191 	case OPTARG_PERFORMANCE:
192 		return HWP_CAP_HIGHEST;
193 	}
194 	return i;
195 }
196 /*
197  * "power" changes hwp_max to cap.lowest
198  * All others leave it at cap.highest
199  */
200 int parse_cmdline_hwp_max(int i)
201 {
202 	update_hwp_max = 1;
203 
204 	switch (i) {
205 	case OPTARG_POWER:
206 		return HWP_CAP_LOWEST;
207 	case OPTARG_NORMAL:
208 	case OPTARG_BALANCE_POWER:
209 	case OPTARG_BALANCE_PERFORMANCE:
210 	case OPTARG_PERFORMANCE:
211 		return HWP_CAP_HIGHEST;
212 	}
213 	return i;
214 }
215 /*
216  * for --hwp-des, all strings leave it in autonomous mode
217  * If you want to change it, you need to explicitly pick a value
218  */
219 int parse_cmdline_hwp_desired(int i)
220 {
221 	update_hwp_desired = 1;
222 
223 	switch (i) {
224 	case OPTARG_POWER:
225 	case OPTARG_BALANCE_POWER:
226 	case OPTARG_BALANCE_PERFORMANCE:
227 	case OPTARG_NORMAL:
228 	case OPTARG_PERFORMANCE:
229 		return 0;	/* autonomous */
230 	}
231 	return i;
232 }
233 
234 int parse_cmdline_hwp_window(int i)
235 {
236 	unsigned int exponent;
237 
238 	update_hwp_window = 1;
239 
240 	switch (i) {
241 	case OPTARG_POWER:
242 	case OPTARG_BALANCE_POWER:
243 	case OPTARG_NORMAL:
244 	case OPTARG_BALANCE_PERFORMANCE:
245 	case OPTARG_PERFORMANCE:
246 		return 0;
247 	}
248 	if (i < 0 || i > 1270000000) {
249 		fprintf(stderr, "--hwp-window: 0 for auto; 1 - 1270000000 usec for window duration\n");
250 		usage();
251 	}
252 	for (exponent = 0; ; ++exponent) {
253 		if (debug)
254 			printf("%d 10^%d\n", i, exponent);
255 
256 		if (i <= 127)
257 			break;
258 
259 		i = i / 10;
260 	}
261 	if (debug)
262 		fprintf(stderr, "%d*10^%d: 0x%x\n", i, exponent, (exponent << 7) | i);
263 
264 	return (exponent << 7) | i;
265 }
266 int parse_cmdline_hwp_epp(int i)
267 {
268 	update_hwp_epp = 1;
269 
270 	switch (i) {
271 	case OPTARG_POWER:
272 		return HWP_EPP_POWERSAVE;
273 	case OPTARG_BALANCE_POWER:
274 		return HWP_EPP_BALANCE_POWERSAVE;
275 	case OPTARG_NORMAL:
276 	case OPTARG_BALANCE_PERFORMANCE:
277 		return HWP_EPP_BALANCE_PERFORMANCE;
278 	case OPTARG_PERFORMANCE:
279 		return HWP_EPP_PERFORMANCE;
280 	}
281 	if (i < 0 || i > 0xff) {
282 		fprintf(stderr, "--hwp-epp must be from 0 to 0xff\n");
283 		usage();
284 	}
285 	return i;
286 }
287 int parse_cmdline_turbo(int i)
288 {
289 	update_turbo = 1;
290 
291 	switch (i) {
292 	case OPTARG_POWER:
293 		return 0;
294 	case OPTARG_NORMAL:
295 	case OPTARG_BALANCE_POWER:
296 	case OPTARG_BALANCE_PERFORMANCE:
297 	case OPTARG_PERFORMANCE:
298 		return 1;
299 	}
300 	if (i < 0 || i > 1) {
301 		fprintf(stderr, "--turbo-enable: 1 to enable, 0 to disable\n");
302 		usage();
303 	}
304 	return i;
305 }
306 
307 int parse_optarg_string(char *s)
308 {
309 	int i;
310 	char *endptr;
311 
312 	if (!strncmp(s, "default", 7))
313 		return OPTARG_NORMAL;
314 
315 	if (!strncmp(s, "normal", 6))
316 		return OPTARG_NORMAL;
317 
318 	if (!strncmp(s, "power", 9))
319 		return OPTARG_POWER;
320 
321 	if (!strncmp(s, "balance-power", 17))
322 		return OPTARG_BALANCE_POWER;
323 
324 	if (!strncmp(s, "balance-performance", 19))
325 		return OPTARG_BALANCE_PERFORMANCE;
326 
327 	if (!strncmp(s, "performance", 11))
328 		return OPTARG_PERFORMANCE;
329 
330 	i = strtol(s, &endptr, 0);
331 	if (s == endptr) {
332 		fprintf(stderr, "no digits in \"%s\"\n", s);
333 		usage();
334 	}
335 	if (i == LONG_MIN || i == LONG_MAX)
336 		errx(-1, "%s", s);
337 
338 	if (i > 0xFF)
339 		errx(-1, "%d (0x%x) must be < 256", i, i);
340 
341 	if (i < 0)
342 		errx(-1, "%d (0x%x) must be >= 0", i, i);
343 	return i;
344 }
345 
346 void parse_cmdline_all(char *s)
347 {
348 	force++;
349 	update_hwp_enable = 1;
350 	req_update.hwp_min = parse_cmdline_hwp_min(parse_optarg_string(s));
351 	req_update.hwp_max = parse_cmdline_hwp_max(parse_optarg_string(s));
352 	req_update.hwp_epp = parse_cmdline_hwp_epp(parse_optarg_string(s));
353 	if (has_epb)
354 		new_epb = parse_cmdline_epb(parse_optarg_string(s));
355 	turbo_update_value = parse_cmdline_turbo(parse_optarg_string(s));
356 	req_update.hwp_desired = parse_cmdline_hwp_desired(parse_optarg_string(s));
357 	req_update.hwp_window = parse_cmdline_hwp_window(parse_optarg_string(s));
358 }
359 
360 void validate_cpu_selected_set(void)
361 {
362 	int cpu;
363 
364 	if (CPU_COUNT_S(cpu_setsize, cpu_selected_set) == 0)
365 		errx(0, "no CPUs requested");
366 
367 	for (cpu = 0; cpu <= max_cpu_num; ++cpu) {
368 		if (CPU_ISSET_S(cpu, cpu_setsize, cpu_selected_set))
369 			if (!CPU_ISSET_S(cpu, cpu_setsize, cpu_present_set))
370 				errx(1, "Requested cpu% is not present", cpu);
371 	}
372 }
373 
374 void parse_cmdline_cpu(char *s)
375 {
376 	char *startp, *endp;
377 	int cpu = 0;
378 
379 	if (pkg_selected_set) {
380 		usage();
381 		errx(1, "--cpu | --pkg");
382 	}
383 	cpu_selected_set = CPU_ALLOC((max_cpu_num + 1));
384 	if (cpu_selected_set == NULL)
385 		err(1, "cpu_selected_set");
386 	CPU_ZERO_S(cpu_setsize, cpu_selected_set);
387 
388 	for (startp = s; startp && *startp;) {
389 
390 		if (*startp == ',') {
391 			startp++;
392 			continue;
393 		}
394 
395 		if (*startp == '-') {
396 			int end_cpu;
397 
398 			startp++;
399 			end_cpu = strtol(startp, &endp, 10);
400 			if (startp == endp)
401 				continue;
402 
403 			while (cpu <= end_cpu) {
404 				if (cpu > max_cpu_num)
405 					errx(1, "Requested cpu%d exceeds max cpu%d", cpu, max_cpu_num);
406 				CPU_SET_S(cpu, cpu_setsize, cpu_selected_set);
407 				cpu++;
408 			}
409 			startp = endp;
410 			continue;
411 		}
412 
413 		if (strncmp(startp, "all", 3) == 0) {
414 			for (cpu = 0; cpu <= max_cpu_num; cpu += 1) {
415 				if (CPU_ISSET_S(cpu, cpu_setsize, cpu_present_set))
416 					CPU_SET_S(cpu, cpu_setsize, cpu_selected_set);
417 			}
418 			startp += 3;
419 			if (*startp == 0)
420 				break;
421 		}
422 		/* "--cpu even" is not documented */
423 		if (strncmp(startp, "even", 4) == 0) {
424 			for (cpu = 0; cpu <= max_cpu_num; cpu += 2) {
425 				if (CPU_ISSET_S(cpu, cpu_setsize, cpu_present_set))
426 					CPU_SET_S(cpu, cpu_setsize, cpu_selected_set);
427 			}
428 			startp += 4;
429 			if (*startp == 0)
430 				break;
431 		}
432 
433 		/* "--cpu odd" is not documented */
434 		if (strncmp(startp, "odd", 3) == 0) {
435 			for (cpu = 1; cpu <= max_cpu_num; cpu += 2) {
436 				if (CPU_ISSET_S(cpu, cpu_setsize, cpu_present_set))
437 					CPU_SET_S(cpu, cpu_setsize, cpu_selected_set);
438 			}
439 			startp += 3;
440 			if (*startp == 0)
441 				break;
442 		}
443 
444 		cpu = strtol(startp, &endp, 10);
445 		if (startp == endp)
446 			errx(1, "--cpu cpu-set: confused by '%s'", startp);
447 		if (cpu > max_cpu_num)
448 			errx(1, "Requested cpu%d exceeds max cpu%d", cpu, max_cpu_num);
449 		CPU_SET_S(cpu, cpu_setsize, cpu_selected_set);
450 		startp = endp;
451 	}
452 
453 	validate_cpu_selected_set();
454 
455 }
456 
457 void parse_cmdline_pkg(char *s)
458 {
459 	char *startp, *endp;
460 	int pkg = 0;
461 
462 	if (cpu_selected_set) {
463 		usage();
464 		errx(1, "--pkg | --cpu");
465 	}
466 	pkg_selected_set = 0;
467 
468 	for (startp = s; startp && *startp;) {
469 
470 		if (*startp == ',') {
471 			startp++;
472 			continue;
473 		}
474 
475 		if (*startp == '-') {
476 			int end_pkg;
477 
478 			startp++;
479 			end_pkg = strtol(startp, &endp, 10);
480 			if (startp == endp)
481 				continue;
482 
483 			while (pkg <= end_pkg) {
484 				if (pkg > max_pkg_num)
485 					errx(1, "Requested pkg%d exceeds max pkg%d", pkg, max_pkg_num);
486 				pkg_selected_set |= 1 << pkg;
487 				pkg++;
488 			}
489 			startp = endp;
490 			continue;
491 		}
492 
493 		if (strncmp(startp, "all", 3) == 0) {
494 			pkg_selected_set = pkg_present_set;
495 			return;
496 		}
497 
498 		pkg = strtol(startp, &endp, 10);
499 		if (pkg > max_pkg_num)
500 			errx(1, "Requested pkg%d Exceeds max pkg%d", pkg, max_pkg_num);
501 		pkg_selected_set |= 1 << pkg;
502 		startp = endp;
503 	}
504 }
505 
506 void for_packages(unsigned long long pkg_set, int (func)(int))
507 {
508 	int pkg_num;
509 
510 	for (pkg_num = 0; pkg_num <= max_pkg_num; ++pkg_num) {
511 		if (pkg_set & (1UL << pkg_num))
512 			func(pkg_num);
513 	}
514 }
515 
516 void print_version(void)
517 {
518 	printf("x86_energy_perf_policy 17.05.11 (C) Len Brown <len.brown@intel.com>\n");
519 }
520 
521 void cmdline(int argc, char **argv)
522 {
523 	int opt;
524 	int option_index = 0;
525 
526 	static struct option long_options[] = {
527 		{"all",		required_argument,	0, 'a'},
528 		{"cpu",		required_argument,	0, 'c'},
529 		{"pkg",		required_argument,	0, 'p'},
530 		{"debug",	no_argument,		0, 'd'},
531 		{"hwp-desired",	required_argument,	0, 'D'},
532 		{"epb",	required_argument,	0, 'B'},
533 		{"force",	no_argument,	0, 'f'},
534 		{"hwp-enable",	no_argument,	0, 'e'},
535 		{"help",	no_argument,	0, 'h'},
536 		{"hwp-epp",	required_argument,	0, 'P'},
537 		{"hwp-min",	required_argument,	0, 'm'},
538 		{"hwp-max",	required_argument,	0, 'M'},
539 		{"read",	no_argument,		0, 'r'},
540 		{"turbo-enable",	required_argument,	0, 't'},
541 		{"hwp-use-pkg",	required_argument,	0, 'u'},
542 		{"version",	no_argument,		0, 'v'},
543 		{"hwp-window",	required_argument,	0, 'w'},
544 		{0,		0,			0, 0 }
545 	};
546 
547 	progname = argv[0];
548 
549 	while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw",
550 				long_options, &option_index)) != -1) {
551 		switch (opt) {
552 		case 'a':
553 			parse_cmdline_all(optarg);
554 			break;
555 		case 'B':
556 			new_epb = parse_cmdline_epb(parse_optarg_string(optarg));
557 			break;
558 		case 'c':
559 			parse_cmdline_cpu(optarg);
560 			break;
561 		case 'e':
562 			update_hwp_enable = 1;
563 			break;
564 		case 'h':
565 			usage();
566 			break;
567 		case 'd':
568 			debug++;
569 			verbose++;
570 			break;
571 		case 'f':
572 			force++;
573 			break;
574 		case 'D':
575 			req_update.hwp_desired = parse_cmdline_hwp_desired(parse_optarg_string(optarg));
576 			break;
577 		case 'm':
578 			req_update.hwp_min = parse_cmdline_hwp_min(parse_optarg_string(optarg));
579 			break;
580 		case 'M':
581 			req_update.hwp_max = parse_cmdline_hwp_max(parse_optarg_string(optarg));
582 			break;
583 		case 'p':
584 			parse_cmdline_pkg(optarg);
585 			break;
586 		case 'P':
587 			req_update.hwp_epp = parse_cmdline_hwp_epp(parse_optarg_string(optarg));
588 			break;
589 		case 'r':
590 			/* v1 used -r to specify read-only mode, now the default */
591 			break;
592 		case 't':
593 			turbo_update_value = parse_cmdline_turbo(parse_optarg_string(optarg));
594 			break;
595 		case 'u':
596 			update_hwp_use_pkg++;
597 			if (atoi(optarg) == 0)
598 				req_update.hwp_use_pkg = 0;
599 			else
600 				req_update.hwp_use_pkg = 1;
601 			break;
602 		case 'v':
603 			print_version();
604 			exit(0);
605 			break;
606 		case 'w':
607 			req_update.hwp_window = parse_cmdline_hwp_window(parse_optarg_string(optarg));
608 			break;
609 		default:
610 			usage();
611 		}
612 	}
613 	/*
614 	 * v1 allowed "performance"|"normal"|"power" with no policy specifier
615 	 * to update BIAS.  Continue to support that, even though no longer documented.
616 	 */
617 	if (argc == optind + 1)
618 		new_epb = parse_cmdline_epb(parse_optarg_string(argv[optind]));
619 
620 	if (argc > optind + 1) {
621 		fprintf(stderr, "stray parameter '%s'\n", argv[optind + 1]);
622 		usage();
623 	}
624 }
625 
626 
627 int get_msr(int cpu, int offset, unsigned long long *msr)
628 {
629 	int retval;
630 	char pathname[32];
631 	int fd;
632 
633 	sprintf(pathname, "/dev/cpu/%d/msr", cpu);
634 	fd = open(pathname, O_RDONLY);
635 	if (fd < 0)
636 		err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
637 
638 	retval = pread(fd, msr, sizeof(*msr), offset);
639 	if (retval != sizeof(*msr))
640 		err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset);
641 
642 	if (debug > 1)
643 		fprintf(stderr, "get_msr(cpu%d, 0x%X, 0x%llX)\n", cpu, offset, *msr);
644 
645 	close(fd);
646 	return 0;
647 }
648 
649 int put_msr(int cpu, int offset, unsigned long long new_msr)
650 {
651 	char pathname[32];
652 	int retval;
653 	int fd;
654 
655 	sprintf(pathname, "/dev/cpu/%d/msr", cpu);
656 	fd = open(pathname, O_RDWR);
657 	if (fd < 0)
658 		err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
659 
660 	retval = pwrite(fd, &new_msr, sizeof(new_msr), offset);
661 	if (retval != sizeof(new_msr))
662 		err(-2, "pwrite(cpu%d, offset 0x%x, 0x%llx) = %d", cpu, offset, new_msr, retval);
663 
664 	close(fd);
665 
666 	if (debug > 1)
667 		fprintf(stderr, "put_msr(cpu%d, 0x%X, 0x%llX)\n", cpu, offset, new_msr);
668 
669 	return 0;
670 }
671 
672 void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
673 {
674 	if (cpu != -1)
675 		printf("cpu%d: ", cpu);
676 
677 	printf("HWP_CAP: low %d eff %d guar %d high %d\n",
678 		cap->lowest, cap->efficient, cap->guaranteed, cap->highest);
679 }
680 void read_hwp_cap(int cpu, struct msr_hwp_cap *cap, unsigned int msr_offset)
681 {
682 	unsigned long long msr;
683 
684 	get_msr(cpu, msr_offset, &msr);
685 
686 	cap->highest = msr_perf_2_ratio(HWP_HIGHEST_PERF(msr));
687 	cap->guaranteed = msr_perf_2_ratio(HWP_GUARANTEED_PERF(msr));
688 	cap->efficient = msr_perf_2_ratio(HWP_MOSTEFFICIENT_PERF(msr));
689 	cap->lowest = msr_perf_2_ratio(HWP_LOWEST_PERF(msr));
690 }
691 
692 void print_hwp_request(int cpu, struct msr_hwp_request *h, char *str)
693 {
694 	if (cpu != -1)
695 		printf("cpu%d: ", cpu);
696 
697 	if (str)
698 		printf("%s", str);
699 
700 	printf("HWP_REQ: min %d max %d des %d epp %d window 0x%x (%d*10^%dus) use_pkg %d\n",
701 		h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
702 		h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg);
703 }
704 void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str)
705 {
706 	printf("pkg%d: ", pkg);
707 
708 	if (str)
709 		printf("%s", str);
710 
711 	printf("HWP_REQ_PKG: min %d max %d des %d epp %d window 0x%x (%d*10^%dus)\n",
712 		h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
713 		h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7);
714 }
715 void read_hwp_request(int cpu, struct msr_hwp_request *hwp_req, unsigned int msr_offset)
716 {
717 	unsigned long long msr;
718 
719 	get_msr(cpu, msr_offset, &msr);
720 
721 	hwp_req->hwp_min = msr_perf_2_ratio((((msr) >> 0) & 0xff));
722 	hwp_req->hwp_max = msr_perf_2_ratio((((msr) >> 8) & 0xff));
723 	hwp_req->hwp_desired = msr_perf_2_ratio((((msr) >> 16) & 0xff));
724 	hwp_req->hwp_epp = (((msr) >> 24) & 0xff);
725 	hwp_req->hwp_window = (((msr) >> 32) & 0x3ff);
726 	hwp_req->hwp_use_pkg = (((msr) >> 42) & 0x1);
727 }
728 
729 void write_hwp_request(int cpu, struct msr_hwp_request *hwp_req, unsigned int msr_offset)
730 {
731 	unsigned long long msr = 0;
732 
733 	if (debug > 1)
734 		printf("cpu%d: requesting min %d max %d des %d epp %d window 0x%0x use_pkg %d\n",
735 			cpu, hwp_req->hwp_min, hwp_req->hwp_max,
736 			hwp_req->hwp_desired, hwp_req->hwp_epp,
737 			hwp_req->hwp_window, hwp_req->hwp_use_pkg);
738 
739 	msr |= HWP_MIN_PERF(ratio_2_msr_perf(hwp_req->hwp_min));
740 	msr |= HWP_MAX_PERF(ratio_2_msr_perf(hwp_req->hwp_max));
741 	msr |= HWP_DESIRED_PERF(ratio_2_msr_perf(hwp_req->hwp_desired));
742 	msr |= HWP_ENERGY_PERF_PREFERENCE(hwp_req->hwp_epp);
743 	msr |= HWP_ACTIVITY_WINDOW(hwp_req->hwp_window);
744 	msr |= HWP_PACKAGE_CONTROL(hwp_req->hwp_use_pkg);
745 
746 	put_msr(cpu, msr_offset, msr);
747 }
748 
749 int print_cpu_msrs(int cpu)
750 {
751 	unsigned long long msr;
752 	struct msr_hwp_request req;
753 	struct msr_hwp_cap cap;
754 
755 	if (has_epb) {
756 		get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr);
757 
758 		printf("cpu%d: EPB %u\n", cpu, (unsigned int) msr);
759 	}
760 
761 	if (!has_hwp)
762 		return 0;
763 
764 	read_hwp_request(cpu, &req, MSR_HWP_REQUEST);
765 	print_hwp_request(cpu, &req, "");
766 
767 	read_hwp_cap(cpu, &cap, MSR_HWP_CAPABILITIES);
768 	print_hwp_cap(cpu, &cap, "");
769 
770 	return 0;
771 }
772 
773 int print_pkg_msrs(int pkg)
774 {
775 	struct msr_hwp_request req;
776 	unsigned long long msr;
777 
778 	if (!has_hwp)
779 		return 0;
780 
781 	read_hwp_request(first_cpu_in_pkg[pkg], &req, MSR_HWP_REQUEST_PKG);
782 	print_hwp_request_pkg(pkg, &req, "");
783 
784 	if (has_hwp_notify) {
785 		get_msr(first_cpu_in_pkg[pkg], MSR_HWP_INTERRUPT, &msr);
786 		fprintf(stderr,
787 		"pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n",
788 		pkg, msr,
789 		((msr) & 0x2) ? "EN" : "Dis",
790 		((msr) & 0x1) ? "EN" : "Dis");
791 	}
792 	get_msr(first_cpu_in_pkg[pkg], MSR_HWP_STATUS, &msr);
793 	fprintf(stderr,
794 		"pkg%d: MSR_HWP_STATUS: 0x%08llx (%sExcursion_Min, %sGuaranteed_Perf_Change)\n",
795 		pkg, msr,
796 		((msr) & 0x4) ? "" : "No-",
797 		((msr) & 0x1) ? "" : "No-");
798 
799 	return 0;
800 }
801 
802 /*
803  * Assumption: All HWP systems have 100 MHz bus clock
804  */
805 int ratio_2_sysfs_khz(int ratio)
806 {
807 	int bclk_khz = 100 * 1000;	/* 100,000 KHz = 100 MHz */
808 
809 	return ratio * bclk_khz;
810 }
811 /*
812  * If HWP is enabled and cpufreq sysfs attribtes are present,
813  * then update sysfs, so that it will not become
814  * stale when we write to MSRs.
815  * (intel_pstate's max_perf_pct and min_perf_pct will follow cpufreq,
816  *  so we don't have to touch that.)
817  */
818 void update_cpufreq_scaling_freq(int is_max, int cpu, unsigned int ratio)
819 {
820 	char pathname[64];
821 	FILE *fp;
822 	int retval;
823 	int khz;
824 
825 	sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq",
826 		cpu, is_max ? "max" : "min");
827 
828 	fp = fopen(pathname, "w");
829 	if (!fp) {
830 		if (debug)
831 			perror(pathname);
832 		return;
833 	}
834 
835 	khz = ratio_2_sysfs_khz(ratio);
836 	retval = fprintf(fp, "%d", khz);
837 	if (retval < 0)
838 		if (debug)
839 			perror("fprintf");
840 	if (debug)
841 		printf("echo %d > %s\n", khz, pathname);
842 
843 	fclose(fp);
844 }
845 
846 /*
847  * We update all sysfs before updating any MSRs because of
848  * bugs in cpufreq/intel_pstate where the sysfs writes
849  * for a CPU may change the min/max values on other CPUS.
850  */
851 
852 int update_sysfs(int cpu)
853 {
854 	if (!has_hwp)
855 		return 0;
856 
857 	if (!hwp_update_enabled())
858 		return 0;
859 
860 	if (access("/sys/devices/system/cpu/cpu0/cpufreq", F_OK))
861 		return 0;
862 
863 	if (update_hwp_min)
864 		update_cpufreq_scaling_freq(0, cpu, req_update.hwp_min);
865 
866 	if (update_hwp_max)
867 		update_cpufreq_scaling_freq(1, cpu, req_update.hwp_max);
868 
869 	return 0;
870 }
871 
872 int verify_hwp_req_self_consistency(int cpu, struct msr_hwp_request *req)
873 {
874 	/* fail if min > max requested */
875 	if (req->hwp_min > req->hwp_max) {
876 		errx(1, "cpu%d: requested hwp-min %d > hwp_max %d",
877 			cpu, req->hwp_min, req->hwp_max);
878 	}
879 
880 	/* fail if desired > max requestd */
881 	if (req->hwp_desired && (req->hwp_desired > req->hwp_max)) {
882 		errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d",
883 			cpu, req->hwp_desired, req->hwp_max);
884 	}
885 	/* fail if desired < min requestd */
886 	if (req->hwp_desired && (req->hwp_desired < req->hwp_min)) {
887 		errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d",
888 			cpu, req->hwp_desired, req->hwp_min);
889 	}
890 
891 	return 0;
892 }
893 
894 int check_hwp_request_v_hwp_capabilities(int cpu, struct msr_hwp_request *req, struct msr_hwp_cap *cap)
895 {
896 	if (update_hwp_max) {
897 		if (req->hwp_max > cap->highest)
898 			errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?",
899 				cpu, req->hwp_max, cap->highest);
900 		if (req->hwp_max < cap->lowest)
901 			errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?",
902 				cpu, req->hwp_max, cap->lowest);
903 	}
904 
905 	if (update_hwp_min) {
906 		if (req->hwp_min > cap->highest)
907 			errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?",
908 				cpu, req->hwp_min, cap->highest);
909 		if (req->hwp_min < cap->lowest)
910 			errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?",
911 				cpu, req->hwp_min, cap->lowest);
912 	}
913 
914 	if (update_hwp_min && update_hwp_max && (req->hwp_min > req->hwp_max))
915 		errx(1, "cpu%d: requested min %d > requested max %d",
916 			cpu, req->hwp_min, req->hwp_max);
917 
918 	if (update_hwp_desired && req->hwp_desired) {
919 		if (req->hwp_desired > req->hwp_max)
920 			errx(1, "cpu%d: requested desired %d > requested max %d, use --force?",
921 				cpu, req->hwp_desired, req->hwp_max);
922 		if (req->hwp_desired < req->hwp_min)
923 			errx(1, "cpu%d: requested desired %d < requested min %d, use --force?",
924 				cpu, req->hwp_desired, req->hwp_min);
925 		if (req->hwp_desired < cap->lowest)
926 			errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?",
927 				cpu, req->hwp_desired, cap->lowest);
928 		if (req->hwp_desired > cap->highest)
929 			errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?",
930 				cpu, req->hwp_desired, cap->highest);
931 	}
932 
933 	return 0;
934 }
935 
936 int update_hwp_request(int cpu)
937 {
938 	struct msr_hwp_request req;
939 	struct msr_hwp_cap cap;
940 
941 	int msr_offset = MSR_HWP_REQUEST;
942 
943 	read_hwp_request(cpu, &req, msr_offset);
944 	if (debug)
945 		print_hwp_request(cpu, &req, "old: ");
946 
947 	if (update_hwp_min)
948 		req.hwp_min = req_update.hwp_min;
949 
950 	if (update_hwp_max)
951 		req.hwp_max = req_update.hwp_max;
952 
953 	if (update_hwp_desired)
954 		req.hwp_desired = req_update.hwp_desired;
955 
956 	if (update_hwp_window)
957 		req.hwp_window = req_update.hwp_window;
958 
959 	if (update_hwp_epp)
960 		req.hwp_epp = req_update.hwp_epp;
961 
962 	req.hwp_use_pkg = req_update.hwp_use_pkg;
963 
964 	read_hwp_cap(cpu, &cap, MSR_HWP_CAPABILITIES);
965 	if (debug)
966 		print_hwp_cap(cpu, &cap, "");
967 
968 	if (!force)
969 		check_hwp_request_v_hwp_capabilities(cpu, &req, &cap);
970 
971 	verify_hwp_req_self_consistency(cpu, &req);
972 
973 	write_hwp_request(cpu, &req, msr_offset);
974 
975 	if (debug) {
976 		read_hwp_request(cpu, &req, msr_offset);
977 		print_hwp_request(cpu, &req, "new: ");
978 	}
979 	return 0;
980 }
981 int update_hwp_request_pkg(int pkg)
982 {
983 	struct msr_hwp_request req;
984 	struct msr_hwp_cap cap;
985 	int cpu = first_cpu_in_pkg[pkg];
986 
987 	int msr_offset = MSR_HWP_REQUEST_PKG;
988 
989 	read_hwp_request(cpu, &req, msr_offset);
990 	if (debug)
991 		print_hwp_request_pkg(pkg, &req, "old: ");
992 
993 	if (update_hwp_min)
994 		req.hwp_min = req_update.hwp_min;
995 
996 	if (update_hwp_max)
997 		req.hwp_max = req_update.hwp_max;
998 
999 	if (update_hwp_desired)
1000 		req.hwp_desired = req_update.hwp_desired;
1001 
1002 	if (update_hwp_window)
1003 		req.hwp_window = req_update.hwp_window;
1004 
1005 	if (update_hwp_epp)
1006 		req.hwp_epp = req_update.hwp_epp;
1007 
1008 	read_hwp_cap(cpu, &cap, MSR_HWP_CAPABILITIES);
1009 	if (debug)
1010 		print_hwp_cap(cpu, &cap, "");
1011 
1012 	if (!force)
1013 		check_hwp_request_v_hwp_capabilities(cpu, &req, &cap);
1014 
1015 	verify_hwp_req_self_consistency(cpu, &req);
1016 
1017 	write_hwp_request(cpu, &req, msr_offset);
1018 
1019 	if (debug) {
1020 		read_hwp_request(cpu, &req, msr_offset);
1021 		print_hwp_request_pkg(pkg, &req, "new: ");
1022 	}
1023 	return 0;
1024 }
1025 
1026 int enable_hwp_on_cpu(int cpu)
1027 {
1028 	unsigned long long msr;
1029 
1030 	get_msr(cpu, MSR_PM_ENABLE, &msr);
1031 	put_msr(cpu, MSR_PM_ENABLE, 1);
1032 
1033 	if (verbose)
1034 		printf("cpu%d: MSR_PM_ENABLE old: %d new: %d\n", cpu, (unsigned int) msr, 1);
1035 
1036 	return 0;
1037 }
1038 
1039 int update_cpu_msrs(int cpu)
1040 {
1041 	unsigned long long msr;
1042 
1043 
1044 	if (update_epb) {
1045 		get_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, &msr);
1046 		put_msr(cpu, MSR_IA32_ENERGY_PERF_BIAS, new_epb);
1047 
1048 		if (verbose)
1049 			printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n",
1050 				cpu, (unsigned int) msr, (unsigned int) new_epb);
1051 	}
1052 
1053 	if (update_turbo) {
1054 		int turbo_is_present_and_disabled;
1055 
1056 		get_msr(cpu, MSR_IA32_MISC_ENABLE, &msr);
1057 
1058 		turbo_is_present_and_disabled = ((msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE) != 0);
1059 
1060 		if (turbo_update_value == 1)	{
1061 			if (turbo_is_present_and_disabled) {
1062 				msr &= ~MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
1063 				put_msr(cpu, MSR_IA32_MISC_ENABLE, msr);
1064 				if (verbose)
1065 					printf("cpu%d: turbo ENABLE\n", cpu);
1066 			}
1067 		} else {
1068 			/*
1069 			 * if "turbo_is_enabled" were known to be describe this cpu
1070 			 * then we could use it here to skip redundant disable requests.
1071 			 * but cpu may be in a different package, so we always write.
1072 			 */
1073 			msr |= MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
1074 			put_msr(cpu, MSR_IA32_MISC_ENABLE, msr);
1075 			if (verbose)
1076 				printf("cpu%d: turbo DISABLE\n", cpu);
1077 		}
1078 	}
1079 
1080 	if (!has_hwp)
1081 		return 0;
1082 
1083 	if (!hwp_update_enabled())
1084 		return 0;
1085 
1086 	update_hwp_request(cpu);
1087 	return 0;
1088 }
1089 
1090 /*
1091  * Open a file, and exit on failure
1092  */
1093 FILE *fopen_or_die(const char *path, const char *mode)
1094 {
1095 	FILE *filep = fopen(path, "r");
1096 
1097 	if (!filep)
1098 		err(1, "%s: open failed", path);
1099 	return filep;
1100 }
1101 
1102 unsigned int get_pkg_num(int cpu)
1103 {
1104 	FILE *fp;
1105 	char pathname[128];
1106 	unsigned int pkg;
1107 	int retval;
1108 
1109 	sprintf(pathname, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu);
1110 
1111 	fp = fopen_or_die(pathname, "r");
1112 	retval = fscanf(fp, "%d\n", &pkg);
1113 	if (retval != 1)
1114 		errx(1, "%s: failed to parse", pathname);
1115 	return pkg;
1116 }
1117 
1118 int set_max_cpu_pkg_num(int cpu)
1119 {
1120 	unsigned int pkg;
1121 
1122 	if (max_cpu_num < cpu)
1123 		max_cpu_num = cpu;
1124 
1125 	pkg = get_pkg_num(cpu);
1126 
1127 	if (pkg >= MAX_PACKAGES)
1128 		errx(1, "cpu%d: %d >= MAX_PACKAGES (%d)", cpu, pkg, MAX_PACKAGES);
1129 
1130 	if (pkg > max_pkg_num)
1131 		max_pkg_num = pkg;
1132 
1133 	if ((pkg_present_set & (1ULL << pkg)) == 0) {
1134 		pkg_present_set |= (1ULL << pkg);
1135 		first_cpu_in_pkg[pkg] = cpu;
1136 	}
1137 
1138 	return 0;
1139 }
1140 int mark_cpu_present(int cpu)
1141 {
1142 	CPU_SET_S(cpu, cpu_setsize, cpu_present_set);
1143 	return 0;
1144 }
1145 
1146 /*
1147  * run func(cpu) on every cpu in /proc/stat
1148  * return max_cpu number
1149  */
1150 int for_all_proc_cpus(int (func)(int))
1151 {
1152 	FILE *fp;
1153 	int cpu_num;
1154 	int retval;
1155 
1156 	fp = fopen_or_die(proc_stat, "r");
1157 
1158 	retval = fscanf(fp, "cpu %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n");
1159 	if (retval != 0)
1160 		err(1, "%s: failed to parse format", proc_stat);
1161 
1162 	while (1) {
1163 		retval = fscanf(fp, "cpu%u %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d\n", &cpu_num);
1164 		if (retval != 1)
1165 			break;
1166 
1167 		retval = func(cpu_num);
1168 		if (retval) {
1169 			fclose(fp);
1170 			return retval;
1171 		}
1172 	}
1173 	fclose(fp);
1174 	return 0;
1175 }
1176 
1177 void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
1178 {
1179 	int cpu_num;
1180 
1181 	for (cpu_num = 0; cpu_num <= max_cpu_num; ++cpu_num)
1182 		if (CPU_ISSET_S(cpu_num, set_size, cpu_set))
1183 			func(cpu_num);
1184 }
1185 
1186 void init_data_structures(void)
1187 {
1188 	for_all_proc_cpus(set_max_cpu_pkg_num);
1189 
1190 	cpu_setsize = CPU_ALLOC_SIZE((max_cpu_num + 1));
1191 
1192 	cpu_present_set = CPU_ALLOC((max_cpu_num + 1));
1193 	if (cpu_present_set == NULL)
1194 		err(3, "CPU_ALLOC");
1195 	CPU_ZERO_S(cpu_setsize, cpu_present_set);
1196 	for_all_proc_cpus(mark_cpu_present);
1197 }
1198 
1199 /* clear has_hwp if it is not enable (or being enabled) */
1200 
1201 void verify_hwp_is_enabled(void)
1202 {
1203 	unsigned long long msr;
1204 
1205 	if (!has_hwp)	/* set in early_cpuid() */
1206 		return;
1207 
1208 	/* MSR_PM_ENABLE[1] == 1 if HWP is enabled and MSRs visible */
1209 	get_msr(base_cpu, MSR_PM_ENABLE, &msr);
1210 	if ((msr & 1) == 0) {
1211 		fprintf(stderr, "HWP can be enabled using '--hwp-enable'\n");
1212 		has_hwp = 0;
1213 		return;
1214 	}
1215 }
1216 
1217 int req_update_bounds_check(void)
1218 {
1219 	if (!hwp_update_enabled())
1220 		return 0;
1221 
1222 	/* fail if min > max requested */
1223 	if ((update_hwp_max && update_hwp_min) &&
1224 	    (req_update.hwp_min > req_update.hwp_max)) {
1225 		printf("hwp-min %d > hwp_max %d\n", req_update.hwp_min, req_update.hwp_max);
1226 		return -EINVAL;
1227 	}
1228 
1229 	/* fail if desired > max requestd */
1230 	if (req_update.hwp_desired && update_hwp_max &&
1231 	    (req_update.hwp_desired > req_update.hwp_max)) {
1232 		printf("hwp-desired cannot be greater than hwp_max\n");
1233 		return -EINVAL;
1234 	}
1235 	/* fail if desired < min requestd */
1236 	if (req_update.hwp_desired && update_hwp_min &&
1237 	    (req_update.hwp_desired < req_update.hwp_min)) {
1238 		printf("hwp-desired cannot be less than hwp_min\n");
1239 		return -EINVAL;
1240 	}
1241 
1242 	return 0;
1243 }
1244 
1245 void set_base_cpu(void)
1246 {
1247 	base_cpu = sched_getcpu();
1248 	if (base_cpu < 0)
1249 		err(-ENODEV, "No valid cpus found");
1250 }
1251 
1252 
1253 void probe_dev_msr(void)
1254 {
1255 	struct stat sb;
1256 	char pathname[32];
1257 
1258 	sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
1259 	if (stat(pathname, &sb))
1260 		if (system("/sbin/modprobe msr > /dev/null 2>&1"))
1261 			err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
1262 }
1263 /*
1264  * early_cpuid()
1265  * initialize turbo_is_enabled, has_hwp, has_epb
1266  * before cmdline is parsed
1267  */
1268 void early_cpuid(void)
1269 {
1270 	unsigned int eax, ebx, ecx, edx, max_level;
1271 	unsigned int fms, family, model;
1272 
1273 	__get_cpuid(0, &max_level, &ebx, &ecx, &edx);
1274 
1275 	if (max_level < 6)
1276 		errx(1, "Processor not supported\n");
1277 
1278 	__get_cpuid(1, &fms, &ebx, &ecx, &edx);
1279 	family = (fms >> 8) & 0xf;
1280 	model = (fms >> 4) & 0xf;
1281 	if (family == 6 || family == 0xf)
1282 		model += ((fms >> 16) & 0xf) << 4;
1283 
1284 	if (model == 0x4F) {
1285 		unsigned long long msr;
1286 
1287 		get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
1288 
1289 		bdx_highest_ratio = msr & 0xFF;
1290 	}
1291 
1292 	__get_cpuid(0x6, &eax, &ebx, &ecx, &edx);
1293 	turbo_is_enabled = (eax >> 1) & 1;
1294 	has_hwp = (eax >> 7) & 1;
1295 	has_epb = (ecx >> 3) & 1;
1296 }
1297 
1298 /*
1299  * parse_cpuid()
1300  * set
1301  * has_hwp, has_hwp_notify, has_hwp_activity_window, has_hwp_epp, has_hwp_request_pkg, has_epb
1302  */
1303 void parse_cpuid(void)
1304 {
1305 	unsigned int eax, ebx, ecx, edx, max_level;
1306 	unsigned int fms, family, model, stepping;
1307 
1308 	eax = ebx = ecx = edx = 0;
1309 
1310 	__get_cpuid(0, &max_level, &ebx, &ecx, &edx);
1311 
1312 	if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
1313 		genuine_intel = 1;
1314 
1315 	if (debug)
1316 		fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
1317 			(char *)&ebx, (char *)&edx, (char *)&ecx);
1318 
1319 	__get_cpuid(1, &fms, &ebx, &ecx, &edx);
1320 	family = (fms >> 8) & 0xf;
1321 	model = (fms >> 4) & 0xf;
1322 	stepping = fms & 0xf;
1323 	if (family == 6 || family == 0xf)
1324 		model += ((fms >> 16) & 0xf) << 4;
1325 
1326 	if (debug) {
1327 		fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
1328 			max_level, family, model, stepping, family, model, stepping);
1329 		fprintf(stderr, "CPUID(1): %s %s %s %s %s %s %s %s\n",
1330 			ecx & (1 << 0) ? "SSE3" : "-",
1331 			ecx & (1 << 3) ? "MONITOR" : "-",
1332 			ecx & (1 << 7) ? "EIST" : "-",
1333 			ecx & (1 << 8) ? "TM2" : "-",
1334 			edx & (1 << 4) ? "TSC" : "-",
1335 			edx & (1 << 5) ? "MSR" : "-",
1336 			edx & (1 << 22) ? "ACPI-TM" : "-",
1337 			edx & (1 << 29) ? "TM" : "-");
1338 	}
1339 
1340 	if (!(edx & (1 << 5)))
1341 		errx(1, "CPUID: no MSR");
1342 
1343 
1344 	__get_cpuid(0x6, &eax, &ebx, &ecx, &edx);
1345 	/* turbo_is_enabled already set */
1346 	/* has_hwp already set */
1347 	has_hwp_notify = eax & (1 << 8);
1348 	has_hwp_activity_window = eax & (1 << 9);
1349 	has_hwp_epp = eax & (1 << 10);
1350 	has_hwp_request_pkg = eax & (1 << 11);
1351 
1352 	if (!has_hwp_request_pkg && update_hwp_use_pkg)
1353 		errx(1, "--hwp-use-pkg is not available on this hardware");
1354 
1355 	/* has_epb already set */
1356 
1357 	if (debug)
1358 		fprintf(stderr,
1359 			"CPUID(6): %sTURBO, %sHWP, %sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
1360 			turbo_is_enabled ? "" : "No-",
1361 			has_hwp ? "" : "No-",
1362 			has_hwp_notify ? "" : "No-",
1363 			has_hwp_activity_window ? "" : "No-",
1364 			has_hwp_epp ? "" : "No-",
1365 			has_hwp_request_pkg ? "" : "No-",
1366 			has_epb ? "" : "No-");
1367 
1368 	return;	/* success */
1369 }
1370 
1371 int main(int argc, char **argv)
1372 {
1373 	set_base_cpu();
1374 	probe_dev_msr();
1375 	init_data_structures();
1376 
1377 	early_cpuid();	/* initial cpuid parse before cmdline */
1378 
1379 	cmdline(argc, argv);
1380 
1381 	if (debug)
1382 		print_version();
1383 
1384 	parse_cpuid();
1385 
1386 	 /* If CPU-set and PKG-set are not initialized, default to all CPUs */
1387 	if ((cpu_selected_set == 0) && (pkg_selected_set == 0))
1388 		cpu_selected_set = cpu_present_set;
1389 
1390 	/*
1391 	 * If HWP is being enabled, do it now, so that subsequent operations
1392 	 * that access HWP registers can work.
1393 	 */
1394 	if (update_hwp_enable)
1395 		for_all_cpus_in_set(cpu_setsize, cpu_selected_set, enable_hwp_on_cpu);
1396 
1397 	/* If HWP present, but disabled, warn and ignore from here forward */
1398 	verify_hwp_is_enabled();
1399 
1400 	if (req_update_bounds_check())
1401 		return -EINVAL;
1402 
1403 	/* display information only, no updates to settings */
1404 	if (!update_epb && !update_turbo && !hwp_update_enabled()) {
1405 		if (cpu_selected_set)
1406 			for_all_cpus_in_set(cpu_setsize, cpu_selected_set, print_cpu_msrs);
1407 
1408 		if (has_hwp_request_pkg) {
1409 			if (pkg_selected_set == 0)
1410 				pkg_selected_set = pkg_present_set;
1411 
1412 			for_packages(pkg_selected_set, print_pkg_msrs);
1413 		}
1414 
1415 		return 0;
1416 	}
1417 
1418 	/* update CPU set */
1419 	if (cpu_selected_set) {
1420 		for_all_cpus_in_set(cpu_setsize, cpu_selected_set, update_sysfs);
1421 		for_all_cpus_in_set(cpu_setsize, cpu_selected_set, update_cpu_msrs);
1422 	} else if (pkg_selected_set)
1423 		for_packages(pkg_selected_set, update_hwp_request_pkg);
1424 
1425 	return 0;
1426 }
1427