est.c revision 1.10
1/*	$NetBSD: est.c,v 1.10 2009/02/17 12:27:13 jmcneill 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 * Copyright (c) 2004 The NetBSD Foundation, Inc.
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 *    notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 *    notice, this list of conditions and the following disclaimer in the
39 *    documentation and/or other materials provided with the distribution.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
42 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
43 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
45 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
46 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
47 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
48 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
49 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
51 * POSSIBILITY OF SUCH DAMAGE.
52 */
53
54/*
55 * This is a driver for Intel's Enhanced SpeedStep Technology (EST),
56 * as implemented in Pentium M processors.
57 *
58 * Reference documentation:
59 *
60 * - IA-32 Intel Architecture Software Developer's Manual, Volume 3:
61 *   System Programming Guide.
62 *   Section 13.14, Enhanced Intel SpeedStep technology.
63 *   Table B-2, MSRs in Pentium M Processors.
64 *   http://www.intel.com/design/pentium4/manuals/253668.htm
65 *
66 * - Intel Pentium M Processor Datasheet.
67 *   Table 5, Voltage and Current Specifications.
68 *   http://www.intel.com/design/mobile/datashts/252612.htm
69 *
70 * - Intel Pentium M Processor on 90 nm Process with 2-MB L2 Cache Datasheet
71 *   Table 3-4, 3-5, 3-6, Voltage and Current Specifications.
72 *   http://www.intel.com/design/mobile/datashts/302189.htm
73 *
74 * - Linux cpufreq patches, speedstep-centrino.c.
75 *   Encoding of MSR_PERF_CTL and MSR_PERF_STATUS.
76 *   http://www.codemonkey.org.uk/projects/cpufreq/cpufreq-2.4.22-pre6-1.gz
77 *
78 *   ACPI objects: _PCT is MSR location, _PSS is freq/voltage, _PPC is caps.
79 */
80
81/* #define EST_DEBUG */
82
83#include <sys/cdefs.h>
84__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.10 2009/02/17 12:27:13 jmcneill Exp $");
85
86#include <sys/param.h>
87#include <sys/systm.h>
88#include <sys/malloc.h>
89#include <sys/sysctl.h>
90#include <sys/once.h>
91
92#include <x86/cpuvar.h>
93#include <x86/cputypes.h>
94#include <x86/cpu_msr.h>
95
96#include <machine/cpu.h>
97#include <machine/specialreg.h>
98
99#include "opt_est.h"
100#ifdef EST_FREQ_USERWRITE
101#define	EST_TARGET_CTLFLAG	(CTLFLAG_READWRITE | CTLFLAG_ANYWRITE)
102#else
103#define	EST_TARGET_CTLFLAG	CTLFLAG_READWRITE
104#endif
105
106/* Convert MHz and mV into IDs for passing to the MSR. */
107#define ID16(MHz, mV, bus_clk) \
108	((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
109
110/* Possible bus speeds (multiplied by 100 for rounding) */
111enum { BUS100 = 10000, BUS133 = 13333, BUS166 = 16666, BUS200 = 20000 };
112
113/* Ultra Low Voltage Intel Pentium M processor 900 MHz */
114static const uint16_t pm130_900_ulv[] = {
115	ID16( 900, 1004, BUS100),
116	ID16( 800,  988, BUS100),
117	ID16( 600,  844, BUS100),
118};
119
120/* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */
121static const uint16_t pm130_1000_ulv[] = {
122	ID16(1000, 1004, BUS100),
123	ID16( 900,  988, BUS100),
124	ID16( 800,  972, BUS100),
125	ID16( 600,  844, BUS100),
126};
127
128/* Ultra Low Voltage Intel Pentium M processor 1.10 GHz */
129static const uint16_t pm130_1100_ulv[] = {
130	ID16(1100, 1004, BUS100),
131	ID16(1000,  988, BUS100),
132	ID16( 900,  972, BUS100),
133	ID16( 800,  956, BUS100),
134	ID16( 600,  844, BUS100),
135};
136
137/* Low Voltage Intel Pentium M processor 1.10 GHz */
138static const uint16_t pm130_1100_lv[] = {
139	ID16(1100, 1180, BUS100),
140	ID16(1000, 1164, BUS100),
141	ID16( 900, 1100, BUS100),
142	ID16( 800, 1020, BUS100),
143	ID16( 600,  956, BUS100),
144};
145
146/* Low Voltage Intel Pentium M processor 1.20 GHz */
147static const uint16_t pm130_1200_lv[] = {
148	ID16(1200, 1180, BUS100),
149	ID16(1100, 1164, BUS100),
150	ID16(1000, 1100, BUS100),
151	ID16( 900, 1020, BUS100),
152	ID16( 800, 1004, BUS100),
153	ID16( 600,  956, BUS100),
154};
155
156/* Low Voltage Intel Pentium M processor 1.30 GHz */
157static const uint16_t pm130_1300_lv[] = {
158	ID16(1300, 1180, BUS100),
159	ID16(1200, 1164, BUS100),
160	ID16(1100, 1100, BUS100),
161	ID16(1000, 1020, BUS100),
162	ID16( 900, 1004, BUS100),
163	ID16( 800,  988, BUS100),
164	ID16( 600,  956, BUS100),
165};
166
167/* Intel Pentium M processor 1.30 GHz */
168static const uint16_t pm130_1300[] = {
169	ID16(1300, 1388, BUS100),
170	ID16(1200, 1356, BUS100),
171	ID16(1000, 1292, BUS100),
172	ID16( 800, 1260, BUS100),
173	ID16( 600,  956, BUS100),
174};
175
176/* Intel Pentium M processor 1.40 GHz */
177static const uint16_t pm130_1400[] = {
178	ID16(1400, 1484, BUS100),
179	ID16(1200, 1436, BUS100),
180	ID16(1000, 1308, BUS100),
181	ID16( 800, 1180, BUS100),
182	ID16( 600,  956, BUS100),
183};
184
185/* Intel Pentium M processor 1.50 GHz */
186static const uint16_t pm130_1500[] = {
187	ID16(1500, 1484, BUS100),
188	ID16(1400, 1452, BUS100),
189	ID16(1200, 1356, BUS100),
190	ID16(1000, 1228, BUS100),
191	ID16( 800, 1116, BUS100),
192	ID16( 600,  956, BUS100),
193};
194
195/* Intel Pentium M processor 1.60 GHz */
196static const uint16_t pm130_1600[] = {
197	ID16(1600, 1484, BUS100),
198	ID16(1400, 1420, BUS100),
199	ID16(1200, 1276, BUS100),
200	ID16(1000, 1164, BUS100),
201	ID16( 800, 1036, BUS100),
202	ID16( 600,  956, BUS100),
203};
204
205/* Intel Pentium M processor 1.70 GHz */
206static const uint16_t pm130_1700[] = {
207	ID16(1700, 1484, BUS100),
208	ID16(1400, 1308, BUS100),
209	ID16(1200, 1228, BUS100),
210	ID16(1000, 1116, BUS100),
211	ID16( 800, 1004, BUS100),
212	ID16( 600,  956, BUS100),
213};
214
215/* Intel Pentium M processor 723 1.0 GHz */
216static const uint16_t pm90_n723[] = {
217	ID16(1000,  940, BUS100),
218	ID16( 900,  908, BUS100),
219	ID16( 800,  876, BUS100),
220	ID16( 600,  812, BUS100),
221};
222
223/* Intel Pentium M processor 733 1.1 GHz, VID #G */
224static const uint16_t pm90_n733g[] = {
225	ID16(1100,  956, BUS100),
226	ID16(1000,  940, BUS100),
227	ID16( 900,  908, BUS100),
228	ID16( 800,  876, BUS100),
229	ID16( 600,  812, BUS100),
230};
231
232/* Intel Pentium M processor 733 1.1 GHz, VID #H */
233static const uint16_t pm90_n733h[] = {
234	ID16(1100,  940, BUS100),
235	ID16(1000,  924, BUS100),
236	ID16( 900,  892, BUS100),
237	ID16( 800,  876, BUS100),
238	ID16( 600,  812, BUS100),
239};
240
241/* Intel Pentium M processor 733 1.1 GHz, VID #I */
242static const uint16_t pm90_n733i[] = {
243	ID16(1100,  924, BUS100),
244	ID16(1000,  908, BUS100),
245	ID16( 900,  892, BUS100),
246	ID16( 800,  860, BUS100),
247	ID16( 600,  812, BUS100),
248};
249
250/* Intel Pentium M processor 733 1.1 GHz, VID #J */
251static const uint16_t pm90_n733j[] = {
252	ID16(1100,  908, BUS100),
253	ID16(1000,  892, BUS100),
254	ID16( 900,  876, BUS100),
255	ID16( 800,  860, BUS100),
256	ID16( 600,  812, BUS100),
257};
258
259/* Intel Pentium M processor 733 1.1 GHz, VID #K */
260static const uint16_t pm90_n733k[] = {
261	ID16(1100,  892, BUS100),
262	ID16(1000,  876, BUS100),
263	ID16( 900,  860, BUS100),
264	ID16( 800,  844, BUS100),
265	ID16( 600,  812, BUS100),
266};
267
268/* Intel Pentium M processor 733 1.1 GHz, VID #L */
269static const uint16_t pm90_n733l[] = {
270	ID16(1100,  876, BUS100),
271	ID16(1000,  876, BUS100),
272	ID16( 900,  860, BUS100),
273	ID16( 800,  844, BUS100),
274	ID16( 600,  812, BUS100),
275};
276
277/* Intel Pentium M processor 753 1.2 GHz, VID #G */
278static const uint16_t pm90_n753g[] = {
279	ID16(1200,  956, BUS100),
280	ID16(1100,  940, BUS100),
281	ID16(1000,  908, BUS100),
282	ID16( 900,  892, BUS100),
283	ID16( 800,  860, BUS100),
284	ID16( 600,  812, BUS100),
285};
286
287/* Intel Pentium M processor 753 1.2 GHz, VID #H */
288static const uint16_t pm90_n753h[] = {
289	ID16(1200,  940, BUS100),
290	ID16(1100,  924, BUS100),
291	ID16(1000,  908, BUS100),
292	ID16( 900,  876, BUS100),
293	ID16( 800,  860, BUS100),
294	ID16( 600,  812, BUS100),
295};
296
297/* Intel Pentium M processor 753 1.2 GHz, VID #I */
298static const uint16_t pm90_n753i[] = {
299	ID16(1200,  924, BUS100),
300	ID16(1100,  908, BUS100),
301	ID16(1000,  892, BUS100),
302	ID16( 900,  876, BUS100),
303	ID16( 800,  860, BUS100),
304	ID16( 600,  812, BUS100),
305};
306
307/* Intel Pentium M processor 753 1.2 GHz, VID #J */
308static const uint16_t pm90_n753j[] = {
309	ID16(1200,  908, BUS100),
310	ID16(1100,  892, BUS100),
311	ID16(1000,  876, BUS100),
312	ID16( 900,  860, BUS100),
313	ID16( 800,  844, BUS100),
314	ID16( 600,  812, BUS100),
315};
316
317/* Intel Pentium M processor 753 1.2 GHz, VID #K */
318static const uint16_t pm90_n753k[] = {
319	ID16(1200,  892, 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 753 1.2 GHz, VID #L */
328static const uint16_t pm90_n753l[] = {
329	ID16(1200,  876, BUS100),
330	ID16(1100,  876, BUS100),
331	ID16(1000,  860, BUS100),
332	ID16( 900,  844, BUS100),
333	ID16( 800,  844, BUS100),
334	ID16( 600,  812, BUS100),
335};
336
337/* Intel Pentium M processor 773 1.3 GHz, VID #G */
338static const uint16_t pm90_n773g[] = {
339	ID16(1300,  956, BUS100),
340	ID16(1200,  940, BUS100),
341	ID16(1100,  924, BUS100),
342	ID16(1000,  908, BUS100),
343	ID16( 900,  876, BUS100),
344	ID16( 800,  860, BUS100),
345	ID16( 600,  812, BUS100),
346};
347
348/* Intel Pentium M processor 773 1.3 GHz, VID #H */
349static const uint16_t pm90_n773h[] = {
350	ID16(1300,  940, BUS100),
351	ID16(1200,  924, BUS100),
352	ID16(1100,  908, BUS100),
353	ID16(1000,  892, BUS100),
354	ID16( 900,  876, BUS100),
355	ID16( 800,  860, BUS100),
356	ID16( 600,  812, BUS100),
357};
358
359/* Intel Pentium M processor 773 1.3 GHz, VID #I */
360static const uint16_t pm90_n773i[] = {
361	ID16(1300,  924, BUS100),
362	ID16(1200,  908, BUS100),
363	ID16(1100,  892, BUS100),
364	ID16(1000,  876, BUS100),
365	ID16( 900,  860, BUS100),
366	ID16( 800,  844, BUS100),
367	ID16( 600,  812, BUS100),
368};
369
370/* Intel Pentium M processor 773 1.3 GHz, VID #J */
371static const uint16_t pm90_n773j[] = {
372	ID16(1300,  908, BUS100),
373	ID16(1200,  908, BUS100),
374	ID16(1100,  892, BUS100),
375	ID16(1000,  876, BUS100),
376	ID16( 900,  860, BUS100),
377	ID16( 800,  844, BUS100),
378	ID16( 600,  812, BUS100),
379};
380
381/* Intel Pentium M processor 773 1.3 GHz, VID #K */
382static const uint16_t pm90_n773k[] = {
383	ID16(1300,  892, BUS100),
384	ID16(1200,  892, BUS100),
385	ID16(1100,  876, BUS100),
386	ID16(1000,  860, BUS100),
387	ID16( 900,  860, BUS100),
388	ID16( 800,  844, BUS100),
389	ID16( 600,  812, BUS100),
390};
391
392/* Intel Pentium M processor 773 1.3 GHz, VID #L */
393static const uint16_t pm90_n773l[] = {
394	ID16(1300,  876, BUS100),
395	ID16(1200,  876, BUS100),
396	ID16(1100,  860, BUS100),
397	ID16(1000,  860, BUS100),
398	ID16( 900,  844, BUS100),
399	ID16( 800,  844, BUS100),
400	ID16( 600,  812, BUS100),
401};
402
403/* Intel Pentium M processor 738 1.4 GHz */
404static const uint16_t pm90_n738[] = {
405	ID16(1400, 1116, BUS100),
406	ID16(1300, 1116, BUS100),
407	ID16(1200, 1100, BUS100),
408	ID16(1100, 1068, BUS100),
409	ID16(1000, 1052, BUS100),
410	ID16( 900, 1036, BUS100),
411	ID16( 800, 1020, BUS100),
412	ID16( 600,  988, BUS100),
413};
414
415/* Intel Pentium M processor 758 1.5 GHz */
416static const uint16_t pm90_n758[] = {
417	ID16(1500, 1116, BUS100),
418	ID16(1400, 1116, BUS100),
419	ID16(1300, 1100, BUS100),
420	ID16(1200, 1084, BUS100),
421	ID16(1100, 1068, BUS100),
422	ID16(1000, 1052, BUS100),
423	ID16( 900, 1036, BUS100),
424	ID16( 800, 1020, BUS100),
425	ID16( 600,  988, BUS100),
426};
427
428/* Intel Pentium M processor 778 1.6 GHz */
429static const uint16_t pm90_n778[] = {
430	ID16(1600, 1116, BUS100),
431	ID16(1500, 1116, BUS100),
432	ID16(1400, 1100, BUS100),
433	ID16(1300, 1184, BUS100),
434	ID16(1200, 1068, BUS100),
435	ID16(1100, 1052, BUS100),
436	ID16(1000, 1052, BUS100),
437	ID16( 900, 1036, BUS100),
438	ID16( 800, 1020, BUS100),
439	ID16( 600,  988, BUS100),
440};
441
442/* Intel Pentium M processor 710 1.4 GHz, 533 MHz FSB */
443static const uint16_t pm90_n710[] = {
444	ID16(1400, 1340, BUS133),
445	ID16(1200, 1228, BUS133),
446	ID16(1000, 1148, BUS133),
447	ID16( 800, 1068, BUS133),
448	ID16( 600,  998, BUS133),
449};
450
451/* Intel Pentium M processor 715 1.5 GHz, VID #A */
452static const uint16_t pm90_n715a[] = {
453	ID16(1500, 1340, BUS100),
454	ID16(1200, 1228, BUS100),
455	ID16(1000, 1148, BUS100),
456	ID16( 800, 1068, BUS100),
457	ID16( 600,  988, BUS100),
458};
459
460/* Intel Pentium M processor 715 1.5 GHz, VID #B */
461static const uint16_t pm90_n715b[] = {
462	ID16(1500, 1324, BUS100),
463	ID16(1200, 1212, BUS100),
464	ID16(1000, 1148, BUS100),
465	ID16( 800, 1068, BUS100),
466	ID16( 600,  988, BUS100),
467};
468
469/* Intel Pentium M processor 715 1.5 GHz, VID #C */
470static const uint16_t pm90_n715c[] = {
471	ID16(1500, 1308, BUS100),
472	ID16(1200, 1212, BUS100),
473	ID16(1000, 1132, BUS100),
474	ID16( 800, 1068, BUS100),
475	ID16( 600,  988, BUS100),
476};
477
478/* Intel Pentium M processor 715 1.5 GHz, VID #D */
479static const uint16_t pm90_n715d[] = {
480	ID16(1500, 1276, 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 #A */
488static const uint16_t pm90_n725a[] = {
489	ID16(1600, 1340, BUS100),
490	ID16(1400, 1276, BUS100),
491	ID16(1200, 1212, BUS100),
492	ID16(1000, 1132, BUS100),
493	ID16( 800, 1068, BUS100),
494	ID16( 600,  988, BUS100),
495};
496
497/* Intel Pentium M processor 725 1.6 GHz, VID #B */
498static const uint16_t pm90_n725b[] = {
499	ID16(1600, 1324, BUS100),
500	ID16(1400, 1260, BUS100),
501	ID16(1200, 1196, BUS100),
502	ID16(1000, 1132, BUS100),
503	ID16( 800, 1068, BUS100),
504	ID16( 600,  988, BUS100),
505};
506
507/* Intel Pentium M processor 725 1.6 GHz, VID #C */
508static const uint16_t pm90_n725c[] = {
509	ID16(1600, 1308, BUS100),
510	ID16(1400, 1244, BUS100),
511	ID16(1200, 1180, BUS100),
512	ID16(1000, 1116, BUS100),
513	ID16( 800, 1052, BUS100),
514	ID16( 600,  988, BUS100),
515};
516
517/* Intel Pentium M processor 725 1.6 GHz, VID #D */
518static const uint16_t pm90_n725d[] = {
519	ID16(1600, 1276, BUS100),
520	ID16(1400, 1228, BUS100),
521	ID16(1200, 1164, BUS100),
522	ID16(1000, 1116, BUS100),
523	ID16( 800, 1052, BUS100),
524	ID16( 600,  988, BUS100),
525};
526
527/* Intel Pentium M processor 730 1.6 GHz, 533 MHz FSB */
528static const uint16_t pm90_n730[] = {
529       ID16(1600, 1308, BUS133),
530       ID16(1333, 1260, BUS133),
531       ID16(1200, 1212, BUS133),
532       ID16(1067, 1180, BUS133),
533       ID16( 800,  988, BUS133),
534};
535
536/* Intel Pentium M processor 735 1.7 GHz, VID #A */
537static const uint16_t pm90_n735a[] = {
538	ID16(1700, 1340, BUS100),
539	ID16(1400, 1244, BUS100),
540	ID16(1200, 1180, BUS100),
541	ID16(1000, 1116, BUS100),
542	ID16( 800, 1052, BUS100),
543	ID16( 600,  988, BUS100),
544};
545
546/* Intel Pentium M processor 735 1.7 GHz, VID #B */
547static const uint16_t pm90_n735b[] = {
548	ID16(1700, 1324, BUS100),
549	ID16(1400, 1244, BUS100),
550	ID16(1200, 1180, BUS100),
551	ID16(1000, 1116, BUS100),
552	ID16( 800, 1052, BUS100),
553	ID16( 600,  988, BUS100),
554};
555
556/* Intel Pentium M processor 735 1.7 GHz, VID #C */
557static const uint16_t pm90_n735c[] = {
558	ID16(1700, 1308, BUS100),
559	ID16(1400, 1228, BUS100),
560	ID16(1200, 1164, BUS100),
561	ID16(1000, 1116, BUS100),
562	ID16( 800, 1052, BUS100),
563	ID16( 600,  988, BUS100),
564};
565
566/* Intel Pentium M processor 735 1.7 GHz, VID #D */
567static const uint16_t pm90_n735d[] = {
568	ID16(1700, 1276, BUS100),
569	ID16(1400, 1212, BUS100),
570	ID16(1200, 1148, BUS100),
571	ID16(1000, 1100, BUS100),
572	ID16( 800, 1052, BUS100),
573	ID16( 600,  988, BUS100),
574};
575
576/* Intel Pentium M processor 740 1.73 GHz, 533 MHz FSB */
577static const uint16_t pm90_n740[] = {
578       ID16(1733, 1356, BUS133),
579       ID16(1333, 1212, BUS133),
580       ID16(1067, 1100, BUS133),
581       ID16( 800,  988, BUS133),
582};
583
584/* Intel Pentium M processor 745 1.8 GHz, VID #A */
585static const uint16_t pm90_n745a[] = {
586	ID16(1800, 1340, BUS100),
587	ID16(1600, 1292, BUS100),
588	ID16(1400, 1228, BUS100),
589	ID16(1200, 1164, BUS100),
590	ID16(1000, 1116, BUS100),
591	ID16( 800, 1052, BUS100),
592	ID16( 600,  988, BUS100),
593};
594
595/* Intel Pentium M processor 745 1.8 GHz, VID #B */
596static const uint16_t pm90_n745b[] = {
597	ID16(1800, 1324, BUS100),
598	ID16(1600, 1276, BUS100),
599	ID16(1400, 1212, BUS100),
600	ID16(1200, 1164, BUS100),
601	ID16(1000, 1116, BUS100),
602	ID16( 800, 1052, BUS100),
603	ID16( 600,  988, BUS100),
604};
605
606/* Intel Pentium M processor 745 1.8 GHz, VID #C */
607static const uint16_t pm90_n745c[] = {
608	ID16(1800, 1308, BUS100),
609	ID16(1600, 1260, BUS100),
610	ID16(1400, 1212, BUS100),
611	ID16(1200, 1148, BUS100),
612	ID16(1000, 1100, BUS100),
613	ID16( 800, 1052, BUS100),
614	ID16( 600,  988, BUS100),
615};
616
617/* Intel Pentium M processor 745 1.8 GHz, VID #D */
618static const uint16_t pm90_n745d[] = {
619	ID16(1800, 1276, BUS100),
620	ID16(1600, 1228, BUS100),
621	ID16(1400, 1180, BUS100),
622	ID16(1200, 1132, BUS100),
623	ID16(1000, 1084, BUS100),
624	ID16( 800, 1036, BUS100),
625	ID16( 600,  988, BUS100),
626};
627
628/* Intel Pentium M processor 750 1.86 GHz, 533 MHz FSB */
629/* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */
630static const uint16_t pm90_n750[] = {
631	ID16(1867, 1308, BUS133),
632	ID16(1600, 1228, BUS133),
633	ID16(1333, 1148, BUS133),
634	ID16(1067, 1068, BUS133),
635	ID16( 800,  988, BUS133),
636};
637
638/* Intel Pentium M processor 755 2.0 GHz, VID #A */
639static const uint16_t pm90_n755a[] = {
640	ID16(2000, 1340, BUS100),
641	ID16(1800, 1292, BUS100),
642	ID16(1600, 1244, BUS100),
643	ID16(1400, 1196, BUS100),
644	ID16(1200, 1148, BUS100),
645	ID16(1000, 1100, BUS100),
646	ID16( 800, 1052, BUS100),
647	ID16( 600,  988, BUS100),
648};
649
650/* Intel Pentium M processor 755 2.0 GHz, VID #B */
651static const uint16_t pm90_n755b[] = {
652	ID16(2000, 1324, BUS100),
653	ID16(1800, 1276, BUS100),
654	ID16(1600, 1228, BUS100),
655	ID16(1400, 1180, BUS100),
656	ID16(1200, 1132, BUS100),
657	ID16(1000, 1084, BUS100),
658	ID16( 800, 1036, BUS100),
659	ID16( 600,  988, BUS100),
660};
661
662/* Intel Pentium M processor 755 2.0 GHz, VID #C */
663static const uint16_t pm90_n755c[] = {
664	ID16(2000, 1308, BUS100),
665	ID16(1800, 1276, BUS100),
666	ID16(1600, 1228, BUS100),
667	ID16(1400, 1180, BUS100),
668	ID16(1200, 1132, BUS100),
669	ID16(1000, 1084, BUS100),
670	ID16( 800, 1036, BUS100),
671	ID16( 600,  988, BUS100),
672};
673
674/* Intel Pentium M processor 755 2.0 GHz, VID #D */
675static const uint16_t pm90_n755d[] = {
676	ID16(2000, 1276, BUS100),
677	ID16(1800, 1244, BUS100),
678	ID16(1600, 1196, BUS100),
679	ID16(1400, 1164, BUS100),
680	ID16(1200, 1116, BUS100),
681	ID16(1000, 1084, BUS100),
682	ID16( 800, 1036, BUS100),
683	ID16( 600,  988, BUS100),
684};
685
686/* Intel Pentium M processor 760 2.0 GHz, 533 MHz FSB */
687static const uint16_t pm90_n760[] = {
688	ID16(2000, 1356, BUS133),
689	ID16(1600, 1244, BUS133),
690	ID16(1333, 1164, BUS133),
691	ID16(1067, 1084, BUS133),
692	ID16( 800,  988, BUS133),
693};
694
695/* Intel Pentium M processor 765 2.1 GHz, VID #A */
696static const uint16_t pm90_n765a[] = {
697	ID16(2100, 1340, BUS100),
698	ID16(1800, 1276, BUS100),
699	ID16(1600, 1228, BUS100),
700	ID16(1400, 1180, BUS100),
701	ID16(1200, 1132, BUS100),
702	ID16(1000, 1084, BUS100),
703	ID16( 800, 1036, BUS100),
704	ID16( 600,  988, BUS100),
705};
706
707/* Intel Pentium M processor 765 2.1 GHz, VID #B */
708static const uint16_t pm90_n765b[] = {
709	ID16(2100, 1324, BUS100),
710	ID16(1800, 1260, BUS100),
711	ID16(1600, 1212, BUS100),
712	ID16(1400, 1180, BUS100),
713	ID16(1200, 1132, BUS100),
714	ID16(1000, 1084, BUS100),
715	ID16( 800, 1036, BUS100),
716	ID16( 600,  988, BUS100),
717};
718
719/* Intel Pentium M processor 765 2.1 GHz, VID #C */
720static const uint16_t pm90_n765c[] = {
721	ID16(2100, 1308, BUS100),
722	ID16(1800, 1244, BUS100),
723	ID16(1600, 1212, BUS100),
724	ID16(1400, 1164, BUS100),
725	ID16(1200, 1116, BUS100),
726	ID16(1000, 1084, BUS100),
727	ID16( 800, 1036, BUS100),
728	ID16( 600,  988, BUS100),
729};
730
731/* Intel Pentium M processor 765 2.1 GHz, VID #E */
732static const uint16_t pm90_n765e[] = {
733	ID16(2100, 1356, BUS100),
734	ID16(1800, 1292, BUS100),
735	ID16(1600, 1244, BUS100),
736	ID16(1400, 1196, BUS100),
737	ID16(1200, 1148, BUS100),
738	ID16(1000, 1100, BUS100),
739	ID16( 800, 1052, BUS100),
740	ID16( 600,  988, BUS100),
741};
742
743/* Intel Pentium M processor 770 2.13 GHz */
744static const uint16_t pm90_n770[] = {
745	ID16(2133, 1356, BUS133),
746	ID16(1867, 1292, BUS133),
747	ID16(1600, 1212, BUS133),
748	ID16(1333, 1148, BUS133),
749	ID16(1067, 1068, BUS133),
750	ID16( 800,  988, BUS133),
751};
752
753/* Intel Pentium M processor 780 2.26 GHz */
754static const uint16_t pm90_n780[] = {
755	ID16(2267, 1388, BUS133),
756	ID16(1867, 1292, BUS133),
757	ID16(1600, 1212, BUS133),
758	ID16(1333, 1148, BUS133),
759	ID16(1067, 1068, BUS133),
760	ID16( 800,  988, BUS133),
761};
762
763/*
764 * VIA C7-M 500 MHz FSB, 400 MHz FSB, and ULV variants.
765 * Data from the "VIA C7-M Processor BIOS Writer's Guide (v2.17)" datasheet.
766 */
767
768/* 1.00GHz Centaur C7-M ULV */
769static const uint16_t C7M_770_ULV[] = {
770	ID16(1000,  844, BUS100),
771	ID16( 800,  796, BUS100),
772	ID16( 600,  796, BUS100),
773	ID16( 400,  796, BUS100),
774};
775
776/* 1.00GHz Centaur C7-M ULV */
777static const uint16_t C7M_779_ULV[] = {
778	ID16(1000,  796, BUS100),
779	ID16( 800,  796, BUS100),
780	ID16( 600,  796, BUS100),
781	ID16( 400,  796, BUS100),
782};
783
784/* 1.20GHz Centaur C7-M ULV */
785static const uint16_t C7M_772_ULV[] = {
786	ID16(1200,  844, BUS100),
787	ID16(1000,  844, BUS100),
788	ID16( 800,  828, BUS100),
789	ID16( 600,  796, BUS100),
790	ID16( 400,  796, BUS100),
791};
792
793/* 1.50GHz Centaur C7-M ULV */
794static const uint16_t C7M_775_ULV[] = {
795	ID16(1500,  956, BUS100),
796	ID16(1400,  940, BUS100),
797	ID16(1000,  860, BUS100),
798	ID16( 800,  828, BUS100),
799	ID16( 600,  796, BUS100),
800	ID16( 400,  796, BUS100),
801};
802
803/* 1.20GHz Centaur C7-M 400 MHz FSB */
804static const uint16_t C7M_771[] = {
805	ID16(1200,  860, BUS100),
806	ID16(1000,  860, BUS100),
807	ID16( 800,  844, BUS100),
808	ID16( 600,  844, BUS100),
809	ID16( 400,  844, BUS100),
810};
811
812/* 1.50GHz Centaur C7-M 400 MHz FSB */
813static const uint16_t C7M_754[] = {
814	ID16(1500, 1004, BUS100),
815	ID16(1400,  988, BUS100),
816	ID16(1000,  940, BUS100),
817	ID16( 800,  844, BUS100),
818	ID16( 600,  844, BUS100),
819	ID16( 400,  844, BUS100),
820};
821
822/* 1.60GHz Centaur C7-M 400 MHz FSB */
823static const uint16_t C7M_764[] = {
824	ID16(1600, 1084, BUS100),
825	ID16(1400, 1052, BUS100),
826	ID16(1000, 1004, BUS100),
827	ID16( 800,  844, BUS100),
828	ID16( 600,  844, BUS100),
829	ID16( 400,  844, BUS100),
830};
831
832/* 1.80GHz Centaur C7-M 400 MHz FSB */
833static const uint16_t C7M_784[] = {
834	ID16(1800, 1148, BUS100),
835	ID16(1600, 1100, BUS100),
836	ID16(1400, 1052, BUS100),
837	ID16(1000, 1004, BUS100),
838	ID16( 800,  844, BUS100),
839	ID16( 600,  844, BUS100),
840	ID16( 400,  844, BUS100),
841};
842
843/* 2.00GHz Centaur C7-M 400 MHz FSB */
844static const uint16_t C7M_794[] = {
845	ID16(2000, 1148, BUS100),
846	ID16(1800, 1132, BUS100),
847	ID16(1600, 1100, BUS100),
848	ID16(1400, 1052, BUS100),
849	ID16(1000, 1004, BUS100),
850	ID16( 800,  844, BUS100),
851	ID16( 600,  844, BUS100),
852	ID16( 400,  844, BUS100),
853};
854
855/* 1.60GHz Centaur C7-M 533 MHz FSB */
856static const uint16_t C7M_765[] = {
857	ID16(1600, 1084, BUS133),
858	ID16(1467, 1052, BUS133),
859	ID16(1200, 1004, BUS133),
860	ID16( 800,  844, BUS133),
861	ID16( 667,  844, BUS133),
862	ID16( 533,  844, BUS133),
863};
864
865/* 2.00GHz Centaur C7-M 533 MHz FSB */
866static const uint16_t C7M_785[] = {
867	ID16(1867, 1148, BUS133),
868	ID16(1600, 1100, BUS133),
869	ID16(1467, 1052, BUS133),
870	ID16(1200, 1004, BUS133),
871	ID16( 800,  844, BUS133),
872	ID16( 667,  844, BUS133),
873	ID16( 533,  844, BUS133),
874};
875
876/* 2.00GHz Centaur C7-M 533 MHz FSB */
877static const uint16_t C7M_795[] = {
878	ID16(2000, 1148, BUS133),
879	ID16(1867, 1132, BUS133),
880	ID16(1600, 1100, BUS133),
881	ID16(1467, 1052, BUS133),
882	ID16(1200, 1004, BUS133),
883	ID16( 800,  844, BUS133),
884	ID16( 667,  844, BUS133),
885	ID16( 533,  844, BUS133),
886};
887
888/* 1.00GHz VIA Eden 90nm 'Esther' */
889static const uint16_t eden90_1000[] = {
890	ID16(1000,  844, BUS100),
891	ID16( 800,  844, BUS100),
892	ID16( 600,  844, BUS100),
893	ID16( 400,  844, BUS100),
894};
895
896struct fqlist {
897	int vendor;
898	unsigned bus_clk;
899	unsigned n;
900	const uint16_t *table;
901};
902
903#define ENTRY(ven, bus_clk, tab) \
904	{ CPUVENDOR_##ven, bus_clk == BUS133 ? 1 : 0, __arraycount(tab), tab }
905
906#define BUS_CLK(fqp) ((fqp)->bus_clk ? BUS133 : BUS100)
907
908static const struct fqlist est_cpus[] = {
909	ENTRY(INTEL, BUS100, pm130_900_ulv),
910	ENTRY(INTEL, BUS100, pm130_1000_ulv),
911	ENTRY(INTEL, BUS100, pm130_1100_ulv),
912	ENTRY(INTEL, BUS100, pm130_1100_lv),
913	ENTRY(INTEL, BUS100, pm130_1200_lv),
914	ENTRY(INTEL, BUS100, pm130_1300_lv),
915	ENTRY(INTEL, BUS100, pm130_1300),
916	ENTRY(INTEL, BUS100, pm130_1400),
917	ENTRY(INTEL, BUS100, pm130_1500),
918	ENTRY(INTEL, BUS100, pm130_1600),
919	ENTRY(INTEL, BUS100, pm130_1700),
920	ENTRY(INTEL, BUS100, pm90_n723),
921	ENTRY(INTEL, BUS100, pm90_n733g),
922	ENTRY(INTEL, BUS100, pm90_n733h),
923	ENTRY(INTEL, BUS100, pm90_n733i),
924	ENTRY(INTEL, BUS100, pm90_n733j),
925	ENTRY(INTEL, BUS100, pm90_n733k),
926	ENTRY(INTEL, BUS100, pm90_n733l),
927	ENTRY(INTEL, BUS100, pm90_n753g),
928	ENTRY(INTEL, BUS100, pm90_n753h),
929	ENTRY(INTEL, BUS100, pm90_n753i),
930	ENTRY(INTEL, BUS100, pm90_n753j),
931	ENTRY(INTEL, BUS100, pm90_n753k),
932	ENTRY(INTEL, BUS100, pm90_n753l),
933	ENTRY(INTEL, BUS100, pm90_n773g),
934	ENTRY(INTEL, BUS100, pm90_n773h),
935	ENTRY(INTEL, BUS100, pm90_n773i),
936	ENTRY(INTEL, BUS100, pm90_n773j),
937	ENTRY(INTEL, BUS100, pm90_n773k),
938	ENTRY(INTEL, BUS100, pm90_n773l),
939	ENTRY(INTEL, BUS100, pm90_n738),
940	ENTRY(INTEL, BUS100, pm90_n758),
941	ENTRY(INTEL, BUS100, pm90_n778),
942
943	ENTRY(INTEL, BUS133, pm90_n710),
944	ENTRY(INTEL, BUS100, pm90_n715a),
945	ENTRY(INTEL, BUS100, pm90_n715b),
946	ENTRY(INTEL, BUS100, pm90_n715c),
947	ENTRY(INTEL, BUS100, pm90_n715d),
948	ENTRY(INTEL, BUS100, pm90_n725a),
949	ENTRY(INTEL, BUS100, pm90_n725b),
950	ENTRY(INTEL, BUS100, pm90_n725c),
951	ENTRY(INTEL, BUS100, pm90_n725d),
952	ENTRY(INTEL, BUS133, pm90_n730),
953	ENTRY(INTEL, BUS100, pm90_n735a),
954	ENTRY(INTEL, BUS100, pm90_n735b),
955	ENTRY(INTEL, BUS100, pm90_n735c),
956	ENTRY(INTEL, BUS100, pm90_n735d),
957	ENTRY(INTEL, BUS133, pm90_n740),
958	ENTRY(INTEL, BUS100, pm90_n745a),
959	ENTRY(INTEL, BUS100, pm90_n745b),
960	ENTRY(INTEL, BUS100, pm90_n745c),
961	ENTRY(INTEL, BUS100, pm90_n745d),
962	ENTRY(INTEL, BUS133, pm90_n750),
963	ENTRY(INTEL, BUS100, pm90_n755a),
964	ENTRY(INTEL, BUS100, pm90_n755b),
965	ENTRY(INTEL, BUS100, pm90_n755c),
966	ENTRY(INTEL, BUS100, pm90_n755d),
967	ENTRY(INTEL, BUS133, pm90_n760),
968	ENTRY(INTEL, BUS100, pm90_n765a),
969	ENTRY(INTEL, BUS100, pm90_n765b),
970	ENTRY(INTEL, BUS100, pm90_n765c),
971	ENTRY(INTEL, BUS100, pm90_n765e),
972	ENTRY(INTEL, BUS133, pm90_n770),
973	ENTRY(INTEL, BUS133, pm90_n780),
974
975	ENTRY(IDT, BUS100, C7M_770_ULV),
976	ENTRY(IDT, BUS100, C7M_779_ULV),
977	ENTRY(IDT, BUS100, C7M_772_ULV),
978	ENTRY(IDT, BUS100, C7M_771),
979	ENTRY(IDT, BUS100, C7M_775_ULV),
980	ENTRY(IDT, BUS100, C7M_754),
981	ENTRY(IDT, BUS100, C7M_764),
982	ENTRY(IDT, BUS133, C7M_765),
983	ENTRY(IDT, BUS100, C7M_784),
984	ENTRY(IDT, BUS133, C7M_785),
985	ENTRY(IDT, BUS100, C7M_794),
986	ENTRY(IDT, BUS133, C7M_795),
987
988	ENTRY(IDT, BUS100, eden90_1000)
989};
990
991#define MSR2FREQINC(msr)	(((int) (msr) >> 8) & 0xff)
992#define MSR2VOLTINC(msr)	((int) (msr) & 0xff)
993
994#define MSR2MHZ(msr, bus)	((MSR2FREQINC((msr)) * (bus) + 50) / 100)
995#define MSR2MV(msr)		(MSR2VOLTINC(msr) * 16 + 700)
996
997static const struct 	fqlist *est_fqlist;	/* not NULL if functional */
998static uint16_t		*fake_table;		/* guessed est_cpu table */
999static struct fqlist    fake_fqlist;
1000static int 		est_node_target, est_node_current;
1001static const char 	est_desc[] = "Enhanced SpeedStep";
1002static int		lvendor, bus_clock;
1003
1004static int		est_sysctl_helper(SYSCTLFN_PROTO);
1005static int		est_init_once(void);
1006static void		est_init_main(int);
1007
1008static int
1009est_sysctl_helper(SYSCTLFN_ARGS)
1010{
1011	struct msr_cpu_broadcast mcb;
1012	struct sysctlnode	node;
1013	int			fq, oldfq, error;
1014
1015	if (est_fqlist == NULL)
1016		return EOPNOTSUPP;
1017
1018	node = *rnode;
1019	node.sysctl_data = &fq;
1020
1021	oldfq = 0;
1022	if (rnode->sysctl_num == est_node_target)
1023		fq = oldfq = MSR2MHZ(rdmsr(MSR_PERF_CTL), bus_clock);
1024	else if (rnode->sysctl_num == est_node_current)
1025		fq = MSR2MHZ(rdmsr(MSR_PERF_STATUS), bus_clock);
1026	else
1027		return EOPNOTSUPP;
1028
1029	error = sysctl_lookup(SYSCTLFN_CALL(&node));
1030	if (error || newp == NULL)
1031		return error;
1032
1033	/* support writing to ...frequency.target */
1034	if (rnode->sysctl_num == est_node_target && fq != oldfq) {
1035		int		i;
1036
1037		for (i = est_fqlist->n - 1; i > 0; i--)
1038			if (MSR2MHZ(est_fqlist->table[i], bus_clock) >= fq)
1039				break;
1040		fq = MSR2MHZ(est_fqlist->table[i], bus_clock);
1041		mcb.msr_read = true;
1042		mcb.msr_type = MSR_PERF_CTL;
1043		mcb.msr_mask = 0xffffULL;
1044		mcb.msr_value = est_fqlist->table[i];
1045		msr_cpu_broadcast(&mcb);
1046	}
1047
1048	return 0;
1049}
1050
1051static int
1052est_init_once(void)
1053{
1054	est_init_main(lvendor);
1055	return 0;
1056}
1057
1058void
1059est_init(int vendor)
1060{
1061	int error;
1062	static ONCE_DECL(est_initialized);
1063
1064	lvendor = vendor;
1065
1066	error = RUN_ONCE(&est_initialized, est_init_once);
1067	if (__predict_false(error != 0))
1068		return;
1069}
1070
1071static void
1072est_init_main(int vendor)
1073{
1074#ifdef __i386__
1075	const struct fqlist	*fql;
1076#endif
1077	const struct sysctlnode	*node, *estnode, *freqnode;
1078	uint64_t		msr;
1079	uint16_t		cur, idhi, idlo;
1080	uint8_t			crhi, crlo, crcur;
1081	int			i, mv, rc;
1082	size_t			len, freq_len;
1083	char			*freq_names;
1084	const char *cpuname;
1085
1086	cpuname	= device_xname(curcpu()->ci_dev);
1087
1088	if (CPUID2FAMILY(curcpu()->ci_signature) == 15)
1089		bus_clock = p4_get_bus_clock(curcpu());
1090	else if (CPUID2FAMILY(curcpu()->ci_signature) == 6) {
1091		if (vendor == CPUVENDOR_IDT)
1092			bus_clock = via_get_bus_clock(curcpu());
1093		else
1094			bus_clock = p3_get_bus_clock(curcpu());
1095	}
1096
1097	if (bus_clock == 0) {
1098		aprint_debug("%s: unknown system bus clock\n", __func__);
1099		return;
1100	}
1101
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#ifdef __i386__
1111	if (idhi == 0 || idlo == 0 || cur == 0 ||
1112	    ((cur >> 8) & 0xff) < ((idlo >> 8) & 0xff) ||
1113	    ((cur >> 8) & 0xff) > ((idhi >> 8) & 0xff)) {
1114		aprint_debug("%s: strange msr value 0x%016llx\n", __func__, msr);
1115		return;
1116	}
1117#endif
1118
1119#ifdef __amd64__
1120	if (crlo == 0 || crhi == crlo) {
1121		aprint_debug("%s: crlo == 0 || crhi == crlo\n", __func__);
1122		return;
1123	}
1124
1125	if (crhi == 0 || crcur == 0 || crlo > crhi ||
1126	    crcur < crlo || crcur > crhi) {
1127		/*
1128		 * Do complain about other weirdness, because we first want to
1129		 * know about it, before we decide what to do with it
1130		 */
1131		aprint_debug("%s: strange msr value 0x%" PRIu64 "\n",
1132		    __func__, msr);
1133		return;
1134	}
1135#endif
1136
1137	msr = rdmsr(MSR_PERF_STATUS);
1138	mv = MSR2MV(msr);
1139
1140#ifdef __i386__
1141	/*
1142	 * Find an entry which matches (vendor, bus_clock, idhi, idlo)
1143	 */
1144	est_fqlist = NULL;
1145	for (i = 0; i < __arraycount(est_cpus); i++) {
1146		fql = &est_cpus[i];
1147		if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) &&
1148		    idhi == fql->table[0] && idlo == fql->table[fql->n - 1]) {
1149			est_fqlist = fql;
1150			break;
1151		}
1152	}
1153#endif
1154
1155	if (est_fqlist == NULL) {
1156		int j, tablesize, freq, volt;
1157		int minfreq, minvolt, maxfreq, maxvolt, freqinc, voltinc;
1158
1159		/*
1160		 * Some CPUs report the same frequency in idhi and idlo,
1161		 * so do not run est on them.
1162		 */
1163		if (idhi == idlo) {
1164			aprint_debug("%s: idhi == idlo\n", __func__);
1165			return;
1166		}
1167
1168#ifdef EST_DEBUG
1169		printf("%s: bus_clock = %d\n", __func__, bus_clock);
1170		printf("%s: idlo = 0x%x\n", __func__, idlo);
1171		printf("%s: lo  %4d mV, %4d MHz\n", __func__,
1172		    MSR2MV(idlo), MSR2MHZ(idlo, bus_clock));
1173		printf("%s: raw %4d   , %4d    \n", __func__,
1174		    (idlo & 0xff), ((idlo >> 8) & 0xff));
1175		printf("%s: idhi = 0x%x\n", __func__, idhi);
1176		printf("%s: hi  %4d mV, %4d MHz\n", __func__,
1177		    MSR2MV(idhi), MSR2MHZ(idhi, bus_clock));
1178		printf("%s: raw %4d   , %4d    \n", __func__,
1179		    (idhi & 0xff), ((idhi >> 8) & 0xff));
1180		printf("%s: cur  = 0x%x\n", __func__, cur);
1181#endif
1182
1183                /*
1184                 * Generate a fake table with the power states we know,
1185		 * interpolating the voltages and frequencies between the
1186		 * high and low values.  The (milli)voltages are always
1187		 * rounded up when computing the table.
1188                 */
1189		minfreq = MSR2FREQINC(idlo);
1190		maxfreq = MSR2FREQINC(idhi);
1191		minvolt = MSR2VOLTINC(idlo);
1192		maxvolt = MSR2VOLTINC(idhi);
1193		freqinc = maxfreq - minfreq;
1194		voltinc = maxvolt - minvolt;
1195
1196		/* Avoid diving by zero. */
1197		if (freqinc == 0)
1198			return;
1199
1200		if (freqinc < voltinc || voltinc == 0) {
1201			tablesize = maxfreq - minfreq + 1;
1202			if (voltinc != 0)
1203				voltinc = voltinc * 100 / freqinc - 1;
1204			freqinc = 100;
1205		} else {
1206			tablesize = maxvolt - minvolt + 1;
1207			freqinc = freqinc * 100 / voltinc - 1;
1208			voltinc = 100;
1209		}
1210
1211		fake_table = malloc(tablesize * sizeof(uint16_t), M_DEVBUF,
1212		    M_WAITOK);
1213		fake_fqlist.n = tablesize;
1214
1215		/* The frequency/voltage table is highest frequency first */
1216		freq = maxfreq * 100;
1217		volt = maxvolt * 100;
1218		for (j = 0; j < tablesize; j++) {
1219			fake_table[j] = (((freq + 99) / 100) << 8) +
1220			    (volt + 99) / 100;
1221#ifdef EST_DEBUG
1222			printf("%s: fake entry %d: %4d mV, %4d MHz  "
1223			    "MSR*100 mV = %4d freq = %4d\n",
1224			    __func__, j, MSR2MV(fake_table[j]),
1225			    MSR2MHZ(fake_table[j], bus_clock),
1226			    volt, freq);
1227#endif /* EST_DEBUG */
1228			freq -= freqinc;
1229			volt -= voltinc;
1230		}
1231		fake_fqlist.vendor = vendor;
1232		fake_fqlist.table = fake_table;
1233		est_fqlist = &fake_fqlist;
1234	}
1235
1236	/*
1237	 * OK, tell the user the available frequencies.
1238	 */
1239	freq_len = est_fqlist->n * (sizeof("9999 ")-1) + 1;
1240	freq_names = malloc(freq_len, M_SYSCTLDATA, M_WAITOK);
1241	freq_names[0] = '\0';
1242	len = 0;
1243	for (i = 0; i < est_fqlist->n; i++) {
1244		len += snprintf(freq_names + len, freq_len - len, "%d%s",
1245		    MSR2MHZ(est_fqlist->table[i], bus_clock),
1246		    i < est_fqlist->n - 1 ? " " : "");
1247	}
1248
1249	aprint_debug("%s: %s (%d mV) ", cpuname, est_desc, mv);
1250	aprint_debug("%d (MHz): %s\n", MSR2MHZ(msr, bus_clock), freq_names);
1251
1252	/*
1253	 * Setup the sysctl sub-tree machdep.est.*
1254	 */
1255	if ((rc = sysctl_createv(NULL, 0, NULL, &node,
1256	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
1257	    NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0)
1258		goto err;
1259
1260	if ((rc = sysctl_createv(NULL, 0, &node, &estnode,
1261	    0, CTLTYPE_NODE, "est", NULL,
1262	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
1263		goto err;
1264
1265	if ((rc = sysctl_createv(NULL, 0, &estnode, &freqnode,
1266	    0, CTLTYPE_NODE, "frequency", NULL,
1267	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
1268		goto err;
1269
1270	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
1271	    EST_TARGET_CTLFLAG, CTLTYPE_INT, "target", NULL,
1272	    est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
1273		goto err;
1274	est_node_target = node->sysctl_num;
1275
1276	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
1277	    0, CTLTYPE_INT, "current", NULL,
1278	    est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
1279		goto err;
1280	est_node_current = node->sysctl_num;
1281
1282	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
1283	    0, CTLTYPE_STRING, "available", NULL,
1284	    NULL, 0, freq_names, freq_len, CTL_CREATE, CTL_EOL)) != 0)
1285		goto err;
1286
1287	return;
1288
1289 err:
1290	free(freq_names, M_SYSCTLDATA);
1291	aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
1292}
1293