Subject: Re: port-amd64/36633 (Enhanced Speedstep is not enabled for Intel
To: None <port-amd64-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Pierre Pronchery <khorben@defora.org>
List: netbsd-bugs
Date: 07/21/2007 16:10:02
The following reply was made to PR port-amd64/36633; it has been noted by GNATS.

From: Pierre Pronchery <khorben@defora.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-amd64/36633 (Enhanced Speedstep is not enabled for Intel
 EM64T CPUs)
Date: Sat, 21 Jul 2007 18:09:06 +0200

 This is a multi-part message in MIME format.
 --------------080106030401060104070403
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit
 
 xtraeme@netbsd.org wrote:
 > Synopsis: Enhanced Speedstep is not enabled for Intel EM64T CPUs
 > 
 > State-Changed-Why:
 > The code in HEAD is able to work on amd64 for long time now:
 > 
 >         amd64: The Enhanced Speedstep driver is now able to work on EM64T
 >                 CPUs running in 64bit mode. [xtraeme 20070603]
 > 
 > And your patch is incorrect because you are duplicating the same
 > code on amd64. Sorry I do not have plans to apply them for netbsd-4,
 > someone else should create the patch and send the PR...
 
 Here is a new one. It should be better, I actually based it on yours. I
 also took the bits for the VIA CPU. I must admit though that I only
 tested it on the amd64 architecture so far, please test it on i386
 (xen?) before anything.
 
 HTH,
 -- 
 khorben
 
 --------------080106030401060104070403
 Content-Type: text/plain;
  name="est.diff"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="est.diff"
 
 Index: arch/amd64/amd64/identcpu.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/amd64/amd64/identcpu.c,v
 retrieving revision 1.7.2.2
 diff -u -r1.7.2.2 identcpu.c
 --- arch/amd64/amd64/identcpu.c	15 Jun 2007 10:27:36 -0000	1.7.2.2
 +++ arch/amd64/amd64/identcpu.c	21 Jul 2007 15:47:30 -0000
 @@ -38,6 +38,7 @@
  #include <sys/cdefs.h>
  __KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.7.2.2 2007/06/15 10:27:36 liamjfoy Exp $");
  
 +#include "opt_enhanced_speedstep.h"
  #include "opt_powernow_k8.h"
  
  #include <sys/types.h>
 @@ -139,6 +140,17 @@
  
  	x86_print_cacheinfo(ci);
  
 +#ifdef ENHANCED_SPEEDSTEP
 +        if ((vendor == CPUVENDOR_INTEL) &&
 +	    (ci->ci_feature2_flags & CPUID2_EST)) {
 +		if (rdmsr(MSR_MISC_ENABLE) & (1 << 16))
 +		    est_init(CPUVENDOR_INTEL);
 +		else
 +		    aprint_normal("%s: Enhanced SpeedStep disabled by "
 +			"BIOS\n", device_xname(ci->ci_dev));
 +	}
 +#endif
 +
  #ifdef POWERNOW_K8
  	if (CPUID2FAMILY(ci->ci_signature) == 15 &&
  	    (cpu_model[0] == 'A' || cpu_model[0] == 'O') &&
 Index: arch/amd64/include/cpu.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/amd64/include/cpu.h,v
 retrieving revision 1.12.8.1
 diff -u -r1.12.8.1 cpu.h
 --- arch/amd64/include/cpu.h	5 Jun 2007 20:28:11 -0000	1.12.8.1
 +++ arch/amd64/include/cpu.h	21 Jul 2007 15:47:30 -0000
 @@ -302,6 +302,9 @@
  /* powernow_k8.c */
  void k8_powernow_init(void);
  
 +/* est.c */
 +void	est_init(int);
 +
  #endif /* _KERNEL */
  
  #include <machine/psl.h>
 Index: arch/i386/conf/files.i386
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/i386/conf/files.i386,v
 retrieving revision 1.296.2.1
 diff -u -r1.296.2.1 files.i386
 --- arch/i386/conf/files.i386	19 Jun 2007 09:26:31 -0000	1.296.2.1
 +++ arch/i386/conf/files.i386	21 Jul 2007 15:47:43 -0000
 @@ -54,9 +54,6 @@
  defparam opt_beep.h		BEEP_ONHALT_COUNT
  defparam opt_beep.h		BEEP_ONHALT_PITCH BEEP_ONHALT_PERIOD
  
 -# Enhanced SpeedStep
 -defflag			ENHANCED_SPEEDSTEP
 -
  # Multiboot support
  defflag opt_multiboot.h		MULTIBOOT
  obsolete defparam		MULTIBOOT_SYMTAB_SPACE
 @@ -512,10 +509,6 @@
  attach vesatext at vesabios
  file	arch/i386/bios/vesa_text.c	vesatext
  
 -# Enhanced SpeedStep
 -file	arch/i386/i386/est.c		enhanced_speedstep
 -defflag	opt_est.h	EST_FREQ_USERWRITE
 -
  # AMD PowerNow K7
  file   arch/i386/i386/powernow_k7.c	powernow_k7
  
 Index: arch/i386/i386/est.c
 ===================================================================
 RCS file: arch/i386/i386/est.c
 diff -N arch/i386/i386/est.c
 --- arch/i386/i386/est.c	20 Apr 2007 20:31:25 -0000	1.31.2.2
 +++ /dev/null	1 Jan 1970 00:00:00 -0000
 @@ -1,1065 +0,0 @@
 -/*	$NetBSD: est.c,v 1.31.2.2 2007/04/20 20:31:25 bouyer Exp $	*/
 -/*
 - * Copyright (c) 2003 Michael Eriksson.
 - * All rights reserved.
 - *
 - * Redistribution and use in source and binary forms, with or without
 - * modification, are permitted provided that the following conditions
 - * are met:
 - * 1. Redistributions of source code must retain the above copyright
 - *    notice, this list of conditions and the following disclaimer.
 - * 2. Redistributions in binary form must reproduce the above copyright
 - *    notice, this list of conditions and the following disclaimer in the
 - *    documentation and/or other materials provided with the distribution.
 - * 3. The name of the author may not be used to endorse or promote products
 - *    derived from this software without specific prior written permission.
 - *
 - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 - */
 -/*-
 - * Copyright (c) 2004 The NetBSD Foundation, Inc.
 - * All rights reserved.
 - *
 - * Redistribution and use in source and binary forms, with or without
 - * modification, are permitted provided that the following conditions
 - * are met:
 - * 1. Redistributions of source code must retain the above copyright
 - *    notice, this list of conditions and the following disclaimer.
 - * 2. Redistributions in binary form must reproduce the above copyright
 - *    notice, this list of conditions and the following disclaimer in the
 - *    documentation and/or other materials provided with the distribution.
 - * 3. All advertising materials mentioning features or use of this software
 - *    must display the following acknowledgement:
 - *        This product includes software developed by the NetBSD
 - *        Foundation, Inc. and its contributors.
 - * 4. Neither the name of The NetBSD Foundation nor the names of its
 - *    contributors may be used to endorse or promote products derived
 - *    from this software without specific prior written permission.
 - *
 - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 - * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 - * POSSIBILITY OF SUCH DAMAGE.
 - */
 -
 -/*
 - * This is a driver for Intel's Enhanced SpeedStep Technology (EST),
 - * as implemented in Pentium M processors.
 - *
 - * Reference documentation:
 - *
 - * - IA-32 Intel Architecture Software Developer's Manual, Volume 3:
 - *   System Programming Guide.
 - *   Section 13.14, Enhanced Intel SpeedStep technology.
 - *   Table B-2, MSRs in Pentium M Processors.
 - *   http://www.intel.com/design/pentium4/manuals/253668.htm
 - *
 - * - Intel Pentium M Processor Datasheet.
 - *   Table 5, Voltage and Current Specifications.
 - *   http://www.intel.com/design/mobile/datashts/252612.htm
 - *
 - * - Intel Pentium M Processor on 90 nm Process with 2-MB L2 Cache Datasheet
 - *   Table 3-4, 3-5, 3-6, Voltage and Current Specifications.
 - *   http://www.intel.com/design/mobile/datashts/302189.htm
 - *
 - * - Linux cpufreq patches, speedstep-centrino.c.
 - *   Encoding of MSR_PERF_CTL and MSR_PERF_STATUS.
 - *   http://www.codemonkey.org.uk/projects/cpufreq/cpufreq-2.4.22-pre6-1.gz
 - *
 - *   ACPI objects: _PCT is MSR location, _PSS is freq/voltage, _PPC is caps.
 - */
 -
 -#include <sys/cdefs.h>
 -__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.31.2.2 2007/04/20 20:31:25 bouyer Exp $");
 -
 -#include <sys/param.h>
 -#include <sys/systm.h>
 -#include <sys/malloc.h>
 -#include <sys/sysctl.h>
 -#include <sys/once.h>
 -
 -#include <x86/cpu_msr.h>
 -
 -#include <machine/cpu.h>
 -#include <machine/specialreg.h>
 -
 -#include "opt_est.h"
 -#ifdef EST_FREQ_USERWRITE
 -#define	EST_TARGET_CTLFLAG	(CTLFLAG_READWRITE | CTLFLAG_ANYWRITE)
 -#else
 -#define	EST_TARGET_CTLFLAG	CTLFLAG_READWRITE
 -#endif
 -
 -/* Convert MHz and mV into IDs for passing to the MSR. */
 -#define ID16(MHz, mV, bus_clk) \
 -	((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
 -
 -/* Possible bus speeds (multiplied by 100 for rounding) */
 -enum { BUS100 = 10000, BUS133 = 13333, BUS166 = 16666, BUS200 = 20000 };
 -
 -/* Ultra Low Voltage Intel Pentium M processor 900 MHz */
 -static const uint16_t pm130_900_ulv[] = {
 -	ID16( 900, 1004, BUS100),
 -	ID16( 800,  988, BUS100),
 -	ID16( 600,  844, BUS100),
 -};
 -
 -/* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */
 -static const uint16_t pm130_1000_ulv[] = {
 -	ID16(1000, 1004, BUS100),
 -	ID16( 900,  988, BUS100),
 -	ID16( 800,  972, BUS100),
 -	ID16( 600,  844, BUS100),
 -};
 -
 -/* Ultra Low Voltage Intel Pentium M processor 1.10 GHz */
 -static const uint16_t pm130_1100_ulv[] = {
 -	ID16(1100, 1004, BUS100),
 -	ID16(1000,  988, BUS100),
 -	ID16( 900,  972, BUS100),
 -	ID16( 800,  956, BUS100),
 -	ID16( 600,  844, BUS100),
 -};
 -
 -/* Low Voltage Intel Pentium M processor 1.10 GHz */
 -static const uint16_t pm130_1100_lv[] = {
 -	ID16(1100, 1180, BUS100),
 -	ID16(1000, 1164, BUS100),
 -	ID16( 900, 1100, BUS100),
 -	ID16( 800, 1020, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Low Voltage Intel Pentium M processor 1.20 GHz */
 -static const uint16_t pm130_1200_lv[] = {
 -	ID16(1200, 1180, BUS100),
 -	ID16(1100, 1164, BUS100),
 -	ID16(1000, 1100, BUS100),
 -	ID16( 900, 1020, BUS100),
 -	ID16( 800, 1004, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Low Voltage Intel Pentium M processor 1.30 GHz */
 -static const uint16_t pm130_1300_lv[] = {
 -	ID16(1300, 1180, BUS100),
 -	ID16(1200, 1164, BUS100),
 -	ID16(1100, 1100, BUS100),
 -	ID16(1000, 1020, BUS100),
 -	ID16( 900, 1004, BUS100),
 -	ID16( 800,  988, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Intel Pentium M processor 1.30 GHz */
 -static const uint16_t pm130_1300[] = {
 -	ID16(1300, 1388, BUS100),
 -	ID16(1200, 1356, BUS100),
 -	ID16(1000, 1292, BUS100),
 -	ID16( 800, 1260, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Intel Pentium M processor 1.40 GHz */
 -static const uint16_t pm130_1400[] = {
 -	ID16(1400, 1484, BUS100),
 -	ID16(1200, 1436, BUS100),
 -	ID16(1000, 1308, BUS100),
 -	ID16( 800, 1180, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Intel Pentium M processor 1.50 GHz */
 -static const uint16_t pm130_1500[] = {
 -	ID16(1500, 1484, BUS100),
 -	ID16(1400, 1452, BUS100),
 -	ID16(1200, 1356, BUS100),
 -	ID16(1000, 1228, BUS100),
 -	ID16( 800, 1116, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Intel Pentium M processor 1.60 GHz */
 -static const uint16_t pm130_1600[] = {
 -	ID16(1600, 1484, BUS100),
 -	ID16(1400, 1420, BUS100),
 -	ID16(1200, 1276, BUS100),
 -	ID16(1000, 1164, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Intel Pentium M processor 1.70 GHz */
 -static const uint16_t pm130_1700[] = {
 -	ID16(1700, 1484, BUS100),
 -	ID16(1400, 1308, BUS100),
 -	ID16(1200, 1228, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1004, BUS100),
 -	ID16( 600,  956, BUS100),
 -};
 -
 -/* Intel Pentium M processor 723 1.0 GHz */
 -static const uint16_t pm90_n723[] = {
 -	ID16(1000,  940, BUS100),
 -	ID16( 900,  908, BUS100),
 -	ID16( 800,  876, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 733 1.1 GHz, VID #G */
 -static const uint16_t pm90_n733g[] = {
 -	ID16(1100,  956, BUS100),
 -	ID16(1000,  940, BUS100),
 -	ID16( 900,  908, BUS100),
 -	ID16( 800,  876, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 733 1.1 GHz, VID #H */
 -static const uint16_t pm90_n733h[] = {
 -	ID16(1100,  940, BUS100),
 -	ID16(1000,  924, BUS100),
 -	ID16( 900,  892, BUS100),
 -	ID16( 800,  876, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 733 1.1 GHz, VID #I */
 -static const uint16_t pm90_n733i[] = {
 -	ID16(1100,  924, BUS100),
 -	ID16(1000,  908, BUS100),
 -	ID16( 900,  892, BUS100),
 -	ID16( 800,  860, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 733 1.1 GHz, VID #J */
 -static const uint16_t pm90_n733j[] = {
 -	ID16(1100,  908, BUS100),
 -	ID16(1000,  892, BUS100),
 -	ID16( 900,  876, BUS100),
 -	ID16( 800,  860, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 733 1.1 GHz, VID #K */
 -static const uint16_t pm90_n733k[] = {
 -	ID16(1100,  892, BUS100),
 -	ID16(1000,  876, BUS100),
 -	ID16( 900,  860, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 733 1.1 GHz, VID #L */
 -static const uint16_t pm90_n733l[] = {
 -	ID16(1100,  876, BUS100),
 -	ID16(1000,  876, BUS100),
 -	ID16( 900,  860, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 753 1.2 GHz, VID #G */
 -static const uint16_t pm90_n753g[] = {
 -	ID16(1200,  956, BUS100),
 -	ID16(1100,  940, BUS100),
 -	ID16(1000,  908, BUS100),
 -	ID16( 900,  892, BUS100),
 -	ID16( 800,  860, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 753 1.2 GHz, VID #H */
 -static const uint16_t pm90_n753h[] = {
 -	ID16(1200,  940, BUS100),
 -	ID16(1100,  924, BUS100),
 -	ID16(1000,  908, BUS100),
 -	ID16( 900,  876, BUS100),
 -	ID16( 800,  860, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 753 1.2 GHz, VID #I */
 -static const uint16_t pm90_n753i[] = {
 -	ID16(1200,  924, BUS100),
 -	ID16(1100,  908, BUS100),
 -	ID16(1000,  892, BUS100),
 -	ID16( 900,  876, BUS100),
 -	ID16( 800,  860, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 753 1.2 GHz, VID #J */
 -static const uint16_t pm90_n753j[] = {
 -	ID16(1200,  908, BUS100),
 -	ID16(1100,  892, BUS100),
 -	ID16(1000,  876, BUS100),
 -	ID16( 900,  860, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 753 1.2 GHz, VID #K */
 -static const uint16_t pm90_n753k[] = {
 -	ID16(1200,  892, BUS100),
 -	ID16(1100,  892, BUS100),
 -	ID16(1000,  876, BUS100),
 -	ID16( 900,  860, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 753 1.2 GHz, VID #L */
 -static const uint16_t pm90_n753l[] = {
 -	ID16(1200,  876, BUS100),
 -	ID16(1100,  876, BUS100),
 -	ID16(1000,  860, BUS100),
 -	ID16( 900,  844, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 773 1.3 GHz, VID #G */
 -static const uint16_t pm90_n773g[] = {
 -	ID16(1300,  956, BUS100),
 -	ID16(1200,  940, BUS100),
 -	ID16(1100,  924, BUS100),
 -	ID16(1000,  908, BUS100),
 -	ID16( 900,  876, BUS100),
 -	ID16( 800,  860, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 773 1.3 GHz, VID #H */
 -static const uint16_t pm90_n773h[] = {
 -	ID16(1300,  940, BUS100),
 -	ID16(1200,  924, BUS100),
 -	ID16(1100,  908, BUS100),
 -	ID16(1000,  892, BUS100),
 -	ID16( 900,  876, BUS100),
 -	ID16( 800,  860, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 773 1.3 GHz, VID #I */
 -static const uint16_t pm90_n773i[] = {
 -	ID16(1300,  924, BUS100),
 -	ID16(1200,  908, BUS100),
 -	ID16(1100,  892, BUS100),
 -	ID16(1000,  876, BUS100),
 -	ID16( 900,  860, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 773 1.3 GHz, VID #J */
 -static const uint16_t pm90_n773j[] = {
 -	ID16(1300,  908, BUS100),
 -	ID16(1200,  908, BUS100),
 -	ID16(1100,  892, BUS100),
 -	ID16(1000,  876, BUS100),
 -	ID16( 900,  860, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 773 1.3 GHz, VID #K */
 -static const uint16_t pm90_n773k[] = {
 -	ID16(1300,  892, BUS100),
 -	ID16(1200,  892, BUS100),
 -	ID16(1100,  876, BUS100),
 -	ID16(1000,  860, BUS100),
 -	ID16( 900,  860, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 773 1.3 GHz, VID #L */
 -static const uint16_t pm90_n773l[] = {
 -	ID16(1300,  876, BUS100),
 -	ID16(1200,  876, BUS100),
 -	ID16(1100,  860, BUS100),
 -	ID16(1000,  860, BUS100),
 -	ID16( 900,  844, BUS100),
 -	ID16( 800,  844, BUS100),
 -	ID16( 600,  812, BUS100),
 -};
 -
 -/* Intel Pentium M processor 738 1.4 GHz */
 -static const uint16_t pm90_n738[] = {
 -	ID16(1400, 1116, BUS100),
 -	ID16(1300, 1116, BUS100),
 -	ID16(1200, 1100, BUS100),
 -	ID16(1100, 1068, BUS100),
 -	ID16(1000, 1052, BUS100),
 -	ID16( 900, 1036, BUS100),
 -	ID16( 800, 1020, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 758 1.5 GHz */
 -static const uint16_t pm90_n758[] = {
 -	ID16(1500, 1116, BUS100),
 -	ID16(1400, 1116, BUS100),
 -	ID16(1300, 1100, BUS100),
 -	ID16(1200, 1084, BUS100),
 -	ID16(1100, 1068, BUS100),
 -	ID16(1000, 1052, BUS100),
 -	ID16( 900, 1036, BUS100),
 -	ID16( 800, 1020, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 778 1.6 GHz */
 -static const uint16_t pm90_n778[] = {
 -	ID16(1600, 1116, BUS100),
 -	ID16(1500, 1116, BUS100),
 -	ID16(1400, 1100, BUS100),
 -	ID16(1300, 1184, BUS100),
 -	ID16(1200, 1068, BUS100),
 -	ID16(1100, 1052, BUS100),
 -	ID16(1000, 1052, BUS100),
 -	ID16( 900, 1036, BUS100),
 -	ID16( 800, 1020, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 710 1.4 GHz, 533 MHz FSB */
 -static const uint16_t pm90_n710[] = {
 -	ID16(1400, 1340, BUS133),
 -	ID16(1200, 1228, BUS133),
 -	ID16(1000, 1148, BUS133),
 -	ID16( 800, 1068, BUS133),
 -	ID16( 600,  998, BUS133),
 -};
 -
 -/* Intel Pentium M processor 715 1.5 GHz, VID #A */
 -static const uint16_t pm90_n715a[] = {
 -	ID16(1500, 1340, BUS100),
 -	ID16(1200, 1228, BUS100),
 -	ID16(1000, 1148, BUS100),
 -	ID16( 800, 1068, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 715 1.5 GHz, VID #B */
 -static const uint16_t pm90_n715b[] = {
 -	ID16(1500, 1324, BUS100),
 -	ID16(1200, 1212, BUS100),
 -	ID16(1000, 1148, BUS100),
 -	ID16( 800, 1068, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 715 1.5 GHz, VID #C */
 -static const uint16_t pm90_n715c[] = {
 -	ID16(1500, 1308, BUS100),
 -	ID16(1200, 1212, BUS100),
 -	ID16(1000, 1132, BUS100),
 -	ID16( 800, 1068, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 715 1.5 GHz, VID #D */
 -static const uint16_t pm90_n715d[] = {
 -	ID16(1500, 1276, BUS100),
 -	ID16(1200, 1180, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 725 1.6 GHz, VID #A */
 -static const uint16_t pm90_n725a[] = {
 -	ID16(1600, 1340, BUS100),
 -	ID16(1400, 1276, BUS100),
 -	ID16(1200, 1212, BUS100),
 -	ID16(1000, 1132, BUS100),
 -	ID16( 800, 1068, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 725 1.6 GHz, VID #B */
 -static const uint16_t pm90_n725b[] = {
 -	ID16(1600, 1324, BUS100),
 -	ID16(1400, 1260, BUS100),
 -	ID16(1200, 1196, BUS100),
 -	ID16(1000, 1132, BUS100),
 -	ID16( 800, 1068, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 725 1.6 GHz, VID #C */
 -static const uint16_t pm90_n725c[] = {
 -	ID16(1600, 1308, BUS100),
 -	ID16(1400, 1244, BUS100),
 -	ID16(1200, 1180, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 725 1.6 GHz, VID #D */
 -static const uint16_t pm90_n725d[] = {
 -	ID16(1600, 1276, BUS100),
 -	ID16(1400, 1228, BUS100),
 -	ID16(1200, 1164, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 730 1.6 GHz, 533 MHz FSB */
 -static const uint16_t pm90_n730[] = {
 -       ID16(1600, 1308, BUS133),
 -       ID16(1333, 1260, BUS133),
 -       ID16(1200, 1212, BUS133),
 -       ID16(1067, 1180, BUS133),
 -       ID16( 800,  988, BUS133),
 -};
 -
 -/* Intel Pentium M processor 735 1.7 GHz, VID #A */
 -static const uint16_t pm90_n735a[] = {
 -	ID16(1700, 1340, BUS100),
 -	ID16(1400, 1244, BUS100),
 -	ID16(1200, 1180, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 735 1.7 GHz, VID #B */
 -static const uint16_t pm90_n735b[] = {
 -	ID16(1700, 1324, BUS100),
 -	ID16(1400, 1244, BUS100),
 -	ID16(1200, 1180, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 735 1.7 GHz, VID #C */
 -static const uint16_t pm90_n735c[] = {
 -	ID16(1700, 1308, BUS100),
 -	ID16(1400, 1228, BUS100),
 -	ID16(1200, 1164, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 735 1.7 GHz, VID #D */
 -static const uint16_t pm90_n735d[] = {
 -	ID16(1700, 1276, BUS100),
 -	ID16(1400, 1212, BUS100),
 -	ID16(1200, 1148, BUS100),
 -	ID16(1000, 1100, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 740 1.73 GHz, 533 MHz FSB */
 -static const uint16_t pm90_n740[] = {
 -       ID16(1733, 1356, BUS133),
 -       ID16(1333, 1212, BUS133),
 -       ID16(1067, 1100, BUS133),
 -       ID16( 800,  988, BUS133),
 -};
 -
 -/* Intel Pentium M processor 745 1.8 GHz, VID #A */
 -static const uint16_t pm90_n745a[] = {
 -	ID16(1800, 1340, BUS100),
 -	ID16(1600, 1292, BUS100),
 -	ID16(1400, 1228, BUS100),
 -	ID16(1200, 1164, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 745 1.8 GHz, VID #B */
 -static const uint16_t pm90_n745b[] = {
 -	ID16(1800, 1324, BUS100),
 -	ID16(1600, 1276, BUS100),
 -	ID16(1400, 1212, BUS100),
 -	ID16(1200, 1164, BUS100),
 -	ID16(1000, 1116, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 745 1.8 GHz, VID #C */
 -static const uint16_t pm90_n745c[] = {
 -	ID16(1800, 1308, BUS100),
 -	ID16(1600, 1260, BUS100),
 -	ID16(1400, 1212, BUS100),
 -	ID16(1200, 1148, BUS100),
 -	ID16(1000, 1100, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 745 1.8 GHz, VID #D */
 -static const uint16_t pm90_n745d[] = {
 -	ID16(1800, 1276, BUS100),
 -	ID16(1600, 1228, BUS100),
 -	ID16(1400, 1180, BUS100),
 -	ID16(1200, 1132, BUS100),
 -	ID16(1000, 1084, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 750 1.86 GHz, 533 MHz FSB */
 -/* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */
 -static const uint16_t pm90_n750[] = {
 -	ID16(1867, 1308, BUS133),
 -	ID16(1600, 1228, BUS133),
 -	ID16(1333, 1148, BUS133),
 -	ID16(1067, 1068, BUS133),
 -	ID16( 800,  988, BUS133),
 -};
 -
 -/* Intel Pentium M processor 755 2.0 GHz, VID #A */
 -static const uint16_t pm90_n755a[] = {
 -	ID16(2000, 1340, BUS100),
 -	ID16(1800, 1292, BUS100),
 -	ID16(1600, 1244, BUS100),
 -	ID16(1400, 1196, BUS100),
 -	ID16(1200, 1148, BUS100),
 -	ID16(1000, 1100, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 755 2.0 GHz, VID #B */
 -static const uint16_t pm90_n755b[] = {
 -	ID16(2000, 1324, BUS100),
 -	ID16(1800, 1276, BUS100),
 -	ID16(1600, 1228, BUS100),
 -	ID16(1400, 1180, BUS100),
 -	ID16(1200, 1132, BUS100),
 -	ID16(1000, 1084, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 755 2.0 GHz, VID #C */
 -static const uint16_t pm90_n755c[] = {
 -	ID16(2000, 1308, BUS100),
 -	ID16(1800, 1276, BUS100),
 -	ID16(1600, 1228, BUS100),
 -	ID16(1400, 1180, BUS100),
 -	ID16(1200, 1132, BUS100),
 -	ID16(1000, 1084, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 755 2.0 GHz, VID #D */
 -static const uint16_t pm90_n755d[] = {
 -	ID16(2000, 1276, BUS100),
 -	ID16(1800, 1244, BUS100),
 -	ID16(1600, 1196, BUS100),
 -	ID16(1400, 1164, BUS100),
 -	ID16(1200, 1116, BUS100),
 -	ID16(1000, 1084, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 760 2.0 GHz, 533 MHz FSB */
 -static const uint16_t pm90_n760[] = {
 -	ID16(2000, 1356, BUS133),
 -	ID16(1600, 1244, BUS133),
 -	ID16(1333, 1164, BUS133),
 -	ID16(1067, 1084, BUS133),
 -	ID16( 800,  988, BUS133),
 -};
 -
 -/* Intel Pentium M processor 765 2.1 GHz, VID #A */
 -static const uint16_t pm90_n765a[] = {
 -	ID16(2100, 1340, BUS100),
 -	ID16(1800, 1276, BUS100),
 -	ID16(1600, 1228, BUS100),
 -	ID16(1400, 1180, BUS100),
 -	ID16(1200, 1132, BUS100),
 -	ID16(1000, 1084, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 765 2.1 GHz, VID #B */
 -static const uint16_t pm90_n765b[] = {
 -	ID16(2100, 1324, BUS100),
 -	ID16(1800, 1260, BUS100),
 -	ID16(1600, 1212, BUS100),
 -	ID16(1400, 1180, BUS100),
 -	ID16(1200, 1132, BUS100),
 -	ID16(1000, 1084, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 765 2.1 GHz, VID #C */
 -static const uint16_t pm90_n765c[] = {
 -	ID16(2100, 1308, BUS100),
 -	ID16(1800, 1244, BUS100),
 -	ID16(1600, 1212, BUS100),
 -	ID16(1400, 1164, BUS100),
 -	ID16(1200, 1116, BUS100),
 -	ID16(1000, 1084, BUS100),
 -	ID16( 800, 1036, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 765 2.1 GHz, VID #E */
 -static const uint16_t pm90_n765e[] = {
 -	ID16(2100, 1356, BUS100),
 -	ID16(1800, 1292, BUS100),
 -	ID16(1600, 1244, BUS100),
 -	ID16(1400, 1196, BUS100),
 -	ID16(1200, 1148, BUS100),
 -	ID16(1000, 1100, BUS100),
 -	ID16( 800, 1052, BUS100),
 -	ID16( 600,  988, BUS100),
 -};
 -
 -/* Intel Pentium M processor 770 2.13 GHz */
 -static const uint16_t pm90_n770[] = {
 -	ID16(2133, 1356, BUS133),
 -	ID16(1867, 1292, BUS133),
 -	ID16(1600, 1212, BUS133),
 -	ID16(1333, 1148, BUS133),
 -	ID16(1067, 1068, BUS133),
 -	ID16( 800,  988, BUS133),
 -};
 -
 -/* Intel Pentium M processor 780 2.26 GHz */ 
 -static const uint16_t pm90_n780[] = {
 -	ID16(2267, 1388, BUS133),
 -	ID16(1867, 1292, BUS133),
 -	ID16(1600, 1212, BUS133),
 -	ID16(1333, 1148, BUS133),
 -	ID16(1067, 1068, BUS133), 
 -	ID16( 800,  988, BUS133),
 -}; 
 -
 -struct fqlist {
 -	int vendor;
 -	unsigned bus_clk;
 -	unsigned n;
 -	const uint16_t *table;
 -};
 -
 -#define ENTRY(ven, bus_clk, tab) \
 -	{ CPUVENDOR_##ven, bus_clk == BUS133 ? 1 : 0, __arraycount(tab), tab }
 -
 -#define BUS_CLK(fqp) ((fqp)->bus_clk ? BUS133 : BUS100)
 -
 -static const struct fqlist est_cpus[] = {
 -	ENTRY(INTEL, BUS100, pm130_900_ulv),
 -	ENTRY(INTEL, BUS100, pm130_1000_ulv),
 -	ENTRY(INTEL, BUS100, pm130_1100_ulv),
 -	ENTRY(INTEL, BUS100, pm130_1100_lv),
 -	ENTRY(INTEL, BUS100, pm130_1200_lv),
 -	ENTRY(INTEL, BUS100, pm130_1300_lv),
 -	ENTRY(INTEL, BUS100, pm130_1300),
 -	ENTRY(INTEL, BUS100, pm130_1400),
 -	ENTRY(INTEL, BUS100, pm130_1500),
 -	ENTRY(INTEL, BUS100, pm130_1600),
 -	ENTRY(INTEL, BUS100, pm130_1700),
 -	ENTRY(INTEL, BUS100, pm90_n723),
 -	ENTRY(INTEL, BUS100, pm90_n733g),
 -	ENTRY(INTEL, BUS100, pm90_n733h),
 -	ENTRY(INTEL, BUS100, pm90_n733i),
 -	ENTRY(INTEL, BUS100, pm90_n733j),
 -	ENTRY(INTEL, BUS100, pm90_n733k),
 -	ENTRY(INTEL, BUS100, pm90_n733l),
 -	ENTRY(INTEL, BUS100, pm90_n753g),
 -	ENTRY(INTEL, BUS100, pm90_n753h),
 -	ENTRY(INTEL, BUS100, pm90_n753i),
 -	ENTRY(INTEL, BUS100, pm90_n753j),
 -	ENTRY(INTEL, BUS100, pm90_n753k),
 -	ENTRY(INTEL, BUS100, pm90_n753l),
 -	ENTRY(INTEL, BUS100, pm90_n773g),
 -	ENTRY(INTEL, BUS100, pm90_n773h),
 -	ENTRY(INTEL, BUS100, pm90_n773i),
 -	ENTRY(INTEL, BUS100, pm90_n773j),
 -	ENTRY(INTEL, BUS100, pm90_n773k),
 -	ENTRY(INTEL, BUS100, pm90_n773l),
 -	ENTRY(INTEL, BUS100, pm90_n738),
 -	ENTRY(INTEL, BUS100, pm90_n758),
 -	ENTRY(INTEL, BUS100, pm90_n778),
 -
 -	ENTRY(INTEL, BUS133, pm90_n710),
 -	ENTRY(INTEL, BUS100, pm90_n715a),
 -	ENTRY(INTEL, BUS100, pm90_n715b),
 -	ENTRY(INTEL, BUS100, pm90_n715c),
 -	ENTRY(INTEL, BUS100, pm90_n715d),
 -	ENTRY(INTEL, BUS100, pm90_n725a),
 -	ENTRY(INTEL, BUS100, pm90_n725b),
 -	ENTRY(INTEL, BUS100, pm90_n725c),
 -	ENTRY(INTEL, BUS100, pm90_n725d),
 -	ENTRY(INTEL, BUS133, pm90_n730),
 -	ENTRY(INTEL, BUS100, pm90_n735a),
 -	ENTRY(INTEL, BUS100, pm90_n735b),
 -	ENTRY(INTEL, BUS100, pm90_n735c),
 -	ENTRY(INTEL, BUS100, pm90_n735d),
 -	ENTRY(INTEL, BUS133, pm90_n740),
 -	ENTRY(INTEL, BUS100, pm90_n745a),
 -	ENTRY(INTEL, BUS100, pm90_n745b),
 -	ENTRY(INTEL, BUS100, pm90_n745c),
 -	ENTRY(INTEL, BUS100, pm90_n745d),
 -	ENTRY(INTEL, BUS133, pm90_n750),
 -	ENTRY(INTEL, BUS100, pm90_n755a),
 -	ENTRY(INTEL, BUS100, pm90_n755b),
 -	ENTRY(INTEL, BUS100, pm90_n755c),
 -	ENTRY(INTEL, BUS100, pm90_n755d),
 -	ENTRY(INTEL, BUS133, pm90_n760),
 -	ENTRY(INTEL, BUS100, pm90_n765a),
 -	ENTRY(INTEL, BUS100, pm90_n765b),
 -	ENTRY(INTEL, BUS100, pm90_n765c),
 -	ENTRY(INTEL, BUS100, pm90_n765e),
 -	ENTRY(INTEL, BUS133, pm90_n770),
 -	ENTRY(INTEL, BUS133, pm90_n780)
 -};
 -
 -#define MSR2FREQINC(msr)	(((int) (msr) >> 8) & 0xff)
 -#define MSR2VOLTINC(msr)	((int) (msr) & 0xff)
 -
 -#define MSR2MHZ(msr, bus)	((MSR2FREQINC((msr)) * (bus) + 50) / 100)
 -#define MSR2MV(msr)		(MSR2VOLTINC(msr) * 16 + 700)
 -
 -static const struct 	fqlist *est_fqlist; /* not NULL if functional */
 -static uint16_t         fake_table[3];      /* guessed est_cpu table */
 -static struct fqlist    fake_fqlist;
 -static int 		est_node_target, est_node_current;
 -static const char 	est_desc[] = "Enhanced SpeedStep";
 -static int		lvendor;
 -/* bus_clock is assigned in identcpu.c */
 -int bus_clock;
 -
 -static int est_sysctl_helper(SYSCTLFN_PROTO);
 -static int est_init_once(void);
 -static void est_init_main(int);
 -
 -static int
 -est_sysctl_helper(SYSCTLFN_ARGS)
 -{
 -	struct msr_cpu_broadcast mcb;
 -	struct sysctlnode	node;
 -	int			fq, oldfq, error;
 -
 -	if (est_fqlist == NULL)
 -		return EOPNOTSUPP;
 -
 -	node = *rnode;
 -	node.sysctl_data = &fq;
 -
 -	oldfq = 0;
 -	if (rnode->sysctl_num == est_node_target)
 -		fq = oldfq = MSR2MHZ(rdmsr(MSR_PERF_CTL), bus_clock);
 -	else if (rnode->sysctl_num == est_node_current)
 -		fq = MSR2MHZ(rdmsr(MSR_PERF_STATUS), bus_clock);
 -	else
 -		return EOPNOTSUPP;
 -
 -	error = sysctl_lookup(SYSCTLFN_CALL(&node));
 -	if (error || newp == NULL)
 -		return error;
 -
 -	/* support writing to ...frequency.target */
 -	if (rnode->sysctl_num == est_node_target && fq != oldfq) {
 -		int		i;
 -
 -		for (i = est_fqlist->n - 1; i > 0; i--)
 -			if (MSR2MHZ(est_fqlist->table[i], bus_clock) >= fq)
 -				break;
 -		fq = MSR2MHZ(est_fqlist->table[i], bus_clock);
 -		mcb.msr_read = true;
 -		mcb.msr_type = MSR_PERF_CTL;
 -		mcb.msr_mask = 0xffffULL;
 -		mcb.msr_value = est_fqlist->table[i];
 -		msr_cpu_broadcast(&mcb);
 -	}
 -
 -	return 0;
 -}
 -
 -static int
 -est_init_once(void)
 -{
 -	est_init_main(lvendor);
 -	return 0;
 -}
 -
 -void
 -est_init(int vendor)
 -{
 -	int error;
 -	static ONCE_DECL(est_initialized);
 -
 -	error = RUN_ONCE(&est_initialized, est_init_once);
 -	if (__predict_false(error != 0)) {
 -		return;
 -	}
 -}
 -
 -static void
 -est_init_main(int vendor)
 -{
 -	const struct fqlist	*fql;
 -	const struct sysctlnode	*node, *estnode, *freqnode;
 -	uint64_t		msr;
 -	uint16_t		cur, idhi, idlo;
 -	int			i, rc;
 -	int			mv;
 -	size_t			len, freq_len;
 -	char			*freq_names, *cpuname;
 -       
 -	cpuname	= curcpu()->ci_dev->dv_xname;
 -
 -	if (bus_clock == 0) {
 -		aprint_debug("%s: unknown system bus clock\n", __func__);
 -		return;
 -	}
 -
 -	lvendor = vendor;
 -
 -	msr = rdmsr(MSR_PERF_STATUS);
 -	idhi = (msr >> 32) & 0xffff;
 -	idlo = (msr >> 48) & 0xffff;
 -	cur = msr & 0xffff;
 -	if (idhi == 0 || idlo == 0 || cur == 0 ||
 -	    ((cur >> 8) & 0xff) < ((idlo >> 8) & 0xff) ||
 -	    ((cur >> 8) & 0xff) > ((idhi >> 8) & 0xff)) {
 -		aprint_debug("%s: strange msr value 0x%016llx\n", __func__, msr);
 -		return;
 -	}
 -
 -	msr = rdmsr(MSR_PERF_STATUS);
 -	mv = MSR2MV(msr);
 -	aprint_normal("%s: %s (%d mV) ", cpuname, est_desc, mv);
 -	aprint_normal("%d MHz\n", MSR2MHZ(msr, bus_clock));
 -
 -	/*
 -	 * Find an entry which matches (vendor, bus_clock, idhi, idlo)
 -	 */
 -	est_fqlist = NULL;
 -	for (i = 0; i < __arraycount(est_cpus); i++) {
 -		fql = &est_cpus[i];
 -		if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) &&
 -		    idhi == fql->table[0] && idlo == fql->table[fql->n - 1]) {
 -			est_fqlist = fql;
 -			break;
 -		}
 -	}
 -
 -	if (est_fqlist == NULL) {
 -                aprint_normal("%s: unknown Enhanced SpeedStep CPU.\n",
 -                    cpuname);
 -
 -		/*
 -		 * Some CPUs report the same frequency in idhi and idlo,
 -		 * so do not run est on them.
 -		 */
 -		if (idhi == idlo)
 -			return;
 -                /*
 -                 * Generate a fake table with the power states we know.
 -                 */
 -                fake_table[0] = idhi;
 -                if (cur == idhi || cur == idlo) {
 -                        aprint_normal("%s: using only highest and lowest "
 -                            "power states.\n", cpuname);
 -
 -                        fake_table[1] = idlo;
 -                        fake_fqlist.n = 2;
 -                } else {
 -                        aprint_normal("%s: using only highest, current "
 -                            "and lowest power states.\n", cpuname);
 -
 -                        fake_table[1] = cur;
 -                        fake_table[2] = idlo;
 -                        fake_fqlist.n = 3;
 -                }
 -		fake_fqlist.vendor = vendor;
 -		fake_fqlist.table = fake_table;
 -		est_fqlist = &fake_fqlist;
 -	}
 -
 -	/*
 -	 * OK, tell the user the available frequencies.
 -	 */
 -	freq_len = est_fqlist->n * (sizeof("9999 ")-1) + 1;
 -	freq_names = malloc(freq_len, M_SYSCTLDATA, M_WAITOK);
 -	freq_names[0] = '\0';
 -	len = 0;
 -	for (i = 0; i < est_fqlist->n; i++) {
 -		len += snprintf(freq_names + len, freq_len - len, "%d%s",
 -		    MSR2MHZ(est_fqlist->table[i], bus_clock),
 -		    i < est_fqlist->n - 1 ? " " : "");
 -	}
 -	aprint_normal("%s: %s frequencies available (MHz): %s\n",
 -	    cpuname, est_desc, freq_names);
 -
 -	/*
 -	 * Setup the sysctl sub-tree machdep.est.*
 -	 */
 -	if ((rc = sysctl_createv(NULL, 0, NULL, &node,
 -	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
 -	    NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0)
 -		goto err;
 -
 -	if ((rc = sysctl_createv(NULL, 0, &node, &estnode,
 -	    0, CTLTYPE_NODE, "est", NULL,
 -	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 -		goto err;
 -
 -	if ((rc = sysctl_createv(NULL, 0, &estnode, &freqnode,
 -	    0, CTLTYPE_NODE, "frequency", NULL,
 -	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 -		goto err;
 -
 -	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
 -	    EST_TARGET_CTLFLAG, CTLTYPE_INT, "target", NULL,
 -	    est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 -		goto err;
 -	est_node_target = node->sysctl_num;
 -
 -	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
 -	    0, CTLTYPE_INT, "current", NULL,
 -	    est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 -		goto err;
 -	est_node_current = node->sysctl_num;
 -
 -	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
 -	    0, CTLTYPE_STRING, "available", NULL,
 -	    NULL, 0, freq_names, freq_len, CTL_CREATE, CTL_EOL)) != 0)
 -		goto err;
 -
 -	return;
 -
 - err:
 -	free(freq_names, M_SYSCTLDATA);
 -	aprint_normal("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
 -}
 Index: arch/x86/conf/files.x86
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/x86/conf/files.x86,v
 retrieving revision 1.20.2.1
 diff -u -r1.20.2.1 files.x86
 --- arch/x86/conf/files.x86	20 Apr 2007 20:31:26 -0000	1.20.2.1
 +++ arch/x86/conf/files.x86	21 Jul 2007 15:48:00 -0000
 @@ -10,6 +10,10 @@
  defflag opt_pcifixup.h	PCI_ADDR_FIXUP PCI_BUS_FIXUP
  			PCI_INTR_FIXUP PCI_INTR_FIXUP_FORCE
  
 +# Intel Enhanced Speedstep
 +defflag			ENHANCED_SPEEDSTEP
 +defflag opt_est.h	EST_FREQ_USERWRITE
 +
  # AMD Powernow/Cool`n'Quiet Technology
  defflag opt_powernow_k8.h	POWERNOW_K8
  
 @@ -57,6 +61,10 @@
  file	arch/x86/x86/powernow_k8.c	powernow_k8
  file	arch/x86/x86/powernow_common.c	powernow_k8 | powernow_k7
  
 +# Intel Enhanced Speedstep
 +file	arch/x86/x86/est.c              enhanced_speedstep
 +file	arch/x86/x86/intel_busclock.c   enhanced_speedstep
 +
  #IPMI device
  device ipmi : sysmon_envsys, sysmon_wdog
  attach ipmi at ipmibus
 Index: arch/x86/include/cpuvar.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/x86/include/cpuvar.h,v
 retrieving revision 1.5
 diff -u -r1.5 cpuvar.h
 --- arch/x86/include/cpuvar.h	8 Aug 2006 16:34:34 -0000	1.5
 +++ arch/x86/include/cpuvar.h	21 Jul 2007 15:48:01 -0000
 @@ -70,6 +70,9 @@
   * SUCH DAMAGE.
   */
  
 +#ifndef _X86_CPUVAR_H_
 +#define	_X86_CPUVAR_H_
 +
  struct cpu_functions {
  	int (*start)(struct cpu_info *);
  	int (*stop)(struct cpu_info *);
 @@ -94,6 +97,9 @@
  #ifdef _KERNEL
  
  #include "opt_multiprocessor.h"
 +#ifndef XEN
 +#include "opt_enhanced_speedstep.h"
 +#endif
  
  #ifdef MULTIPROCESSOR
  extern u_int32_t cpus_running;
 @@ -107,4 +113,13 @@
  void cpu_init(struct cpu_info *);
  void cpu_init_first(void);
  
 +#ifdef ENHANCED_SPEEDSTEP
 +void	est_init(int);
 +int	via_get_bus_clock(struct cpu_info *);
 +int	p3_get_bus_clock(struct cpu_info *);
 +int	p4_get_bus_clock(struct cpu_info *);
  #endif
 +
 +#endif
 +
 +#endif /* !_X86_CPUVAR_H_ */
 Index: arch/x86/x86/est.c
 ===================================================================
 RCS file: arch/x86/x86/est.c
 diff -N arch/x86/x86/est.c
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ arch/x86/x86/est.c	21 Jul 2007 15:48:02 -0000
 @@ -0,0 +1,1249 @@
 +/*	$NetBSD: est.c,v 1.2 2007/07/01 20:12:35 xtraeme Exp $	*/
 +/*
 + * Copyright (c) 2003 Michael Eriksson.
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. The name of the author may not be used to endorse or promote products
 + *    derived from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +/*-
 + * Copyright (c) 2004 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. All advertising materials mentioning features or use of this software
 + *    must display the following acknowledgement:
 + *        This product includes software developed by the NetBSD
 + *        Foundation, Inc. and its contributors.
 + * 4. Neither the name of The NetBSD Foundation nor the names of its
 + *    contributors may be used to endorse or promote products derived
 + *    from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +/*
 + * This is a driver for Intel's Enhanced SpeedStep Technology (EST),
 + * as implemented in Pentium M processors.
 + *
 + * Reference documentation:
 + *
 + * - IA-32 Intel Architecture Software Developer's Manual, Volume 3:
 + *   System Programming Guide.
 + *   Section 13.14, Enhanced Intel SpeedStep technology.
 + *   Table B-2, MSRs in Pentium M Processors.
 + *   http://www.intel.com/design/pentium4/manuals/253668.htm
 + *
 + * - Intel Pentium M Processor Datasheet.
 + *   Table 5, Voltage and Current Specifications.
 + *   http://www.intel.com/design/mobile/datashts/252612.htm
 + *
 + * - Intel Pentium M Processor on 90 nm Process with 2-MB L2 Cache Datasheet
 + *   Table 3-4, 3-5, 3-6, Voltage and Current Specifications.
 + *   http://www.intel.com/design/mobile/datashts/302189.htm
 + *
 + * - Linux cpufreq patches, speedstep-centrino.c.
 + *   Encoding of MSR_PERF_CTL and MSR_PERF_STATUS.
 + *   http://www.codemonkey.org.uk/projects/cpufreq/cpufreq-2.4.22-pre6-1.gz
 + *
 + *   ACPI objects: _PCT is MSR location, _PSS is freq/voltage, _PPC is caps.
 + */
 +
 +#include <sys/cdefs.h>
 +__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.2 2007/07/01 20:12:35 xtraeme Exp $");
 +
 +#include <sys/param.h>
 +#include <sys/systm.h>
 +#include <sys/malloc.h>
 +#include <sys/sysctl.h>
 +#include <sys/once.h>
 +
 +#include <x86/cpuvar.h>
 +#include <x86/cputypes.h>
 +#include <x86/cpu_msr.h>
 +
 +#include <machine/cpu.h>
 +#include <machine/specialreg.h>
 +
 +#include "opt_est.h"
 +#ifdef EST_FREQ_USERWRITE
 +#define	EST_TARGET_CTLFLAG	(CTLFLAG_READWRITE | CTLFLAG_ANYWRITE)
 +#else
 +#define	EST_TARGET_CTLFLAG	CTLFLAG_READWRITE
 +#endif
 +
 +/* Convert MHz and mV into IDs for passing to the MSR. */
 +#define ID16(MHz, mV, bus_clk) \
 +	((((MHz * 100 + 50) / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4))
 +
 +/* Possible bus speeds (multiplied by 100 for rounding) */
 +enum { BUS100 = 10000, BUS133 = 13333, BUS166 = 16666, BUS200 = 20000 };
 +
 +/* Ultra Low Voltage Intel Pentium M processor 900 MHz */
 +static const uint16_t pm130_900_ulv[] = {
 +	ID16( 900, 1004, BUS100),
 +	ID16( 800,  988, BUS100),
 +	ID16( 600,  844, BUS100),
 +};
 +
 +/* Ultra Low Voltage Intel Pentium M processor 1.00 GHz */
 +static const uint16_t pm130_1000_ulv[] = {
 +	ID16(1000, 1004, BUS100),
 +	ID16( 900,  988, BUS100),
 +	ID16( 800,  972, BUS100),
 +	ID16( 600,  844, BUS100),
 +};
 +
 +/* Ultra Low Voltage Intel Pentium M processor 1.10 GHz */
 +static const uint16_t pm130_1100_ulv[] = {
 +	ID16(1100, 1004, BUS100),
 +	ID16(1000,  988, BUS100),
 +	ID16( 900,  972, BUS100),
 +	ID16( 800,  956, BUS100),
 +	ID16( 600,  844, BUS100),
 +};
 +
 +/* Low Voltage Intel Pentium M processor 1.10 GHz */
 +static const uint16_t pm130_1100_lv[] = {
 +	ID16(1100, 1180, BUS100),
 +	ID16(1000, 1164, BUS100),
 +	ID16( 900, 1100, BUS100),
 +	ID16( 800, 1020, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Low Voltage Intel Pentium M processor 1.20 GHz */
 +static const uint16_t pm130_1200_lv[] = {
 +	ID16(1200, 1180, BUS100),
 +	ID16(1100, 1164, BUS100),
 +	ID16(1000, 1100, BUS100),
 +	ID16( 900, 1020, BUS100),
 +	ID16( 800, 1004, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Low Voltage Intel Pentium M processor 1.30 GHz */
 +static const uint16_t pm130_1300_lv[] = {
 +	ID16(1300, 1180, BUS100),
 +	ID16(1200, 1164, BUS100),
 +	ID16(1100, 1100, BUS100),
 +	ID16(1000, 1020, BUS100),
 +	ID16( 900, 1004, BUS100),
 +	ID16( 800,  988, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Intel Pentium M processor 1.30 GHz */
 +static const uint16_t pm130_1300[] = {
 +	ID16(1300, 1388, BUS100),
 +	ID16(1200, 1356, BUS100),
 +	ID16(1000, 1292, BUS100),
 +	ID16( 800, 1260, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Intel Pentium M processor 1.40 GHz */
 +static const uint16_t pm130_1400[] = {
 +	ID16(1400, 1484, BUS100),
 +	ID16(1200, 1436, BUS100),
 +	ID16(1000, 1308, BUS100),
 +	ID16( 800, 1180, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Intel Pentium M processor 1.50 GHz */
 +static const uint16_t pm130_1500[] = {
 +	ID16(1500, 1484, BUS100),
 +	ID16(1400, 1452, BUS100),
 +	ID16(1200, 1356, BUS100),
 +	ID16(1000, 1228, BUS100),
 +	ID16( 800, 1116, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Intel Pentium M processor 1.60 GHz */
 +static const uint16_t pm130_1600[] = {
 +	ID16(1600, 1484, BUS100),
 +	ID16(1400, 1420, BUS100),
 +	ID16(1200, 1276, BUS100),
 +	ID16(1000, 1164, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Intel Pentium M processor 1.70 GHz */
 +static const uint16_t pm130_1700[] = {
 +	ID16(1700, 1484, BUS100),
 +	ID16(1400, 1308, BUS100),
 +	ID16(1200, 1228, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1004, BUS100),
 +	ID16( 600,  956, BUS100),
 +};
 +
 +/* Intel Pentium M processor 723 1.0 GHz */
 +static const uint16_t pm90_n723[] = {
 +	ID16(1000,  940, BUS100),
 +	ID16( 900,  908, BUS100),
 +	ID16( 800,  876, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 733 1.1 GHz, VID #G */
 +static const uint16_t pm90_n733g[] = {
 +	ID16(1100,  956, BUS100),
 +	ID16(1000,  940, BUS100),
 +	ID16( 900,  908, BUS100),
 +	ID16( 800,  876, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 733 1.1 GHz, VID #H */
 +static const uint16_t pm90_n733h[] = {
 +	ID16(1100,  940, BUS100),
 +	ID16(1000,  924, BUS100),
 +	ID16( 900,  892, BUS100),
 +	ID16( 800,  876, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 733 1.1 GHz, VID #I */
 +static const uint16_t pm90_n733i[] = {
 +	ID16(1100,  924, BUS100),
 +	ID16(1000,  908, BUS100),
 +	ID16( 900,  892, BUS100),
 +	ID16( 800,  860, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 733 1.1 GHz, VID #J */
 +static const uint16_t pm90_n733j[] = {
 +	ID16(1100,  908, BUS100),
 +	ID16(1000,  892, BUS100),
 +	ID16( 900,  876, BUS100),
 +	ID16( 800,  860, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 733 1.1 GHz, VID #K */
 +static const uint16_t pm90_n733k[] = {
 +	ID16(1100,  892, BUS100),
 +	ID16(1000,  876, BUS100),
 +	ID16( 900,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 733 1.1 GHz, VID #L */
 +static const uint16_t pm90_n733l[] = {
 +	ID16(1100,  876, BUS100),
 +	ID16(1000,  876, BUS100),
 +	ID16( 900,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 753 1.2 GHz, VID #G */
 +static const uint16_t pm90_n753g[] = {
 +	ID16(1200,  956, BUS100),
 +	ID16(1100,  940, BUS100),
 +	ID16(1000,  908, BUS100),
 +	ID16( 900,  892, BUS100),
 +	ID16( 800,  860, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 753 1.2 GHz, VID #H */
 +static const uint16_t pm90_n753h[] = {
 +	ID16(1200,  940, BUS100),
 +	ID16(1100,  924, BUS100),
 +	ID16(1000,  908, BUS100),
 +	ID16( 900,  876, BUS100),
 +	ID16( 800,  860, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 753 1.2 GHz, VID #I */
 +static const uint16_t pm90_n753i[] = {
 +	ID16(1200,  924, BUS100),
 +	ID16(1100,  908, BUS100),
 +	ID16(1000,  892, BUS100),
 +	ID16( 900,  876, BUS100),
 +	ID16( 800,  860, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 753 1.2 GHz, VID #J */
 +static const uint16_t pm90_n753j[] = {
 +	ID16(1200,  908, BUS100),
 +	ID16(1100,  892, BUS100),
 +	ID16(1000,  876, BUS100),
 +	ID16( 900,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 753 1.2 GHz, VID #K */
 +static const uint16_t pm90_n753k[] = {
 +	ID16(1200,  892, BUS100),
 +	ID16(1100,  892, BUS100),
 +	ID16(1000,  876, BUS100),
 +	ID16( 900,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 753 1.2 GHz, VID #L */
 +static const uint16_t pm90_n753l[] = {
 +	ID16(1200,  876, BUS100),
 +	ID16(1100,  876, BUS100),
 +	ID16(1000,  860, BUS100),
 +	ID16( 900,  844, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 773 1.3 GHz, VID #G */
 +static const uint16_t pm90_n773g[] = {
 +	ID16(1300,  956, BUS100),
 +	ID16(1200,  940, BUS100),
 +	ID16(1100,  924, BUS100),
 +	ID16(1000,  908, BUS100),
 +	ID16( 900,  876, BUS100),
 +	ID16( 800,  860, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 773 1.3 GHz, VID #H */
 +static const uint16_t pm90_n773h[] = {
 +	ID16(1300,  940, BUS100),
 +	ID16(1200,  924, BUS100),
 +	ID16(1100,  908, BUS100),
 +	ID16(1000,  892, BUS100),
 +	ID16( 900,  876, BUS100),
 +	ID16( 800,  860, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 773 1.3 GHz, VID #I */
 +static const uint16_t pm90_n773i[] = {
 +	ID16(1300,  924, BUS100),
 +	ID16(1200,  908, BUS100),
 +	ID16(1100,  892, BUS100),
 +	ID16(1000,  876, BUS100),
 +	ID16( 900,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 773 1.3 GHz, VID #J */
 +static const uint16_t pm90_n773j[] = {
 +	ID16(1300,  908, BUS100),
 +	ID16(1200,  908, BUS100),
 +	ID16(1100,  892, BUS100),
 +	ID16(1000,  876, BUS100),
 +	ID16( 900,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 773 1.3 GHz, VID #K */
 +static const uint16_t pm90_n773k[] = {
 +	ID16(1300,  892, BUS100),
 +	ID16(1200,  892, BUS100),
 +	ID16(1100,  876, BUS100),
 +	ID16(1000,  860, BUS100),
 +	ID16( 900,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 773 1.3 GHz, VID #L */
 +static const uint16_t pm90_n773l[] = {
 +	ID16(1300,  876, BUS100),
 +	ID16(1200,  876, BUS100),
 +	ID16(1100,  860, BUS100),
 +	ID16(1000,  860, BUS100),
 +	ID16( 900,  844, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  812, BUS100),
 +};
 +
 +/* Intel Pentium M processor 738 1.4 GHz */
 +static const uint16_t pm90_n738[] = {
 +	ID16(1400, 1116, BUS100),
 +	ID16(1300, 1116, BUS100),
 +	ID16(1200, 1100, BUS100),
 +	ID16(1100, 1068, BUS100),
 +	ID16(1000, 1052, BUS100),
 +	ID16( 900, 1036, BUS100),
 +	ID16( 800, 1020, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 758 1.5 GHz */
 +static const uint16_t pm90_n758[] = {
 +	ID16(1500, 1116, BUS100),
 +	ID16(1400, 1116, BUS100),
 +	ID16(1300, 1100, BUS100),
 +	ID16(1200, 1084, BUS100),
 +	ID16(1100, 1068, BUS100),
 +	ID16(1000, 1052, BUS100),
 +	ID16( 900, 1036, BUS100),
 +	ID16( 800, 1020, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 778 1.6 GHz */
 +static const uint16_t pm90_n778[] = {
 +	ID16(1600, 1116, BUS100),
 +	ID16(1500, 1116, BUS100),
 +	ID16(1400, 1100, BUS100),
 +	ID16(1300, 1184, BUS100),
 +	ID16(1200, 1068, BUS100),
 +	ID16(1100, 1052, BUS100),
 +	ID16(1000, 1052, BUS100),
 +	ID16( 900, 1036, BUS100),
 +	ID16( 800, 1020, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 710 1.4 GHz, 533 MHz FSB */
 +static const uint16_t pm90_n710[] = {
 +	ID16(1400, 1340, BUS133),
 +	ID16(1200, 1228, BUS133),
 +	ID16(1000, 1148, BUS133),
 +	ID16( 800, 1068, BUS133),
 +	ID16( 600,  998, BUS133),
 +};
 +
 +/* Intel Pentium M processor 715 1.5 GHz, VID #A */
 +static const uint16_t pm90_n715a[] = {
 +	ID16(1500, 1340, BUS100),
 +	ID16(1200, 1228, BUS100),
 +	ID16(1000, 1148, BUS100),
 +	ID16( 800, 1068, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 715 1.5 GHz, VID #B */
 +static const uint16_t pm90_n715b[] = {
 +	ID16(1500, 1324, BUS100),
 +	ID16(1200, 1212, BUS100),
 +	ID16(1000, 1148, BUS100),
 +	ID16( 800, 1068, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 715 1.5 GHz, VID #C */
 +static const uint16_t pm90_n715c[] = {
 +	ID16(1500, 1308, BUS100),
 +	ID16(1200, 1212, BUS100),
 +	ID16(1000, 1132, BUS100),
 +	ID16( 800, 1068, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 715 1.5 GHz, VID #D */
 +static const uint16_t pm90_n715d[] = {
 +	ID16(1500, 1276, BUS100),
 +	ID16(1200, 1180, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 725 1.6 GHz, VID #A */
 +static const uint16_t pm90_n725a[] = {
 +	ID16(1600, 1340, BUS100),
 +	ID16(1400, 1276, BUS100),
 +	ID16(1200, 1212, BUS100),
 +	ID16(1000, 1132, BUS100),
 +	ID16( 800, 1068, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 725 1.6 GHz, VID #B */
 +static const uint16_t pm90_n725b[] = {
 +	ID16(1600, 1324, BUS100),
 +	ID16(1400, 1260, BUS100),
 +	ID16(1200, 1196, BUS100),
 +	ID16(1000, 1132, BUS100),
 +	ID16( 800, 1068, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 725 1.6 GHz, VID #C */
 +static const uint16_t pm90_n725c[] = {
 +	ID16(1600, 1308, BUS100),
 +	ID16(1400, 1244, BUS100),
 +	ID16(1200, 1180, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 725 1.6 GHz, VID #D */
 +static const uint16_t pm90_n725d[] = {
 +	ID16(1600, 1276, BUS100),
 +	ID16(1400, 1228, BUS100),
 +	ID16(1200, 1164, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 730 1.6 GHz, 533 MHz FSB */
 +static const uint16_t pm90_n730[] = {
 +       ID16(1600, 1308, BUS133),
 +       ID16(1333, 1260, BUS133),
 +       ID16(1200, 1212, BUS133),
 +       ID16(1067, 1180, BUS133),
 +       ID16( 800,  988, BUS133),
 +};
 +
 +/* Intel Pentium M processor 735 1.7 GHz, VID #A */
 +static const uint16_t pm90_n735a[] = {
 +	ID16(1700, 1340, BUS100),
 +	ID16(1400, 1244, BUS100),
 +	ID16(1200, 1180, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 735 1.7 GHz, VID #B */
 +static const uint16_t pm90_n735b[] = {
 +	ID16(1700, 1324, BUS100),
 +	ID16(1400, 1244, BUS100),
 +	ID16(1200, 1180, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 735 1.7 GHz, VID #C */
 +static const uint16_t pm90_n735c[] = {
 +	ID16(1700, 1308, BUS100),
 +	ID16(1400, 1228, BUS100),
 +	ID16(1200, 1164, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 735 1.7 GHz, VID #D */
 +static const uint16_t pm90_n735d[] = {
 +	ID16(1700, 1276, BUS100),
 +	ID16(1400, 1212, BUS100),
 +	ID16(1200, 1148, BUS100),
 +	ID16(1000, 1100, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 740 1.73 GHz, 533 MHz FSB */
 +static const uint16_t pm90_n740[] = {
 +       ID16(1733, 1356, BUS133),
 +       ID16(1333, 1212, BUS133),
 +       ID16(1067, 1100, BUS133),
 +       ID16( 800,  988, BUS133),
 +};
 +
 +/* Intel Pentium M processor 745 1.8 GHz, VID #A */
 +static const uint16_t pm90_n745a[] = {
 +	ID16(1800, 1340, BUS100),
 +	ID16(1600, 1292, BUS100),
 +	ID16(1400, 1228, BUS100),
 +	ID16(1200, 1164, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 745 1.8 GHz, VID #B */
 +static const uint16_t pm90_n745b[] = {
 +	ID16(1800, 1324, BUS100),
 +	ID16(1600, 1276, BUS100),
 +	ID16(1400, 1212, BUS100),
 +	ID16(1200, 1164, BUS100),
 +	ID16(1000, 1116, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 745 1.8 GHz, VID #C */
 +static const uint16_t pm90_n745c[] = {
 +	ID16(1800, 1308, BUS100),
 +	ID16(1600, 1260, BUS100),
 +	ID16(1400, 1212, BUS100),
 +	ID16(1200, 1148, BUS100),
 +	ID16(1000, 1100, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 745 1.8 GHz, VID #D */
 +static const uint16_t pm90_n745d[] = {
 +	ID16(1800, 1276, BUS100),
 +	ID16(1600, 1228, BUS100),
 +	ID16(1400, 1180, BUS100),
 +	ID16(1200, 1132, BUS100),
 +	ID16(1000, 1084, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 750 1.86 GHz, 533 MHz FSB */
 +/* values extracted from \_PR\NPSS (via _PSS) SDST ACPI table */
 +static const uint16_t pm90_n750[] = {
 +	ID16(1867, 1308, BUS133),
 +	ID16(1600, 1228, BUS133),
 +	ID16(1333, 1148, BUS133),
 +	ID16(1067, 1068, BUS133),
 +	ID16( 800,  988, BUS133),
 +};
 +
 +/* Intel Pentium M processor 755 2.0 GHz, VID #A */
 +static const uint16_t pm90_n755a[] = {
 +	ID16(2000, 1340, BUS100),
 +	ID16(1800, 1292, BUS100),
 +	ID16(1600, 1244, BUS100),
 +	ID16(1400, 1196, BUS100),
 +	ID16(1200, 1148, BUS100),
 +	ID16(1000, 1100, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 755 2.0 GHz, VID #B */
 +static const uint16_t pm90_n755b[] = {
 +	ID16(2000, 1324, BUS100),
 +	ID16(1800, 1276, BUS100),
 +	ID16(1600, 1228, BUS100),
 +	ID16(1400, 1180, BUS100),
 +	ID16(1200, 1132, BUS100),
 +	ID16(1000, 1084, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 755 2.0 GHz, VID #C */
 +static const uint16_t pm90_n755c[] = {
 +	ID16(2000, 1308, BUS100),
 +	ID16(1800, 1276, BUS100),
 +	ID16(1600, 1228, BUS100),
 +	ID16(1400, 1180, BUS100),
 +	ID16(1200, 1132, BUS100),
 +	ID16(1000, 1084, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 755 2.0 GHz, VID #D */
 +static const uint16_t pm90_n755d[] = {
 +	ID16(2000, 1276, BUS100),
 +	ID16(1800, 1244, BUS100),
 +	ID16(1600, 1196, BUS100),
 +	ID16(1400, 1164, BUS100),
 +	ID16(1200, 1116, BUS100),
 +	ID16(1000, 1084, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 760 2.0 GHz, 533 MHz FSB */
 +static const uint16_t pm90_n760[] = {
 +	ID16(2000, 1356, BUS133),
 +	ID16(1600, 1244, BUS133),
 +	ID16(1333, 1164, BUS133),
 +	ID16(1067, 1084, BUS133),
 +	ID16( 800,  988, BUS133),
 +};
 +
 +/* Intel Pentium M processor 765 2.1 GHz, VID #A */
 +static const uint16_t pm90_n765a[] = {
 +	ID16(2100, 1340, BUS100),
 +	ID16(1800, 1276, BUS100),
 +	ID16(1600, 1228, BUS100),
 +	ID16(1400, 1180, BUS100),
 +	ID16(1200, 1132, BUS100),
 +	ID16(1000, 1084, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 765 2.1 GHz, VID #B */
 +static const uint16_t pm90_n765b[] = {
 +	ID16(2100, 1324, BUS100),
 +	ID16(1800, 1260, BUS100),
 +	ID16(1600, 1212, BUS100),
 +	ID16(1400, 1180, BUS100),
 +	ID16(1200, 1132, BUS100),
 +	ID16(1000, 1084, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 765 2.1 GHz, VID #C */
 +static const uint16_t pm90_n765c[] = {
 +	ID16(2100, 1308, BUS100),
 +	ID16(1800, 1244, BUS100),
 +	ID16(1600, 1212, BUS100),
 +	ID16(1400, 1164, BUS100),
 +	ID16(1200, 1116, BUS100),
 +	ID16(1000, 1084, BUS100),
 +	ID16( 800, 1036, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 765 2.1 GHz, VID #E */
 +static const uint16_t pm90_n765e[] = {
 +	ID16(2100, 1356, BUS100),
 +	ID16(1800, 1292, BUS100),
 +	ID16(1600, 1244, BUS100),
 +	ID16(1400, 1196, BUS100),
 +	ID16(1200, 1148, BUS100),
 +	ID16(1000, 1100, BUS100),
 +	ID16( 800, 1052, BUS100),
 +	ID16( 600,  988, BUS100),
 +};
 +
 +/* Intel Pentium M processor 770 2.13 GHz */
 +static const uint16_t pm90_n770[] = {
 +	ID16(2133, 1356, BUS133),
 +	ID16(1867, 1292, BUS133),
 +	ID16(1600, 1212, BUS133),
 +	ID16(1333, 1148, BUS133),
 +	ID16(1067, 1068, BUS133),
 +	ID16( 800,  988, BUS133),
 +};
 +
 +/* Intel Pentium M processor 780 2.26 GHz */ 
 +static const uint16_t pm90_n780[] = {
 +	ID16(2267, 1388, BUS133),
 +	ID16(1867, 1292, BUS133),
 +	ID16(1600, 1212, BUS133),
 +	ID16(1333, 1148, BUS133),
 +	ID16(1067, 1068, BUS133), 
 +	ID16( 800,  988, BUS133),
 +}; 
 +
 +/*
 + * VIA C7-M 500 MHz FSB, 400 MHz FSB, and ULV variants.
 + * Data from the "VIA C7-M Processor BIOS Writer's Guide (v2.17)" datasheet.
 + */
 +
 +/* 1.00GHz Centaur C7-M ULV */
 +static const uint16_t C7M_770_ULV[] = {
 +	ID16(1000,  844, BUS100),
 +	ID16( 800,  796, BUS100),
 +	ID16( 600,  796, BUS100),
 +	ID16( 400,  796, BUS100),
 +};
 +
 +/* 1.00GHz Centaur C7-M ULV */
 +static const uint16_t C7M_779_ULV[] = {
 +	ID16(1000,  796, BUS100),
 +	ID16( 800,  796, BUS100),
 +	ID16( 600,  796, BUS100),
 +	ID16( 400,  796, BUS100),
 +};
 +
 +/* 1.20GHz Centaur C7-M ULV */
 +static const uint16_t C7M_772_ULV[] = {
 +	ID16(1200,  844, BUS100),
 +	ID16(1000,  844, BUS100),
 +	ID16( 800,  828, BUS100),
 +	ID16( 600,  796, BUS100),
 +	ID16( 400,  796, BUS100),
 +};
 +
 +/* 1.50GHz Centaur C7-M ULV */
 +static const uint16_t C7M_775_ULV[] = {
 +	ID16(1500,  956, BUS100),
 +	ID16(1400,  940, BUS100),
 +	ID16(1000,  860, BUS100),
 +	ID16( 800,  828, BUS100),
 +	ID16( 600,  796, BUS100),
 +	ID16( 400,  796, BUS100),
 +};
 +
 +/* 1.20GHz Centaur C7-M 400 MHz FSB */
 +static const uint16_t C7M_771[] = {
 +	ID16(1200,  860, BUS100),
 +	ID16(1000,  860, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  844, BUS100),
 +	ID16( 400,  844, BUS100),
 +};
 +
 +/* 1.50GHz Centaur C7-M 400 MHz FSB */
 +static const u_int16_t C7M_754[] = {
 +	ID16(1500, 1004, BUS100),
 +	ID16(1400,  988, BUS100),
 +	ID16(1000,  940, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  844, BUS100),
 +	ID16( 400,  844, BUS100),
 +};
 +
 +/* 1.60GHz Centaur C7-M 400 MHz FSB */
 +static const uint16_t C7M_764[] = {
 +	ID16(1600, 1084, BUS100),
 +	ID16(1400, 1052, BUS100),
 +	ID16(1000, 1004, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  844, BUS100),
 +	ID16( 400,  844, BUS100),
 +};
 +
 +/* 1.80GHz Centaur C7-M 400 MHz FSB */
 +static const uint16_t C7M_784[] = {
 +	ID16(1800, 1148, BUS100),
 +	ID16(1600, 1100, BUS100),
 +	ID16(1400, 1052, BUS100),
 +	ID16(1000, 1004, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  844, BUS100),
 +	ID16( 400,  844, BUS100),
 +};
 +
 +/* 2.00GHz Centaur C7-M 400 MHz FSB */
 +static const uint16_t C7M_794[] = {
 +	ID16(2000, 1148, BUS100),
 +	ID16(1800, 1132, BUS100),
 +	ID16(1600, 1100, BUS100),
 +	ID16(1400, 1052, BUS100),
 +	ID16(1000, 1004, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  844, BUS100),
 +	ID16( 400,  844, BUS100),
 +};
 +
 +/* 1.60GHz Centaur C7-M 533 MHz FSB */
 +static const uint16_t C7M_765[] = {
 +	ID16(1600, 1084, BUS133),
 +	ID16(1467, 1052, BUS133),
 +	ID16(1200, 1004, BUS133),
 +	ID16( 800,  844, BUS133),
 +	ID16( 667,  844, BUS133),
 +	ID16( 533,  844, BUS133),
 +};
 +
 +/* 2.00GHz Centaur C7-M 533 MHz FSB */
 +static const uint16_t C7M_785[] = {
 +	ID16(1867, 1148, BUS133),
 +	ID16(1600, 1100, BUS133),
 +	ID16(1467, 1052, BUS133),
 +	ID16(1200, 1004, BUS133),
 +	ID16( 800,  844, BUS133),
 +	ID16( 667,  844, BUS133),
 +	ID16( 533,  844, BUS133),
 +};
 +
 +/* 2.00GHz Centaur C7-M 533 MHz FSB */
 +static const uint16_t C7M_795[] = {
 +	ID16(2000, 1148, BUS133),
 +	ID16(1867, 1132, BUS133),
 +	ID16(1600, 1100, BUS133),
 +	ID16(1467, 1052, BUS133),
 +	ID16(1200, 1004, BUS133),
 +	ID16( 800,  844, BUS133),
 +	ID16( 667,  844, BUS133),
 +	ID16( 533,  844, BUS133),
 +};
 +
 +/* 1.00GHz VIA Eden 90nm 'Esther' */
 +static const uint16_t eden90_1000[] = {
 +	ID16(1000,  844, BUS100),
 +	ID16( 800,  844, BUS100),
 +	ID16( 600,  844, BUS100),
 +	ID16( 400,  844, BUS100),
 +};
 +
 +struct fqlist {
 +	int vendor;
 +	unsigned bus_clk;
 +	unsigned n;
 +	const uint16_t *table;
 +};
 +
 +#define ENTRY(ven, bus_clk, tab) \
 +	{ CPUVENDOR_##ven, bus_clk == BUS133 ? 1 : 0, __arraycount(tab), tab }
 +
 +#define BUS_CLK(fqp) ((fqp)->bus_clk ? BUS133 : BUS100)
 +
 +static const struct fqlist est_cpus[] = {
 +	ENTRY(INTEL, BUS100, pm130_900_ulv),
 +	ENTRY(INTEL, BUS100, pm130_1000_ulv),
 +	ENTRY(INTEL, BUS100, pm130_1100_ulv),
 +	ENTRY(INTEL, BUS100, pm130_1100_lv),
 +	ENTRY(INTEL, BUS100, pm130_1200_lv),
 +	ENTRY(INTEL, BUS100, pm130_1300_lv),
 +	ENTRY(INTEL, BUS100, pm130_1300),
 +	ENTRY(INTEL, BUS100, pm130_1400),
 +	ENTRY(INTEL, BUS100, pm130_1500),
 +	ENTRY(INTEL, BUS100, pm130_1600),
 +	ENTRY(INTEL, BUS100, pm130_1700),
 +	ENTRY(INTEL, BUS100, pm90_n723),
 +	ENTRY(INTEL, BUS100, pm90_n733g),
 +	ENTRY(INTEL, BUS100, pm90_n733h),
 +	ENTRY(INTEL, BUS100, pm90_n733i),
 +	ENTRY(INTEL, BUS100, pm90_n733j),
 +	ENTRY(INTEL, BUS100, pm90_n733k),
 +	ENTRY(INTEL, BUS100, pm90_n733l),
 +	ENTRY(INTEL, BUS100, pm90_n753g),
 +	ENTRY(INTEL, BUS100, pm90_n753h),
 +	ENTRY(INTEL, BUS100, pm90_n753i),
 +	ENTRY(INTEL, BUS100, pm90_n753j),
 +	ENTRY(INTEL, BUS100, pm90_n753k),
 +	ENTRY(INTEL, BUS100, pm90_n753l),
 +	ENTRY(INTEL, BUS100, pm90_n773g),
 +	ENTRY(INTEL, BUS100, pm90_n773h),
 +	ENTRY(INTEL, BUS100, pm90_n773i),
 +	ENTRY(INTEL, BUS100, pm90_n773j),
 +	ENTRY(INTEL, BUS100, pm90_n773k),
 +	ENTRY(INTEL, BUS100, pm90_n773l),
 +	ENTRY(INTEL, BUS100, pm90_n738),
 +	ENTRY(INTEL, BUS100, pm90_n758),
 +	ENTRY(INTEL, BUS100, pm90_n778),
 +
 +	ENTRY(INTEL, BUS133, pm90_n710),
 +	ENTRY(INTEL, BUS100, pm90_n715a),
 +	ENTRY(INTEL, BUS100, pm90_n715b),
 +	ENTRY(INTEL, BUS100, pm90_n715c),
 +	ENTRY(INTEL, BUS100, pm90_n715d),
 +	ENTRY(INTEL, BUS100, pm90_n725a),
 +	ENTRY(INTEL, BUS100, pm90_n725b),
 +	ENTRY(INTEL, BUS100, pm90_n725c),
 +	ENTRY(INTEL, BUS100, pm90_n725d),
 +	ENTRY(INTEL, BUS133, pm90_n730),
 +	ENTRY(INTEL, BUS100, pm90_n735a),
 +	ENTRY(INTEL, BUS100, pm90_n735b),
 +	ENTRY(INTEL, BUS100, pm90_n735c),
 +	ENTRY(INTEL, BUS100, pm90_n735d),
 +	ENTRY(INTEL, BUS133, pm90_n740),
 +	ENTRY(INTEL, BUS100, pm90_n745a),
 +	ENTRY(INTEL, BUS100, pm90_n745b),
 +	ENTRY(INTEL, BUS100, pm90_n745c),
 +	ENTRY(INTEL, BUS100, pm90_n745d),
 +	ENTRY(INTEL, BUS133, pm90_n750),
 +	ENTRY(INTEL, BUS100, pm90_n755a),
 +	ENTRY(INTEL, BUS100, pm90_n755b),
 +	ENTRY(INTEL, BUS100, pm90_n755c),
 +	ENTRY(INTEL, BUS100, pm90_n755d),
 +	ENTRY(INTEL, BUS133, pm90_n760),
 +	ENTRY(INTEL, BUS100, pm90_n765a),
 +	ENTRY(INTEL, BUS100, pm90_n765b),
 +	ENTRY(INTEL, BUS100, pm90_n765c),
 +	ENTRY(INTEL, BUS100, pm90_n765e),
 +	ENTRY(INTEL, BUS133, pm90_n770),
 +	ENTRY(INTEL, BUS133, pm90_n780),
 +
 +	ENTRY(IDT, BUS100, C7M_770_ULV),
 +	ENTRY(IDT, BUS100, C7M_779_ULV),
 +	ENTRY(IDT, BUS100, C7M_772_ULV),
 +	ENTRY(IDT, BUS100, C7M_771),
 +	ENTRY(IDT, BUS100, C7M_775_ULV),
 +	ENTRY(IDT, BUS100, C7M_754),
 +	ENTRY(IDT, BUS100, C7M_764),
 +	ENTRY(IDT, BUS133, C7M_765),
 +	ENTRY(IDT, BUS100, C7M_784),
 +	ENTRY(IDT, BUS133, C7M_785),
 +	ENTRY(IDT, BUS100, C7M_794),
 +	ENTRY(IDT, BUS133, C7M_795),
 +
 +	ENTRY(IDT, BUS100, eden90_1000)
 +};
 +
 +#define MSR2FREQINC(msr)	(((int) (msr) >> 8) & 0xff)
 +#define MSR2VOLTINC(msr)	((int) (msr) & 0xff)
 +
 +#define MSR2MHZ(msr, bus)	((MSR2FREQINC((msr)) * (bus) + 50) / 100)
 +#define MSR2MV(msr)		(MSR2VOLTINC(msr) * 16 + 700)
 +
 +static const struct 	fqlist *est_fqlist; /* not NULL if functional */
 +static uint16_t         fake_table[3];      /* guessed est_cpu table */
 +static struct fqlist    fake_fqlist;
 +static int 		est_node_target, est_node_current;
 +static const char 	est_desc[] = "Enhanced SpeedStep";
 +static int		lvendor, bus_clock;
 +
 +static int		est_sysctl_helper(SYSCTLFN_PROTO);
 +static int		est_init_once(void);
 +static void		est_init_main(int);
 +
 +static int
 +est_sysctl_helper(SYSCTLFN_ARGS)
 +{
 +	struct msr_cpu_broadcast mcb;
 +	struct sysctlnode	node;
 +	int			fq, oldfq, error;
 +
 +	if (est_fqlist == NULL)
 +		return EOPNOTSUPP;
 +
 +	node = *rnode;
 +	node.sysctl_data = &fq;
 +
 +	oldfq = 0;
 +	if (rnode->sysctl_num == est_node_target)
 +		fq = oldfq = MSR2MHZ(rdmsr(MSR_PERF_CTL), bus_clock);
 +	else if (rnode->sysctl_num == est_node_current)
 +		fq = MSR2MHZ(rdmsr(MSR_PERF_STATUS), bus_clock);
 +	else
 +		return EOPNOTSUPP;
 +
 +	error = sysctl_lookup(SYSCTLFN_CALL(&node));
 +	if (error || newp == NULL)
 +		return error;
 +
 +	/* support writing to ...frequency.target */
 +	if (rnode->sysctl_num == est_node_target && fq != oldfq) {
 +		int		i;
 +
 +		for (i = est_fqlist->n - 1; i > 0; i--)
 +			if (MSR2MHZ(est_fqlist->table[i], bus_clock) >= fq)
 +				break;
 +		fq = MSR2MHZ(est_fqlist->table[i], bus_clock);
 +		mcb.msr_read = true;
 +		mcb.msr_type = MSR_PERF_CTL;
 +		mcb.msr_mask = 0xffffULL;
 +		mcb.msr_value = est_fqlist->table[i];
 +		msr_cpu_broadcast(&mcb);
 +	}
 +
 +	return 0;
 +}
 +
 +static int
 +est_init_once(void)
 +{
 +	est_init_main(lvendor);
 +	return 0;
 +}
 +
 +void
 +est_init(int vendor)
 +{
 +	int error;
 +	static ONCE_DECL(est_initialized);
 +
 +	lvendor = vendor;
 +
 +	error = RUN_ONCE(&est_initialized, est_init_once);
 +	if (__predict_false(error != 0))
 +		return;
 +}
 +
 +static void
 +est_init_main(int vendor)
 +{
 +#ifdef __i386__
 +	const struct fqlist	*fql;
 +#endif
 +	const struct sysctlnode	*node, *estnode, *freqnode;
 +	uint64_t		msr;
 +	uint16_t		cur, idhi, idlo;
 +	uint8_t			crhi, crlo, crcur;
 +	int			i, mv, rc;
 +	size_t			len, freq_len;
 +	char			*freq_names, *cpuname;
 +       
 +	cpuname	= curcpu()->ci_dev->dv_xname;
 +
 +	if (CPUID2FAMILY(curcpu()->ci_signature) == 15)
 +		bus_clock = p4_get_bus_clock(curcpu());
 +	else if (CPUID2FAMILY(curcpu()->ci_signature) == 6) {
 +		if (vendor == CPUVENDOR_IDT)
 +			bus_clock = via_get_bus_clock(curcpu());
 +		else
 +			bus_clock = p3_get_bus_clock(curcpu());
 +	}
 +
 +	if (bus_clock == 0) {
 +		aprint_normal("%s: unknown system bus clock\n", __func__);
 +		return;
 +	}
 +
 +	msr = rdmsr(MSR_PERF_STATUS);
 +	idhi = (msr >> 32) & 0xffff;
 +	idlo = (msr >> 48) & 0xffff;
 +	cur = msr & 0xffff;
 +	crhi = (idhi  >> 8) & 0xff;
 +	crlo = (idlo  >> 8) & 0xff;
 +	crcur = (cur >> 8) & 0xff;
 +
 +#ifdef __i386__
 +	if (idhi == 0 || idlo == 0 || cur == 0 ||
 +	    ((cur >> 8) & 0xff) < ((idlo >> 8) & 0xff) ||
 +	    ((cur >> 8) & 0xff) > ((idhi >> 8) & 0xff)) {
 +		aprint_debug("%s: strange msr value 0x%016llx\n", __func__, msr);
 +		return;
 +	}
 +#endif
 +
 +#ifdef __amd64__
 +	if (crlo == 0 || crhi == crlo) {
 +		aprint_debug("%s: crlo == 0 || crhi == crlo\n", __func__);
 +		return;
 +	}
 +
 +	if (crhi == 0 || crcur == 0 || crlo > crhi ||
 +	    crcur < crlo || crcur > crhi) {
 +		/*
 +		 * Do complain about other weirdness, because we first want to
 +		 * know about it, before we decide what to do with it
 +		 */
 +		aprint_normal("%s: EST: strange msr value 0x%" PRIu64 "\n",
 +		    cpuname, msr);
 +		return;
 +	}
 +#endif
 +
 +	msr = rdmsr(MSR_PERF_STATUS);
 +	mv = MSR2MV(msr);
 +	aprint_normal("%s: %s (%d mV) ", cpuname, est_desc, mv);
 +	aprint_normal("%d MHz\n", MSR2MHZ(msr, bus_clock));
 +
 +#ifdef __i386__
 +	/*
 +	 * Find an entry which matches (vendor, bus_clock, idhi, idlo)
 +	 */
 +	est_fqlist = NULL;
 +	for (i = 0; i < __arraycount(est_cpus); i++) {
 +		fql = &est_cpus[i];
 +		if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) &&
 +		    idhi == fql->table[0] && idlo == fql->table[fql->n - 1]) {
 +			est_fqlist = fql;
 +			break;
 +		}
 +	}
 +#endif
 +
 +	if (est_fqlist == NULL) {
 +                aprint_normal("%s: unknown Enhanced SpeedStep CPU.\n",
 +                    cpuname);
 +
 +		/*
 +		 * Some CPUs report the same frequency in idhi and idlo,
 +		 * so do not run est on them.
 +		 */
 +		if (idhi == idlo)
 +			return;
 +                /*
 +                 * Generate a fake table with the power states we know.
 +                 */
 +                fake_table[0] = idhi;
 +                if (cur == idhi || cur == idlo) {
 +                        aprint_normal("%s: using only highest and lowest "
 +                            "power states.\n", cpuname);
 +
 +                        fake_table[1] = idlo;
 +                        fake_fqlist.n = 2;
 +                } else {
 +                        aprint_normal("%s: using only highest, current "
 +                            "and lowest power states.\n", cpuname);
 +
 +                        fake_table[1] = cur;
 +                        fake_table[2] = idlo;
 +                        fake_fqlist.n = 3;
 +                }
 +		fake_fqlist.vendor = vendor;
 +		fake_fqlist.table = fake_table;
 +		est_fqlist = &fake_fqlist;
 +	}
 +
 +	/*
 +	 * OK, tell the user the available frequencies.
 +	 */
 +	freq_len = est_fqlist->n * (sizeof("9999 ")-1) + 1;
 +	freq_names = malloc(freq_len, M_SYSCTLDATA, M_WAITOK);
 +	freq_names[0] = '\0';
 +	len = 0;
 +	for (i = 0; i < est_fqlist->n; i++) {
 +		len += snprintf(freq_names + len, freq_len - len, "%d%s",
 +		    MSR2MHZ(est_fqlist->table[i], bus_clock),
 +		    i < est_fqlist->n - 1 ? " " : "");
 +	}
 +	aprint_normal("%s: %s frequencies available (MHz): %s\n",
 +	    cpuname, est_desc, freq_names);
 +
 +	/*
 +	 * Setup the sysctl sub-tree machdep.est.*
 +	 */
 +	if ((rc = sysctl_createv(NULL, 0, NULL, &node,
 +	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
 +	    NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0)
 +		goto err;
 +
 +	if ((rc = sysctl_createv(NULL, 0, &node, &estnode,
 +	    0, CTLTYPE_NODE, "est", NULL,
 +	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 +		goto err;
 +
 +	if ((rc = sysctl_createv(NULL, 0, &estnode, &freqnode,
 +	    0, CTLTYPE_NODE, "frequency", NULL,
 +	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 +		goto err;
 +
 +	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
 +	    EST_TARGET_CTLFLAG, CTLTYPE_INT, "target", NULL,
 +	    est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 +		goto err;
 +	est_node_target = node->sysctl_num;
 +
 +	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
 +	    0, CTLTYPE_INT, "current", NULL,
 +	    est_sysctl_helper, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
 +		goto err;
 +	est_node_current = node->sysctl_num;
 +
 +	if ((rc = sysctl_createv(NULL, 0, &freqnode, &node,
 +	    0, CTLTYPE_STRING, "available", NULL,
 +	    NULL, 0, freq_names, freq_len, CTL_CREATE, CTL_EOL)) != 0)
 +		goto err;
 +
 +	return;
 +
 + err:
 +	free(freq_names, M_SYSCTLDATA);
 +	aprint_normal("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
 +}
 Index: arch/x86/x86/intel_busclock.c
 ===================================================================
 RCS file: arch/x86/x86/intel_busclock.c
 diff -N arch/x86/x86/intel_busclock.c
 --- /dev/null	1 Jan 1970 00:00:00 -0000
 +++ arch/x86/x86/intel_busclock.c	21 Jul 2007 15:48:02 -0000
 @@ -0,0 +1,225 @@
 +/*	$NetBSD: intel_busclock.c,v 1.2 2007/07/01 20:12:36 xtraeme Exp $	*/
 +
 +/*-
 + * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
 + * All rights reserved.
 + *
 + * This code is derived from software contributed to The NetBSD Foundation
 + * by Frank van der Linden,  and by Jason R. Thorpe.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. All advertising materials mentioning features or use of this software
 + *    must display the following acknowledgement:
 + *      This product includes software developed by the NetBSD
 + *      Foundation, Inc. and its contributors.
 + * 4. Neither the name of The NetBSD Foundation nor the names of its
 + *    contributors may be used to endorse or promote products derived
 + *    from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#include <sys/cdefs.h>
 +__KERNEL_RCSID(0, "$NetBSD: intel_busclock.c,v 1.2 2007/07/01 20:12:36 xtraeme Exp $");
 +
 +#include <sys/param.h>
 +#include <sys/systm.h>
 +
 +#include <machine/specialreg.h>
 +#include <machine/pio.h>
 +#include <machine/cpu.h>
 +
 +#include <x86/cpuvar.h>
 +
 +int
 +via_get_bus_clock(struct cpu_info *ci)
 +{
 +	uint64_t msr;
 +	int bus, bus_clock = 0;
 +
 +	msr = rdmsr(MSR_EBL_CR_POWERON);
 +	bus = (msr >> 18) & 0x3;
 +	switch (bus) {
 +	case 0:
 +		bus_clock = 10000;
 +		break;
 +	case 1:
 +		bus_clock = 13333;
 +		break;
 +	case 2:
 +		bus_clock = 20000;
 +		break;
 +	case 3:
 +		bus_clock = 16667;
 +		break;
 +	default:
 +		break;
 +	}
 +
 +	return bus_clock;
 +}
 +
 +int
 +p3_get_bus_clock(struct cpu_info *ci)
 +{
 +	uint64_t msr;
 +	int bus, bus_clock = 0;
 +
 +	switch (CPUID2MODEL(ci->ci_signature)) {
 +	case 0x9: /* Pentium M (130 nm, Banias) */
 +		bus_clock = 10000;
 +		break;
 +	case 0xd: /* Pentium M (90 nm, Dothan) */
 +		msr = rdmsr(MSR_FSB_FREQ);
 +		bus = (msr >> 0) & 0x7;
 +		switch (bus) {
 +		case 0:
 +			bus_clock = 10000;
 +			break;
 +		case 1:
 +			bus_clock = 13333;
 +			break;
 +		default:
 +			aprint_debug("%s: unknown Pentium M FSB_FREQ "
 +			    "value %d", device_xname(ci->ci_dev), bus);
 +			goto print_msr;
 +		}
 +		break;
 +	case 0xe: /* Core Duo/Solo */
 +	case 0xf: /* Core Xeon */
 +		msr = rdmsr(MSR_FSB_FREQ);
 +		bus = (msr >> 0) & 0x7;
 +		switch (bus) {
 +		case 5:
 +			bus_clock = 10000;
 +			break;
 +		case 1:
 +			bus_clock = 13333;
 +			break;
 +		case 3:
 +			bus_clock = 16667;
 +			break;
 +		case 2:
 +			bus_clock = 20000;
 +			break;
 +		case 0:
 +			bus_clock = 26667;
 +			break;
 +		case 4:
 +			bus_clock = 33333;
 +			break;
 +		default:
 +			aprint_debug("%s: unknown Core FSB_FREQ value %d",
 +			    device_xname(ci->ci_dev), bus);
 +			goto print_msr;
 +		}
 +		break;
 +	case 0x1: /* Pentium Pro, model 1 */
 +	case 0x3: /* Pentium II, model 3 */
 +	case 0x5: /* Pentium II, II Xeon, Celeron, model 5 */
 +	case 0x6: /* Celeron, model 6 */
 +	case 0x7: /* Pentium III, III Xeon, model 7 */
 +	case 0x8: /* Pentium III, III Xeon, Celeron, model 8 */
 +	case 0xa: /* Pentium III Xeon, model A */
 +	case 0xb: /* Pentium III, model B */
 +		msr = rdmsr(MSR_EBL_CR_POWERON);
 +		bus = (msr >> 18) & 0x3;
 +		switch (bus) {
 +		case 0:
 +			bus_clock = 6666;
 +			break;
 +		case 1:
 +			bus_clock = 13333;
 +			break;
 +		case 2:
 +			bus_clock = 10000;
 +			break;
 +		default:
 +			aprint_debug("%s: unknown i686 EBL_CR_POWERON "
 +			    "value %d ", device_xname(ci->ci_dev), bus);
 +			goto print_msr;
 +		}
 +		break;
 +	default:
 +		aprint_debug("%s: unknown i686 model %d, can't get bus clock",
 +		    device_xname(ci->ci_dev),
 +		    CPUID2MODEL(ci->ci_signature));
 +print_msr:
 +		/*
 +		 * Show the EBL_CR_POWERON MSR, so we'll at least have
 +		 * some extra information, such as clock ratio, etc.
 +		 */
 +		aprint_debug(" (0x%" PRIu64 ")\n", rdmsr(MSR_EBL_CR_POWERON));
 +		break;
 +	}
 +
 +	return bus_clock;
 +}
 +
 +int
 +p4_get_bus_clock(struct cpu_info *ci)
 +{
 +	uint64_t msr;
 +	int bus, bus_clock = 0;
 +
 +	msr = rdmsr(MSR_EBC_FREQUENCY_ID);
 +	if (CPUID2MODEL(ci->ci_signature) < 2) {
 +		bus = (msr >> 21) & 0x7;
 +		switch (bus) {
 +		case 0:
 +			bus_clock = 10000;
 +			break;
 +		case 1:
 +			bus_clock = 13333;
 +			break;
 +		default:
 +			aprint_debug("%s: unknown Pentium 4 (model %d) "
 +			    "EBC_FREQUENCY_ID value %d\n",
 +			    device_xname(ci->ci_dev),
 +			    CPUID2MODEL(ci->ci_signature), bus);
 +			break;
 +		}
 +	} else {
 +		bus = (msr >> 16) & 0x7;
 +		switch (bus) {
 +		case 0:
 +			bus_clock = (CPUID2MODEL(ci->ci_signature) == 2) ?
 +			    10000 : 26666;
 +			break;
 +		case 1:
 +			bus_clock = 13333;
 +			break;
 +		case 2:
 +			bus_clock = 20000;
 +			break;
 +		case 3:
 +			bus_clock = 16666;
 +			break;
 +		default:
 +			aprint_debug("%s: unknown Pentium 4 (model %d) "
 +			    "EBC_FREQUENCY_ID value %d\n",
 +			    device_xname(ci->ci_dev),
 +			    CPUID2MODEL(ci->ci_signature), bus);
 +			break;
 +		}
 +	}
 +
 +	return bus_clock;
 +}
 
 --------------080106030401060104070403--