From owner-svn-src-stable@FreeBSD.ORG Wed Jan 21 15:01:36 2009 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5BC231065670; Wed, 21 Jan 2009 15:01:36 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 48C798FC17; Wed, 21 Jan 2009 15:01:36 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0LF1aLu080912; Wed, 21 Jan 2009 15:01:36 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0LF1agR080911; Wed, 21 Jan 2009 15:01:36 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200901211501.n0LF1agR080911@svn.freebsd.org> From: John Baldwin Date: Wed, 21 Jan 2009 15:01:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187529 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb i386/cpufreq X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Jan 2009 15:01:37 -0000 Author: jhb Date: Wed Jan 21 15:01:36 2009 New Revision: 187529 URL: http://svn.freebsd.org/changeset/base/187529 Log: MFC: If we are unable to obtain a frequency list from either ACPI or the static tables, then attempt to build a simple list containing just the high and low frequencies if the hw.est.msr_info tunable is set to 1. By default this is disabled. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) stable/7/sys/i386/cpufreq/est.c Modified: stable/7/sys/i386/cpufreq/est.c ============================================================================== --- stable/7/sys/i386/cpufreq/est.c Wed Jan 21 14:51:38 2009 (r187528) +++ stable/7/sys/i386/cpufreq/est.c Wed Jan 21 15:01:36 2009 (r187529) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include "cpufreq_if.h" +#include #include #include @@ -71,6 +72,7 @@ typedef struct { struct est_softc { device_t dev; int acpi_settings; + int msr_settings; freq_info *freq_list; }; @@ -92,6 +94,8 @@ struct est_softc { const char intel_id[] = "GenuineIntel"; const char centaur_id[] = "CentaurHauls"; +static int msr_info_enabled = 0; +TUNABLE_INT("hw.est.msr_info", &msr_info_enabled); /* Default bus clock value for Centrino processors. */ #define INTEL_BUS_CLK 100 @@ -898,6 +902,7 @@ static int est_detach(device_t parent); static int est_get_info(device_t dev); static int est_acpi_info(device_t dev, freq_info **freqs); static int est_table_info(device_t dev, uint64_t msr, freq_info **freqs); +static int est_msr_info(device_t dev, uint64_t msr, freq_info **freqs); static freq_info *est_get_current(freq_info *freq_list); static int est_settings(device_t dev, struct cf_setting *sets, int *count); static int est_set(device_t dev, const struct cf_setting *set); @@ -1039,7 +1044,7 @@ est_detach(device_t dev) return (error); sc = device_get_softc(dev); - if (sc->acpi_settings) + if (sc->acpi_settings || sc->msr_settings) free(sc->freq_list, M_DEVBUF); return (0); } @@ -1063,6 +1068,8 @@ est_get_info(device_t dev) error = est_table_info(dev, msr, &sc->freq_list); if (error) error = est_acpi_info(dev, &sc->freq_list); + if (error) + error = est_msr_info(dev, msr, &sc->freq_list); if (error) { printf( @@ -1168,6 +1175,91 @@ est_table_info(device_t dev, uint64_t ms return (0); } +static int +bus_speed_ok(int bus) +{ + + switch (bus) { + case 100: + case 133: + case 333: + return (1); + default: + return (0); + } +} + +/* + * Flesh out a simple rate table containing the high and low frequencies + * based on the current clock speed and the upper 32 bits of the MSR. + */ +static int +est_msr_info(device_t dev, uint64_t msr, freq_info **freqs) +{ + struct est_softc *sc; + freq_info *fp; + int bus, freq, volts; + uint16_t id; + + if (!msr_info_enabled) + return (EOPNOTSUPP); + + /* Figure out the bus clock. */ + freq = tsc_freq / 1000000; + id = msr >> 32; + bus = freq / (id >> 8); + device_printf(dev, "Guessed bus clock (high) of %d MHz\n", bus); + if (!bus_speed_ok(bus)) { + /* We may be running on the low frequency. */ + id = msr >> 48; + bus = freq / (id >> 8); + device_printf(dev, "Guessed bus clock (low) of %d MHz\n", bus); + if (!bus_speed_ok(bus)) + return (EOPNOTSUPP); + + /* Calculate high frequency. */ + id = msr >> 32; + freq = ((id >> 8) & 0xff) * bus; + } + + /* Fill out a new freq table containing just the high and low freqs. */ + sc = device_get_softc(dev); + fp = malloc(sizeof(freq_info) * 3, M_DEVBUF, M_WAITOK | M_ZERO); + + /* First, the high frequency. */ + volts = id & 0xff; + if (volts != 0) { + volts <<= 4; + volts += 700; + } + fp[0].freq = freq; + fp[0].volts = volts; + fp[0].id16 = id; + fp[0].power = CPUFREQ_VAL_UNKNOWN; + device_printf(dev, "Guessed high setting of %d MHz @ %d Mv\n", freq, + volts); + + /* Second, the low frequency. */ + id = msr >> 48; + freq = ((id >> 8) & 0xff) * bus; + volts = id & 0xff; + if (volts != 0) { + volts <<= 4; + volts += 700; + } + fp[1].freq = freq; + fp[1].volts = volts; + fp[1].id16 = id; + fp[1].power = CPUFREQ_VAL_UNKNOWN; + device_printf(dev, "Guessed low setting of %d MHz @ %d Mv\n", freq, + volts); + + /* Table is already terminated due to M_ZERO. */ + sc->msr_settings = TRUE; + *freqs = fp; + return (0); +} + static void est_get_id16(uint16_t *id16_p) {