Module Name: src Committed By: jruoho Date: Wed Feb 23 11:43:23 UTC 2011
Modified Files: src/sys/arch/amd64/conf: GENERIC XEN3_DOM0 src/sys/arch/i386/conf: ALL GENERIC src/sys/arch/x86/conf: files.x86 src/sys/arch/x86/include: cpu.h cpuvar.h src/sys/arch/x86/x86: cpu.c est.c identcpu.c intel_busclock.c src/sys/arch/xen/conf: files.xen Added Files: src/sys/arch/x86/include: est.h Log Message: Move ENHANCED_SPEEDSTEP, or henceforth est(4), to the cpufeaturebus. To generate a diff of this commit: cvs rdiff -u -r1.312 -r1.313 src/sys/arch/amd64/conf/GENERIC cvs rdiff -u -r1.61 -r1.62 src/sys/arch/amd64/conf/XEN3_DOM0 cvs rdiff -u -r1.293 -r1.294 src/sys/arch/i386/conf/ALL cvs rdiff -u -r1.1020 -r1.1021 src/sys/arch/i386/conf/GENERIC cvs rdiff -u -r1.59 -r1.60 src/sys/arch/x86/conf/files.x86 cvs rdiff -u -r1.29 -r1.30 src/sys/arch/x86/include/cpu.h cvs rdiff -u -r1.40 -r1.41 src/sys/arch/x86/include/cpuvar.h cvs rdiff -u -r0 -r1.1 src/sys/arch/x86/include/est.h cvs rdiff -u -r1.82 -r1.83 src/sys/arch/x86/x86/cpu.c cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x86/x86/est.c cvs rdiff -u -r1.24 -r1.25 src/sys/arch/x86/x86/identcpu.c cvs rdiff -u -r1.11 -r1.12 src/sys/arch/x86/x86/intel_busclock.c cvs rdiff -u -r1.110 -r1.111 src/sys/arch/xen/conf/files.xen Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/conf/GENERIC diff -u src/sys/arch/amd64/conf/GENERIC:1.312 src/sys/arch/amd64/conf/GENERIC:1.313 --- src/sys/arch/amd64/conf/GENERIC:1.312 Wed Feb 23 00:46:29 2011 +++ src/sys/arch/amd64/conf/GENERIC Wed Feb 23 11:43:21 2011 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.312 2011/02/23 00:46:29 jmcneill Exp $ +# $NetBSD: GENERIC,v 1.313 2011/02/23 11:43:21 jruoho Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.312 $" +#ident "GENERIC-$Revision: 1.313 $" maxusers 64 # estimated number of users @@ -78,15 +78,12 @@ #options PIPE_SOCKETPAIR # smaller, but slower pipe(2) options SYSCTL_INCLUDE_DESCR # Include sysctl descriptions in kernel -# Intel Enhanced Speedstep for EM64T CPUs -options ENHANCED_SPEEDSTEP -#options EST_FREQ_USERWRITE # any user can set frequency - # AMD PowerNow! and Cool`n'Quiet technology options POWERNOW_K8 -# Intel Core's on-die Thermal sensor -coretemp* at cpu? +# CPU features +coretemp* at cpu? # Intel on-die thermal sensor +est0 at cpu0 # Intel Enhanced SpeedStep (non-ACPI) # Intel(R) On Demand Clock Modulation (aka ODCM) # options INTEL_ONDEMAND_CLOCKMOD Index: src/sys/arch/amd64/conf/XEN3_DOM0 diff -u src/sys/arch/amd64/conf/XEN3_DOM0:1.61 src/sys/arch/amd64/conf/XEN3_DOM0:1.62 --- src/sys/arch/amd64/conf/XEN3_DOM0:1.61 Sat Nov 27 20:19:41 2010 +++ src/sys/arch/amd64/conf/XEN3_DOM0 Wed Feb 23 11:43:21 2011 @@ -1,4 +1,4 @@ -# $NetBSD: XEN3_DOM0,v 1.61 2010/11/27 20:19:41 christos Exp $ +# $NetBSD: XEN3_DOM0,v 1.62 2011/02/23 11:43:21 jruoho Exp $ include "arch/amd64/conf/std.xen" @@ -20,10 +20,6 @@ #options VM86 # virtual 8086 emulation #options USER_LDT # user-settable LDT; used by WINE -# Enhanced SpeedStep Technology in the Pentium M -options ENHANCED_SPEEDSTEP -#options EST_FREQ_USERWRITE # any user can set frequency - # AMD PowerNow! and Cool`n'Quiet technology options POWERNOW_K8 Index: src/sys/arch/i386/conf/ALL diff -u src/sys/arch/i386/conf/ALL:1.293 src/sys/arch/i386/conf/ALL:1.294 --- src/sys/arch/i386/conf/ALL:1.293 Wed Feb 23 00:45:56 2011 +++ src/sys/arch/i386/conf/ALL Wed Feb 23 11:43:22 2011 @@ -1,4 +1,4 @@ -# $NetBSD: ALL,v 1.293 2011/02/23 00:45:56 jmcneill Exp $ +# $NetBSD: ALL,v 1.294 2011/02/23 11:43:22 jruoho Exp $ # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp # # ALL machine description file @@ -17,7 +17,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "ALL-$Revision: 1.293 $" +#ident "ALL-$Revision: 1.294 $" maxusers 64 # estimated number of users @@ -29,21 +29,16 @@ options X86EMU # 386 Real Mode emulator options PAE # PAE mode (36 bits physical addressing) -# Enhanced SpeedStep Technology in the Pentium M -options ENHANCED_SPEEDSTEP -options EST_FREQ_USERWRITE # any user can set frequency - # AMD PowerNow! K7 options POWERNOW_K7 # AMD PowerNow! and Cool`n'Quiet technology options POWERNOW_K8 -# VIA PadLock -padlock0 at cpu0 - -# Intel Core's on-die Thermal sensor -coretemp* at cpu? +# CPU features +coretemp* at cpu? # Intel on-die thermal sensor +est0 at cpu0 # Intel Enhanced SpeedStep (non-ACPI) +padlock0 at cpu0 # VIA PadLock # Intel(R) On Demand Clock Modulation (aka ODCM) options INTEL_ONDEMAND_CLOCKMOD Index: src/sys/arch/i386/conf/GENERIC diff -u src/sys/arch/i386/conf/GENERIC:1.1020 src/sys/arch/i386/conf/GENERIC:1.1021 --- src/sys/arch/i386/conf/GENERIC:1.1020 Wed Feb 23 00:45:56 2011 +++ src/sys/arch/i386/conf/GENERIC Wed Feb 23 11:43:22 2011 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.1020 2011/02/23 00:45:56 jmcneill Exp $ +# $NetBSD: GENERIC,v 1.1021 2011/02/23 11:43:22 jruoho Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.1020 $" +#ident "GENERIC-$Revision: 1.1021 $" maxusers 64 # estimated number of users @@ -37,21 +37,16 @@ options USER_LDT # user-settable LDT; used by WINE #options PAE # PAE mode (36 bits physical addressing) -# Enhanced SpeedStep Technology in the Pentium M -options ENHANCED_SPEEDSTEP -#options EST_FREQ_USERWRITE # any user can set frequency - # AMD PowerNow! K7 options POWERNOW_K7 # AMD PowerNow! and Cool`n'Quiet technology options POWERNOW_K8 -# Intel Core's on-die Thermal sensor -coretemp* at cpu? - -# VIA PadLock -#padlock0 at cpu0 +# CPU features +coretemp* at cpu? # Intel on-die thermal sensor +est0 at cpu0 # Intel Enhanced SpeedStep (non-ACPI) +#padlock0 at cpu0 # VIA PadLock # Intel(R) On Demand Clock Modulation (aka ODCM) #options INTEL_ONDEMAND_CLOCKMOD Index: src/sys/arch/x86/conf/files.x86 diff -u src/sys/arch/x86/conf/files.x86:1.59 src/sys/arch/x86/conf/files.x86:1.60 --- src/sys/arch/x86/conf/files.x86:1.59 Sun Feb 20 13:42:45 2011 +++ src/sys/arch/x86/conf/files.x86 Wed Feb 23 11:43:22 2011 @@ -1,4 +1,4 @@ -# $NetBSD: files.x86,v 1.59 2011/02/20 13:42:45 jruoho Exp $ +# $NetBSD: files.x86,v 1.60 2011/02/23 11:43:22 jruoho Exp $ # options for MP configuration through the MP spec defflag opt_mpbios.h MPBIOS MPVERBOSE MPDEBUG MPBIOS_SCANPCI @@ -13,10 +13,6 @@ 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 - # Pentium 4+ Thermal Monitor ODCM (aka On Demand Clock Modulation) defflag opt_intel_odcm.h INTEL_ONDEMAND_CLOCKMOD @@ -35,12 +31,17 @@ define ipmibus {} # -# CPUs +# CPU features # device cpu: cpufeaturebus attach cpu at cpubus file arch/x86/x86/cpu.c cpu +device est +attach est at cpufeaturebus +file arch/x86/x86/est.c est +file arch/x86/x86/intel_busclock.c est + device coretemp: sysmon_envsys attach coretemp at cpufeaturebus file arch/x86/x86/coretemp.c coretemp @@ -104,10 +105,6 @@ # Intel On Demand Clock Modulation file arch/x86/x86/iclockmod.c intel_ondemand_clockmod -# Intel Enhanced Speedstep -file arch/x86/x86/est.c enhanced_speedstep -file arch/x86/x86/intel_busclock.c enhanced_speedstep - # VIA C7 Temperature sensor file arch/x86/x86/viac7temp.c via_c7temp Index: src/sys/arch/x86/include/cpu.h diff -u src/sys/arch/x86/include/cpu.h:1.29 src/sys/arch/x86/include/cpu.h:1.30 --- src/sys/arch/x86/include/cpu.h:1.29 Sun Feb 20 13:42:45 2011 +++ src/sys/arch/x86/include/cpu.h Wed Feb 23 11:43:22 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.29 2011/02/20 13:42:45 jruoho Exp $ */ +/* $NetBSD: cpu.h,v 1.30 2011/02/23 11:43:22 jruoho Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -179,6 +179,7 @@ struct evcnt ci_ipi_events[X86_NIPI]; + device_t ci_frequency; /* Frequency scaling technology */ device_t ci_padlock; /* VIA PadLock private storage */ device_t ci_tempsensor; /* Intel coretemp(4) or equivalent */ Index: src/sys/arch/x86/include/cpuvar.h diff -u src/sys/arch/x86/include/cpuvar.h:1.40 src/sys/arch/x86/include/cpuvar.h:1.41 --- src/sys/arch/x86/include/cpuvar.h:1.40 Sun Feb 20 13:42:45 2011 +++ src/sys/arch/x86/include/cpuvar.h Wed Feb 23 11:43:22 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpuvar.h,v 1.40 2011/02/20 13:42:45 jruoho Exp $ */ +/* $NetBSD: cpuvar.h,v 1.41 2011/02/23 11:43:22 jruoho Exp $ */ /*- * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc. @@ -94,7 +94,6 @@ #if defined(_KERNEL_OPT) #include "opt_multiprocessor.h" -#include "opt_enhanced_speedstep.h" #ifndef XEN #include "opt_intel_odcm.h" #include "opt_via_c7temp.h" @@ -132,14 +131,6 @@ void clockmod_init(void); #endif -#ifdef ENHANCED_SPEEDSTEP -void est_init(int); -int via_get_bus_clock(struct cpu_info *); -int viac7_get_bus_clock(struct cpu_info *); -int p3_get_bus_clock(struct cpu_info *); -int p4_get_bus_clock(struct cpu_info *); -#endif - void cpu_get_tsc_freq(struct cpu_info *); void pat_init(struct cpu_info *); Index: src/sys/arch/x86/x86/cpu.c diff -u src/sys/arch/x86/x86/cpu.c:1.82 src/sys/arch/x86/x86/cpu.c:1.83 --- src/sys/arch/x86/x86/cpu.c:1.82 Sun Feb 20 13:42:46 2011 +++ src/sys/arch/x86/x86/cpu.c Wed Feb 23 11:43:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.c,v 1.82 2011/02/20 13:42:46 jruoho Exp $ */ +/* $NetBSD: cpu.c,v 1.83 2011/02/23 11:43:23 jruoho Exp $ */ /*- * Copyright (c) 2000, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.82 2011/02/20 13:42:46 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.83 2011/02/23 11:43:23 jruoho Exp $"); #include "opt_ddb.h" #include "opt_mpbios.h" /* for MPDEBUG */ @@ -455,8 +455,8 @@ int cpu_rescan(device_t self, const char *ifattr, const int *locators) { - struct cpufeature_attach_args cfaa; struct cpu_softc *sc = device_private(self); + struct cpufeature_attach_args cfaa; struct cpu_info *ci = sc->sc_info; memset(&cfaa, 0, sizeof(cfaa)); @@ -464,6 +464,12 @@ if (ifattr_match(ifattr, "cpufeaturebus")) { + if (ci->ci_frequency == NULL) { + cfaa.name = "est"; + ci->ci_frequency = config_found_ia(self, + "cpufeaturebus", &cfaa, NULL); + } + if (ci->ci_padlock == NULL) { cfaa.name = "padlock"; ci->ci_padlock = config_found_ia(self, @@ -486,11 +492,14 @@ struct cpu_softc *sc = device_private(self); struct cpu_info *ci = sc->sc_info; - if (ci->ci_tempsensor == child) - ci->ci_tempsensor = NULL; + if (ci->ci_frequency == child) + ci->ci_frequency = NULL; if (ci->ci_padlock == child) ci->ci_padlock = NULL; + + if (ci->ci_tempsensor == child) + ci->ci_tempsensor = NULL; } /* Index: src/sys/arch/x86/x86/est.c diff -u src/sys/arch/x86/x86/est.c:1.19 src/sys/arch/x86/x86/est.c:1.20 --- src/sys/arch/x86/x86/est.c:1.19 Fri Aug 20 06:34:32 2010 +++ src/sys/arch/x86/x86/est.c Wed Feb 23 11:43:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: est.c,v 1.19 2010/08/20 06:34:32 jruoho Exp $ */ +/* $NetBSD: est.c,v 1.20 2011/02/23 11:43:23 jruoho Exp $ */ /* * Copyright (c) 2003 Michael Eriksson. * All rights reserved. @@ -74,41 +74,47 @@ * - 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. */ - -/* #define EST_DEBUG */ - #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.19 2010/08/20 06:34:32 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.20 2011/02/23 11:43:23 jruoho Exp $"); #include <sys/param.h> -#include <sys/systm.h> #include <sys/device.h> -#include <sys/malloc.h> +#include <sys/kmem.h> +#include <sys/module.h> #include <sys/sysctl.h> -#include <sys/once.h> #include <sys/xcall.h> #include <x86/cpuvar.h> #include <x86/cputypes.h> #include <x86/cpu_msr.h> +#include <x86/est.h> +#include <x86/specialreg.h> -#include <machine/cpu.h> -#include <machine/specialreg.h> +#define MSR2FREQINC(msr) (((int) (msr) >> 8) & 0xff) +#define MSR2VOLTINC(msr) ((int) (msr) & 0xff) -#include "opt_est.h" -#ifdef EST_FREQ_USERWRITE -#define EST_TARGET_CTLFLAG (CTLFLAG_READWRITE | CTLFLAG_ANYWRITE) -#else -#define EST_TARGET_CTLFLAG CTLFLAG_READWRITE -#endif +#define MSR2MHZ(msr, bus) ((MSR2FREQINC((msr)) * (bus) + 50) / 100) +#define MSR2MV(msr) (MSR2VOLTINC(msr) * 16 + 700) /* 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)) +#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) + +struct fqlist { + int vendor; + unsigned bus_clk; + unsigned n; + const uint16_t *table; +}; + +#ifdef __i386__ + /* Possible bus speeds (multiplied by 100 for rounding) */ enum { BUS100 = 10000, BUS133 = 13333, BUS166 = 16666, BUS200 = 20000 }; @@ -752,15 +758,15 @@ ID16( 800, 988, BUS133), }; -/* Intel Pentium M processor 780 2.26 GHz */ +/* 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(1067, 1068, BUS133), ID16( 800, 988, BUS133), -}; +}; /* * VIA C7-M 500 MHz FSB, 400 MHz FSB, and ULV variants. @@ -895,18 +901,6 @@ 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), @@ -941,7 +935,6 @@ 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), @@ -973,144 +966,163 @@ 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) +}; + +#endif /* __i386__ */ + +static int est_match(device_t, cfdata_t, void *); +static void est_attach(device_t, device_t, void *); +static int est_detach(device_t, int); +static int est_bus_clock(struct cpu_info *); +static bool est_tables(device_t); +static void est_xcall(uint16_t); +static bool est_sysctl(device_t); +static int est_sysctl_helper(SYSCTLFN_PROTO); + +struct est_softc { + device_t sc_dev; + struct cpu_info *sc_ci; + struct sysctllog *sc_log; + struct fqlist *sc_fqlist; + struct fqlist sc_fake_fqlist; + uint16_t *sc_fake_table; + char *sc_freqs; + size_t sc_freqs_len; + int sc_bus_clock; + int sc_node_target; + int sc_node_current; +}; - 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), +CFATTACH_DECL_NEW(est, sizeof(struct est_softc), + est_match, est_attach, est_detach, NULL); - ENTRY(IDT, BUS100, eden90_1000) -}; +static int +est_match(device_t parent, cfdata_t cf, void *aux) +{ + struct cpufeature_attach_args *cfaa = aux; + struct cpu_info *ci = cfaa->ci; -#define MSR2FREQINC(msr) (((int) (msr) >> 8) & 0xff) -#define MSR2VOLTINC(msr) ((int) (msr) & 0xff) + if (strcmp(cfaa->name, "est") != 0) + return 0; -#define MSR2MHZ(msr, bus) ((MSR2FREQINC((msr)) * (bus) + 50) / 100) -#define MSR2MV(msr) (MSR2VOLTINC(msr) * 16 + 700) + if ((ci->ci_feat_val[1] & CPUID2_EST) == 0) + return 0; -static const struct fqlist *est_fqlist; /* not NULL if functional */ -static uint16_t *fake_table; /* 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); + return est_bus_clock(ci); +} -static int -est_sysctl_helper(SYSCTLFN_ARGS) +static void +est_attach(device_t parent, device_t self, void *aux) { - struct sysctlnode node; - int fq, oldfq, error; + struct est_softc *sc = device_private(self); + struct cpufeature_attach_args *cfaa = aux; + struct cpu_info *ci = cfaa->ci; + + sc->sc_ci = ci; + sc->sc_dev = self; + sc->sc_log = NULL; + sc->sc_freqs = NULL; + sc->sc_fqlist = NULL; + sc->sc_fake_table = NULL; + sc->sc_bus_clock = est_bus_clock(ci); + + KASSERT(sc->sc_bus_clock != 0); - if (est_fqlist == NULL) - return EOPNOTSUPP; + aprint_naive("\n"); + aprint_normal(": Enhanced SpeedStep\n"); - node = *rnode; - node.sysctl_data = &fq; + (void)pmf_device_register(self, NULL, NULL); - 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; + if (est_tables(self) != false) + est_sysctl(self); +} - error = sysctl_lookup(SYSCTLFN_CALL(&node)); - if (error || newp == NULL) - return error; +static int +est_detach(device_t self, int flags) +{ + struct est_softc *sc = device_private(self); + uint16_t n = sc->sc_fake_fqlist.n; - /* support writing to ...frequency.target */ - if (rnode->sysctl_num == est_node_target && fq != oldfq) { - struct msr_rw_info msr; - uint64_t where; - int i; + if (sc->sc_log != NULL) + sysctl_teardown(&sc->sc_log); - 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); + if (sc->sc_freqs != NULL) + kmem_free(sc->sc_freqs, sc->sc_freqs_len); - msr.msr_read = true; - msr.msr_type = MSR_PERF_CTL; - msr.msr_mask = 0xffffULL; - msr.msr_value = est_fqlist->table[i]; + if (sc->sc_fake_table != NULL) + kmem_free(sc->sc_fake_table, n * sizeof(*sc->sc_fake_table)); - where = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL); - xc_wait(where); - } + pmf_device_deregister(self); return 0; } static int -est_init_once(void) +est_bus_clock(struct cpu_info *ci) { - est_init_main(lvendor); - return 0; -} + uint32_t family, model; + int bus_clock = 0; -void -est_init(int vendor) -{ - int error; - static ONCE_DECL(est_initialized); + model = CPUID2MODEL(ci->ci_signature); + family = CPUID2FAMILY(ci->ci_signature); - lvendor = vendor; + switch (family) { - error = RUN_ONCE(&est_initialized, est_init_once); - if (__predict_false(error != 0)) - return; -} + case 0x0f: + bus_clock = p4_get_bus_clock(ci); + break; -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; - - if (CPUID2FAMILY(curcpu()->ci_signature) == 15) - bus_clock = p4_get_bus_clock(curcpu()); - else if (CPUID2FAMILY(curcpu()->ci_signature) == 6) { - if (vendor == CPUVENDOR_IDT) { - switch (CPUID2MODEL(curcpu()->ci_signature)) { - case 0xa: /* C7 Esther */ - case 0xd: /* C7 Esther */ - bus_clock = viac7_get_bus_clock(curcpu()); + case 0x06: + + if (cpu_vendor != CPUVENDOR_IDT) + bus_clock = p3_get_bus_clock(ci); + else { + switch (model) { + + case 0x0a: /* C7 Esther */ + case 0x0d: /* C7 Esther */ + bus_clock = viac7_get_bus_clock(ci); break; + default: - bus_clock = via_get_bus_clock(curcpu()); + bus_clock = via_get_bus_clock(ci); break; } - } else - bus_clock = p3_get_bus_clock(curcpu()); + } } - if (bus_clock == 0) { - aprint_debug("%s: unknown system bus clock\n", __func__); - return; - } + return bus_clock; +} + +static bool +est_tables(device_t self) +{ + struct est_softc *sc = device_private(self); + +#ifdef __i386__ + const struct fqlist *fql; +#endif + uint64_t msr; + uint16_t cur, idhi, idlo; + uint8_t crhi, crlo, crcur; + size_t len; + int i, mv; msr = rdmsr(MSR_PERF_STATUS); + idhi = (msr >> 32) & 0xffff; idlo = (msr >> 48) & 0xffff; cur = msr & 0xffff; @@ -1122,9 +1134,8 @@ 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; + aprint_debug_dev(self, "strange msr value 0x%"PRIx64"\n", msr); + return false; } #endif @@ -1135,11 +1146,10 @@ * Do complain about other weirdness, because we first want to * know about it, before we decide what to do with it */ - aprint_debug("%s: strange msr value 0x%" PRIu64 "\n", - __func__, msr); - aprint_debug("%s: crhi=%" PRIu8 ", crlo=%" PRIu8 ", crcur=%" - PRIu8 "\n", __func__, crhi, crlo, crcur); - return; + aprint_debug_dev(self, "strange msr value 0x%"PRIu64"\n", msr); + aprint_debug_dev(self, " crhi=%u, crlo=%u, crcur=%u\n", + crhi, crlo, crcur); + return false; } #endif @@ -1148,20 +1158,24 @@ #ifdef __i386__ /* - * Find an entry which matches (vendor, bus_clock, idhi, idlo) + * Find an entry which matches (vendor, bus_clock, idhi, idlo). */ - est_fqlist = NULL; + sc->sc_fqlist = NULL; + for (i = 0; i < __arraycount(est_cpus); i++) { + fql = &est_cpus[i]; - if (vendor == fql->vendor && bus_clock == BUS_CLK(fql) && + + if (cpu_vendor == fql->vendor && + sc->sc_bus_clock == BUS_CLK(fql) && idhi == fql->table[0] && idlo == fql->table[fql->n - 1]) { - est_fqlist = fql; + sc->sc_fqlist = __UNCONST(fql); break; } } #endif - if (est_fqlist == NULL) { + if (sc->sc_fqlist == NULL) { int j, tablesize, freq, volt; int minfreq, minvolt, maxfreq, maxvolt, freqinc, voltinc; @@ -1170,23 +1184,23 @@ * so do not run est on them. */ if (idhi == idlo) { - aprint_debug("%s: idhi == idlo\n", __func__); - return; + aprint_debug_dev(self, "idhi == idlo\n"); + return false; } #ifdef EST_DEBUG - printf("%s: bus_clock = %d\n", __func__, bus_clock); - printf("%s: idlo = 0x%x\n", __func__, idlo); - printf("%s: lo %4d mV, %4d MHz\n", __func__, - MSR2MV(idlo), MSR2MHZ(idlo, bus_clock)); - printf("%s: raw %4d , %4d \n", __func__, + aprint_normal_dev(self, "bus_clock = %d\n", sc->sc_bus_clock); + aprint_normal_dev(self, "idlo = 0x%x\n", idlo); + aprint_normal_dev(self, "lo %4d mV, %4d MHz\n", + MSR2MV(idlo), MSR2MHZ(idlo, sc->sc_bus_clock)); + aprint_normal_dev(self, "raw %4d , %4d \n", (idlo & 0xff), ((idlo >> 8) & 0xff)); - printf("%s: idhi = 0x%x\n", __func__, idhi); - printf("%s: hi %4d mV, %4d MHz\n", __func__, - MSR2MV(idhi), MSR2MHZ(idhi, bus_clock)); - printf("%s: raw %4d , %4d \n", __func__, + aprint_normal_dev(self, "idhi = 0x%x\n", idhi); + aprint_normal_dev(self, "hi %4d mV, %4d MHz\n", + MSR2MV(idhi), MSR2MHZ(idhi, sc->sc_bus_clock)); + aprint_normal_dev(self, "raw %4d , %4d \n", (idhi & 0xff), ((idhi >> 8) & 0xff)); - printf("%s: cur = 0x%x\n", __func__, cur); + aprint_normal_dev(self, "cur = 0x%x\n", cur); #endif /* @@ -1204,7 +1218,7 @@ /* Avoid diving by zero. */ if (freqinc == 0) - return; + return false; if (freqinc < voltinc || voltinc == 0) { tablesize = maxfreq - minfreq + 1; @@ -1217,85 +1231,210 @@ voltinc = 100; } - fake_table = malloc(tablesize * sizeof(uint16_t), M_DEVBUF, - M_WAITOK); - fake_fqlist.n = tablesize; + sc->sc_fake_table = kmem_alloc(tablesize * + sizeof(uint16_t), KM_SLEEP); + + if (sc->sc_fake_table == NULL) + return false; + + sc->sc_fake_fqlist.n = tablesize; /* The frequency/voltage table is highest frequency first */ freq = maxfreq * 100; volt = maxvolt * 100; + for (j = 0; j < tablesize; j++) { - fake_table[j] = (((freq + 99) / 100) << 8) + + sc->sc_fake_table[j] = (((freq + 99) / 100) << 8) + (volt + 99) / 100; #ifdef EST_DEBUG - printf("%s: fake entry %d: %4d mV, %4d MHz " - "MSR*100 mV = %4d freq = %4d\n", - __func__, j, MSR2MV(fake_table[j]), - MSR2MHZ(fake_table[j], bus_clock), + aprint_normal_dev(self, "fake entry %d: %4d mV, " + "%4d MHz, MSR*100 mV = %4d freq = %4d\n", + j, MSR2MV(sc->sc_fake_table[j]), + MSR2MHZ(sc->sc_fake_table[j], sc->sc_bus_clock), volt, freq); #endif /* EST_DEBUG */ freq -= freqinc; volt -= voltinc; } - fake_fqlist.vendor = vendor; - fake_fqlist.table = fake_table; - est_fqlist = &fake_fqlist; + + sc->sc_fake_fqlist.table = sc->sc_fake_table; + sc->sc_fake_fqlist.vendor = cpu_vendor; + sc->sc_fqlist = &sc->sc_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 ? " " : ""); + sc->sc_freqs_len = sc->sc_fqlist->n * (sizeof("9999 ") - 1) + 1; + sc->sc_freqs = kmem_zalloc(sc->sc_freqs_len, KM_SLEEP); + + if (sc->sc_freqs == NULL) + return false; + + for (i = len = 0; i < sc->sc_fqlist->n; i++) { + + len += snprintf(sc->sc_freqs + len, sc->sc_freqs_len - len, + "%d%s", MSR2MHZ(sc->sc_fqlist->table[i], sc->sc_bus_clock), + i < sc->sc_fqlist->n - 1 ? " " : ""); } - aprint_debug_dev(curcpu()->ci_dev, "%s (%d mV) ", est_desc, mv); - aprint_debug("%d (MHz): %s\n", MSR2MHZ(msr, bus_clock), freq_names); + aprint_debug_dev(self, "%d mV, %d (MHz): %s\n", mv, + MSR2MHZ(msr, sc->sc_bus_clock), sc->sc_freqs); + + return true; +} + +static void +est_xcall(uint16_t val) +{ + struct msr_rw_info msr; + uint64_t xc; + + msr.msr_read = true; + msr.msr_type = MSR_PERF_CTL; + msr.msr_mask = 0xffffULL; + msr.msr_value = val; + + xc = xc_broadcast(0, x86_msr_xcall, &msr, NULL); + xc_wait(xc); +} + +static bool +est_sysctl(device_t self) +{ + struct est_softc *sc = device_private(self); + const struct sysctlnode *node, *estnode, *freqnode; + int rv; /* * Setup the sysctl sub-tree machdep.est.* */ - if ((rc = sysctl_createv(NULL, 0, NULL, &node, + rv = sysctl_createv(&sc->sc_log, 0, NULL, &node, CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL, - NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL)) != 0) - goto err; + NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL); + + if (rv != 0) + goto fail; - if ((rc = sysctl_createv(NULL, 0, &node, &estnode, + rv = sysctl_createv(&sc->sc_log, 0, &node, &estnode, 0, CTLTYPE_NODE, "est", NULL, - NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) - goto err; + NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); - if ((rc = sysctl_createv(NULL, 0, &estnode, &freqnode, + if (rv != 0) + goto fail; + + rv = sysctl_createv(&sc->sc_log, 0, &estnode, &freqnode, 0, CTLTYPE_NODE, "frequency", NULL, - NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0) - goto err; + NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node, + CTLFLAG_READWRITE, CTLTYPE_INT, "target", NULL, + est_sysctl_helper, 0, sc, 0, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; - 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; + sc->sc_node_target = node->sysctl_num; - if ((rc = sysctl_createv(NULL, 0, &freqnode, &node, + rv = sysctl_createv(&sc->sc_log, 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; + est_sysctl_helper, 0, sc, 0, CTL_CREATE, CTL_EOL); - if ((rc = sysctl_createv(NULL, 0, &freqnode, &node, + if (rv != 0) + goto fail; + + sc->sc_node_current = node->sysctl_num; + + rv = sysctl_createv(&sc->sc_log, 0, &freqnode, &node, 0, CTLTYPE_STRING, "available", NULL, - NULL, 0, freq_names, freq_len, CTL_CREATE, CTL_EOL)) != 0) - goto err; + NULL, 0, sc->sc_freqs, sc->sc_freqs_len, + CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + return true; + +fail: + aprint_error_dev(self, "failed to initialize sysctl (err %d)\n", rv); + + sysctl_teardown(&sc->sc_log); + sc->sc_log = NULL; + + return false; +} + +static int +est_sysctl_helper(SYSCTLFN_ARGS) +{ + struct sysctlnode node; + struct est_softc *sc; + int fq, err, i, oldfq; + + fq = oldfq = 0; + + node = *rnode; + sc = node.sysctl_data; + + if (sc->sc_fqlist == NULL) + return EOPNOTSUPP; + + node.sysctl_data = &fq; + + if (rnode->sysctl_num == sc->sc_node_target) { + + fq = oldfq = MSR2MHZ(rdmsr(MSR_PERF_CTL), sc->sc_bus_clock); + + } else if (rnode->sysctl_num == sc->sc_node_current) { + + fq = MSR2MHZ(rdmsr(MSR_PERF_STATUS), sc->sc_bus_clock); + + } else + return EOPNOTSUPP; + + err = sysctl_lookup(SYSCTLFN_CALL(&node)); + + if (err != 0 || newp == NULL) + return err; - return; + if (fq == oldfq || rnode->sysctl_num != sc->sc_node_target) + return 0; - err: - free(freq_names, M_SYSCTLDATA); - aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc); + for (i = sc->sc_fqlist->n - 1; i > 0; i--) { + + if (MSR2MHZ(sc->sc_fqlist->table[i], sc->sc_bus_clock) >= fq) + break; + } + + est_xcall(sc->sc_fqlist->table[i]); + return 0; +} + +MODULE(MODULE_CLASS_DRIVER, est, NULL); + +#ifdef _MODULE +#include "ioconf.c" +#endif + +static int +est_modcmd(modcmd_t cmd, void *aux) +{ + int error = 0; + + switch (cmd) { + case MODULE_CMD_INIT: +#ifdef _MODULE + error = config_init_component(cfdriver_ioconf_est, + cfattach_ioconf_est, cfdata_ioconf_est); +#endif + return error; + case MODULE_CMD_FINI: +#ifdef _MODULE + error = config_fini_component(cfdriver_ioconf_est, + cfattach_ioconf_est, cfdata_ioconf_est); +#endif + return error; + default: + return ENOTTY; + } } Index: src/sys/arch/x86/x86/identcpu.c diff -u src/sys/arch/x86/x86/identcpu.c:1.24 src/sys/arch/x86/x86/identcpu.c:1.25 --- src/sys/arch/x86/x86/identcpu.c:1.24 Sun Feb 20 13:42:46 2011 +++ src/sys/arch/x86/x86/identcpu.c Wed Feb 23 11:43:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: identcpu.c,v 1.24 2011/02/20 13:42:46 jruoho Exp $ */ +/* $NetBSD: identcpu.c,v 1.25 2011/02/23 11:43:23 jruoho Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -30,9 +30,8 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.24 2011/02/20 13:42:46 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.25 2011/02/23 11:43:23 jruoho Exp $"); -#include "opt_enhanced_speedstep.h" #include "opt_intel_odcm.h" #include "opt_via_c7temp.h" #include "opt_powernow_k8.h" @@ -802,13 +801,6 @@ i386_use_fxsave = 0; #endif /* i386 */ -#ifdef ENHANCED_SPEEDSTEP - if (cpu_feature[1] & CPUID2_EST) { - if (rdmsr(MSR_MISC_ENABLE) & (1 << 16)) - est_init(cpu_vendor); - } -#endif /* ENHANCED_SPEEDSTEP */ - #ifdef VIA_C7TEMP if (cpu_vendor == CPUVENDOR_IDT && CPUID2FAMILY(ci->ci_signature) == 6 && Index: src/sys/arch/x86/x86/intel_busclock.c diff -u src/sys/arch/x86/x86/intel_busclock.c:1.11 src/sys/arch/x86/x86/intel_busclock.c:1.12 --- src/sys/arch/x86/x86/intel_busclock.c:1.11 Sun Aug 8 00:48:46 2010 +++ src/sys/arch/x86/x86/intel_busclock.c Wed Feb 23 11:43:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: intel_busclock.c,v 1.11 2010/08/08 00:48:46 jym Exp $ */ +/* $NetBSD: intel_busclock.c,v 1.12 2011/02/23 11:43:23 jruoho Exp $ */ /*- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intel_busclock.c,v 1.11 2010/08/08 00:48:46 jym Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intel_busclock.c,v 1.12 2011/02/23 11:43:23 jruoho Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -39,10 +39,10 @@ #include <machine/specialreg.h> #include <machine/pio.h> -#include <machine/cpufunc.h> #include <x86/cpuvar.h> #include <x86/cpufunc.h> +#include <x86/est.h> int via_get_bus_clock(struct cpu_info *ci) Index: src/sys/arch/xen/conf/files.xen diff -u src/sys/arch/xen/conf/files.xen:1.110 src/sys/arch/xen/conf/files.xen:1.111 --- src/sys/arch/xen/conf/files.xen:1.110 Thu Dec 2 23:12:30 2010 +++ src/sys/arch/xen/conf/files.xen Wed Feb 23 11:43:23 2011 @@ -1,4 +1,4 @@ -# $NetBSD: files.xen,v 1.110 2010/12/02 23:12:30 bouyer Exp $ +# $NetBSD: files.xen,v 1.111 2011/02/23 11:43:23 jruoho Exp $ # NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp # NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp @@ -33,12 +33,6 @@ defparam PCI_CONF_MODE -# Intel Enhanced Speedstep -defflag ENHANCED_SPEEDSTEP -defflag opt_est.h EST_FREQ_USERWRITE -file arch/x86/x86/est.c enhanced_speedstep -file arch/x86/x86/intel_busclock.c enhanced_speedstep - # AMD Powernow/Cool`n'Quiet Technology defflag opt_powernow_k8.h POWERNOW_K8 # Powernow common functions Added files: Index: src/sys/arch/x86/include/est.h diff -u /dev/null src/sys/arch/x86/include/est.h:1.1 --- /dev/null Wed Feb 23 11:43:24 2011 +++ src/sys/arch/x86/include/est.h Wed Feb 23 11:43:22 2011 @@ -0,0 +1,64 @@ +/* $NetBSD: est.h,v 1.1 2011/02/23 11:43:22 jruoho 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. + * + * 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. + */ + +#ifndef _X86_EST_H_ +#define _X86_EST_H_ + +int via_get_bus_clock(struct cpu_info *); +int viac7_get_bus_clock(struct cpu_info *); +int p3_get_bus_clock(struct cpu_info *); +int p4_get_bus_clock(struct cpu_info *); + +#endif /* !_X86_EST_H_ */