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