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

Annotation of sys/arch/i386/i386/p4tcc.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: p4tcc.c,v 1.14 2007/08/03 20:36:02 deraadt Exp $ */
                      2: /*
                      3:  * Copyright (c) 2003 Ted Unangst
                      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:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     17:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     18:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     19:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
                     20:  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
                     21:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
                     22:  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                     23:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  */
                     27: /*
                     28:  * Restrict power consumption by using thermal control circuit.
                     29:  * This operates independently of speedstep.
                     30:  * Found on Pentium 4 and later models (feature TM).
                     31:  *
                     32:  * References:
                     33:  * Intel Developer's manual v.3 #245472-012
                     34:  *
                     35:  * On some models, the cpu can hang if it's running at a slow speed.
                     36:  * Workarounds included below.
                     37:  */
                     38:
                     39: #include <sys/param.h>
                     40: #include <sys/sysctl.h>
                     41:
                     42: #include <machine/cpu.h>
                     43: #include <machine/cpufunc.h>
                     44: #include <machine/specialreg.h>
                     45:
                     46: static struct {
                     47:        u_short level;
                     48:        u_short reg;
                     49: } tcc[] = {
                     50:        { 88, 0 },
                     51:        { 75, 7 },
                     52:        { 63, 6 },
                     53:        { 50, 5 },
                     54:        { 38, 4 },
                     55:        { 25, 3 },
                     56:        { 13, 2 },
                     57:        { 0, 1 }
                     58: };
                     59:
                     60: #define TCC_LEVELS sizeof(tcc) / sizeof(tcc[0])
                     61:
                     62: extern int setperf_prio;
                     63: int p4tcc_level;
                     64:
                     65: int p4tcc_cpuspeed(int *);
                     66:
                     67: void
                     68: p4tcc_init(int family, int step)
                     69: {
                     70:        if (setperf_prio > 1)
                     71:                return;
                     72:
                     73:        switch (family) {
                     74:        case 0xf:       /* Pentium 4 */
                     75:                switch (step) {
                     76:                case 0x22:      /* errata O50 P44 and Z21 */
                     77:                case 0x24:
                     78:                case 0x25:
                     79:                case 0x27:
                     80:                case 0x29:
                     81:                        /* hang with 12.5 */
                     82:                        tcc[TCC_LEVELS - 1].reg = 2;
                     83:                        break;
                     84:                case 0x07:      /* errata N44 and P18 */
                     85:                case 0x0a:
                     86:                case 0x12:
                     87:                case 0x13:
                     88:                        /* hang at 12.5 and 25 */
                     89:                        tcc[TCC_LEVELS - 1].reg = 3;
                     90:                        tcc[TCC_LEVELS - 2].reg = 3;
                     91:                        break;
                     92:                }
                     93:                break;
                     94:        }
                     95:
                     96:        p4tcc_level = tcc[0].level;
                     97:        cpu_setperf = p4tcc_setperf;
                     98:        cpu_cpuspeed = p4tcc_cpuspeed;
                     99:        setperf_prio = 1;
                    100: }
                    101:
                    102: int
                    103: p4tcc_cpuspeed(int *speed)
                    104: {
                    105:        *speed = cpuspeed * (p4tcc_level + 12) / 100;
                    106:
                    107:        return 0;
                    108: }
                    109:
                    110: void
                    111: p4tcc_setperf(int level)
                    112: {
                    113:        int i;
                    114:        uint64_t msreg, vet;
                    115:
                    116:        for (i = 0; i < TCC_LEVELS; i++) {
                    117:                if (level >= tcc[i].level)
                    118:                        break;
                    119:        }
                    120:
                    121:        msreg = rdmsr(MSR_THERM_CONTROL);
                    122:        msreg &= ~0x1e; /* bit 0 reserved */
                    123:        if (tcc[i].reg != 0) /* enable it */
                    124:                msreg |= tcc[i].reg << 1 | 1 << 4;
                    125:        wrmsr(MSR_THERM_CONTROL, msreg);
                    126:        vet = rdmsr(MSR_THERM_CONTROL);
                    127:
                    128:        if ((vet & 0x1e) != (msreg & 0x1e))
                    129:                printf("p4_tcc: cpu did not honor request\n");
                    130:        else
                    131:                p4tcc_level = tcc[i].level;
                    132: }

CVSweb