GNU Linux-libre 4.14.265-gnu1
[releases.git] / tools / power / x86 / x86_energy_perf_policy / x86_energy_perf_policy.c
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 static void get_cpuid_or_exit(unsigned int leaf,
1265                              unsigned int *eax, unsigned int *ebx,
1266                              unsigned int *ecx, unsigned int *edx)
1267 {
1268         if (!__get_cpuid(leaf, eax, ebx, ecx, edx))
1269                 errx(1, "Processor not supported\n");
1270 }
1271
1272 /*
1273  * early_cpuid()
1274  * initialize turbo_is_enabled, has_hwp, has_epb
1275  * before cmdline is parsed
1276  */
1277 void early_cpuid(void)
1278 {
1279         unsigned int eax, ebx, ecx, edx;
1280         unsigned int fms, family, model;
1281
1282         get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx);
1283         family = (fms >> 8) & 0xf;
1284         model = (fms >> 4) & 0xf;
1285         if (family == 6 || family == 0xf)
1286                 model += ((fms >> 16) & 0xf) << 4;
1287
1288         if (model == 0x4F) {
1289                 unsigned long long msr;
1290
1291                 get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr);
1292
1293                 bdx_highest_ratio = msr & 0xFF;
1294         }
1295
1296         get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx);
1297         turbo_is_enabled = (eax >> 1) & 1;
1298         has_hwp = (eax >> 7) & 1;
1299         has_epb = (ecx >> 3) & 1;
1300 }
1301
1302 /*
1303  * parse_cpuid()
1304  * set
1305  * has_hwp, has_hwp_notify, has_hwp_activity_window, has_hwp_epp, has_hwp_request_pkg, has_epb
1306  */
1307 void parse_cpuid(void)
1308 {
1309         unsigned int eax, ebx, ecx, edx, max_level;
1310         unsigned int fms, family, model, stepping;
1311
1312         eax = ebx = ecx = edx = 0;
1313
1314         get_cpuid_or_exit(0, &max_level, &ebx, &ecx, &edx);
1315
1316         if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
1317                 genuine_intel = 1;
1318
1319         if (debug)
1320                 fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
1321                         (char *)&ebx, (char *)&edx, (char *)&ecx);
1322
1323         get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx);
1324         family = (fms >> 8) & 0xf;
1325         model = (fms >> 4) & 0xf;
1326         stepping = fms & 0xf;
1327         if (family == 6 || family == 0xf)
1328                 model += ((fms >> 16) & 0xf) << 4;
1329
1330         if (debug) {
1331                 fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
1332                         max_level, family, model, stepping, family, model, stepping);
1333                 fprintf(stderr, "CPUID(1): %s %s %s %s %s %s %s %s\n",
1334                         ecx & (1 << 0) ? "SSE3" : "-",
1335                         ecx & (1 << 3) ? "MONITOR" : "-",
1336                         ecx & (1 << 7) ? "EIST" : "-",
1337                         ecx & (1 << 8) ? "TM2" : "-",
1338                         edx & (1 << 4) ? "TSC" : "-",
1339                         edx & (1 << 5) ? "MSR" : "-",
1340                         edx & (1 << 22) ? "ACPI-TM" : "-",
1341                         edx & (1 << 29) ? "TM" : "-");
1342         }
1343
1344         if (!(edx & (1 << 5)))
1345                 errx(1, "CPUID: no MSR");
1346
1347
1348         get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx);
1349         /* turbo_is_enabled already set */
1350         /* has_hwp already set */
1351         has_hwp_notify = eax & (1 << 8);
1352         has_hwp_activity_window = eax & (1 << 9);
1353         has_hwp_epp = eax & (1 << 10);
1354         has_hwp_request_pkg = eax & (1 << 11);
1355
1356         if (!has_hwp_request_pkg && update_hwp_use_pkg)
1357                 errx(1, "--hwp-use-pkg is not available on this hardware");
1358
1359         /* has_epb already set */
1360
1361         if (debug)
1362                 fprintf(stderr,
1363                         "CPUID(6): %sTURBO, %sHWP, %sHWPnotify, %sHWPwindow, %sHWPepp, %sHWPpkg, %sEPB\n",
1364                         turbo_is_enabled ? "" : "No-",
1365                         has_hwp ? "" : "No-",
1366                         has_hwp_notify ? "" : "No-",
1367                         has_hwp_activity_window ? "" : "No-",
1368                         has_hwp_epp ? "" : "No-",
1369                         has_hwp_request_pkg ? "" : "No-",
1370                         has_epb ? "" : "No-");
1371
1372         return; /* success */
1373 }
1374
1375 int main(int argc, char **argv)
1376 {
1377         set_base_cpu();
1378         probe_dev_msr();
1379         init_data_structures();
1380
1381         early_cpuid();  /* initial cpuid parse before cmdline */
1382
1383         cmdline(argc, argv);
1384
1385         if (debug)
1386                 print_version();
1387
1388         parse_cpuid();
1389
1390          /* If CPU-set and PKG-set are not initialized, default to all CPUs */
1391         if ((cpu_selected_set == 0) && (pkg_selected_set == 0))
1392                 cpu_selected_set = cpu_present_set;
1393
1394         /*
1395          * If HWP is being enabled, do it now, so that subsequent operations
1396          * that access HWP registers can work.
1397          */
1398         if (update_hwp_enable)
1399                 for_all_cpus_in_set(cpu_setsize, cpu_selected_set, enable_hwp_on_cpu);
1400
1401         /* If HWP present, but disabled, warn and ignore from here forward */
1402         verify_hwp_is_enabled();
1403
1404         if (req_update_bounds_check())
1405                 return -EINVAL;
1406
1407         /* display information only, no updates to settings */
1408         if (!update_epb && !update_turbo && !hwp_update_enabled()) {
1409                 if (cpu_selected_set)
1410                         for_all_cpus_in_set(cpu_setsize, cpu_selected_set, print_cpu_msrs);
1411
1412                 if (has_hwp_request_pkg) {
1413                         if (pkg_selected_set == 0)
1414                                 pkg_selected_set = pkg_present_set;
1415
1416                         for_packages(pkg_selected_set, print_pkg_msrs);
1417                 }
1418
1419                 return 0;
1420         }
1421
1422         /* update CPU set */
1423         if (cpu_selected_set) {
1424                 for_all_cpus_in_set(cpu_setsize, cpu_selected_set, update_sysfs);
1425                 for_all_cpus_in_set(cpu_setsize, cpu_selected_set, update_cpu_msrs);
1426         } else if (pkg_selected_set)
1427                 for_packages(pkg_selected_set, update_hwp_request_pkg);
1428
1429         return 0;
1430 }