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