root/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usage
  2. ratio_2_msr_perf
  3. msr_perf_2_ratio
  4. parse_cmdline_epb
  5. parse_cmdline_hwp_min
  6. parse_cmdline_hwp_max
  7. parse_cmdline_hwp_desired
  8. parse_cmdline_hwp_window
  9. parse_cmdline_hwp_epp
  10. parse_cmdline_turbo
  11. parse_optarg_string
  12. parse_cmdline_all
  13. validate_cpu_selected_set
  14. parse_cmdline_cpu
  15. parse_cmdline_pkg
  16. for_packages
  17. print_version
  18. cmdline
  19. get_msr
  20. put_msr
  21. print_hwp_cap
  22. read_hwp_cap
  23. print_hwp_request
  24. print_hwp_request_pkg
  25. read_hwp_request
  26. write_hwp_request
  27. print_cpu_msrs
  28. print_pkg_msrs
  29. ratio_2_sysfs_khz
  30. update_cpufreq_scaling_freq
  31. update_sysfs
  32. verify_hwp_req_self_consistency
  33. check_hwp_request_v_hwp_capabilities
  34. update_hwp_request
  35. update_hwp_request_pkg
  36. enable_hwp_on_cpu
  37. update_cpu_msrs
  38. fopen_or_die
  39. get_pkg_num
  40. set_max_cpu_pkg_num
  41. mark_cpu_present
  42. for_all_proc_cpus
  43. for_all_cpus_in_set
  44. init_data_structures
  45. verify_hwp_is_enabled
  46. req_update_bounds_check
  47. set_base_cpu
  48. probe_dev_msr
  49. get_cpuid_or_exit
  50. early_cpuid
  51. parse_cpuid
  52. main

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

/* [<][>][^][v][top][bottom][index][help] */