est.c revision 142394
1/*- 2 * Copyright (c) 2004 Colin Percival 3 * Copyright (c) 2005 Nate Lawson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted providing that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD: head/sys/i386/cpufreq/est.c 142394 2005-02-24 20:20:11Z njl $"); 30 31#include <sys/param.h> 32#include <sys/bus.h> 33#include <sys/cpu.h> 34#include <sys/kernel.h> 35#include <sys/module.h> 36#include <sys/smp.h> 37#include <sys/systm.h> 38 39#include "cpufreq_if.h" 40#include <machine/md_var.h> 41 42/* Status/control registers (from the IA-32 System Programming Guide). */ 43#define MSR_PERF_STATUS 0x198 44#define MSR_PERF_CTL 0x199 45 46/* Register and bit for enabling SpeedStep. */ 47#define MSR_MISC_ENABLE 0x1a0 48#define MSR_SS_ENABLE (1<<16) 49 50/* Frequency and MSR control values. */ 51typedef struct { 52 uint16_t freq; 53 uint16_t volts; 54 uint16_t id16; 55} freq_info; 56 57/* Identifying characteristics of a processor and supported frequencies. */ 58typedef struct { 59 const char *vendor; 60 uint32_t id32; 61 uint32_t bus_clk; 62 const freq_info *freqtab; 63} cpu_info; 64 65struct est_softc { 66 device_t dev; 67 const freq_info *freq_list; 68}; 69 70/* Convert MHz and mV into IDs for passing to the MSR. */ 71#define ID16(MHz, mV, bus_clk) \ 72 (((MHz / bus_clk) << 8) | ((mV ? mV - 700 : 0) >> 4)) 73#define ID32(MHz_hi, mV_hi, MHz_lo, mV_lo, bus_clk) \ 74 ((ID16(MHz_lo, mV_lo, bus_clk) << 16) | (ID16(MHz_hi, mV_hi, bus_clk))) 75 76/* Format for storing IDs in our table. */ 77#define FREQ_INFO(MHz, mV, bus_clk) \ 78 { MHz, mV, ID16(MHz, mV, bus_clk) } 79#define INTEL(tab, zhi, vhi, zlo, vlo, bus_clk) \ 80 { GenuineIntel, ID32(zhi, vhi, zlo, vlo, bus_clk), bus_clk, tab } 81 82const char GenuineIntel[] = "GenuineIntel"; 83 84/* Default bus clock value for Centrino processors. */ 85#define INTEL_BUS_CLK 100 86 87/* XXX Update this if new CPUs have more settings. */ 88#define EST_MAX_SETTINGS 10 89CTASSERT(EST_MAX_SETTINGS <= MAX_SETTINGS); 90 91/* Estimate in microseconds of latency for performing a transition. */ 92#define EST_TRANS_LAT 10 93 94/* 95 * Frequency (MHz) and voltage (mV) settings. Data from the 96 * Intel Pentium M Processor Datasheet (Order Number 252612), Table 5. 97 * 98 * XXX New Dothan processors have multiple VID# with different 99 * settings for each VID#. Since we can't uniquely identify this info 100 * without undisclosed methods from Intel, we can't support newer 101 * processors with this table method. If ACPI Px states are supported, 102 * we can get info from them. 103 */ 104const freq_info PM17_130[] = { 105 /* 130nm 1.70GHz Pentium M */ 106 FREQ_INFO(1700, 1484, INTEL_BUS_CLK), 107 FREQ_INFO(1400, 1308, INTEL_BUS_CLK), 108 FREQ_INFO(1200, 1228, INTEL_BUS_CLK), 109 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 110 FREQ_INFO( 800, 1004, INTEL_BUS_CLK), 111 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 112 FREQ_INFO( 0, 0, 1), 113}; 114const freq_info PM16_130[] = { 115 /* 130nm 1.60GHz Pentium M */ 116 FREQ_INFO(1600, 1484, INTEL_BUS_CLK), 117 FREQ_INFO(1400, 1420, INTEL_BUS_CLK), 118 FREQ_INFO(1200, 1276, INTEL_BUS_CLK), 119 FREQ_INFO(1000, 1164, INTEL_BUS_CLK), 120 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 121 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 122 FREQ_INFO( 0, 0, 1), 123}; 124const freq_info PM15_130[] = { 125 /* 130nm 1.50GHz Pentium M */ 126 FREQ_INFO(1500, 1484, INTEL_BUS_CLK), 127 FREQ_INFO(1400, 1452, INTEL_BUS_CLK), 128 FREQ_INFO(1200, 1356, INTEL_BUS_CLK), 129 FREQ_INFO(1000, 1228, INTEL_BUS_CLK), 130 FREQ_INFO( 800, 1116, INTEL_BUS_CLK), 131 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 132 FREQ_INFO( 0, 0, 1), 133}; 134const freq_info PM14_130[] = { 135 /* 130nm 1.40GHz Pentium M */ 136 FREQ_INFO(1400, 1484, INTEL_BUS_CLK), 137 FREQ_INFO(1200, 1436, INTEL_BUS_CLK), 138 FREQ_INFO(1000, 1308, INTEL_BUS_CLK), 139 FREQ_INFO( 800, 1180, INTEL_BUS_CLK), 140 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 141 FREQ_INFO( 0, 0, 1), 142}; 143const freq_info PM13_130[] = { 144 /* 130nm 1.30GHz Pentium M */ 145 FREQ_INFO(1300, 1388, INTEL_BUS_CLK), 146 FREQ_INFO(1200, 1356, INTEL_BUS_CLK), 147 FREQ_INFO(1000, 1292, INTEL_BUS_CLK), 148 FREQ_INFO( 800, 1260, INTEL_BUS_CLK), 149 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 150 FREQ_INFO( 0, 0, 1), 151}; 152const freq_info PM13_LV_130[] = { 153 /* 130nm 1.30GHz Low Voltage Pentium M */ 154 FREQ_INFO(1300, 1180, INTEL_BUS_CLK), 155 FREQ_INFO(1200, 1164, INTEL_BUS_CLK), 156 FREQ_INFO(1100, 1100, INTEL_BUS_CLK), 157 FREQ_INFO(1000, 1020, INTEL_BUS_CLK), 158 FREQ_INFO( 900, 1004, INTEL_BUS_CLK), 159 FREQ_INFO( 800, 988, INTEL_BUS_CLK), 160 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 161 FREQ_INFO( 0, 0, 1), 162}; 163const freq_info PM12_LV_130[] = { 164 /* 130 nm 1.20GHz Low Voltage Pentium M */ 165 FREQ_INFO(1200, 1180, INTEL_BUS_CLK), 166 FREQ_INFO(1100, 1164, INTEL_BUS_CLK), 167 FREQ_INFO(1000, 1100, INTEL_BUS_CLK), 168 FREQ_INFO( 900, 1020, INTEL_BUS_CLK), 169 FREQ_INFO( 800, 1004, INTEL_BUS_CLK), 170 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 171 FREQ_INFO( 0, 0, 1), 172}; 173const freq_info PM11_LV_130[] = { 174 /* 130 nm 1.10GHz Low Voltage Pentium M */ 175 FREQ_INFO(1100, 1180, INTEL_BUS_CLK), 176 FREQ_INFO(1000, 1164, INTEL_BUS_CLK), 177 FREQ_INFO( 900, 1100, INTEL_BUS_CLK), 178 FREQ_INFO( 800, 1020, INTEL_BUS_CLK), 179 FREQ_INFO( 600, 956, INTEL_BUS_CLK), 180 FREQ_INFO( 0, 0, 1), 181}; 182const freq_info PM11_ULV_130[] = { 183 /* 130 nm 1.10GHz Ultra Low Voltage Pentium M */ 184 FREQ_INFO(1100, 1004, INTEL_BUS_CLK), 185 FREQ_INFO(1000, 988, INTEL_BUS_CLK), 186 FREQ_INFO( 900, 972, INTEL_BUS_CLK), 187 FREQ_INFO( 800, 956, INTEL_BUS_CLK), 188 FREQ_INFO( 600, 844, INTEL_BUS_CLK), 189 FREQ_INFO( 0, 0, 1), 190}; 191const freq_info PM10_ULV_130[] = { 192 /* 130 nm 1.00GHz Ultra Low Voltage Pentium M */ 193 FREQ_INFO(1000, 1004, INTEL_BUS_CLK), 194 FREQ_INFO( 900, 988, INTEL_BUS_CLK), 195 FREQ_INFO( 800, 972, INTEL_BUS_CLK), 196 FREQ_INFO( 600, 844, INTEL_BUS_CLK), 197 FREQ_INFO( 0, 0, 1), 198}; 199 200/* 201 * Data from "Intel Pentium M Processor on 90nm Process with 202 * 2-MB L2 Cache Datasheet", Order Number 302189, Table 5. 203 */ 204const freq_info PM_765A_90[] = { 205 /* 90 nm 2.10GHz Pentium M, VID #A */ 206 FREQ_INFO(2100, 1340, INTEL_BUS_CLK), 207 FREQ_INFO(1800, 1276, INTEL_BUS_CLK), 208 FREQ_INFO(1600, 1228, INTEL_BUS_CLK), 209 FREQ_INFO(1400, 1180, INTEL_BUS_CLK), 210 FREQ_INFO(1200, 1132, INTEL_BUS_CLK), 211 FREQ_INFO(1000, 1084, INTEL_BUS_CLK), 212 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 213 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 214 FREQ_INFO( 0, 0, 1), 215}; 216const freq_info PM_765B_90[] = { 217 /* 90 nm 2.10GHz Pentium M, VID #B */ 218 FREQ_INFO(2100, 1324, INTEL_BUS_CLK), 219 FREQ_INFO(1800, 1260, INTEL_BUS_CLK), 220 FREQ_INFO(1600, 1212, INTEL_BUS_CLK), 221 FREQ_INFO(1400, 1180, INTEL_BUS_CLK), 222 FREQ_INFO(1200, 1132, INTEL_BUS_CLK), 223 FREQ_INFO(1000, 1084, INTEL_BUS_CLK), 224 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 225 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 226 FREQ_INFO( 0, 0, 1), 227}; 228const freq_info PM_765C_90[] = { 229 /* 90 nm 2.10GHz Pentium M, VID #C */ 230 FREQ_INFO(2100, 1308, INTEL_BUS_CLK), 231 FREQ_INFO(1800, 1244, INTEL_BUS_CLK), 232 FREQ_INFO(1600, 1212, INTEL_BUS_CLK), 233 FREQ_INFO(1400, 1164, INTEL_BUS_CLK), 234 FREQ_INFO(1200, 1116, INTEL_BUS_CLK), 235 FREQ_INFO(1000, 1084, INTEL_BUS_CLK), 236 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 237 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 238 FREQ_INFO( 0, 0, 1), 239}; 240const freq_info PM_765E_90[] = { 241 /* 90 nm 2.10GHz Pentium M, VID #E */ 242 FREQ_INFO(2100, 1356, INTEL_BUS_CLK), 243 FREQ_INFO(1800, 1292, INTEL_BUS_CLK), 244 FREQ_INFO(1600, 1244, INTEL_BUS_CLK), 245 FREQ_INFO(1400, 1196, INTEL_BUS_CLK), 246 FREQ_INFO(1200, 1148, INTEL_BUS_CLK), 247 FREQ_INFO(1000, 1100, INTEL_BUS_CLK), 248 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 249 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 250 FREQ_INFO( 0, 0, 1), 251}; 252const freq_info PM_755A_90[] = { 253 /* 90 nm 2.00GHz Pentium M, VID #A */ 254 FREQ_INFO(2000, 1340, INTEL_BUS_CLK), 255 FREQ_INFO(1800, 1292, INTEL_BUS_CLK), 256 FREQ_INFO(1600, 1244, INTEL_BUS_CLK), 257 FREQ_INFO(1400, 1196, INTEL_BUS_CLK), 258 FREQ_INFO(1200, 1148, INTEL_BUS_CLK), 259 FREQ_INFO(1000, 1100, INTEL_BUS_CLK), 260 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 261 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 262 FREQ_INFO( 0, 0, 1), 263}; 264const freq_info PM_755B_90[] = { 265 /* 90 nm 2.00GHz Pentium M, VID #B */ 266 FREQ_INFO(2000, 1324, INTEL_BUS_CLK), 267 FREQ_INFO(1800, 1276, INTEL_BUS_CLK), 268 FREQ_INFO(1600, 1228, INTEL_BUS_CLK), 269 FREQ_INFO(1400, 1180, INTEL_BUS_CLK), 270 FREQ_INFO(1200, 1132, INTEL_BUS_CLK), 271 FREQ_INFO(1000, 1084, INTEL_BUS_CLK), 272 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 273 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 274 FREQ_INFO( 0, 0, 1), 275}; 276const freq_info PM_755C_90[] = { 277 /* 90 nm 2.00GHz Pentium M, VID #C */ 278 FREQ_INFO(2000, 1308, INTEL_BUS_CLK), 279 FREQ_INFO(1800, 1276, INTEL_BUS_CLK), 280 FREQ_INFO(1600, 1228, INTEL_BUS_CLK), 281 FREQ_INFO(1400, 1180, INTEL_BUS_CLK), 282 FREQ_INFO(1200, 1132, INTEL_BUS_CLK), 283 FREQ_INFO(1000, 1084, INTEL_BUS_CLK), 284 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 285 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 286 FREQ_INFO( 0, 0, 1), 287}; 288const freq_info PM_755D_90[] = { 289 /* 90 nm 2.00GHz Pentium M, VID #D */ 290 FREQ_INFO(2000, 1276, INTEL_BUS_CLK), 291 FREQ_INFO(1800, 1244, INTEL_BUS_CLK), 292 FREQ_INFO(1600, 1196, INTEL_BUS_CLK), 293 FREQ_INFO(1400, 1164, INTEL_BUS_CLK), 294 FREQ_INFO(1200, 1116, INTEL_BUS_CLK), 295 FREQ_INFO(1000, 1084, INTEL_BUS_CLK), 296 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 297 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 298 FREQ_INFO( 0, 0, 1), 299}; 300const freq_info PM_745A_90[] = { 301 /* 90 nm 1.80GHz Pentium M, VID #A */ 302 FREQ_INFO(1800, 1340, INTEL_BUS_CLK), 303 FREQ_INFO(1600, 1292, INTEL_BUS_CLK), 304 FREQ_INFO(1400, 1228, INTEL_BUS_CLK), 305 FREQ_INFO(1200, 1164, INTEL_BUS_CLK), 306 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 307 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 308 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 309 FREQ_INFO( 0, 0, 1), 310}; 311const freq_info PM_745B_90[] = { 312 /* 90 nm 1.80GHz Pentium M, VID #B */ 313 FREQ_INFO(1800, 1324, INTEL_BUS_CLK), 314 FREQ_INFO(1600, 1276, INTEL_BUS_CLK), 315 FREQ_INFO(1400, 1212, INTEL_BUS_CLK), 316 FREQ_INFO(1200, 1164, INTEL_BUS_CLK), 317 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 318 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 319 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 320 FREQ_INFO( 0, 0, 1), 321}; 322const freq_info PM_745C_90[] = { 323 /* 90 nm 1.80GHz Pentium M, VID #C */ 324 FREQ_INFO(1800, 1308, INTEL_BUS_CLK), 325 FREQ_INFO(1600, 1260, INTEL_BUS_CLK), 326 FREQ_INFO(1400, 1212, INTEL_BUS_CLK), 327 FREQ_INFO(1200, 1148, INTEL_BUS_CLK), 328 FREQ_INFO(1000, 1100, INTEL_BUS_CLK), 329 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 330 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 331 FREQ_INFO( 0, 0, 1), 332}; 333const freq_info PM_745D_90[] = { 334 /* 90 nm 1.80GHz Pentium M, VID #D */ 335 FREQ_INFO(1800, 1276, INTEL_BUS_CLK), 336 FREQ_INFO(1600, 1228, INTEL_BUS_CLK), 337 FREQ_INFO(1400, 1180, INTEL_BUS_CLK), 338 FREQ_INFO(1200, 1132, INTEL_BUS_CLK), 339 FREQ_INFO(1000, 1084, INTEL_BUS_CLK), 340 FREQ_INFO( 800, 1036, INTEL_BUS_CLK), 341 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 342 FREQ_INFO( 0, 0, 1), 343}; 344const freq_info PM_735A_90[] = { 345 /* 90 nm 1.70GHz Pentium M, VID #A */ 346 FREQ_INFO(1700, 1340, INTEL_BUS_CLK), 347 FREQ_INFO(1400, 1244, INTEL_BUS_CLK), 348 FREQ_INFO(1200, 1180, INTEL_BUS_CLK), 349 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 350 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 351 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 352 FREQ_INFO( 0, 0, 1), 353}; 354const freq_info PM_735B_90[] = { 355 /* 90 nm 1.70GHz Pentium M, VID #B */ 356 FREQ_INFO(1700, 1324, INTEL_BUS_CLK), 357 FREQ_INFO(1400, 1244, INTEL_BUS_CLK), 358 FREQ_INFO(1200, 1180, INTEL_BUS_CLK), 359 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 360 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 361 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 362 FREQ_INFO( 0, 0, 1), 363}; 364const freq_info PM_735C_90[] = { 365 /* 90 nm 1.70GHz Pentium M, VID #C */ 366 FREQ_INFO(1700, 1308, INTEL_BUS_CLK), 367 FREQ_INFO(1400, 1228, INTEL_BUS_CLK), 368 FREQ_INFO(1200, 1164, INTEL_BUS_CLK), 369 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 370 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 371 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 372 FREQ_INFO( 0, 0, 1), 373}; 374const freq_info PM_735D_90[] = { 375 /* 90 nm 1.70GHz Pentium M, VID #D */ 376 FREQ_INFO(1700, 1276, INTEL_BUS_CLK), 377 FREQ_INFO(1400, 1212, INTEL_BUS_CLK), 378 FREQ_INFO(1200, 1148, INTEL_BUS_CLK), 379 FREQ_INFO(1000, 1100, INTEL_BUS_CLK), 380 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 381 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 382 FREQ_INFO( 0, 0, 1), 383}; 384const freq_info PM_725A_90[] = { 385 /* 90 nm 1.60GHz Pentium M, VID #A */ 386 FREQ_INFO(1600, 1340, INTEL_BUS_CLK), 387 FREQ_INFO(1400, 1276, INTEL_BUS_CLK), 388 FREQ_INFO(1200, 1212, INTEL_BUS_CLK), 389 FREQ_INFO(1000, 1132, INTEL_BUS_CLK), 390 FREQ_INFO( 800, 1068, INTEL_BUS_CLK), 391 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 392 FREQ_INFO( 0, 0, 1), 393}; 394const freq_info PM_725B_90[] = { 395 /* 90 nm 1.60GHz Pentium M, VID #B */ 396 FREQ_INFO(1600, 1324, INTEL_BUS_CLK), 397 FREQ_INFO(1400, 1260, INTEL_BUS_CLK), 398 FREQ_INFO(1200, 1196, INTEL_BUS_CLK), 399 FREQ_INFO(1000, 1132, INTEL_BUS_CLK), 400 FREQ_INFO( 800, 1068, INTEL_BUS_CLK), 401 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 402 FREQ_INFO( 0, 0, 1), 403}; 404const freq_info PM_725C_90[] = { 405 /* 90 nm 1.60GHz Pentium M, VID #C */ 406 FREQ_INFO(1600, 1308, INTEL_BUS_CLK), 407 FREQ_INFO(1400, 1244, INTEL_BUS_CLK), 408 FREQ_INFO(1200, 1180, INTEL_BUS_CLK), 409 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 410 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 411 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 412 FREQ_INFO( 0, 0, 1), 413}; 414const freq_info PM_725D_90[] = { 415 /* 90 nm 1.60GHz Pentium M, VID #D */ 416 FREQ_INFO(1600, 1276, INTEL_BUS_CLK), 417 FREQ_INFO(1400, 1228, INTEL_BUS_CLK), 418 FREQ_INFO(1200, 1164, INTEL_BUS_CLK), 419 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 420 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 421 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 422 FREQ_INFO( 0, 0, 1), 423}; 424const freq_info PM_715A_90[] = { 425 /* 90 nm 1.50GHz Pentium M, VID #A */ 426 FREQ_INFO(1500, 1340, INTEL_BUS_CLK), 427 FREQ_INFO(1200, 1228, INTEL_BUS_CLK), 428 FREQ_INFO(1000, 1148, INTEL_BUS_CLK), 429 FREQ_INFO( 800, 1068, INTEL_BUS_CLK), 430 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 431 FREQ_INFO( 0, 0, 1), 432}; 433const freq_info PM_715B_90[] = { 434 /* 90 nm 1.50GHz Pentium M, VID #B */ 435 FREQ_INFO(1500, 1324, INTEL_BUS_CLK), 436 FREQ_INFO(1200, 1212, INTEL_BUS_CLK), 437 FREQ_INFO(1000, 1148, INTEL_BUS_CLK), 438 FREQ_INFO( 800, 1068, INTEL_BUS_CLK), 439 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 440 FREQ_INFO( 0, 0, 1), 441}; 442const freq_info PM_715C_90[] = { 443 /* 90 nm 1.50GHz Pentium M, VID #C */ 444 FREQ_INFO(1500, 1308, INTEL_BUS_CLK), 445 FREQ_INFO(1200, 1212, INTEL_BUS_CLK), 446 FREQ_INFO(1000, 1132, INTEL_BUS_CLK), 447 FREQ_INFO( 800, 1068, INTEL_BUS_CLK), 448 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 449 FREQ_INFO( 0, 0, 1), 450}; 451const freq_info PM_715D_90[] = { 452 /* 90 nm 1.50GHz Pentium M, VID #D */ 453 FREQ_INFO(1500, 1276, INTEL_BUS_CLK), 454 FREQ_INFO(1200, 1180, INTEL_BUS_CLK), 455 FREQ_INFO(1000, 1116, INTEL_BUS_CLK), 456 FREQ_INFO( 800, 1052, INTEL_BUS_CLK), 457 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 458 FREQ_INFO( 0, 0, 1), 459}; 460const freq_info PM_738_90[] = { 461 /* 90 nm 1.40GHz Low Voltage Pentium M */ 462 FREQ_INFO(1400, 1116, INTEL_BUS_CLK), 463 FREQ_INFO(1300, 1116, INTEL_BUS_CLK), 464 FREQ_INFO(1200, 1100, INTEL_BUS_CLK), 465 FREQ_INFO(1100, 1068, INTEL_BUS_CLK), 466 FREQ_INFO(1000, 1052, INTEL_BUS_CLK), 467 FREQ_INFO( 900, 1036, INTEL_BUS_CLK), 468 FREQ_INFO( 800, 1020, INTEL_BUS_CLK), 469 FREQ_INFO( 600, 988, INTEL_BUS_CLK), 470 FREQ_INFO( 0, 0, 1), 471}; 472const freq_info PM_733_90[] = { 473 /* 90 nm 1.10GHz Ultra Low Voltage Pentium M */ 474 FREQ_INFO(1100, 940, INTEL_BUS_CLK), 475 FREQ_INFO(1000, 924, INTEL_BUS_CLK), 476 FREQ_INFO( 900, 892, INTEL_BUS_CLK), 477 FREQ_INFO( 800, 876, INTEL_BUS_CLK), 478 FREQ_INFO( 600, 812, INTEL_BUS_CLK), 479 FREQ_INFO( 0, 0, 1), 480}; 481const freq_info PM_723_90[] = { 482 /* 90 nm 1.00GHz Ultra Low Voltage Pentium M */ 483 FREQ_INFO(1000, 940, INTEL_BUS_CLK), 484 FREQ_INFO( 900, 908, INTEL_BUS_CLK), 485 FREQ_INFO( 800, 876, INTEL_BUS_CLK), 486 FREQ_INFO( 600, 812, INTEL_BUS_CLK), 487 FREQ_INFO( 0, 0, 1), 488}; 489 490const cpu_info ESTprocs[] = { 491 INTEL(PM17_130, 1700, 1484, 600, 956, INTEL_BUS_CLK), 492 INTEL(PM16_130, 1600, 1484, 600, 956, INTEL_BUS_CLK), 493 INTEL(PM15_130, 1500, 1484, 600, 956, INTEL_BUS_CLK), 494 INTEL(PM14_130, 1400, 1484, 600, 956, INTEL_BUS_CLK), 495 INTEL(PM13_130, 1300, 1388, 600, 956, INTEL_BUS_CLK), 496 INTEL(PM13_LV_130, 1300, 1180, 600, 956, INTEL_BUS_CLK), 497 INTEL(PM12_LV_130, 1200, 1180, 600, 956, INTEL_BUS_CLK), 498 INTEL(PM11_LV_130, 1100, 1180, 600, 956, INTEL_BUS_CLK), 499 INTEL(PM11_ULV_130, 1100, 1004, 600, 844, INTEL_BUS_CLK), 500 INTEL(PM10_ULV_130, 1000, 1004, 600, 844, INTEL_BUS_CLK), 501 INTEL(PM_765A_90, 2100, 1340, 600, 988, INTEL_BUS_CLK), 502 INTEL(PM_765B_90, 2100, 1324, 600, 988, INTEL_BUS_CLK), 503 INTEL(PM_765C_90, 2100, 1308, 600, 988, INTEL_BUS_CLK), 504 INTEL(PM_765E_90, 2100, 1356, 600, 988, INTEL_BUS_CLK), 505 INTEL(PM_755A_90, 2000, 1340, 600, 988, INTEL_BUS_CLK), 506 INTEL(PM_755B_90, 2000, 1324, 600, 988, INTEL_BUS_CLK), 507 INTEL(PM_755C_90, 2000, 1308, 600, 988, INTEL_BUS_CLK), 508 INTEL(PM_755D_90, 2000, 1276, 600, 988, INTEL_BUS_CLK), 509 INTEL(PM_745A_90, 1800, 1340, 600, 988, INTEL_BUS_CLK), 510 INTEL(PM_745B_90, 1800, 1324, 600, 988, INTEL_BUS_CLK), 511 INTEL(PM_745C_90, 1800, 1308, 600, 988, INTEL_BUS_CLK), 512 INTEL(PM_745D_90, 1800, 1276, 600, 988, INTEL_BUS_CLK), 513 INTEL(PM_735A_90, 1700, 1340, 600, 988, INTEL_BUS_CLK), 514 INTEL(PM_735B_90, 1700, 1324, 600, 988, INTEL_BUS_CLK), 515 INTEL(PM_735C_90, 1700, 1308, 600, 988, INTEL_BUS_CLK), 516 INTEL(PM_735D_90, 1700, 1276, 600, 988, INTEL_BUS_CLK), 517 INTEL(PM_725A_90, 1600, 1340, 600, 988, INTEL_BUS_CLK), 518 INTEL(PM_725B_90, 1600, 1324, 600, 988, INTEL_BUS_CLK), 519 INTEL(PM_725C_90, 1600, 1308, 600, 988, INTEL_BUS_CLK), 520 INTEL(PM_725D_90, 1600, 1276, 600, 988, INTEL_BUS_CLK), 521 INTEL(PM_715A_90, 1500, 1340, 600, 988, INTEL_BUS_CLK), 522 INTEL(PM_715B_90, 1500, 1324, 600, 988, INTEL_BUS_CLK), 523 INTEL(PM_715C_90, 1500, 1308, 600, 988, INTEL_BUS_CLK), 524 INTEL(PM_715D_90, 1500, 1276, 600, 988, INTEL_BUS_CLK), 525 INTEL(PM_738_90, 1400, 1116, 600, 988, INTEL_BUS_CLK), 526 INTEL(PM_733_90, 1100, 940, 600, 812, INTEL_BUS_CLK), 527 INTEL(PM_723_90, 1000, 940, 600, 812, INTEL_BUS_CLK), 528 { NULL, 0, 0, NULL }, 529}; 530 531static void est_identify(driver_t *driver, device_t parent); 532static int est_probe(device_t parent); 533static int est_attach(device_t parent); 534static int est_detach(device_t parent); 535static int est_find_cpu(const char *vendor, uint64_t msr, uint32_t bus_clk, 536 const freq_info **freqs); 537static const freq_info *est_get_current(const freq_info *freq_list); 538static int est_settings(device_t dev, struct cf_setting *sets, int *count); 539static int est_set(device_t dev, const struct cf_setting *set); 540static int est_get(device_t dev, struct cf_setting *set); 541static int est_type(device_t dev, int *type); 542 543static device_method_t est_methods[] = { 544 /* Device interface */ 545 DEVMETHOD(device_identify, est_identify), 546 DEVMETHOD(device_probe, est_probe), 547 DEVMETHOD(device_attach, est_attach), 548 DEVMETHOD(device_detach, est_detach), 549 550 /* cpufreq interface */ 551 DEVMETHOD(cpufreq_drv_set, est_set), 552 DEVMETHOD(cpufreq_drv_get, est_get), 553 DEVMETHOD(cpufreq_drv_type, est_type), 554 DEVMETHOD(cpufreq_drv_settings, est_settings), 555 {0, 0} 556}; 557 558static driver_t est_driver = { 559 "est", 560 est_methods, 561 sizeof(struct est_softc), 562}; 563 564static devclass_t est_devclass; 565DRIVER_MODULE(est, cpu, est_driver, est_devclass, 0, 0); 566 567static void 568est_identify(driver_t *driver, device_t parent) 569{ 570 u_int p[4]; 571 572 /* Make sure we're not being doubly invoked. */ 573 if (device_find_child(parent, "est", -1) != NULL) 574 return; 575 576 /* Check that CPUID is supported and the vendor is Intel.*/ 577 if (cpu_high == 0 || strcmp(cpu_vendor, GenuineIntel) != 0) 578 return; 579 580 /* Read capability bits and check if the CPU supports EST. */ 581 do_cpuid(1, p); 582 if ((p[2] & 0x80) == 0) 583 return; 584 585 if (BUS_ADD_CHILD(parent, 0, "est", -1) == NULL) 586 device_printf(parent, "add est child failed\n"); 587} 588 589static int 590est_probe(device_t dev) 591{ 592 const freq_info *f; 593 device_t perf_dev; 594 uint64_t msr; 595 int error, type; 596 597 if (resource_disabled("est", 0)) 598 return (ENXIO); 599 600 /* 601 * If the ACPI perf driver has attached and is not just offering 602 * info, let it manage things. 603 */ 604 perf_dev = device_find_child(device_get_parent(dev), "acpi_perf", -1); 605 if (perf_dev && device_is_attached(perf_dev)) { 606 error = CPUFREQ_DRV_TYPE(perf_dev, &type); 607 if (error == 0 && (type & CPUFREQ_FLAG_INFO_ONLY) == 0) 608 return (ENXIO); 609 } 610 611 /* Attempt to enable SpeedStep if not currently enabled. */ 612 msr = rdmsr(MSR_MISC_ENABLE); 613 if ((msr & MSR_SS_ENABLE) == 0) { 614 wrmsr(MSR_MISC_ENABLE, msr | MSR_SS_ENABLE); 615 616 /* Check if the enable failed. */ 617 msr = rdmsr(MSR_MISC_ENABLE); 618 if ((msr & MSR_SS_ENABLE) == 0) { 619 device_printf(dev, "failed to enable SpeedStep\n"); 620 return (ENXIO); 621 } 622 } 623 624 /* Identify the exact CPU model */ 625 msr = rdmsr(MSR_PERF_STATUS); 626 if (est_find_cpu(cpu_vendor, msr, INTEL_BUS_CLK, &f) != 0) { 627 printf( 628 "CPU claims to support Enhanced Speedstep, but is not recognized.\n" 629 "Please update driver or contact the maintainer.\n" 630 "cpu_vendor = %s msr = %0jx, bus_clk = %x\n", 631 cpu_vendor, msr, INTEL_BUS_CLK); 632 return (ENXIO); 633 } 634 635 device_set_desc(dev, "Enhanced SpeedStep Frequency Control"); 636 return (0); 637} 638 639static int 640est_attach(device_t dev) 641{ 642 struct est_softc *sc; 643 uint64_t msr; 644 645 sc = device_get_softc(dev); 646 sc->dev = dev; 647 msr = rdmsr(MSR_PERF_STATUS); 648 est_find_cpu(cpu_vendor, msr, INTEL_BUS_CLK, &sc->freq_list); 649 cpufreq_register(dev); 650 651 return (0); 652} 653 654static int 655est_detach(device_t dev) 656{ 657 return (ENXIO); 658} 659 660static int 661est_find_cpu(const char *vendor, uint64_t msr, uint32_t bus_clk, 662 const freq_info **freqs) 663{ 664 const cpu_info *p; 665 uint32_t id; 666 667 /* Find a table which matches (vendor, id, bus_clk). */ 668 id = msr >> 32; 669 for (p = ESTprocs; p->id32 != 0; p++) { 670 if (strcmp(p->vendor, vendor) == 0 && p->id32 == id && 671 p->bus_clk == bus_clk) 672 break; 673 } 674 if (p->id32 == 0) 675 return (EOPNOTSUPP); 676 677 /* Make sure the current setpoint is valid. */ 678 if (est_get_current(p->freqtab) == NULL) 679 return (EOPNOTSUPP); 680 681 *freqs = p->freqtab; 682 return (0); 683} 684 685static const freq_info * 686est_get_current(const freq_info *freq_list) 687{ 688 const freq_info *f; 689 int i; 690 uint16_t id16; 691 692 /* 693 * Try a few times to get a valid value. Sometimes, if the CPU 694 * is in the middle of an asynchronous transition (i.e., P4TCC), 695 * we get a temporary invalid result. 696 */ 697 for (i = 0; i < 5; i++) { 698 id16 = rdmsr(MSR_PERF_STATUS) & 0xffff; 699 for (f = freq_list; f->id16 != 0; f++) { 700 if (f->id16 == id16) 701 return (f); 702 } 703 DELAY(100); 704 } 705 return (NULL); 706} 707 708static int 709est_settings(device_t dev, struct cf_setting *sets, int *count) 710{ 711 struct est_softc *sc; 712 const freq_info *f; 713 int i; 714 715 sc = device_get_softc(dev); 716 if (*count < EST_MAX_SETTINGS) 717 return (E2BIG); 718 719 i = 0; 720 for (f = sc->freq_list; f->freq != 0; f++, i++) { 721 sets[i].freq = f->freq; 722 sets[i].volts = f->volts; 723 sets[i].power = CPUFREQ_VAL_UNKNOWN; 724 sets[i].lat = EST_TRANS_LAT; 725 sets[i].dev = dev; 726 } 727 *count = i; 728 729 return (0); 730} 731 732static int 733est_set(device_t dev, const struct cf_setting *set) 734{ 735 struct est_softc *sc; 736 const freq_info *f; 737 uint64_t msr; 738 739 /* Find the setting matching the requested one. */ 740 sc = device_get_softc(dev); 741 for (f = sc->freq_list; f->freq != 0; f++) { 742 if (f->freq == set->freq) 743 break; 744 } 745 if (f->freq == 0) 746 return (EINVAL); 747 748 /* Read the current register, mask out the old, set the new id. */ 749 msr = rdmsr(MSR_PERF_CTL); 750 msr = (msr & ~0xffff) | f->id16; 751 wrmsr(MSR_PERF_CTL, msr); 752 753 /* Wait a short while for the new setting. XXX Is this necessary? */ 754 DELAY(EST_TRANS_LAT); 755 756 return (0); 757} 758 759static int 760est_get(device_t dev, struct cf_setting *set) 761{ 762 struct est_softc *sc; 763 const freq_info *f; 764 765 sc = device_get_softc(dev); 766 f = est_get_current(sc->freq_list); 767 if (f == NULL) 768 return (ENXIO); 769 770 set->freq = f->freq; 771 set->volts = f->volts; 772 set->power = CPUFREQ_VAL_UNKNOWN; 773 set->lat = EST_TRANS_LAT; 774 set->dev = dev; 775 return (0); 776} 777 778static int 779est_type(device_t dev, int *type) 780{ 781 782 if (type == NULL) 783 return (EINVAL); 784 785 *type = CPUFREQ_TYPE_ABSOLUTE; 786 return (0); 787} 788