xref: /openbsd-src/sys/arch/i386/i386/est.c (revision f4e7063748a2ac72b2bab4389c0a7efc72d82189)
1 /*	$OpenBSD: est.c,v 1.55 2023/01/30 10:49:05 jsg 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 #include <sys/malloc.h>
60 
61 #include <machine/cpu.h>
62 #include <machine/cpufunc.h>
63 #include <machine/specialreg.h>
64 #include <machine/bus.h>
65 
66 #include "acpicpu.h"
67 
68 #if NACPICPU > 0
69 #include <dev/acpi/acpidev.h>
70 #endif
71 
72 /* Convert MHz and mV into IDs for passing to the MSR. */
73 #define ID16(MHz, mV, bus_clk) \
74     { ((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4)), \
75 	 MHz }
76 
77 struct est_op {
78 	uint16_t ctrl;
79 	uint16_t mhz;
80 	uint16_t pct;
81 };
82 
83 /* Ultra Low Voltage Intel Pentium M processor 900 MHz */
84 static struct est_op pm130_900_ulv[] = {
85 	ID16( 900, 1004, BUS100),
86 	ID16( 800,  988, BUS100),
87 	ID16( 600,  844, BUS100),
88 };
89 
90 /* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */
91 static struct est_op pm130_1000_ulv[] = {
92 	ID16(1000, 1004, BUS100),
93 	ID16( 900,  988, BUS100),
94 	ID16( 800,  972, BUS100),
95 	ID16( 600,  844, BUS100),
96 };
97 
98 /* Ultra Low Voltage Intel Pentium M processor 1.10 GHz */
99 static struct est_op pm130_1100_ulv[] = {
100 	ID16(1100, 1004, BUS100),
101 	ID16(1000,  988, BUS100),
102 	ID16( 900,  972, BUS100),
103 	ID16( 800,  956, BUS100),
104 	ID16( 600,  844, BUS100),
105 };
106 
107 /* Low Voltage Intel Pentium M processor 1.10 GHz */
108 static struct est_op pm130_1100_lv[] = {
109 	ID16(1100, 1180, BUS100),
110 	ID16(1000, 1164, BUS100),
111 	ID16( 900, 1100, BUS100),
112 	ID16( 800, 1020, BUS100),
113 	ID16( 600,  956, BUS100),
114 };
115 
116 /* Low Voltage Intel Pentium M processor 1.20 GHz */
117 static struct est_op pm130_1200_lv[] = {
118 	ID16(1200, 1180, BUS100),
119 	ID16(1100, 1164, BUS100),
120 	ID16(1000, 1100, BUS100),
121 	ID16( 900, 1020, BUS100),
122 	ID16( 800, 1004, BUS100),
123 	ID16( 600,  956, BUS100),
124 };
125 
126 /* Low Voltage Intel Pentium M processor 1.30 GHz */
127 static struct est_op pm130_1300_lv[] = {
128 	ID16(1300, 1180, BUS100),
129 	ID16(1200, 1164, BUS100),
130 	ID16(1100, 1100, BUS100),
131 	ID16(1000, 1020, BUS100),
132 	ID16( 900, 1004, BUS100),
133 	ID16( 800,  988, BUS100),
134 	ID16( 600,  956, BUS100),
135 };
136 
137 /* Intel Pentium M processor 1.30 GHz */
138 static struct est_op pm130_1300[] = {
139 	ID16(1300, 1388, BUS100),
140 	ID16(1200, 1356, BUS100),
141 	ID16(1000, 1292, BUS100),
142 	ID16( 800, 1260, BUS100),
143 	ID16( 600,  956, BUS100),
144 };
145 
146 /* Intel Pentium M processor 1.40 GHz */
147 static struct est_op pm130_1400[] = {
148 	ID16(1400, 1484, BUS100),
149 	ID16(1200, 1436, BUS100),
150 	ID16(1000, 1308, BUS100),
151 	ID16( 800, 1180, BUS100),
152 	ID16( 600,  956, BUS100),
153 };
154 
155 /* Intel Pentium M processor 1.50 GHz */
156 static struct est_op pm130_1500[] = {
157 	ID16(1500, 1484, BUS100),
158 	ID16(1400, 1452, BUS100),
159 	ID16(1200, 1356, BUS100),
160 	ID16(1000, 1228, BUS100),
161 	ID16( 800, 1116, BUS100),
162 	ID16( 600,  956, BUS100),
163 };
164 
165 /* Intel Pentium M processor 1.60 GHz */
166 static struct est_op pm130_1600[] = {
167 	ID16(1600, 1484, BUS100),
168 	ID16(1400, 1420, BUS100),
169 	ID16(1200, 1276, BUS100),
170 	ID16(1000, 1164, BUS100),
171 	ID16( 800, 1036, BUS100),
172 	ID16( 600,  956, BUS100),
173 };
174 
175 /* Intel Pentium M processor 1.70 GHz */
176 static struct est_op pm130_1700[] = {
177 	ID16(1700, 1484, BUS100),
178 	ID16(1400, 1308, BUS100),
179 	ID16(1200, 1228, BUS100),
180 	ID16(1000, 1116, BUS100),
181 	ID16( 800, 1004, BUS100),
182 	ID16( 600,  956, BUS100),
183 };
184 
185 /* Intel Pentium M processor 723 1.0 GHz */
186 static struct est_op pm90_n723[] = {
187 	ID16(1000,  940, BUS100),
188 	ID16( 900,  908, BUS100),
189 	ID16( 800,  876, BUS100),
190 	ID16( 600,  812, BUS100),
191 };
192 
193 /* Intel Pentium M processor 733 1.1 GHz, VID #G */
194 static struct est_op pm90_n733g[] = {
195 	ID16(1100,  956, BUS100),
196 	ID16(1000,  940, BUS100),
197 	ID16( 900,  908, BUS100),
198 	ID16( 800,  876, BUS100),
199 	ID16( 600,  812, BUS100),
200 };
201 
202 /* Intel Pentium M processor 733 1.1 GHz, VID #H */
203 static struct est_op pm90_n733h[] = {
204 	ID16(1100,  940, BUS100),
205 	ID16(1000,  924, BUS100),
206 	ID16( 900,  892, BUS100),
207 	ID16( 800,  876, BUS100),
208 	ID16( 600,  812, BUS100),
209 };
210 
211 /* Intel Pentium M processor 733 1.1 GHz, VID #I */
212 static struct est_op pm90_n733i[] = {
213 	ID16(1100,  924, BUS100),
214 	ID16(1000,  908, BUS100),
215 	ID16( 900,  892, BUS100),
216 	ID16( 800,  860, BUS100),
217 	ID16( 600,  812, BUS100),
218 };
219 
220 /* Intel Pentium M processor 733 1.1 GHz, VID #J */
221 static struct est_op pm90_n733j[] = {
222 	ID16(1100,  908, BUS100),
223 	ID16(1000,  892, BUS100),
224 	ID16( 900,  876, BUS100),
225 	ID16( 800,  860, BUS100),
226 	ID16( 600,  812, BUS100),
227 };
228 
229 /* Intel Pentium M processor 733 1.1 GHz, VID #K */
230 static struct est_op pm90_n733k[] = {
231 	ID16(1100,  892, BUS100),
232 	ID16(1000,  876, BUS100),
233 	ID16( 900,  860, BUS100),
234 	ID16( 800,  844, BUS100),
235 	ID16( 600,  812, BUS100),
236 };
237 
238 /* Intel Pentium M processor 733 1.1 GHz, VID #L */
239 static struct est_op pm90_n733l[] = {
240 	ID16(1100,  876, BUS100),
241 	ID16(1000,  876, BUS100),
242 	ID16( 900,  860, BUS100),
243 	ID16( 800,  844, BUS100),
244 	ID16( 600,  812, BUS100),
245 };
246 
247 /* Intel Pentium M processor 753 1.2 GHz, VID #G */
248 static struct est_op pm90_n753g[] = {
249 	ID16(1200,  956, BUS100),
250 	ID16(1100,  940, BUS100),
251 	ID16(1000,  908, BUS100),
252 	ID16( 900,  892, BUS100),
253 	ID16( 800,  860, BUS100),
254 	ID16( 600,  812, BUS100),
255 };
256 
257 /* Intel Pentium M processor 753 1.2 GHz, VID #H */
258 static struct est_op pm90_n753h[] = {
259 	ID16(1200,  940, BUS100),
260 	ID16(1100,  924, BUS100),
261 	ID16(1000,  908, BUS100),
262 	ID16( 900,  876, BUS100),
263 	ID16( 800,  860, BUS100),
264 	ID16( 600,  812, BUS100),
265 };
266 
267 /* Intel Pentium M processor 753 1.2 GHz, VID #I */
268 static struct est_op pm90_n753i[] = {
269 	ID16(1200,  924, BUS100),
270 	ID16(1100,  908, BUS100),
271 	ID16(1000,  892, BUS100),
272 	ID16( 900,  876, BUS100),
273 	ID16( 800,  860, BUS100),
274 	ID16( 600,  812, BUS100),
275 };
276 
277 /* Intel Pentium M processor 753 1.2 GHz, VID #J */
278 static struct est_op pm90_n753j[] = {
279 	ID16(1200,  908, BUS100),
280 	ID16(1100,  892, BUS100),
281 	ID16(1000,  876, BUS100),
282 	ID16( 900,  860, BUS100),
283 	ID16( 800,  844, BUS100),
284 	ID16( 600,  812, BUS100),
285 };
286 
287 /* Intel Pentium M processor 753 1.2 GHz, VID #K */
288 static struct est_op pm90_n753k[] = {
289 	ID16(1200,  892, BUS100),
290 	ID16(1100,  892, BUS100),
291 	ID16(1000,  876, BUS100),
292 	ID16( 900,  860, BUS100),
293 	ID16( 800,  844, BUS100),
294 	ID16( 600,  812, BUS100),
295 };
296 
297 /* Intel Pentium M processor 753 1.2 GHz, VID #L */
298 static struct est_op pm90_n753l[] = {
299 	ID16(1200,  876, BUS100),
300 	ID16(1100,  876, BUS100),
301 	ID16(1000,  860, BUS100),
302 	ID16( 900,  844, BUS100),
303 	ID16( 800,  844, BUS100),
304 	ID16( 600,  812, BUS100),
305 };
306 
307 /* Intel Pentium M processor 773 1.3 GHz, VID #G */
308 static struct est_op pm90_n773g[] = {
309 	ID16(1300,  956, BUS100),
310 	ID16(1200,  940, BUS100),
311 	ID16(1100,  924, BUS100),
312 	ID16(1000,  908, BUS100),
313 	ID16( 900,  876, BUS100),
314 	ID16( 800,  860, BUS100),
315 	ID16( 600,  812, BUS100),
316 };
317 
318 /* Intel Pentium M processor 773 1.3 GHz, VID #H */
319 static struct est_op pm90_n773h[] = {
320 	ID16(1300,  940, BUS100),
321 	ID16(1200,  924, BUS100),
322 	ID16(1100,  908, BUS100),
323 	ID16(1000,  892, BUS100),
324 	ID16( 900,  876, BUS100),
325 	ID16( 800,  860, BUS100),
326 	ID16( 600,  812, BUS100),
327 };
328 
329 /* Intel Pentium M processor 773 1.3 GHz, VID #I */
330 static struct est_op pm90_n773i[] = {
331 	ID16(1300,  924, BUS100),
332 	ID16(1200,  908, BUS100),
333 	ID16(1100,  892, BUS100),
334 	ID16(1000,  876, BUS100),
335 	ID16( 900,  860, BUS100),
336 	ID16( 800,  844, BUS100),
337 	ID16( 600,  812, BUS100),
338 };
339 
340 /* Intel Pentium M processor 773 1.3 GHz, VID #J */
341 static struct est_op pm90_n773j[] = {
342 	ID16(1300,  908, BUS100),
343 	ID16(1200,  908, BUS100),
344 	ID16(1100,  892, BUS100),
345 	ID16(1000,  876, BUS100),
346 	ID16( 900,  860, BUS100),
347 	ID16( 800,  844, BUS100),
348 	ID16( 600,  812, BUS100),
349 };
350 
351 /* Intel Pentium M processor 773 1.3 GHz, VID #K */
352 static struct est_op pm90_n773k[] = {
353 	ID16(1300,  892, BUS100),
354 	ID16(1200,  892, BUS100),
355 	ID16(1100,  876, BUS100),
356 	ID16(1000,  860, BUS100),
357 	ID16( 900,  860, BUS100),
358 	ID16( 800,  844, BUS100),
359 	ID16( 600,  812, BUS100),
360 };
361 
362 /* Intel Pentium M processor 773 1.3 GHz, VID #L */
363 static struct est_op pm90_n773l[] = {
364 	ID16(1300,  876, BUS100),
365 	ID16(1200,  876, BUS100),
366 	ID16(1100,  860, BUS100),
367 	ID16(1000,  860, BUS100),
368 	ID16( 900,  844, BUS100),
369 	ID16( 800,  844, BUS100),
370 	ID16( 600,  812, BUS100),
371 };
372 
373 /* Intel Pentium M processor 738 1.4 GHz */
374 static struct est_op pm90_n738[] = {
375 	ID16(1400, 1116, BUS100),
376 	ID16(1300, 1116, BUS100),
377 	ID16(1200, 1100, 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 758 1.5 GHz */
386 static struct est_op pm90_n758[] = {
387 	ID16(1500, 1116, BUS100),
388 	ID16(1400, 1116, BUS100),
389 	ID16(1300, 1100, BUS100),
390 	ID16(1200, 1084, BUS100),
391 	ID16(1100, 1068, BUS100),
392 	ID16(1000, 1052, BUS100),
393 	ID16( 900, 1036, BUS100),
394 	ID16( 800, 1020, BUS100),
395 	ID16( 600,  988, BUS100),
396 };
397 
398 /* Intel Pentium M processor 778 1.6 GHz */
399 static struct est_op pm90_n778[] = {
400 	ID16(1600, 1116, BUS100),
401 	ID16(1500, 1116, BUS100),
402 	ID16(1400, 1100, BUS100),
403 	ID16(1300, 1184, BUS100),
404 	ID16(1200, 1068, BUS100),
405 	ID16(1100, 1052, BUS100),
406 	ID16(1000, 1052, BUS100),
407 	ID16( 900, 1036, BUS100),
408 	ID16( 800, 1020, BUS100),
409 	ID16( 600,  988, BUS100),
410 };
411 
412 /* Intel Pentium M processor 710 1.4 GHz, 533 MHz FSB */
413 static struct est_op pm90_n710[] = {
414 	ID16(1400, 1340, BUS133),
415 	ID16(1200, 1228, BUS133),
416 	ID16(1000, 1148, BUS133),
417 	ID16( 800, 1068, BUS133),
418 	ID16( 600,  998, BUS133),
419 };
420 
421 /* Intel Pentium M processor 715 1.5 GHz, VID #A */
422 static struct est_op pm90_n715a[] = {
423 	ID16(1500, 1340, BUS100),
424 	ID16(1200, 1228, BUS100),
425 	ID16(1000, 1148, BUS100),
426 	ID16( 800, 1068, BUS100),
427 	ID16( 600,  988, BUS100),
428 };
429 
430 /* Intel Pentium M processor 715 1.5 GHz, VID #B */
431 static struct est_op pm90_n715b[] = {
432 	ID16(1500, 1324, BUS100),
433 	ID16(1200, 1212, BUS100),
434 	ID16(1000, 1148, BUS100),
435 	ID16( 800, 1068, BUS100),
436 	ID16( 600,  988, BUS100),
437 };
438 
439 /* Intel Pentium M processor 715 1.5 GHz, VID #C */
440 static struct est_op pm90_n715c[] = {
441 	ID16(1500, 1308, BUS100),
442 	ID16(1200, 1212, BUS100),
443 	ID16(1000, 1132, BUS100),
444 	ID16( 800, 1068, BUS100),
445 	ID16( 600,  988, BUS100),
446 };
447 
448 /* Intel Pentium M processor 715 1.5 GHz, VID #D */
449 static struct est_op pm90_n715d[] = {
450 	ID16(1500, 1276, BUS100),
451 	ID16(1200, 1180, BUS100),
452 	ID16(1000, 1116, BUS100),
453 	ID16( 800, 1052, BUS100),
454 	ID16( 600,  988, BUS100),
455 };
456 
457 /* Intel Pentium M processor 725 1.6 GHz, VID #A */
458 static struct est_op pm90_n725a[] = {
459 	ID16(1600, 1340, BUS100),
460 	ID16(1400, 1276, BUS100),
461 	ID16(1200, 1212, BUS100),
462 	ID16(1000, 1132, BUS100),
463 	ID16( 800, 1068, BUS100),
464 	ID16( 600,  988, BUS100),
465 };
466 
467 /* Intel Pentium M processor 725 1.6 GHz, VID #B */
468 static struct est_op pm90_n725b[] = {
469 	ID16(1600, 1324, BUS100),
470 	ID16(1400, 1260, BUS100),
471 	ID16(1200, 1196, BUS100),
472 	ID16(1000, 1132, BUS100),
473 	ID16( 800, 1068, BUS100),
474 	ID16( 600,  988, BUS100),
475 };
476 
477 /* Intel Pentium M processor 725 1.6 GHz, VID #C */
478 static struct est_op pm90_n725c[] = {
479 	ID16(1600, 1308, BUS100),
480 	ID16(1400, 1244, BUS100),
481 	ID16(1200, 1180, BUS100),
482 	ID16(1000, 1116, BUS100),
483 	ID16( 800, 1052, BUS100),
484 	ID16( 600,  988, BUS100),
485 };
486 
487 /* Intel Pentium M processor 725 1.6 GHz, VID #D */
488 static struct est_op pm90_n725d[] = {
489 	ID16(1600, 1276, BUS100),
490 	ID16(1400, 1228, BUS100),
491 	ID16(1200, 1164, BUS100),
492 	ID16(1000, 1116, BUS100),
493 	ID16( 800, 1052, BUS100),
494 	ID16( 600,  988, BUS100),
495 };
496 
497 /* Intel Pentium M processor 730 1.6 GHz, 533 MHz FSB */
498 static struct est_op pm90_n730[] = {
499 	ID16(1600, 1308, BUS133),
500 	ID16(1333, 1260, BUS133),
501 	ID16(1200, 1212, BUS133),
502 	ID16(1067, 1180, BUS133),
503 	ID16( 800,  988, BUS133),
504 };
505 
506 /* Intel Pentium M processor 735 1.7 GHz, VID #A */
507 static struct est_op pm90_n735a[] = {
508 	ID16(1700, 1340, BUS100),
509 	ID16(1400, 1244, BUS100),
510 	ID16(1200, 1180, BUS100),
511 	ID16(1000, 1116, BUS100),
512 	ID16( 800, 1052, BUS100),
513 	ID16( 600,  988, BUS100),
514 };
515 
516 /* Intel Pentium M processor 735 1.7 GHz, VID #B */
517 static struct est_op pm90_n735b[] = {
518 	ID16(1700, 1324, BUS100),
519 	ID16(1400, 1244, BUS100),
520 	ID16(1200, 1180, BUS100),
521 	ID16(1000, 1116, BUS100),
522 	ID16( 800, 1052, BUS100),
523 	ID16( 600,  988, BUS100),
524 };
525 
526 /* Intel Pentium M processor 735 1.7 GHz, VID #C */
527 static struct est_op pm90_n735c[] = {
528 	ID16(1700, 1308, BUS100),
529 	ID16(1400, 1228, BUS100),
530 	ID16(1200, 1164, BUS100),
531 	ID16(1000, 1116, BUS100),
532 	ID16( 800, 1052, BUS100),
533 	ID16( 600,  988, BUS100),
534 };
535 
536 /* Intel Pentium M processor 735 1.7 GHz, VID #D */
537 static struct est_op pm90_n735d[] = {
538 	ID16(1700, 1276, BUS100),
539 	ID16(1400, 1212, BUS100),
540 	ID16(1200, 1148, BUS100),
541 	ID16(1000, 1100, BUS100),
542 	ID16( 800, 1052, BUS100),
543 	ID16( 600,  988, BUS100),
544 };
545 
546 /* Intel Pentium M processor 740 1.73 GHz, 533 MHz FSB */
547 static struct est_op pm90_n740[] = {
548 	ID16(1733, 1356, BUS133),
549 	ID16(1333, 1212, BUS133),
550 	ID16(1067, 1100, BUS133),
551 	ID16( 800,  988, BUS133),
552 };
553 
554 /* Intel Pentium M processor 745 1.8 GHz, VID #A */
555 static struct est_op pm90_n745a[] = {
556 	ID16(1800, 1340, BUS100),
557 	ID16(1600, 1292, BUS100),
558 	ID16(1400, 1228, BUS100),
559 	ID16(1200, 1164, BUS100),
560 	ID16(1000, 1116, BUS100),
561 	ID16( 800, 1052, BUS100),
562 	ID16( 600,  988, BUS100),
563 };
564 
565 /* Intel Pentium M processor 745 1.8 GHz, VID #B */
566 static struct est_op pm90_n745b[] = {
567 	ID16(1800, 1324, BUS100),
568 	ID16(1600, 1276, BUS100),
569 	ID16(1400, 1212, BUS100),
570 	ID16(1200, 1164, BUS100),
571 	ID16(1000, 1116, BUS100),
572 	ID16( 800, 1052, BUS100),
573 	ID16( 600,  988, BUS100),
574 };
575 
576 /* Intel Pentium M processor 745 1.8 GHz, VID #C */
577 static struct est_op pm90_n745c[] = {
578 	ID16(1800, 1308, BUS100),
579 	ID16(1600, 1260, BUS100),
580 	ID16(1400, 1212, BUS100),
581 	ID16(1200, 1148, BUS100),
582 	ID16(1000, 1100, BUS100),
583 	ID16( 800, 1052, BUS100),
584 	ID16( 600,  988, BUS100),
585 };
586 
587 /* Intel Pentium M processor 745 1.8 GHz, VID #D */
588 static struct est_op pm90_n745d[] = {
589 	ID16(1800, 1276, BUS100),
590 	ID16(1600, 1228, BUS100),
591 	ID16(1400, 1180, BUS100),
592 	ID16(1200, 1132, BUS100),
593 	ID16(1000, 1084, BUS100),
594 	ID16( 800, 1036, BUS100),
595 	ID16( 600,  988, BUS100),
596 };
597 
598 /* Intel Pentium M processor 750 1.86 GHz, 533 MHz FSB */
599 /* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */
600 static struct est_op pm90_n750[] = {
601 	ID16(1867, 1308, BUS133),
602 	ID16(1600, 1228, BUS133),
603 	ID16(1333, 1148, BUS133),
604 	ID16(1067, 1068, BUS133),
605 	ID16( 800,  988, BUS133),
606 };
607 
608 /* Intel Pentium M processor 755 2.0 GHz, VID #A */
609 static struct est_op pm90_n755a[] = {
610 	ID16(2000, 1340, BUS100),
611 	ID16(1800, 1292, BUS100),
612 	ID16(1600, 1244, BUS100),
613 	ID16(1400, 1196, BUS100),
614 	ID16(1200, 1148, BUS100),
615 	ID16(1000, 1100, BUS100),
616 	ID16( 800, 1052, BUS100),
617 	ID16( 600,  988, BUS100),
618 };
619 
620 /* Intel Pentium M processor 755 2.0 GHz, VID #B */
621 static struct est_op pm90_n755b[] = {
622 	ID16(2000, 1324, BUS100),
623 	ID16(1800, 1276, BUS100),
624 	ID16(1600, 1228, BUS100),
625 	ID16(1400, 1180, BUS100),
626 	ID16(1200, 1132, BUS100),
627 	ID16(1000, 1084, BUS100),
628 	ID16( 800, 1036, BUS100),
629 	ID16( 600,  988, BUS100),
630 };
631 
632 /* Intel Pentium M processor 755 2.0 GHz, VID #C */
633 static struct est_op pm90_n755c[] = {
634 	ID16(2000, 1308, BUS100),
635 	ID16(1800, 1276, BUS100),
636 	ID16(1600, 1228, BUS100),
637 	ID16(1400, 1180, BUS100),
638 	ID16(1200, 1132, BUS100),
639 	ID16(1000, 1084, BUS100),
640 	ID16( 800, 1036, BUS100),
641 	ID16( 600,  988, BUS100),
642 };
643 
644 /* Intel Pentium M processor 755 2.0 GHz, VID #D */
645 static struct est_op pm90_n755d[] = {
646 	ID16(2000, 1276, BUS100),
647 	ID16(1800, 1244, BUS100),
648 	ID16(1600, 1196, BUS100),
649 	ID16(1400, 1164, BUS100),
650 	ID16(1200, 1116, BUS100),
651 	ID16(1000, 1084, BUS100),
652 	ID16( 800, 1036, BUS100),
653 	ID16( 600,  988, BUS100),
654 };
655 
656 /* Intel Pentium M processor 760 2.0 GHz, 533 MHz FSB */
657 static struct est_op pm90_n760[] = {
658 	ID16(2000, 1356, BUS133),
659 	ID16(1600, 1244, BUS133),
660 	ID16(1333, 1164, BUS133),
661 	ID16(1067, 1084, BUS133),
662 	ID16( 800,  988, BUS133),
663 };
664 
665 /* Intel Pentium M processor 765 2.1 GHz, VID #A */
666 static struct est_op pm90_n765a[] = {
667 	ID16(2100, 1340, BUS100),
668 	ID16(1800, 1276, BUS100),
669 	ID16(1600, 1228, BUS100),
670 	ID16(1400, 1180, BUS100),
671 	ID16(1200, 1132, BUS100),
672 	ID16(1000, 1084, BUS100),
673 	ID16( 800, 1036, BUS100),
674 	ID16( 600,  988, BUS100),
675 };
676 
677 /* Intel Pentium M processor 765 2.1 GHz, VID #B */
678 static struct est_op pm90_n765b[] = {
679 	ID16(2100, 1324, BUS100),
680 	ID16(1800, 1260, BUS100),
681 	ID16(1600, 1212, BUS100),
682 	ID16(1400, 1180, BUS100),
683 	ID16(1200, 1132, BUS100),
684 	ID16(1000, 1084, BUS100),
685 	ID16( 800, 1036, BUS100),
686 	ID16( 600,  988, BUS100),
687 };
688 
689 /* Intel Pentium M processor 765 2.1 GHz, VID #C */
690 static struct est_op pm90_n765c[] = {
691 	ID16(2100, 1308, BUS100),
692 	ID16(1800, 1244, BUS100),
693 	ID16(1600, 1212, BUS100),
694 	ID16(1400, 1164, BUS100),
695 	ID16(1200, 1116, BUS100),
696 	ID16(1000, 1084, BUS100),
697 	ID16( 800, 1036, BUS100),
698 	ID16( 600,  988, BUS100),
699 };
700 
701 /* Intel Pentium M processor 765 2.1 GHz, VID #E */
702 static struct est_op pm90_n765e[] = {
703 	ID16(2100, 1356, BUS100),
704 	ID16(1800, 1292, BUS100),
705 	ID16(1600, 1244, BUS100),
706 	ID16(1400, 1196, BUS100),
707 	ID16(1200, 1148, BUS100),
708 	ID16(1000, 1100, BUS100),
709 	ID16( 800, 1052, BUS100),
710 	ID16( 600,  988, BUS100),
711 };
712 
713 /* Intel Pentium M processor 770 2.13 GHz */
714 static struct est_op pm90_n770[] = {
715 	ID16(2133, 1356, BUS133),
716 	ID16(1867, 1292, BUS133),
717 	ID16(1600, 1212, BUS133),
718 	ID16(1333, 1148, BUS133),
719 	ID16(1067, 1068, BUS133),
720 	ID16( 800,  988, BUS133),
721 };
722 
723 /*
724  * VIA C7-M 500 MHz FSB, 400 MHz FSB, and ULV variants.
725  * Data from the "VIA C7-M Processor BIOS Writer's Guide (v2.17)" datasheet.
726  */
727 
728 /* 1.00GHz Centaur C7-M ULV */
729 static struct est_op C7M_770_ULV[] = {
730 	ID16(1000,  844, BUS100),
731 	ID16( 800,  796, BUS100),
732 	ID16( 600,  796, BUS100),
733 	ID16( 400,  796, BUS100),
734 };
735 
736 /* 1.00GHz Centaur C7-M ULV */
737 static struct est_op C7M_779_ULV[] = {
738 	ID16(1000,  796, BUS100),
739 	ID16( 800,  796, BUS100),
740 	ID16( 600,  796, BUS100),
741 	ID16( 400,  796, BUS100),
742 };
743 
744 /* 1.20GHz Centaur C7-M ULV */
745 static struct est_op C7M_772_ULV[] = {
746 	ID16(1200,  844, BUS100),
747 	ID16(1000,  844, BUS100),
748 	ID16( 800,  828, BUS100),
749 	ID16( 600,  796, BUS100),
750 	ID16( 400,  796, BUS100),
751 };
752 
753 /* 1.50GHz Centaur C7-M ULV */
754 static struct est_op C7M_775_ULV[] = {
755 	ID16(1500,  956, BUS100),
756 	ID16(1400,  940, BUS100),
757 	ID16(1000,  860, BUS100),
758 	ID16( 800,  828, BUS100),
759 	ID16( 600,  796, BUS100),
760 	ID16( 400,  796, BUS100),
761 };
762 
763 /* 1.20GHz Centaur C7-M 400 MHz FSB */
764 static struct est_op C7M_771[] = {
765 	ID16(1200,  860, BUS100),
766 	ID16(1000,  860, BUS100),
767 	ID16( 800,  844, BUS100),
768 	ID16( 600,  844, BUS100),
769 	ID16( 400,  844, BUS100),
770 };
771 
772 /* 1.50GHz Centaur C7-M 400 MHz FSB */
773 static struct est_op C7M_754[] = {
774 	ID16(1500, 1004, BUS100),
775 	ID16(1400,  988, BUS100),
776 	ID16(1000,  940, BUS100),
777 	ID16( 800,  844, BUS100),
778 	ID16( 600,  844, BUS100),
779 	ID16( 400,  844, BUS100),
780 };
781 
782 /* 1.60GHz Centaur C7-M 400 MHz FSB */
783 static struct est_op C7M_764[] = {
784 	ID16(1600, 1084, BUS100),
785 	ID16(1400, 1052, BUS100),
786 	ID16(1000, 1004, BUS100),
787 	ID16( 800,  844, BUS100),
788 	ID16( 600,  844, BUS100),
789 	ID16( 400,  844, BUS100),
790 };
791 
792 /* 1.80GHz Centaur C7-M 400 MHz FSB */
793 static struct est_op C7M_784[] = {
794 	ID16(1800, 1148, BUS100),
795 	ID16(1600, 1100, BUS100),
796 	ID16(1400, 1052, BUS100),
797 	ID16(1000, 1004, BUS100),
798 	ID16( 800,  844, BUS100),
799 	ID16( 600,  844, BUS100),
800 	ID16( 400,  844, BUS100),
801 };
802 
803 /* 2.00GHz Centaur C7-M 400 MHz FSB */
804 static struct est_op C7M_794[] = {
805 	ID16(2000, 1148, BUS100),
806 	ID16(1800, 1132, BUS100),
807 	ID16(1600, 1100, BUS100),
808 	ID16(1400, 1052, BUS100),
809 	ID16(1000, 1004, BUS100),
810 	ID16( 800,  844, BUS100),
811 	ID16( 600,  844, BUS100),
812 	ID16( 400,  844, BUS100),
813 };
814 
815 /* 1.60GHz Centaur C7-M 533 MHz FSB */
816 static struct est_op C7M_765[] = {
817 	ID16(1600, 1084, BUS133),
818 	ID16(1467, 1052, BUS133),
819 	ID16(1200, 1004, BUS133),
820 	ID16( 800,  844, BUS133),
821 	ID16( 667,  844, BUS133),
822 	ID16( 533,  844, BUS133),
823 };
824 
825 /* 2.00GHz Centaur C7-M 533 MHz FSB */
826 static struct est_op C7M_785[] = {
827 	ID16(1867, 1148, BUS133),
828 	ID16(1600, 1100, BUS133),
829 	ID16(1467, 1052, BUS133),
830 	ID16(1200, 1004, BUS133),
831 	ID16( 800,  844, BUS133),
832 	ID16( 667,  844, BUS133),
833 	ID16( 533,  844, BUS133),
834 };
835 
836 /* 2.00GHz Centaur C7-M 533 MHz FSB */
837 static struct est_op C7M_795[] = {
838 	ID16(2000, 1148, BUS133),
839 	ID16(1867, 1132, BUS133),
840 	ID16(1600, 1100, BUS133),
841 	ID16(1467, 1052, BUS133),
842 	ID16(1200, 1004, BUS133),
843 	ID16( 800,  844, BUS133),
844 	ID16( 667,  844, BUS133),
845 	ID16( 533,  844, BUS133),
846 };
847 
848 /* 1.00GHz VIA Eden 90nm 'Esther' */
849 static struct est_op eden90_1000[] = {
850 	ID16(1000,  844, BUS100),
851 	ID16( 800,  844, BUS100),
852 	ID16( 600,  844, BUS100),
853 	ID16( 400,  844, BUS100),
854 };
855 
856 
857 struct fqlist {
858 	int vendor: 5;
859 	unsigned bus_clk : 1;
860 	unsigned n : 5;
861 	struct est_op *table;
862 };
863 
864 #define ENTRY(ven, bus_clk, tab) \
865 	{ CPUVENDOR_##ven, bus_clk == BUS133 ? 1 : 0, nitems(tab), tab }
866 
867 #define BUS_CLK(fqp) ((fqp)->bus_clk ? BUS133 : BUS100)
868 
869 static struct fqlist est_cpus[] = {
870 	ENTRY(INTEL, BUS100, pm130_900_ulv),
871 	ENTRY(INTEL, BUS100, pm130_1000_ulv),
872 	ENTRY(INTEL, BUS100, pm130_1100_ulv),
873 	ENTRY(INTEL, BUS100, pm130_1100_lv),
874 	ENTRY(INTEL, BUS100, pm130_1200_lv),
875 	ENTRY(INTEL, BUS100, pm130_1300_lv),
876 	ENTRY(INTEL, BUS100, pm130_1300),
877 	ENTRY(INTEL, BUS100, pm130_1400),
878 	ENTRY(INTEL, BUS100, pm130_1500),
879 	ENTRY(INTEL, BUS100, pm130_1600),
880 	ENTRY(INTEL, BUS100, pm130_1700),
881 
882 	ENTRY(INTEL, BUS100, pm90_n723),
883 	ENTRY(INTEL, BUS100, pm90_n733g),
884 	ENTRY(INTEL, BUS100, pm90_n733h),
885 	ENTRY(INTEL, BUS100, pm90_n733i),
886 	ENTRY(INTEL, BUS100, pm90_n733j),
887 	ENTRY(INTEL, BUS100, pm90_n733k),
888 	ENTRY(INTEL, BUS100, pm90_n733l),
889 	ENTRY(INTEL, BUS100, pm90_n753g),
890 	ENTRY(INTEL, BUS100, pm90_n753h),
891 	ENTRY(INTEL, BUS100, pm90_n753i),
892 	ENTRY(INTEL, BUS100, pm90_n753j),
893 	ENTRY(INTEL, BUS100, pm90_n753k),
894 	ENTRY(INTEL, BUS100, pm90_n753l),
895 	ENTRY(INTEL, BUS100, pm90_n773g),
896 	ENTRY(INTEL, BUS100, pm90_n773h),
897 	ENTRY(INTEL, BUS100, pm90_n773i),
898 	ENTRY(INTEL, BUS100, pm90_n773j),
899 	ENTRY(INTEL, BUS100, pm90_n773k),
900 	ENTRY(INTEL, BUS100, pm90_n773l),
901 	ENTRY(INTEL, BUS100, pm90_n738),
902 	ENTRY(INTEL, BUS100, pm90_n758),
903 	ENTRY(INTEL, BUS100, pm90_n778),
904 
905 	ENTRY(INTEL, BUS133, pm90_n710),
906 	ENTRY(INTEL, BUS100, pm90_n715a),
907 	ENTRY(INTEL, BUS100, pm90_n715b),
908 	ENTRY(INTEL, BUS100, pm90_n715c),
909 	ENTRY(INTEL, BUS100, pm90_n715d),
910 	ENTRY(INTEL, BUS100, pm90_n725a),
911 	ENTRY(INTEL, BUS100, pm90_n725b),
912 	ENTRY(INTEL, BUS100, pm90_n725c),
913 	ENTRY(INTEL, BUS100, pm90_n725d),
914 	ENTRY(INTEL, BUS133, pm90_n730),
915 	ENTRY(INTEL, BUS100, pm90_n735a),
916 	ENTRY(INTEL, BUS100, pm90_n735b),
917 	ENTRY(INTEL, BUS100, pm90_n735c),
918 	ENTRY(INTEL, BUS100, pm90_n735d),
919 	ENTRY(INTEL, BUS133, pm90_n740),
920 	ENTRY(INTEL, BUS100, pm90_n745a),
921 	ENTRY(INTEL, BUS100, pm90_n745b),
922 	ENTRY(INTEL, BUS100, pm90_n745c),
923 	ENTRY(INTEL, BUS100, pm90_n745d),
924 	ENTRY(INTEL, BUS133, pm90_n750),
925 	ENTRY(INTEL, BUS100, pm90_n755a),
926 	ENTRY(INTEL, BUS100, pm90_n755b),
927 	ENTRY(INTEL, BUS100, pm90_n755c),
928 	ENTRY(INTEL, BUS100, pm90_n755d),
929 	ENTRY(INTEL, BUS133, pm90_n760),
930 	ENTRY(INTEL, BUS100, pm90_n765a),
931 	ENTRY(INTEL, BUS100, pm90_n765b),
932 	ENTRY(INTEL, BUS100, pm90_n765c),
933 	ENTRY(INTEL, BUS100, pm90_n765e),
934 	ENTRY(INTEL, BUS133, pm90_n770),
935 
936 	ENTRY(VIA,   BUS100, C7M_770_ULV),
937 	ENTRY(VIA,   BUS100, C7M_779_ULV),
938 	ENTRY(VIA,   BUS100, C7M_772_ULV),
939 	ENTRY(VIA,   BUS100, C7M_771),
940 	ENTRY(VIA,   BUS100, C7M_775_ULV),
941 	ENTRY(VIA,   BUS100, C7M_754),
942 	ENTRY(VIA,   BUS100, C7M_764),
943 	ENTRY(VIA,   BUS133, C7M_765),
944 	ENTRY(VIA,   BUS100, C7M_784),
945 	ENTRY(VIA,   BUS133, C7M_785),
946 	ENTRY(VIA,   BUS100, C7M_794),
947 	ENTRY(VIA,   BUS133, C7M_795),
948 
949 	ENTRY(VIA,   BUS100, eden90_1000),
950 };
951 
952 #define MSR2MHZ(msr, bus) \
953 	(((((int) (msr) >> 8) & 0xff) * (bus) + 50) / 100)
954 #define MSR2MV(msr) \
955 	(((int) (msr) & 0xff) * 16 + 700)
956 
957 static struct fqlist *est_fqlist;
958 
959 extern int setperf_prio;
960 extern int perflevel;
961 
962 void p4_get_bus_clock(struct cpu_info *);
963 void p3_get_bus_clock(struct cpu_info *);
964 void cyrix3_get_bus_clock(struct cpu_info *);
965 
966 #if NACPICPU > 0
967 struct fqlist * est_acpi_init(void);
968 void est_acpi_pss_changed(struct acpicpu_pss *, int);
969 
970 struct fqlist *
est_acpi_init(void)971 est_acpi_init(void)
972 {
973 	struct acpicpu_pss *pss;
974 	struct fqlist *acpilist;
975 	int nstates, i;
976 	int high, low;
977 
978 	if ((nstates = acpicpu_fetch_pss(&pss)) == 0)
979 		goto nolist;
980 
981 	high = pss[0].pss_core_freq;
982 	low = pss[nstates - 1].pss_core_freq;
983 	if (high - low <= 0)
984 		goto nolist;
985 
986 	if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT))
987 	    == NULL)
988 		goto nolist;
989 
990 	if ((acpilist->table = mallocarray(nstates, sizeof(struct est_op),
991 	    M_DEVBUF, M_NOWAIT)) == NULL)
992 		goto notable;
993 
994 	acpilist->n = nstates;
995 
996 	for (i = 0; i < nstates; i++) {
997 		acpilist->table[i].mhz = pss[i].pss_core_freq;
998 		acpilist->table[i].ctrl = pss[i].pss_ctrl;
999 		acpilist->table[i].pct =
1000 		    (pss[i].pss_core_freq - low) * 100 / (high - low);
1001 	}
1002 
1003 	acpicpu_set_notify(est_acpi_pss_changed);
1004 
1005 	return acpilist;
1006 
1007 notable:
1008 	free(acpilist, M_DEVBUF, sizeof(*acpilist));
1009 	acpilist = NULL;
1010 nolist:
1011 	return NULL;
1012 }
1013 
1014 void
est_acpi_pss_changed(struct acpicpu_pss * pss,int npss)1015 est_acpi_pss_changed(struct acpicpu_pss *pss, int npss)
1016 {
1017 	struct fqlist *acpilist;
1018 	int needtran = 1, i;
1019 	int high, low;
1020 	u_int64_t msr;
1021 	u_int16_t cur;
1022 
1023 	msr = rdmsr(MSR_PERF_STATUS);
1024 	cur = msr & 0xffff;
1025 
1026 	high = pss[0].pss_core_freq;
1027 	low = pss[npss - 1].pss_core_freq;
1028 	if (high - low <= 0) {
1029 		printf("est_acpi_pss_changed: new est state has no "
1030 		    "speed step\n");
1031 		return;
1032 	}
1033 
1034 	if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT))
1035 	    == NULL) {
1036 		printf("est_acpi_pss_changed: cannot allocate memory for new "
1037 		    "est state\n");
1038 		return;
1039 	}
1040 
1041 	if ((acpilist->table = mallocarray(npss, sizeof(struct est_op),
1042 	    M_DEVBUF, M_NOWAIT)) == NULL) {
1043 		printf("est_acpi_pss_changed: cannot allocate memory for new "
1044 		    "operating points\n");
1045 		free(acpilist, M_DEVBUF, sizeof(*acpilist));
1046 		return;
1047 	}
1048 
1049 	for (i = 0; i < npss; i++) {
1050 		acpilist->table[i].mhz = pss[i].pss_core_freq;
1051 		acpilist->table[i].ctrl = pss[i].pss_ctrl;
1052 		acpilist->table[i].pct =
1053 		    (pss[i].pss_core_freq - low) * 100 / (high - low);
1054 		if (pss[i].pss_ctrl == cur)
1055 			needtran = 0;
1056 	}
1057 
1058 	free(est_fqlist->table, M_DEVBUF, npss * sizeof(struct est_op));
1059 	free(est_fqlist, M_DEVBUF, sizeof *est_fqlist);
1060 	est_fqlist = acpilist;
1061 
1062 	if (needtran) {
1063 		est_setperf(perflevel);
1064 	}
1065 }
1066 #endif
1067 
1068 void
est_init(struct cpu_info * ci,int vendor)1069 est_init(struct cpu_info *ci, int vendor)
1070 {
1071 	const char *cpu_device = ci->ci_dev->dv_xname;
1072 	int i, low, high;
1073 	u_int64_t msr;
1074 	u_int16_t idhi, idlo, cur;
1075 	u_int8_t crhi, crlo, crcur;
1076 	struct fqlist *fql;
1077 	struct fqlist *fake_fqlist;
1078 	struct est_op *fake_table;
1079 
1080 	if (setperf_prio > 3)
1081 		return;
1082 
1083 #if NACPICPU > 0
1084 	est_fqlist = est_acpi_init();
1085 #endif
1086 
1087 	/* bus_clock is only used if we can't get values from ACPI */
1088 	if (est_fqlist == NULL) {
1089 		if (vendor == CPUVENDOR_VIA)
1090 			cyrix3_get_bus_clock(ci);
1091 		else if (ci->ci_family == 0xf)
1092 			p4_get_bus_clock(ci);
1093 		else if (ci->ci_family == 6)
1094 			p3_get_bus_clock(ci);
1095 	}
1096 
1097 	/*
1098 	 * Interpreting the values of PERF_STATUS is not valid
1099 	 * on recent processors so don't do it on anything unknown
1100 	 */
1101 	if (est_fqlist == NULL && bus_clock != 0) {
1102 		msr = rdmsr(MSR_PERF_STATUS);
1103 		idhi = (msr >> 32) & 0xffff;
1104 		idlo = (msr >> 48) & 0xffff;
1105 		cur = msr & 0xffff;
1106 		crhi = (idhi  >> 8) & 0xff;
1107 		crlo = (idlo  >> 8) & 0xff;
1108 		crcur = (cur >> 8) & 0xff;
1109 		/*
1110 		 * Find an entry which matches (vendor, bus_clock, idhi, idlo)
1111 		 */
1112 		for (i = 0; i < nitems(est_cpus); i++) {
1113 			fql = &est_cpus[i];
1114 			if (vendor == fql->vendor && bus_clock == BUS_CLK(fql)
1115 			    && idhi == fql->table[0].ctrl
1116 			    && idlo == fql->table[fql->n - 1].ctrl) {
1117 				est_fqlist = fql;
1118 				break;
1119 			}
1120 		}
1121 	}
1122 
1123 	if (est_fqlist == NULL && bus_clock != 0) {
1124 		if (crhi == 0 || crcur == 0 || crlo > crhi ||
1125 		    crcur < crlo || crcur > crhi) {
1126 			/*
1127 			 * Do complain about other weirdness, because we first
1128 			 * want to know about it, before we decide what to do
1129 			 * with it.
1130 			 */
1131 			printf("%s: EST: strange msr value 0x%016llx\n",
1132 			    cpu_device, msr);
1133 			return;
1134 		}
1135 		if (crlo == 0 || crhi == crlo) {
1136 			/*
1137 			 * Don't complain about these cases, and silently
1138 			 * disable EST: - A lowest clock ratio of 0, which
1139 			 * seems to happen on all Pentium 4's that report EST.
1140 			 * - An equal highest and lowest clock ratio, which
1141 			 * happens on at least the Core 2 Duo X6800, maybe on
1142 			 * newer models too.
1143 			 */
1144 			return;
1145 		}
1146 
1147 		printf("%s: unknown Enhanced SpeedStep CPU, msr 0x%016llx\n",
1148 		    cpu_device, msr);
1149 		/*
1150 		 * Generate a fake table with the power states we know.
1151 		 */
1152 
1153 		if ((fake_fqlist = malloc(sizeof(struct fqlist), M_DEVBUF,
1154 		    M_NOWAIT)) == NULL) {
1155 			printf("%s: EST: cannot allocate memory for fake "
1156 			    "list\n", cpu_device);
1157 			return;
1158 		}
1159 
1160 
1161 		if ((fake_table = mallocarray(3, sizeof(struct est_op),
1162 		    M_DEVBUF, M_NOWAIT)) == NULL) {
1163 			free(fake_fqlist, M_DEVBUF, sizeof(struct fqlist));
1164 			printf("%s: EST: cannot allocate memory for fake "
1165 			    "table\n", cpu_device);
1166 			return;
1167 		}
1168 		fake_table[0].ctrl = idhi;
1169 		fake_table[0].mhz = MSR2MHZ(idhi, bus_clock);
1170 		if (cur == idhi || cur == idlo) {
1171 			printf("%s: using only highest and lowest power "
1172 			       "states\n", cpu_device);
1173 
1174 			fake_table[0].pct = 51;
1175 
1176 			fake_table[1].ctrl = idlo;
1177 			fake_table[1].mhz = MSR2MHZ(idlo, bus_clock);
1178 			fake_table[1].pct = 0;
1179 			fake_fqlist->n = 2;
1180 		} else {
1181 			printf("%s: using only highest, current and lowest "
1182 			    "power states\n", cpu_device);
1183 
1184 			fake_table[0].pct = 67;
1185 
1186 			fake_table[1].ctrl = cur;
1187 			fake_table[1].mhz = MSR2MHZ(cur, bus_clock);
1188 			fake_table[1].pct = 34;
1189 
1190 			fake_table[2].ctrl = idlo;
1191 			fake_table[2].mhz = MSR2MHZ(idlo, bus_clock);
1192 			fake_table[2].pct = 0;
1193 			fake_fqlist->n = 3;
1194 		}
1195 
1196 		fake_fqlist->vendor = vendor;
1197 		fake_fqlist->table = fake_table;
1198 		est_fqlist = fake_fqlist;
1199 	}
1200 
1201 	if (est_fqlist == NULL)
1202 		return;
1203 
1204 	if (est_fqlist->n < 2)
1205 		goto nospeedstep;
1206 
1207 	low = est_fqlist->table[est_fqlist->n - 1].mhz;
1208 	high = est_fqlist->table[0].mhz;
1209 	if (low == high)
1210 		goto nospeedstep;
1211 
1212 	perflevel = (cpuspeed - low) * 100 / (high - low);
1213 
1214 	printf("%s: Enhanced SpeedStep %d MHz", cpu_device, cpuspeed);
1215 
1216 	/*
1217 	 * OK, tell the user the available frequencies.
1218 	 */
1219 	printf(": speeds: ");
1220 	for (i = 0; i < est_fqlist->n; i++)
1221 		printf("%d%s", est_fqlist->table[i].mhz, i < est_fqlist->n - 1
1222 		    ?  ", " : " MHz\n");
1223 
1224 	cpu_setperf = est_setperf;
1225 	setperf_prio = 3;
1226 
1227 	return;
1228 
1229 nospeedstep:
1230 	/*
1231 	 * While est_fqlist can point into the static est_cpus[],
1232 	 * it can't fail in that case and therefore can't reach here.
1233 	 */
1234 	free(est_fqlist->table, M_DEVBUF, 0);
1235 	free(est_fqlist, M_DEVBUF, sizeof(*est_fqlist));
1236 }
1237 
1238 void
est_setperf(int level)1239 est_setperf(int level)
1240 {
1241 	int i;
1242 	uint64_t msr;
1243 
1244 	if (est_fqlist == NULL)
1245 		return;
1246 
1247 	for (i = 0; i < est_fqlist->n; i++) {
1248 		if (level >= est_fqlist->table[i].pct)
1249 			break;
1250 	}
1251 
1252 	msr = rdmsr(MSR_PERF_CTL);
1253 	msr &= ~0xffffULL;
1254 	msr |= est_fqlist->table[i].ctrl;
1255 
1256 	wrmsr(MSR_PERF_CTL, msr);
1257 	cpuspeed = est_fqlist->table[i].mhz;
1258 }
1259