Annotation of sys/arch/i386/i386/est.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: est.c,v 1.30 2007/06/07 11:20:58 dim Exp $ */
! 2: /*
! 3: * Copyright (c) 2003 Michael Eriksson.
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: * 1. Redistributions of source code must retain the above copyright
! 10: * notice, this list of conditions and the following disclaimer.
! 11: * 2. Redistributions in binary form must reproduce the above copyright
! 12: * notice, this list of conditions and the following disclaimer in the
! 13: * documentation and/or other materials provided with the distribution.
! 14: * 3. The name of the author may not be used to endorse or promote products
! 15: * derived from this software without specific prior written permission.
! 16: *
! 17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 19: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 20: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 21: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 22: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 23: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 24: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 25: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 26: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 27: */
! 28:
! 29:
! 30: /*
! 31: * This is a driver for Intel's Enhanced SpeedStep, as implemented in
! 32: * Pentium M processors.
! 33: *
! 34: * Reference documentation:
! 35: *
! 36: * - IA-32 Intel Architecture Software Developer's Manual, Volume 3:
! 37: * System Programming Guide.
! 38: * Section 13.14, Enhanced Intel SpeedStep technology.
! 39: * Table B-2, MSRs in Pentium M Processors.
! 40: * http://www.intel.com/design/pentium4/manuals/245472.htm
! 41: *
! 42: * - Intel Pentium M Processor Datasheet.
! 43: * Table 5, Voltage and Current Specifications.
! 44: * http://www.intel.com/design/mobile/datashts/252612.htm
! 45: *
! 46: * - Intel Pentium M Processor on 90 nm Process with 2-MB L2 Cache Datasheet
! 47: * Table 3-4, Voltage and Current Specifications.
! 48: * http://www.intel.com/design/mobile/datashts/302189.htm
! 49: *
! 50: * - Linux cpufreq patches, speedstep-centrino.c.
! 51: * Encoding of MSR_PERF_CTL and MSR_PERF_STATUS.
! 52: * http://www.codemonkey.org.uk/projects/cpufreq/cpufreq-2.4.22-pre6-1.gz
! 53: */
! 54:
! 55:
! 56: #include <sys/param.h>
! 57: #include <sys/systm.h>
! 58: #include <sys/sysctl.h>
! 59:
! 60: #include <machine/cpu.h>
! 61: #include <machine/cpufunc.h>
! 62: #include <machine/specialreg.h>
! 63:
! 64:
! 65: /* Convert MHz and mV into IDs for passing to the MSR. */
! 66: #define ID16(MHz, mV, bus_clk) \
! 67: ((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
! 68:
! 69:
! 70: /* Ultra Low Voltage Intel Pentium M processor 900 MHz */
! 71: static const u_int16_t pm130_900_ulv[] = {
! 72: ID16( 900, 1004, BUS100),
! 73: ID16( 800, 988, BUS100),
! 74: ID16( 600, 844, BUS100),
! 75: };
! 76:
! 77: /* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */
! 78: static const u_int16_t pm130_1000_ulv[] = {
! 79: ID16(1000, 1004, BUS100),
! 80: ID16( 900, 988, BUS100),
! 81: ID16( 800, 972, BUS100),
! 82: ID16( 600, 844, BUS100),
! 83: };
! 84:
! 85: /* Ultra Low Voltage Intel Pentium M processor 1.10 GHz */
! 86: static const u_int16_t pm130_1100_ulv[] = {
! 87: ID16(1100, 1004, BUS100),
! 88: ID16(1000, 988, BUS100),
! 89: ID16( 900, 972, BUS100),
! 90: ID16( 800, 956, BUS100),
! 91: ID16( 600, 844, BUS100),
! 92: };
! 93:
! 94: /* Low Voltage Intel Pentium M processor 1.10 GHz */
! 95: static const u_int16_t pm130_1100_lv[] = {
! 96: ID16(1100, 1180, BUS100),
! 97: ID16(1000, 1164, BUS100),
! 98: ID16( 900, 1100, BUS100),
! 99: ID16( 800, 1020, BUS100),
! 100: ID16( 600, 956, BUS100),
! 101: };
! 102:
! 103: /* Low Voltage Intel Pentium M processor 1.20 GHz */
! 104: static const u_int16_t pm130_1200_lv[] = {
! 105: ID16(1200, 1180, BUS100),
! 106: ID16(1100, 1164, BUS100),
! 107: ID16(1000, 1100, BUS100),
! 108: ID16( 900, 1020, BUS100),
! 109: ID16( 800, 1004, BUS100),
! 110: ID16( 600, 956, BUS100),
! 111: };
! 112:
! 113: /* Low Voltage Intel Pentium M processor 1.30 GHz */
! 114: static const u_int16_t pm130_1300_lv[] = {
! 115: ID16(1300, 1180, BUS100),
! 116: ID16(1200, 1164, BUS100),
! 117: ID16(1100, 1100, BUS100),
! 118: ID16(1000, 1020, BUS100),
! 119: ID16( 900, 1004, BUS100),
! 120: ID16( 800, 988, BUS100),
! 121: ID16( 600, 956, BUS100),
! 122: };
! 123:
! 124: /* Intel Pentium M processor 1.30 GHz */
! 125: static const u_int16_t pm130_1300[] = {
! 126: ID16(1300, 1388, BUS100),
! 127: ID16(1200, 1356, BUS100),
! 128: ID16(1000, 1292, BUS100),
! 129: ID16( 800, 1260, BUS100),
! 130: ID16( 600, 956, BUS100),
! 131: };
! 132:
! 133: /* Intel Pentium M processor 1.40 GHz */
! 134: static const u_int16_t pm130_1400[] = {
! 135: ID16(1400, 1484, BUS100),
! 136: ID16(1200, 1436, BUS100),
! 137: ID16(1000, 1308, BUS100),
! 138: ID16( 800, 1180, BUS100),
! 139: ID16( 600, 956, BUS100),
! 140: };
! 141:
! 142: /* Intel Pentium M processor 1.50 GHz */
! 143: static const u_int16_t pm130_1500[] = {
! 144: ID16(1500, 1484, BUS100),
! 145: ID16(1400, 1452, BUS100),
! 146: ID16(1200, 1356, BUS100),
! 147: ID16(1000, 1228, BUS100),
! 148: ID16( 800, 1116, BUS100),
! 149: ID16( 600, 956, BUS100),
! 150: };
! 151:
! 152: /* Intel Pentium M processor 1.60 GHz */
! 153: static const u_int16_t pm130_1600[] = {
! 154: ID16(1600, 1484, BUS100),
! 155: ID16(1400, 1420, BUS100),
! 156: ID16(1200, 1276, BUS100),
! 157: ID16(1000, 1164, BUS100),
! 158: ID16( 800, 1036, BUS100),
! 159: ID16( 600, 956, BUS100),
! 160: };
! 161:
! 162: /* Intel Pentium M processor 1.70 GHz */
! 163: static const u_int16_t pm130_1700[] = {
! 164: ID16(1700, 1484, BUS100),
! 165: ID16(1400, 1308, BUS100),
! 166: ID16(1200, 1228, BUS100),
! 167: ID16(1000, 1116, BUS100),
! 168: ID16( 800, 1004, BUS100),
! 169: ID16( 600, 956, BUS100),
! 170: };
! 171:
! 172: /* Intel Pentium M processor 723 1.0 GHz */
! 173: static const u_int16_t pm90_n723[] = {
! 174: ID16(1000, 940, BUS100),
! 175: ID16( 900, 908, BUS100),
! 176: ID16( 800, 876, BUS100),
! 177: ID16( 600, 812, BUS100),
! 178: };
! 179:
! 180: /* Intel Pentium M processor 733 1.1 GHz, VID #G */
! 181: static const u_int16_t pm90_n733g[] = {
! 182: ID16(1100, 956, BUS100),
! 183: ID16(1000, 940, BUS100),
! 184: ID16( 900, 908, BUS100),
! 185: ID16( 800, 876, BUS100),
! 186: ID16( 600, 812, BUS100),
! 187: };
! 188:
! 189: /* Intel Pentium M processor 733 1.1 GHz, VID #H */
! 190: static const u_int16_t pm90_n733h[] = {
! 191: ID16(1100, 940, BUS100),
! 192: ID16(1000, 924, BUS100),
! 193: ID16( 900, 892, BUS100),
! 194: ID16( 800, 876, BUS100),
! 195: ID16( 600, 812, BUS100),
! 196: };
! 197:
! 198: /* Intel Pentium M processor 733 1.1 GHz, VID #I */
! 199: static const u_int16_t pm90_n733i[] = {
! 200: ID16(1100, 924, BUS100),
! 201: ID16(1000, 908, BUS100),
! 202: ID16( 900, 892, BUS100),
! 203: ID16( 800, 860, BUS100),
! 204: ID16( 600, 812, BUS100),
! 205: };
! 206:
! 207: /* Intel Pentium M processor 733 1.1 GHz, VID #J */
! 208: static const u_int16_t pm90_n733j[] = {
! 209: ID16(1100, 908, BUS100),
! 210: ID16(1000, 892, BUS100),
! 211: ID16( 900, 876, BUS100),
! 212: ID16( 800, 860, BUS100),
! 213: ID16( 600, 812, BUS100),
! 214: };
! 215:
! 216: /* Intel Pentium M processor 733 1.1 GHz, VID #K */
! 217: static const u_int16_t pm90_n733k[] = {
! 218: ID16(1100, 892, BUS100),
! 219: ID16(1000, 876, BUS100),
! 220: ID16( 900, 860, BUS100),
! 221: ID16( 800, 844, BUS100),
! 222: ID16( 600, 812, BUS100),
! 223: };
! 224:
! 225: /* Intel Pentium M processor 733 1.1 GHz, VID #L */
! 226: static const u_int16_t pm90_n733l[] = {
! 227: ID16(1100, 876, BUS100),
! 228: ID16(1000, 876, BUS100),
! 229: ID16( 900, 860, BUS100),
! 230: ID16( 800, 844, BUS100),
! 231: ID16( 600, 812, BUS100),
! 232: };
! 233:
! 234: /* Intel Pentium M processor 753 1.2 GHz, VID #G */
! 235: static const u_int16_t pm90_n753g[] = {
! 236: ID16(1200, 956, BUS100),
! 237: ID16(1100, 940, BUS100),
! 238: ID16(1000, 908, BUS100),
! 239: ID16( 900, 892, BUS100),
! 240: ID16( 800, 860, BUS100),
! 241: ID16( 600, 812, BUS100),
! 242: };
! 243:
! 244: /* Intel Pentium M processor 753 1.2 GHz, VID #H */
! 245: static const u_int16_t pm90_n753h[] = {
! 246: ID16(1200, 940, BUS100),
! 247: ID16(1100, 924, BUS100),
! 248: ID16(1000, 908, BUS100),
! 249: ID16( 900, 876, BUS100),
! 250: ID16( 800, 860, BUS100),
! 251: ID16( 600, 812, BUS100),
! 252: };
! 253:
! 254: /* Intel Pentium M processor 753 1.2 GHz, VID #I */
! 255: static const u_int16_t pm90_n753i[] = {
! 256: ID16(1200, 924, BUS100),
! 257: ID16(1100, 908, BUS100),
! 258: ID16(1000, 892, BUS100),
! 259: ID16( 900, 876, BUS100),
! 260: ID16( 800, 860, BUS100),
! 261: ID16( 600, 812, BUS100),
! 262: };
! 263:
! 264: /* Intel Pentium M processor 753 1.2 GHz, VID #J */
! 265: static const u_int16_t pm90_n753j[] = {
! 266: ID16(1200, 908, BUS100),
! 267: ID16(1100, 892, BUS100),
! 268: ID16(1000, 876, BUS100),
! 269: ID16( 900, 860, BUS100),
! 270: ID16( 800, 844, BUS100),
! 271: ID16( 600, 812, BUS100),
! 272: };
! 273:
! 274: /* Intel Pentium M processor 753 1.2 GHz, VID #K */
! 275: static const u_int16_t pm90_n753k[] = {
! 276: ID16(1200, 892, BUS100),
! 277: ID16(1100, 892, BUS100),
! 278: ID16(1000, 876, BUS100),
! 279: ID16( 900, 860, BUS100),
! 280: ID16( 800, 844, BUS100),
! 281: ID16( 600, 812, BUS100),
! 282: };
! 283:
! 284: /* Intel Pentium M processor 753 1.2 GHz, VID #L */
! 285: static const u_int16_t pm90_n753l[] = {
! 286: ID16(1200, 876, BUS100),
! 287: ID16(1100, 876, BUS100),
! 288: ID16(1000, 860, BUS100),
! 289: ID16( 900, 844, BUS100),
! 290: ID16( 800, 844, BUS100),
! 291: ID16( 600, 812, BUS100),
! 292: };
! 293:
! 294: /* Intel Pentium M processor 773 1.3 GHz, VID #G */
! 295: static const u_int16_t pm90_n773g[] = {
! 296: ID16(1300, 956, BUS100),
! 297: ID16(1200, 940, BUS100),
! 298: ID16(1100, 924, BUS100),
! 299: ID16(1000, 908, BUS100),
! 300: ID16( 900, 876, BUS100),
! 301: ID16( 800, 860, BUS100),
! 302: ID16( 600, 812, BUS100),
! 303: };
! 304:
! 305: /* Intel Pentium M processor 773 1.3 GHz, VID #H */
! 306: static const u_int16_t pm90_n773h[] = {
! 307: ID16(1300, 940, BUS100),
! 308: ID16(1200, 924, BUS100),
! 309: ID16(1100, 908, BUS100),
! 310: ID16(1000, 892, BUS100),
! 311: ID16( 900, 876, BUS100),
! 312: ID16( 800, 860, BUS100),
! 313: ID16( 600, 812, BUS100),
! 314: };
! 315:
! 316: /* Intel Pentium M processor 773 1.3 GHz, VID #I */
! 317: static const u_int16_t pm90_n773i[] = {
! 318: ID16(1300, 924, BUS100),
! 319: ID16(1200, 908, BUS100),
! 320: ID16(1100, 892, BUS100),
! 321: ID16(1000, 876, BUS100),
! 322: ID16( 900, 860, BUS100),
! 323: ID16( 800, 844, BUS100),
! 324: ID16( 600, 812, BUS100),
! 325: };
! 326:
! 327: /* Intel Pentium M processor 773 1.3 GHz, VID #J */
! 328: static const u_int16_t pm90_n773j[] = {
! 329: ID16(1300, 908, BUS100),
! 330: ID16(1200, 908, BUS100),
! 331: ID16(1100, 892, BUS100),
! 332: ID16(1000, 876, BUS100),
! 333: ID16( 900, 860, BUS100),
! 334: ID16( 800, 844, BUS100),
! 335: ID16( 600, 812, BUS100),
! 336: };
! 337:
! 338: /* Intel Pentium M processor 773 1.3 GHz, VID #K */
! 339: static const u_int16_t pm90_n773k[] = {
! 340: ID16(1300, 892, BUS100),
! 341: ID16(1200, 892, BUS100),
! 342: ID16(1100, 876, BUS100),
! 343: ID16(1000, 860, BUS100),
! 344: ID16( 900, 860, BUS100),
! 345: ID16( 800, 844, BUS100),
! 346: ID16( 600, 812, BUS100),
! 347: };
! 348:
! 349: /* Intel Pentium M processor 773 1.3 GHz, VID #L */
! 350: static const u_int16_t pm90_n773l[] = {
! 351: ID16(1300, 876, BUS100),
! 352: ID16(1200, 876, BUS100),
! 353: ID16(1100, 860, BUS100),
! 354: ID16(1000, 860, BUS100),
! 355: ID16( 900, 844, BUS100),
! 356: ID16( 800, 844, BUS100),
! 357: ID16( 600, 812, BUS100),
! 358: };
! 359:
! 360: /* Intel Pentium M processor 738 1.4 GHz */
! 361: static const u_int16_t pm90_n738[] = {
! 362: ID16(1400, 1116, BUS100),
! 363: ID16(1300, 1116, BUS100),
! 364: ID16(1200, 1100, BUS100),
! 365: ID16(1100, 1068, BUS100),
! 366: ID16(1000, 1052, BUS100),
! 367: ID16( 900, 1036, BUS100),
! 368: ID16( 800, 1020, BUS100),
! 369: ID16( 600, 988, BUS100),
! 370: };
! 371:
! 372: /* Intel Pentium M processor 758 1.5 GHz */
! 373: static const u_int16_t pm90_n758[] = {
! 374: ID16(1500, 1116, BUS100),
! 375: ID16(1400, 1116, BUS100),
! 376: ID16(1300, 1100, BUS100),
! 377: ID16(1200, 1084, BUS100),
! 378: ID16(1100, 1068, BUS100),
! 379: ID16(1000, 1052, BUS100),
! 380: ID16( 900, 1036, BUS100),
! 381: ID16( 800, 1020, BUS100),
! 382: ID16( 600, 988, BUS100),
! 383: };
! 384:
! 385: /* Intel Pentium M processor 778 1.6 GHz */
! 386: static const u_int16_t pm90_n778[] = {
! 387: ID16(1600, 1116, BUS100),
! 388: ID16(1500, 1116, BUS100),
! 389: ID16(1400, 1100, BUS100),
! 390: ID16(1300, 1184, BUS100),
! 391: ID16(1200, 1068, BUS100),
! 392: ID16(1100, 1052, BUS100),
! 393: ID16(1000, 1052, BUS100),
! 394: ID16( 900, 1036, BUS100),
! 395: ID16( 800, 1020, BUS100),
! 396: ID16( 600, 988, BUS100),
! 397: };
! 398:
! 399: /* Intel Pentium M processor 710 1.4 GHz, 533 MHz FSB */
! 400: static const u_int16_t pm90_n710[] = {
! 401: ID16(1400, 1340, BUS133),
! 402: ID16(1200, 1228, BUS133),
! 403: ID16(1000, 1148, BUS133),
! 404: ID16( 800, 1068, BUS133),
! 405: ID16( 600, 998, BUS133),
! 406: };
! 407:
! 408: /* Intel Pentium M processor 715 1.5 GHz, VID #A */
! 409: static const u_int16_t pm90_n715a[] = {
! 410: ID16(1500, 1340, BUS100),
! 411: ID16(1200, 1228, BUS100),
! 412: ID16(1000, 1148, BUS100),
! 413: ID16( 800, 1068, BUS100),
! 414: ID16( 600, 988, BUS100),
! 415: };
! 416:
! 417: /* Intel Pentium M processor 715 1.5 GHz, VID #B */
! 418: static const u_int16_t pm90_n715b[] = {
! 419: ID16(1500, 1324, BUS100),
! 420: ID16(1200, 1212, BUS100),
! 421: ID16(1000, 1148, BUS100),
! 422: ID16( 800, 1068, BUS100),
! 423: ID16( 600, 988, BUS100),
! 424: };
! 425:
! 426: /* Intel Pentium M processor 715 1.5 GHz, VID #C */
! 427: static const u_int16_t pm90_n715c[] = {
! 428: ID16(1500, 1308, BUS100),
! 429: ID16(1200, 1212, BUS100),
! 430: ID16(1000, 1132, BUS100),
! 431: ID16( 800, 1068, BUS100),
! 432: ID16( 600, 988, BUS100),
! 433: };
! 434:
! 435: /* Intel Pentium M processor 715 1.5 GHz, VID #D */
! 436: static const u_int16_t pm90_n715d[] = {
! 437: ID16(1500, 1276, BUS100),
! 438: ID16(1200, 1180, BUS100),
! 439: ID16(1000, 1116, BUS100),
! 440: ID16( 800, 1052, BUS100),
! 441: ID16( 600, 988, BUS100),
! 442: };
! 443:
! 444: /* Intel Pentium M processor 725 1.6 GHz, VID #A */
! 445: static const u_int16_t pm90_n725a[] = {
! 446: ID16(1600, 1340, BUS100),
! 447: ID16(1400, 1276, BUS100),
! 448: ID16(1200, 1212, BUS100),
! 449: ID16(1000, 1132, BUS100),
! 450: ID16( 800, 1068, BUS100),
! 451: ID16( 600, 988, BUS100),
! 452: };
! 453:
! 454: /* Intel Pentium M processor 725 1.6 GHz, VID #B */
! 455: static const u_int16_t pm90_n725b[] = {
! 456: ID16(1600, 1324, BUS100),
! 457: ID16(1400, 1260, BUS100),
! 458: ID16(1200, 1196, BUS100),
! 459: ID16(1000, 1132, BUS100),
! 460: ID16( 800, 1068, BUS100),
! 461: ID16( 600, 988, BUS100),
! 462: };
! 463:
! 464: /* Intel Pentium M processor 725 1.6 GHz, VID #C */
! 465: static const u_int16_t pm90_n725c[] = {
! 466: ID16(1600, 1308, BUS100),
! 467: ID16(1400, 1244, BUS100),
! 468: ID16(1200, 1180, BUS100),
! 469: ID16(1000, 1116, BUS100),
! 470: ID16( 800, 1052, BUS100),
! 471: ID16( 600, 988, BUS100),
! 472: };
! 473:
! 474: /* Intel Pentium M processor 725 1.6 GHz, VID #D */
! 475: static const u_int16_t pm90_n725d[] = {
! 476: ID16(1600, 1276, BUS100),
! 477: ID16(1400, 1228, BUS100),
! 478: ID16(1200, 1164, BUS100),
! 479: ID16(1000, 1116, BUS100),
! 480: ID16( 800, 1052, BUS100),
! 481: ID16( 600, 988, BUS100),
! 482: };
! 483:
! 484: /* Intel Pentium M processor 730 1.6 GHz, 533 MHz FSB */
! 485: static const u_int16_t pm90_n730[] = {
! 486: ID16(1600, 1308, BUS133),
! 487: ID16(1333, 1260, BUS133),
! 488: ID16(1200, 1212, BUS133),
! 489: ID16(1067, 1180, BUS133),
! 490: ID16( 800, 988, BUS133),
! 491: };
! 492:
! 493: /* Intel Pentium M processor 735 1.7 GHz, VID #A */
! 494: static const u_int16_t pm90_n735a[] = {
! 495: ID16(1700, 1340, BUS100),
! 496: ID16(1400, 1244, BUS100),
! 497: ID16(1200, 1180, BUS100),
! 498: ID16(1000, 1116, BUS100),
! 499: ID16( 800, 1052, BUS100),
! 500: ID16( 600, 988, BUS100),
! 501: };
! 502:
! 503: /* Intel Pentium M processor 735 1.7 GHz, VID #B */
! 504: static const u_int16_t pm90_n735b[] = {
! 505: ID16(1700, 1324, BUS100),
! 506: ID16(1400, 1244, BUS100),
! 507: ID16(1200, 1180, BUS100),
! 508: ID16(1000, 1116, BUS100),
! 509: ID16( 800, 1052, BUS100),
! 510: ID16( 600, 988, BUS100),
! 511: };
! 512:
! 513: /* Intel Pentium M processor 735 1.7 GHz, VID #C */
! 514: static const u_int16_t pm90_n735c[] = {
! 515: ID16(1700, 1308, BUS100),
! 516: ID16(1400, 1228, BUS100),
! 517: ID16(1200, 1164, BUS100),
! 518: ID16(1000, 1116, BUS100),
! 519: ID16( 800, 1052, BUS100),
! 520: ID16( 600, 988, BUS100),
! 521: };
! 522:
! 523: /* Intel Pentium M processor 735 1.7 GHz, VID #D */
! 524: static const u_int16_t pm90_n735d[] = {
! 525: ID16(1700, 1276, BUS100),
! 526: ID16(1400, 1212, BUS100),
! 527: ID16(1200, 1148, BUS100),
! 528: ID16(1000, 1100, BUS100),
! 529: ID16( 800, 1052, BUS100),
! 530: ID16( 600, 988, BUS100),
! 531: };
! 532:
! 533: /* Intel Pentium M processor 740 1.73 GHz, 533 MHz FSB */
! 534: static const u_int16_t pm90_n740[] = {
! 535: ID16(1733, 1356, BUS133),
! 536: ID16(1333, 1212, BUS133),
! 537: ID16(1067, 1100, BUS133),
! 538: ID16( 800, 988, BUS133),
! 539: };
! 540:
! 541: /* Intel Pentium M processor 745 1.8 GHz, VID #A */
! 542: static const u_int16_t pm90_n745a[] = {
! 543: ID16(1800, 1340, BUS100),
! 544: ID16(1600, 1292, BUS100),
! 545: ID16(1400, 1228, BUS100),
! 546: ID16(1200, 1164, BUS100),
! 547: ID16(1000, 1116, BUS100),
! 548: ID16( 800, 1052, BUS100),
! 549: ID16( 600, 988, BUS100),
! 550: };
! 551:
! 552: /* Intel Pentium M processor 745 1.8 GHz, VID #B */
! 553: static const u_int16_t pm90_n745b[] = {
! 554: ID16(1800, 1324, BUS100),
! 555: ID16(1600, 1276, BUS100),
! 556: ID16(1400, 1212, BUS100),
! 557: ID16(1200, 1164, BUS100),
! 558: ID16(1000, 1116, BUS100),
! 559: ID16( 800, 1052, BUS100),
! 560: ID16( 600, 988, BUS100),
! 561: };
! 562:
! 563: /* Intel Pentium M processor 745 1.8 GHz, VID #C */
! 564: static const u_int16_t pm90_n745c[] = {
! 565: ID16(1800, 1308, BUS100),
! 566: ID16(1600, 1260, BUS100),
! 567: ID16(1400, 1212, BUS100),
! 568: ID16(1200, 1148, BUS100),
! 569: ID16(1000, 1100, BUS100),
! 570: ID16( 800, 1052, BUS100),
! 571: ID16( 600, 988, BUS100),
! 572: };
! 573:
! 574: /* Intel Pentium M processor 745 1.8 GHz, VID #D */
! 575: static const u_int16_t pm90_n745d[] = {
! 576: ID16(1800, 1276, BUS100),
! 577: ID16(1600, 1228, BUS100),
! 578: ID16(1400, 1180, BUS100),
! 579: ID16(1200, 1132, BUS100),
! 580: ID16(1000, 1084, BUS100),
! 581: ID16( 800, 1036, BUS100),
! 582: ID16( 600, 988, BUS100),
! 583: };
! 584:
! 585: /* Intel Pentium M processor 750 1.86 GHz, 533 MHz FSB */
! 586: /* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */
! 587: static const u_int16_t pm90_n750[] = {
! 588: ID16(1867, 1308, BUS133),
! 589: ID16(1600, 1228, BUS133),
! 590: ID16(1333, 1148, BUS133),
! 591: ID16(1067, 1068, BUS133),
! 592: ID16( 800, 988, BUS133),
! 593: };
! 594:
! 595: /* Intel Pentium M processor 755 2.0 GHz, VID #A */
! 596: static const u_int16_t pm90_n755a[] = {
! 597: ID16(2000, 1340, BUS100),
! 598: ID16(1800, 1292, BUS100),
! 599: ID16(1600, 1244, BUS100),
! 600: ID16(1400, 1196, BUS100),
! 601: ID16(1200, 1148, BUS100),
! 602: ID16(1000, 1100, BUS100),
! 603: ID16( 800, 1052, BUS100),
! 604: ID16( 600, 988, BUS100),
! 605: };
! 606:
! 607: /* Intel Pentium M processor 755 2.0 GHz, VID #B */
! 608: static const u_int16_t pm90_n755b[] = {
! 609: ID16(2000, 1324, BUS100),
! 610: ID16(1800, 1276, BUS100),
! 611: ID16(1600, 1228, BUS100),
! 612: ID16(1400, 1180, BUS100),
! 613: ID16(1200, 1132, BUS100),
! 614: ID16(1000, 1084, BUS100),
! 615: ID16( 800, 1036, BUS100),
! 616: ID16( 600, 988, BUS100),
! 617: };
! 618:
! 619: /* Intel Pentium M processor 755 2.0 GHz, VID #C */
! 620: static const u_int16_t pm90_n755c[] = {
! 621: ID16(2000, 1308, BUS100),
! 622: ID16(1800, 1276, BUS100),
! 623: ID16(1600, 1228, BUS100),
! 624: ID16(1400, 1180, BUS100),
! 625: ID16(1200, 1132, BUS100),
! 626: ID16(1000, 1084, BUS100),
! 627: ID16( 800, 1036, BUS100),
! 628: ID16( 600, 988, BUS100),
! 629: };
! 630:
! 631: /* Intel Pentium M processor 755 2.0 GHz, VID #D */
! 632: static const u_int16_t pm90_n755d[] = {
! 633: ID16(2000, 1276, BUS100),
! 634: ID16(1800, 1244, BUS100),
! 635: ID16(1600, 1196, BUS100),
! 636: ID16(1400, 1164, BUS100),
! 637: ID16(1200, 1116, BUS100),
! 638: ID16(1000, 1084, BUS100),
! 639: ID16( 800, 1036, BUS100),
! 640: ID16( 600, 988, BUS100),
! 641: };
! 642:
! 643: /* Intel Pentium M processor 760 2.0 GHz, 533 MHz FSB */
! 644: static const u_int16_t pm90_n760[] = {
! 645: ID16(2000, 1356, BUS133),
! 646: ID16(1600, 1244, BUS133),
! 647: ID16(1333, 1164, BUS133),
! 648: ID16(1067, 1084, BUS133),
! 649: ID16( 800, 988, BUS133),
! 650: };
! 651:
! 652: /* Intel Pentium M processor 765 2.1 GHz, VID #A */
! 653: static const u_int16_t pm90_n765a[] = {
! 654: ID16(2100, 1340, BUS100),
! 655: ID16(1800, 1276, BUS100),
! 656: ID16(1600, 1228, BUS100),
! 657: ID16(1400, 1180, BUS100),
! 658: ID16(1200, 1132, BUS100),
! 659: ID16(1000, 1084, BUS100),
! 660: ID16( 800, 1036, BUS100),
! 661: ID16( 600, 988, BUS100),
! 662: };
! 663:
! 664: /* Intel Pentium M processor 765 2.1 GHz, VID #B */
! 665: static const u_int16_t pm90_n765b[] = {
! 666: ID16(2100, 1324, BUS100),
! 667: ID16(1800, 1260, BUS100),
! 668: ID16(1600, 1212, BUS100),
! 669: ID16(1400, 1180, BUS100),
! 670: ID16(1200, 1132, BUS100),
! 671: ID16(1000, 1084, BUS100),
! 672: ID16( 800, 1036, BUS100),
! 673: ID16( 600, 988, BUS100),
! 674: };
! 675:
! 676: /* Intel Pentium M processor 765 2.1 GHz, VID #C */
! 677: static const u_int16_t pm90_n765c[] = {
! 678: ID16(2100, 1308, BUS100),
! 679: ID16(1800, 1244, BUS100),
! 680: ID16(1600, 1212, BUS100),
! 681: ID16(1400, 1164, BUS100),
! 682: ID16(1200, 1116, BUS100),
! 683: ID16(1000, 1084, BUS100),
! 684: ID16( 800, 1036, BUS100),
! 685: ID16( 600, 988, BUS100),
! 686: };
! 687:
! 688: /* Intel Pentium M processor 765 2.1 GHz, VID #E */
! 689: static const u_int16_t pm90_n765e[] = {
! 690: ID16(2100, 1356, BUS100),
! 691: ID16(1800, 1292, BUS100),
! 692: ID16(1600, 1244, BUS100),
! 693: ID16(1400, 1196, BUS100),
! 694: ID16(1200, 1148, BUS100),
! 695: ID16(1000, 1100, BUS100),
! 696: ID16( 800, 1052, BUS100),
! 697: ID16( 600, 988, BUS100),
! 698: };
! 699:
! 700: /* Intel Pentium M processor 770 2.13 GHz */
! 701: static const u_int16_t pm90_n770[] = {
! 702: ID16(2133, 1356, BUS133),
! 703: ID16(1867, 1292, BUS133),
! 704: ID16(1600, 1212, BUS133),
! 705: ID16(1333, 1148, BUS133),
! 706: ID16(1067, 1068, BUS133),
! 707: ID16( 800, 988, BUS133),
! 708: };
! 709:
! 710: /*
! 711: * VIA C7-M 500 MHz FSB, 400 MHz FSB, and ULV variants.
! 712: * Data from the "VIA C7-M Processor BIOS Writer's Guide (v2.17)" datasheet.
! 713: */
! 714:
! 715: /* 1.00GHz Centaur C7-M ULV */
! 716: static const u_int16_t C7M_770_ULV[] = {
! 717: ID16(1000, 844, BUS100),
! 718: ID16( 800, 796, BUS100),
! 719: ID16( 600, 796, BUS100),
! 720: ID16( 400, 796, BUS100),
! 721: };
! 722:
! 723: /* 1.00GHz Centaur C7-M ULV */
! 724: static const u_int16_t C7M_779_ULV[] = {
! 725: ID16(1000, 796, BUS100),
! 726: ID16( 800, 796, BUS100),
! 727: ID16( 600, 796, BUS100),
! 728: ID16( 400, 796, BUS100),
! 729: };
! 730:
! 731: /* 1.20GHz Centaur C7-M ULV */
! 732: static const u_int16_t C7M_772_ULV[] = {
! 733: ID16(1200, 844, BUS100),
! 734: ID16(1000, 844, BUS100),
! 735: ID16( 800, 828, BUS100),
! 736: ID16( 600, 796, BUS100),
! 737: ID16( 400, 796, BUS100),
! 738: };
! 739:
! 740: /* 1.50GHz Centaur C7-M ULV */
! 741: static const u_int16_t C7M_775_ULV[] = {
! 742: ID16(1500, 956, BUS100),
! 743: ID16(1400, 940, BUS100),
! 744: ID16(1000, 860, BUS100),
! 745: ID16( 800, 828, BUS100),
! 746: ID16( 600, 796, BUS100),
! 747: ID16( 400, 796, BUS100),
! 748: };
! 749:
! 750: /* 1.20GHz Centaur C7-M 400 MHz FSB */
! 751: static const u_int16_t C7M_771[] = {
! 752: ID16(1200, 860, BUS100),
! 753: ID16(1000, 860, BUS100),
! 754: ID16( 800, 844, BUS100),
! 755: ID16( 600, 844, BUS100),
! 756: ID16( 400, 844, BUS100),
! 757: };
! 758:
! 759: /* 1.50GHz Centaur C7-M 400 MHz FSB */
! 760: static const u_int16_t C7M_754[] = {
! 761: ID16(1500, 1004, BUS100),
! 762: ID16(1400, 988, BUS100),
! 763: ID16(1000, 940, BUS100),
! 764: ID16( 800, 844, BUS100),
! 765: ID16( 600, 844, BUS100),
! 766: ID16( 400, 844, BUS100),
! 767: };
! 768:
! 769: /* 1.60GHz Centaur C7-M 400 MHz FSB */
! 770: static const u_int16_t C7M_764[] = {
! 771: ID16(1600, 1084, BUS100),
! 772: ID16(1400, 1052, BUS100),
! 773: ID16(1000, 1004, BUS100),
! 774: ID16( 800, 844, BUS100),
! 775: ID16( 600, 844, BUS100),
! 776: ID16( 400, 844, BUS100),
! 777: };
! 778:
! 779: /* 1.80GHz Centaur C7-M 400 MHz FSB */
! 780: static const u_int16_t C7M_784[] = {
! 781: ID16(1800, 1148, BUS100),
! 782: ID16(1600, 1100, BUS100),
! 783: ID16(1400, 1052, BUS100),
! 784: ID16(1000, 1004, BUS100),
! 785: ID16( 800, 844, BUS100),
! 786: ID16( 600, 844, BUS100),
! 787: ID16( 400, 844, BUS100),
! 788: };
! 789:
! 790: /* 2.00GHz Centaur C7-M 400 MHz FSB */
! 791: static const u_int16_t C7M_794[] = {
! 792: ID16(2000, 1148, BUS100),
! 793: ID16(1800, 1132, BUS100),
! 794: ID16(1600, 1100, BUS100),
! 795: ID16(1400, 1052, BUS100),
! 796: ID16(1000, 1004, BUS100),
! 797: ID16( 800, 844, BUS100),
! 798: ID16( 600, 844, BUS100),
! 799: ID16( 400, 844, BUS100),
! 800: };
! 801:
! 802: /* 1.60GHz Centaur C7-M 533 MHz FSB */
! 803: static const u_int16_t C7M_765[] = {
! 804: ID16(1600, 1084, BUS133),
! 805: ID16(1467, 1052, BUS133),
! 806: ID16(1200, 1004, BUS133),
! 807: ID16( 800, 844, BUS133),
! 808: ID16( 667, 844, BUS133),
! 809: ID16( 533, 844, BUS133),
! 810: };
! 811:
! 812: /* 2.00GHz Centaur C7-M 533 MHz FSB */
! 813: static const u_int16_t C7M_785[] = {
! 814: ID16(1867, 1148, BUS133),
! 815: ID16(1600, 1100, BUS133),
! 816: ID16(1467, 1052, BUS133),
! 817: ID16(1200, 1004, BUS133),
! 818: ID16( 800, 844, BUS133),
! 819: ID16( 667, 844, BUS133),
! 820: ID16( 533, 844, BUS133),
! 821: };
! 822:
! 823: /* 2.00GHz Centaur C7-M 533 MHz FSB */
! 824: static const u_int16_t C7M_795[] = {
! 825: ID16(2000, 1148, BUS133),
! 826: ID16(1867, 1132, BUS133),
! 827: ID16(1600, 1100, BUS133),
! 828: ID16(1467, 1052, BUS133),
! 829: ID16(1200, 1004, BUS133),
! 830: ID16( 800, 844, BUS133),
! 831: ID16( 667, 844, BUS133),
! 832: ID16( 533, 844, BUS133),
! 833: };
! 834:
! 835: /* 1.00GHz VIA Eden 90nm 'Esther' */
! 836: static const u_int16_t eden90_1000[] = {
! 837: ID16(1000, 844, BUS100),
! 838: ID16( 800, 844, BUS100),
! 839: ID16( 600, 844, BUS100),
! 840: ID16( 400, 844, BUS100),
! 841: };
! 842:
! 843: struct fqlist {
! 844: int vendor : 5;
! 845: unsigned bus_clk : 1;
! 846: unsigned n : 5;
! 847: const u_int16_t *table;
! 848: };
! 849:
! 850: #define NELEM(x) (sizeof(x) / sizeof((x)[0]))
! 851:
! 852: #define ENTRY(ven, bus_clk, tab) \
! 853: { CPUVENDOR_##ven, bus_clk == BUS133 ? 1 : 0, NELEM(tab), tab }
! 854:
! 855: #define BUS_CLK(fqp) ((fqp)->bus_clk ? BUS133 : BUS100)
! 856:
! 857: static const struct fqlist est_cpus[] = {
! 858: ENTRY(INTEL, BUS100, pm130_900_ulv),
! 859: ENTRY(INTEL, BUS100, pm130_1000_ulv),
! 860: ENTRY(INTEL, BUS100, pm130_1100_ulv),
! 861: ENTRY(INTEL, BUS100, pm130_1100_lv),
! 862: ENTRY(INTEL, BUS100, pm130_1200_lv),
! 863: ENTRY(INTEL, BUS100, pm130_1300_lv),
! 864: ENTRY(INTEL, BUS100, pm130_1300),
! 865: ENTRY(INTEL, BUS100, pm130_1400),
! 866: ENTRY(INTEL, BUS100, pm130_1500),
! 867: ENTRY(INTEL, BUS100, pm130_1600),
! 868: ENTRY(INTEL, BUS100, pm130_1700),
! 869:
! 870: ENTRY(INTEL, BUS100, pm90_n723),
! 871: ENTRY(INTEL, BUS100, pm90_n733g),
! 872: ENTRY(INTEL, BUS100, pm90_n733h),
! 873: ENTRY(INTEL, BUS100, pm90_n733i),
! 874: ENTRY(INTEL, BUS100, pm90_n733j),
! 875: ENTRY(INTEL, BUS100, pm90_n733k),
! 876: ENTRY(INTEL, BUS100, pm90_n733l),
! 877: ENTRY(INTEL, BUS100, pm90_n753g),
! 878: ENTRY(INTEL, BUS100, pm90_n753h),
! 879: ENTRY(INTEL, BUS100, pm90_n753i),
! 880: ENTRY(INTEL, BUS100, pm90_n753j),
! 881: ENTRY(INTEL, BUS100, pm90_n753k),
! 882: ENTRY(INTEL, BUS100, pm90_n753l),
! 883: ENTRY(INTEL, BUS100, pm90_n773g),
! 884: ENTRY(INTEL, BUS100, pm90_n773h),
! 885: ENTRY(INTEL, BUS100, pm90_n773i),
! 886: ENTRY(INTEL, BUS100, pm90_n773j),
! 887: ENTRY(INTEL, BUS100, pm90_n773k),
! 888: ENTRY(INTEL, BUS100, pm90_n773l),
! 889: ENTRY(INTEL, BUS100, pm90_n738),
! 890: ENTRY(INTEL, BUS100, pm90_n758),
! 891: ENTRY(INTEL, BUS100, pm90_n778),
! 892:
! 893: ENTRY(INTEL, BUS133, pm90_n710),
! 894: ENTRY(INTEL, BUS100, pm90_n715a),
! 895: ENTRY(INTEL, BUS100, pm90_n715b),
! 896: ENTRY(INTEL, BUS100, pm90_n715c),
! 897: ENTRY(INTEL, BUS100, pm90_n715d),
! 898: ENTRY(INTEL, BUS100, pm90_n725a),
! 899: ENTRY(INTEL, BUS100, pm90_n725b),
! 900: ENTRY(INTEL, BUS100, pm90_n725c),
! 901: ENTRY(INTEL, BUS100, pm90_n725d),
! 902: ENTRY(INTEL, BUS133, pm90_n730),
! 903: ENTRY(INTEL, BUS100, pm90_n735a),
! 904: ENTRY(INTEL, BUS100, pm90_n735b),
! 905: ENTRY(INTEL, BUS100, pm90_n735c),
! 906: ENTRY(INTEL, BUS100, pm90_n735d),
! 907: ENTRY(INTEL, BUS133, pm90_n740),
! 908: ENTRY(INTEL, BUS100, pm90_n745a),
! 909: ENTRY(INTEL, BUS100, pm90_n745b),
! 910: ENTRY(INTEL, BUS100, pm90_n745c),
! 911: ENTRY(INTEL, BUS100, pm90_n745d),
! 912: ENTRY(INTEL, BUS133, pm90_n750),
! 913: ENTRY(INTEL, BUS100, pm90_n755a),
! 914: ENTRY(INTEL, BUS100, pm90_n755b),
! 915: ENTRY(INTEL, BUS100, pm90_n755c),
! 916: ENTRY(INTEL, BUS100, pm90_n755d),
! 917: ENTRY(INTEL, BUS133, pm90_n760),
! 918: ENTRY(INTEL, BUS100, pm90_n765a),
! 919: ENTRY(INTEL, BUS100, pm90_n765b),
! 920: ENTRY(INTEL, BUS100, pm90_n765c),
! 921: ENTRY(INTEL, BUS100, pm90_n765e),
! 922: ENTRY(INTEL, BUS133, pm90_n770),
! 923:
! 924: ENTRY(VIA, BUS100, C7M_770_ULV),
! 925: ENTRY(VIA, BUS100, C7M_779_ULV),
! 926: ENTRY(VIA, BUS100, C7M_772_ULV),
! 927: ENTRY(VIA, BUS100, C7M_771),
! 928: ENTRY(VIA, BUS100, C7M_775_ULV),
! 929: ENTRY(VIA, BUS100, C7M_754),
! 930: ENTRY(VIA, BUS100, C7M_764),
! 931: ENTRY(VIA, BUS133, C7M_765),
! 932: ENTRY(VIA, BUS100, C7M_784),
! 933: ENTRY(VIA, BUS133, C7M_785),
! 934: ENTRY(VIA, BUS100, C7M_794),
! 935: ENTRY(VIA, BUS133, C7M_795),
! 936:
! 937: ENTRY(VIA, BUS100, eden90_1000),
! 938: };
! 939:
! 940:
! 941: #define MSR2MHZ(msr, bus) \
! 942: (((((int) (msr) >> 8) & 0xff) * (bus) + 50) / 100)
! 943: #define MSR2MV(msr) \
! 944: (((int) (msr) & 0xff) * 16 + 700)
! 945:
! 946: static const struct fqlist *est_fqlist;
! 947:
! 948: static u_int16_t fake_table[3];
! 949: static struct fqlist fake_fqlist;
! 950:
! 951: extern int setperf_prio;
! 952: extern int perflevel;
! 953:
! 954: void
! 955: est_init(const char *cpu_device, int vendor)
! 956: {
! 957: int i, mhz, mv, low, high;
! 958: u_int64_t msr;
! 959: u_int16_t idhi, idlo, cur;
! 960: u_int8_t crhi, crlo, crcur;
! 961: const struct fqlist *fql;
! 962:
! 963: if (setperf_prio > 3)
! 964: return;
! 965:
! 966: if ((cpu_ecxfeature & CPUIDECX_EST) == 0)
! 967: return;
! 968:
! 969: if (bus_clock == 0) {
! 970: printf("%s: EST: unknown system bus clock\n", cpu_device);
! 971: return;
! 972: }
! 973:
! 974: msr = rdmsr(MSR_PERF_STATUS);
! 975: idhi = (msr >> 32) & 0xffff;
! 976: idlo = (msr >> 48) & 0xffff;
! 977: cur = msr & 0xffff;
! 978: crhi = (idhi >> 8) & 0xff;
! 979: crlo = (idlo >> 8) & 0xff;
! 980: crcur = (cur >> 8) & 0xff;
! 981: if (crlo == 0 || crhi == crlo) {
! 982: /*
! 983: * Don't complain about these cases, and silently disable EST:
! 984: * - A lowest clock ratio of 0, which seems to happen on all
! 985: * Pentium 4's that report EST.
! 986: * - An equal highest and lowest clock ratio, which happens on
! 987: * at least the Core 2 Duo X6800, maybe on newer models too.
! 988: */
! 989: return;
! 990: }
! 991: if (crhi == 0 || crcur == 0 || crlo > crhi ||
! 992: crcur < crlo || crcur > crhi) {
! 993: /*
! 994: * Do complain about other weirdness, because we first want to
! 995: * know about it, before we decide what to do with it.
! 996: */
! 997: printf("%s: EST: strange msr value 0x%016llx\n",
! 998: cpu_device, msr);
! 999: return;
! 1000: }
! 1001: /*
! 1002: * Find an entry which matches (vendor, bus_clock, idhi, idlo)
! 1003: */
! 1004: for (i = 0; i < NELEM(est_cpus); i++) {
! 1005: fql = &est_cpus[i];
! 1006: if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) &&
! 1007: idhi == fql->table[0] && idlo == fql->table[fql->n - 1]) {
! 1008: est_fqlist = fql;
! 1009: break;
! 1010: }
! 1011: }
! 1012: if (est_fqlist == NULL) {
! 1013: printf("%s: unknown Enhanced SpeedStep CPU, msr 0x%016llx\n",
! 1014: cpu_device, msr);
! 1015:
! 1016: /*
! 1017: * Generate a fake table with the power states we know.
! 1018: */
! 1019: fake_table[0] = idhi;
! 1020: if (cur == idhi || cur == idlo) {
! 1021: printf("%s: using only highest and lowest power "
! 1022: "states\n", cpu_device);
! 1023:
! 1024: fake_table[1] = idlo;
! 1025: fake_fqlist.n = 2;
! 1026: } else {
! 1027: printf("%s: using only highest, current and lowest "
! 1028: "power states\n", cpu_device);
! 1029:
! 1030: fake_table[1] = cur;
! 1031: fake_table[2] = idlo;
! 1032: fake_fqlist.n = 3;
! 1033: }
! 1034: fake_fqlist.vendor = vendor;
! 1035: fake_fqlist.table = fake_table;
! 1036: est_fqlist = &fake_fqlist;
! 1037: }
! 1038:
! 1039: mhz = MSR2MHZ(cur, bus_clock);
! 1040: mv = MSR2MV(cur);
! 1041: printf("%s: Enhanced SpeedStep %d MHz (%d mV)", cpu_device, mhz, mv);
! 1042:
! 1043: /*
! 1044: * Check that the current operating point is in our list.
! 1045: */
! 1046: for (i = est_fqlist->n - 1; i >= 0; i--) {
! 1047: if (cur == est_fqlist->table[i])
! 1048: break;
! 1049: }
! 1050: if (i < 0) {
! 1051: printf(" (not in table, msr 0x%016llx)\n", msr);
! 1052: return;
! 1053: }
! 1054: low = MSR2MHZ(est_fqlist->table[est_fqlist->n - 1], bus_clock);
! 1055: high = MSR2MHZ(est_fqlist->table[0], bus_clock);
! 1056: perflevel = (mhz - low) * 100 / (high - low);
! 1057:
! 1058: /*
! 1059: * OK, tell the user the available frequencies.
! 1060: */
! 1061: printf(": speeds: ");
! 1062: for (i = 0; i < est_fqlist->n; i++)
! 1063: printf("%d%s", MSR2MHZ(est_fqlist->table[i], bus_clock),
! 1064: i < est_fqlist->n - 1 ? ", " : " MHz\n");
! 1065:
! 1066: cpu_setperf = est_setperf;
! 1067: setperf_prio = 3;
! 1068: }
! 1069:
! 1070: void
! 1071: est_setperf(int level)
! 1072: {
! 1073: int i;
! 1074: uint64_t msr;
! 1075:
! 1076: if (est_fqlist == NULL)
! 1077: return;
! 1078:
! 1079: i = ((level * est_fqlist->n) + 1) / 101;
! 1080: if (i >= est_fqlist->n)
! 1081: i = est_fqlist->n - 1;
! 1082: i = est_fqlist->n - 1 - i;
! 1083:
! 1084: msr = rdmsr(MSR_PERF_CTL);
! 1085: msr &= ~0xffffULL;
! 1086: msr |= est_fqlist->table[i];
! 1087: wrmsr(MSR_PERF_CTL, msr);
! 1088: cpuspeed = MSR2MHZ(est_fqlist->table[i], bus_clock);
! 1089: }
CVSweb