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