[BACK]Return to est.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / i386

Annotation of sys/arch/i386/i386/est.c, Revision 1.1.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