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