Mon Aug 9 04:18:49 2010 UTC ()
Move the sysctl function pointers used by acpicpu(4) to x86/cpu.c.
Rename these so that the same pointers may be used in other parts.


(jruoho)
diff -r1.5 -r1.6 src/sys/arch/x86/acpi/acpi_cpu_md.c
diff -r1.35 -r1.36 src/sys/arch/x86/include/cpuvar.h
diff -r1.74 -r1.75 src/sys/arch/x86/x86/cpu.c
diff -r1.16 -r1.17 src/sys/arch/x86/x86/est.c

cvs diff -r1.5 -r1.6 src/sys/arch/x86/acpi/acpi_cpu_md.c (switch to unified diff)

--- src/sys/arch/x86/acpi/acpi_cpu_md.c 2010/08/08 16:58:41 1.5
+++ src/sys/arch/x86/acpi/acpi_cpu_md.c 2010/08/09 04:18:48 1.6
@@ -1,444 +1,428 @@ @@ -1,444 +1,428 @@
1/* $NetBSD: acpi_cpu_md.c,v 1.5 2010/08/08 16:58:41 jruoho Exp $ */ 1/* $NetBSD: acpi_cpu_md.c,v 1.6 2010/08/09 04:18:48 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi> 4 * Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.5 2010/08/08 16:58:41 jruoho Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.6 2010/08/09 04:18:48 jruoho Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bus.h> 33#include <sys/bus.h>
34#include <sys/kcore.h> 34#include <sys/kcore.h>
35#include <sys/sysctl.h> 35#include <sys/sysctl.h>
36#include <sys/xcall.h> 36#include <sys/xcall.h>
37 37
38#include <x86/cpu.h> 38#include <x86/cpu.h>
39#include <x86/cpufunc.h> 39#include <x86/cpufunc.h>
40#include <x86/cputypes.h> 40#include <x86/cputypes.h>
41#include <x86/cpuvar.h> 41#include <x86/cpuvar.h>
42#include <x86/cpu_msr.h> 42#include <x86/cpu_msr.h>
43#include <x86/machdep.h> 43#include <x86/machdep.h>
44 44
45#include <dev/acpi/acpica.h> 45#include <dev/acpi/acpica.h>
46#include <dev/acpi/acpi_cpu.h> 46#include <dev/acpi/acpi_cpu.h>
47 47
48static char native_idle_text[16]; 48static char native_idle_text[16];
49void (*native_idle)(void) = NULL; 49void (*native_idle)(void) = NULL;
50 50
51static int acpicpu_md_pstate_sysctl_get(SYSCTLFN_PROTO); 51static int acpicpu_md_pstate_sysctl_get(SYSCTLFN_PROTO);
52static int acpicpu_md_pstate_sysctl_set(SYSCTLFN_PROTO); 52static int acpicpu_md_pstate_sysctl_set(SYSCTLFN_PROTO);
53static int acpicpu_md_pstate_sysctl_all(SYSCTLFN_PROTO); 53static int acpicpu_md_pstate_sysctl_all(SYSCTLFN_PROTO);
54 54
55extern uint32_t cpus_running; 55extern uint32_t cpus_running;
56extern struct acpicpu_softc **acpicpu_sc; 56extern struct acpicpu_softc **acpicpu_sc;
57 57
58uint32_t 58uint32_t
59acpicpu_md_cap(void) 59acpicpu_md_cap(void)
60{ 60{
61 struct cpu_info *ci = curcpu(); 61 struct cpu_info *ci = curcpu();
62 uint32_t val = 0; 62 uint32_t val = 0;
63 63
64 if (cpu_vendor != CPUVENDOR_INTEL) 64 if (cpu_vendor != CPUVENDOR_INTEL)
65 return val; 65 return val;
66 66
67 /* 67 /*
68 * Basic SMP C-states (required for _CST). 68 * Basic SMP C-states (required for _CST).
69 */ 69 */
70 val |= ACPICPU_PDC_C_C1PT | ACPICPU_PDC_C_C2C3; 70 val |= ACPICPU_PDC_C_C1PT | ACPICPU_PDC_C_C2C3;
71 71
72 /* 72 /*
73 * If MONITOR/MWAIT is available, announce 73 * If MONITOR/MWAIT is available, announce
74 * support for native instructions in all C-states. 74 * support for native instructions in all C-states.
75 */ 75 */
76 if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0) 76 if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0)
77 val |= ACPICPU_PDC_C_C1_FFH | ACPICPU_PDC_C_C2C3_FFH; 77 val |= ACPICPU_PDC_C_C1_FFH | ACPICPU_PDC_C_C2C3_FFH;
78 78
79 /* 79 /*
80 * Set native P-states if EST is available. 80 * Set native P-states if EST is available.
81 */ 81 */
82 if ((ci->ci_feat_val[1] & CPUID2_EST) != 0) 82 if ((ci->ci_feat_val[1] & CPUID2_EST) != 0)
83 val |= ACPICPU_PDC_P_FFH; 83 val |= ACPICPU_PDC_P_FFH;
84 84
85 return val; 85 return val;
86} 86}
87 87
88uint32_t 88uint32_t
89acpicpu_md_quirks(void) 89acpicpu_md_quirks(void)
90{ 90{
91 struct cpu_info *ci = curcpu(); 91 struct cpu_info *ci = curcpu();
92 uint32_t val = 0; 92 uint32_t val = 0;
93 93
94 if (acpicpu_md_cpus_running() == 1) 94 if (acpicpu_md_cpus_running() == 1)
95 val |= ACPICPU_FLAG_C_BM; 95 val |= ACPICPU_FLAG_C_BM;
96 96
97 if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0) 97 if ((ci->ci_feat_val[1] & CPUID2_MONITOR) != 0)
98 val |= ACPICPU_FLAG_C_FFH; 98 val |= ACPICPU_FLAG_C_FFH;
99 99
100 switch (cpu_vendor) { 100 switch (cpu_vendor) {
101 101
102 case CPUVENDOR_INTEL: 102 case CPUVENDOR_INTEL:
103 103
104 val |= ACPICPU_FLAG_C_BM | ACPICPU_FLAG_C_ARB; 104 val |= ACPICPU_FLAG_C_BM | ACPICPU_FLAG_C_ARB;
105 105
106 if ((ci->ci_feat_val[1] & CPUID2_EST) != 0) 106 if ((ci->ci_feat_val[1] & CPUID2_EST) != 0)
107 val |= ACPICPU_FLAG_P_FFH; 107 val |= ACPICPU_FLAG_P_FFH;
108 108
109 /* 109 /*
110 * Bus master arbitration is not 110 * Bus master arbitration is not
111 * needed on some recent Intel CPUs. 111 * needed on some recent Intel CPUs.
112 */ 112 */
113 if (CPUID2FAMILY(ci->ci_signature) > 15) 113 if (CPUID2FAMILY(ci->ci_signature) > 15)
114 val &= ~ACPICPU_FLAG_C_ARB; 114 val &= ~ACPICPU_FLAG_C_ARB;
115 115
116 if (CPUID2FAMILY(ci->ci_signature) == 6 && 116 if (CPUID2FAMILY(ci->ci_signature) == 6 &&
117 CPUID2MODEL(ci->ci_signature) >= 15) 117 CPUID2MODEL(ci->ci_signature) >= 15)
118 val &= ~ACPICPU_FLAG_C_ARB; 118 val &= ~ACPICPU_FLAG_C_ARB;
119 119
120 break; 120 break;
121 121
122 case CPUVENDOR_AMD: 122 case CPUVENDOR_AMD:
123 123
124 /* 124 /*
125 * XXX: Deal with the AMD C1E extension here. 125 * XXX: Deal with the AMD C1E extension here.
126 */ 126 */
127 break; 127 break;
128 } 128 }
129 129
130 return val; 130 return val;
131} 131}
132 132
133uint32_t 133uint32_t
134acpicpu_md_cpus_running(void) 134acpicpu_md_cpus_running(void)
135{ 135{
136 136
137 return popcount32(cpus_running); 137 return popcount32(cpus_running);
138} 138}
139 139
140int 140int
141acpicpu_md_idle_init(void) 141acpicpu_md_idle_init(void)
142{ 142{
143 const size_t size = sizeof(native_idle_text); 143 const size_t size = sizeof(native_idle_text);
144 144
145 x86_disable_intr(); 145 x86_disable_intr();
146 x86_cpu_idle_get(&native_idle, native_idle_text, size); 146 x86_cpu_idle_get(&native_idle, native_idle_text, size);
147 x86_enable_intr(); 147 x86_enable_intr();
148 148
149 return 0; 149 return 0;
150} 150}
151 151
152int 152int
153acpicpu_md_idle_start(void) 153acpicpu_md_idle_start(void)
154{ 154{
155 155
156 x86_disable_intr(); 156 x86_disable_intr();
157 x86_cpu_idle_set(acpicpu_cstate_idle, "acpi"); 157 x86_cpu_idle_set(acpicpu_cstate_idle, "acpi");
158 x86_enable_intr(); 158 x86_enable_intr();
159 159
160 return 0; 160 return 0;
161} 161}
162 162
163int 163int
164acpicpu_md_idle_stop(void) 164acpicpu_md_idle_stop(void)
165{ 165{
166 uint64_t xc; 166 uint64_t xc;
167 167
168 x86_disable_intr(); 168 x86_disable_intr();
169 x86_cpu_idle_set(native_idle, native_idle_text); 169 x86_cpu_idle_set(native_idle, native_idle_text);
170 x86_enable_intr(); 170 x86_enable_intr();
171 171
172 /* 172 /*
173 * Run a cross-call to ensure that all CPUs are 173 * Run a cross-call to ensure that all CPUs are
174 * out from the ACPI idle-loop before detachment. 174 * out from the ACPI idle-loop before detachment.
175 */ 175 */
176 xc = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL); 176 xc = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
177 xc_wait(xc); 177 xc_wait(xc);
178 178
179 return 0; 179 return 0;
180} 180}
181 181
182/* 182/*
183 * The MD idle loop. Called with interrupts disabled. 183 * The MD idle loop. Called with interrupts disabled.
184 */ 184 */
185void 185void
186acpicpu_md_idle_enter(int method, int state) 186acpicpu_md_idle_enter(int method, int state)
187{ 187{
188 struct cpu_info *ci = curcpu(); 188 struct cpu_info *ci = curcpu();
189 189
190 switch (method) { 190 switch (method) {
191 191
192 case ACPICPU_C_STATE_FFH: 192 case ACPICPU_C_STATE_FFH:
193 193
194 x86_enable_intr(); 194 x86_enable_intr();
195 x86_monitor(&ci->ci_want_resched, 0, 0); 195 x86_monitor(&ci->ci_want_resched, 0, 0);
196 196
197 if (__predict_false(ci->ci_want_resched) != 0) 197 if (__predict_false(ci->ci_want_resched) != 0)
198 return; 198 return;
199 199
200 x86_mwait((state - 1) << 4, 0); 200 x86_mwait((state - 1) << 4, 0);
201 break; 201 break;
202 202
203 case ACPICPU_C_STATE_HALT: 203 case ACPICPU_C_STATE_HALT:
204 204
205 if (__predict_false(ci->ci_want_resched) != 0) { 205 if (__predict_false(ci->ci_want_resched) != 0) {
206 x86_enable_intr(); 206 x86_enable_intr();
207 return; 207 return;
208 } 208 }
209 209
210 x86_stihlt(); 210 x86_stihlt();
211 break; 211 break;
212 } 212 }
213} 213}
214 214
215int 215int
216acpicpu_md_pstate_start(void) 216acpicpu_md_pstate_start(void)
217{ 217{
218 218
219 switch (cpu_vendor) { 219 cpu_freq_sysctl_get = acpicpu_md_pstate_sysctl_get;
220 220 cpu_freq_sysctl_set = acpicpu_md_pstate_sysctl_set;
221 case CPUVENDOR_INTEL: 221 cpu_freq_sysctl_all = acpicpu_md_pstate_sysctl_all;
222 est_sysctl_get = acpicpu_md_pstate_sysctl_get; 
223 est_sysctl_set = acpicpu_md_pstate_sysctl_set; 
224 est_sysctl_all = acpicpu_md_pstate_sysctl_all; 
225 break; 
226 
227 default: 
228 return ENODEV; 
229 } 
230 222
231 return 0; 223 return 0;
232} 224}
233 225
234int 226int
235acpicpu_md_pstate_stop(void) 227acpicpu_md_pstate_stop(void)
236{ 228{
237 229
238 switch (cpu_vendor) { 230 cpu_freq_sysctl_get = NULL;
239 231 cpu_freq_sysctl_set = NULL;
240 case CPUVENDOR_INTEL: 232 cpu_freq_sysctl_all = NULL;
241 est_sysctl_get = NULL; 
242 est_sysctl_set = NULL; 
243 est_sysctl_all = NULL; 
244 break; 
245 
246 default: 
247 return ENODEV; 
248 } 
249 233
250 return 0; 234 return 0;
251} 235}
252 236
253static int 237static int
254acpicpu_md_pstate_sysctl_get(SYSCTLFN_ARGS) 238acpicpu_md_pstate_sysctl_get(SYSCTLFN_ARGS)
255{ 239{
256 struct cpu_info *ci = curcpu(); 240 struct cpu_info *ci = curcpu();
257 struct acpicpu_softc *sc; 241 struct acpicpu_softc *sc;
258 struct sysctlnode node; 242 struct sysctlnode node;
259 uint32_t freq; 243 uint32_t freq;
260 int err; 244 int err;
261 245
262 /* 246 /*
263 * We can use any ACPI CPU to manipulate the 247 * We can use any ACPI CPU to manipulate the
264 * frequencies. In MP environments all CPUs 248 * frequencies. In MP environments all CPUs
265 * are mandated to support the same number of 249 * are mandated to support the same number of
266 * P-states and each state must have identical 250 * P-states and each state must have identical
267 * parameters across CPUs. 251 * parameters across CPUs.
268 */ 252 */
269 sc = acpicpu_sc[ci->ci_acpiid]; 253 sc = acpicpu_sc[ci->ci_acpiid];
270 254
271 if (sc == NULL) 255 if (sc == NULL)
272 return ENXIO; 256 return ENXIO;
273 257
274 err = acpicpu_pstate_get(sc, &freq); 258 err = acpicpu_pstate_get(sc, &freq);
275 259
276 if (err != 0) 260 if (err != 0)
277 return err; 261 return err;
278 262
279 node = *rnode; 263 node = *rnode;
280 node.sysctl_data = &freq; 264 node.sysctl_data = &freq;
281 265
282 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 266 err = sysctl_lookup(SYSCTLFN_CALL(&node));
283 267
284 if (err != 0 || newp == NULL) 268 if (err != 0 || newp == NULL)
285 return err; 269 return err;
286 270
287 return 0; 271 return 0;
288} 272}
289 273
290static int 274static int
291acpicpu_md_pstate_sysctl_set(SYSCTLFN_ARGS) 275acpicpu_md_pstate_sysctl_set(SYSCTLFN_ARGS)
292{ 276{
293 struct cpu_info *ci = curcpu(); 277 struct cpu_info *ci = curcpu();
294 struct acpicpu_softc *sc; 278 struct acpicpu_softc *sc;
295 struct sysctlnode node; 279 struct sysctlnode node;
296 uint32_t freq; 280 uint32_t freq;
297 int err; 281 int err;
298 282
299 sc = acpicpu_sc[ci->ci_acpiid]; 283 sc = acpicpu_sc[ci->ci_acpiid];
300 284
301 if (sc == NULL) 285 if (sc == NULL)
302 return ENXIO; 286 return ENXIO;
303 287
304 err = acpicpu_pstate_get(sc, &freq); 288 err = acpicpu_pstate_get(sc, &freq);
305 289
306 if (err != 0) 290 if (err != 0)
307 return err; 291 return err;
308 292
309 node = *rnode; 293 node = *rnode;
310 node.sysctl_data = &freq; 294 node.sysctl_data = &freq;
311 295
312 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 296 err = sysctl_lookup(SYSCTLFN_CALL(&node));
313 297
314 if (err != 0 || newp == NULL) 298 if (err != 0 || newp == NULL)
315 return err; 299 return err;
316 300
317 err = acpicpu_pstate_set(sc, freq); 301 err = acpicpu_pstate_set(sc, freq);
318 302
319 if (err != 0) 303 if (err != 0)
320 return err; 304 return err;
321 305
322 return 0; 306 return 0;
323} 307}
324 308
325static int 309static int
326acpicpu_md_pstate_sysctl_all(SYSCTLFN_ARGS) 310acpicpu_md_pstate_sysctl_all(SYSCTLFN_ARGS)
327{ 311{
328 struct cpu_info *ci = curcpu(); 312 struct cpu_info *ci = curcpu();
329 struct acpicpu_softc *sc; 313 struct acpicpu_softc *sc;
330 struct sysctlnode node; 314 struct sysctlnode node;
331 char buf[1024]; 315 char buf[1024];
332 size_t len; 316 size_t len;
333 uint32_t i; 317 uint32_t i;
334 int err; 318 int err;
335 319
336 sc = acpicpu_sc[ci->ci_acpiid]; 320 sc = acpicpu_sc[ci->ci_acpiid];
337 321
338 if (sc == NULL) 322 if (sc == NULL)
339 return ENXIO; 323 return ENXIO;
340 324
341 (void)memset(&buf, 0, sizeof(buf)); 325 (void)memset(&buf, 0, sizeof(buf));
342 326
343 mutex_enter(&sc->sc_mtx); 327 mutex_enter(&sc->sc_mtx);
344 328
345 for (len = 0, i = sc->sc_pstate_max; i < sc->sc_pstate_count; i++) { 329 for (len = 0, i = sc->sc_pstate_max; i < sc->sc_pstate_count; i++) {
346 330
347 if (sc->sc_pstate[i].ps_freq == 0) 331 if (sc->sc_pstate[i].ps_freq == 0)
348 continue; 332 continue;
349 333
350 len += snprintf(buf + len, sizeof(buf) - len, "%u%s", 334 len += snprintf(buf + len, sizeof(buf) - len, "%u%s",
351 sc->sc_pstate[i].ps_freq, 335 sc->sc_pstate[i].ps_freq,
352 i < (sc->sc_pstate_count - 1) ? " " : ""); 336 i < (sc->sc_pstate_count - 1) ? " " : "");
353 } 337 }
354 338
355 mutex_exit(&sc->sc_mtx); 339 mutex_exit(&sc->sc_mtx);
356 340
357 node = *rnode; 341 node = *rnode;
358 node.sysctl_data = buf; 342 node.sysctl_data = buf;
359 343
360 err = sysctl_lookup(SYSCTLFN_CALL(&node)); 344 err = sysctl_lookup(SYSCTLFN_CALL(&node));
361 345
362 if (err != 0 || newp == NULL) 346 if (err != 0 || newp == NULL)
363 return err; 347 return err;
364 348
365 return 0; 349 return 0;
366} 350}
367 351
368int 352int
369acpicpu_md_pstate_get(struct acpicpu_softc *sc, uint32_t *freq) 353acpicpu_md_pstate_get(struct acpicpu_softc *sc, uint32_t *freq)
370{ 354{
371 struct acpicpu_pstate *ps; 355 struct acpicpu_pstate *ps;
372 uint64_t val; 356 uint64_t val;
373 uint32_t i; 357 uint32_t i;
374 358
375 switch (cpu_vendor) { 359 switch (cpu_vendor) {
376 360
377 case CPUVENDOR_INTEL: 361 case CPUVENDOR_INTEL:
378 362
379 val = rdmsr(MSR_PERF_STATUS); 363 val = rdmsr(MSR_PERF_STATUS);
380 val = val & 0xffff; 364 val = val & 0xffff;
381 365
382 mutex_enter(&sc->sc_mtx); 366 mutex_enter(&sc->sc_mtx);
383 367
384 for (i = sc->sc_pstate_max; i < sc->sc_pstate_count; i++) { 368 for (i = sc->sc_pstate_max; i < sc->sc_pstate_count; i++) {
385 369
386 ps = &sc->sc_pstate[i]; 370 ps = &sc->sc_pstate[i];
387 371
388 if (ps->ps_freq == 0) 372 if (ps->ps_freq == 0)
389 continue; 373 continue;
390 374
391 if (val == ps->ps_status) { 375 if (val == ps->ps_status) {
392 mutex_exit(&sc->sc_mtx); 376 mutex_exit(&sc->sc_mtx);
393 *freq = ps->ps_freq; 377 *freq = ps->ps_freq;
394 return 0; 378 return 0;
395 } 379 }
396 } 380 }
397 381
398 mutex_exit(&sc->sc_mtx); 382 mutex_exit(&sc->sc_mtx);
399 383
400 return EIO; 384 return EIO;
401 385
402 default: 386 default:
403 return ENODEV; 387 return ENODEV;
404 } 388 }
405 389
406 return 0; 390 return 0;
407} 391}
408 392
409int 393int
410acpicpu_md_pstate_set(struct acpicpu_pstate *ps) 394acpicpu_md_pstate_set(struct acpicpu_pstate *ps)
411{ 395{
412 struct msr_rw_info msr; 396 struct msr_rw_info msr;
413 uint64_t xc, val; 397 uint64_t xc, val;
414 int i; 398 int i;
415 399
416 switch (cpu_vendor) { 400 switch (cpu_vendor) {
417 401
418 case CPUVENDOR_INTEL: 402 case CPUVENDOR_INTEL:
419 msr.msr_read = true; 403 msr.msr_read = true;
420 msr.msr_type = MSR_PERF_CTL; 404 msr.msr_type = MSR_PERF_CTL;
421 msr.msr_value = ps->ps_control; 405 msr.msr_value = ps->ps_control;
422 msr.msr_mask = 0xffffULL; 406 msr.msr_mask = 0xffffULL;
423 break; 407 break;
424 408
425 default: 409 default:
426 return ENODEV; 410 return ENODEV;
427 } 411 }
428 412
429 xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL); 413 xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL);
430 xc_wait(xc); 414 xc_wait(xc);
431 415
432 for (i = val = 0; i < ACPICPU_P_STATE_RETRY; i++) { 416 for (i = val = 0; i < ACPICPU_P_STATE_RETRY; i++) {
433 417
434 val = rdmsr(MSR_PERF_STATUS); 418 val = rdmsr(MSR_PERF_STATUS);
435 val = val & 0xffff; 419 val = val & 0xffff;
436 420
437 if (val == ps->ps_status) 421 if (val == ps->ps_status)
438 return 0; 422 return 0;
439 423
440 DELAY(ps->ps_latency); 424 DELAY(ps->ps_latency);
441 } 425 }
442 426
443 return EAGAIN; 427 return EAGAIN;
444} 428}

cvs diff -r1.35 -r1.36 src/sys/arch/x86/include/cpuvar.h (switch to unified diff)

--- src/sys/arch/x86/include/cpuvar.h 2010/08/08 16:58:42 1.35
+++ src/sys/arch/x86/include/cpuvar.h 2010/08/09 04:18:48 1.36
@@ -1,159 +1,159 @@ @@ -1,159 +1,159 @@
1/* $NetBSD: cpuvar.h,v 1.35 2010/08/08 16:58:42 jruoho Exp $ */ 1/* $NetBSD: cpuvar.h,v 1.36 2010/08/09 04:18:48 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by RedBack Networks Inc. 8 * by RedBack Networks Inc.
9 * 9 *
10 * Author: Bill Sommerfeld 10 * Author: Bill Sommerfeld
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34/* 34/*
35 * Copyright (c) 1999 Stefan Grefen 35 * Copyright (c) 1999 Stefan Grefen
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software 45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement: 46 * must display the following acknowledgement:
47 * This product includes software developed by the NetBSD 47 * This product includes software developed by the NetBSD
48 * Foundation, Inc. and its contributors. 48 * Foundation, Inc. and its contributors.
49 * 4. Neither the name of The NetBSD Foundation nor the names of its 49 * 4. Neither the name of The NetBSD Foundation nor the names of its
50 * contributors may be used to endorse or promote products derived 50 * contributors may be used to endorse or promote products derived
51 * from this software without specific prior written permission.  51 * from this software without specific prior written permission.
52 * 52 *
53 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 53 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
54 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 */ 64 */
65 65
66#ifndef _X86_CPUVAR_H_ 66#ifndef _X86_CPUVAR_H_
67#define _X86_CPUVAR_H_ 67#define _X86_CPUVAR_H_
68 68
69#include <sys/sysctl.h> 69#include <sys/sysctl.h>
70 70
71struct cpu_functions { 71struct cpu_functions {
72 int (*start)(struct cpu_info *, paddr_t); 72 int (*start)(struct cpu_info *, paddr_t);
73 int (*stop)(struct cpu_info *); 73 int (*stop)(struct cpu_info *);
74 void (*cleanup)(struct cpu_info *); 74 void (*cleanup)(struct cpu_info *);
75}; 75};
76 76
77extern const struct cpu_functions mp_cpu_funcs; 77extern const struct cpu_functions mp_cpu_funcs;
78 78
79#define CPU_ROLE_SP 0 79#define CPU_ROLE_SP 0
80#define CPU_ROLE_BP 1 80#define CPU_ROLE_BP 1
81#define CPU_ROLE_AP 2 81#define CPU_ROLE_AP 2
82 82
83struct cpu_attach_args { 83struct cpu_attach_args {
84 int cpu_id; 84 int cpu_id;
85 int cpu_number; 85 int cpu_number;
86 int cpu_role; 86 int cpu_role;
87 const struct cpu_functions *cpu_func; 87 const struct cpu_functions *cpu_func;
88}; 88};
89 89
90#ifdef _KERNEL 90#ifdef _KERNEL
91 91
92#if defined(_KERNEL_OPT) 92#if defined(_KERNEL_OPT)
93#include "opt_multiprocessor.h" 93#include "opt_multiprocessor.h"
94#include "opt_enhanced_speedstep.h" 94#include "opt_enhanced_speedstep.h"
95#ifndef XEN 95#ifndef XEN
96#include "opt_intel_coretemp.h" 96#include "opt_intel_coretemp.h"
97#include "opt_intel_odcm.h" 97#include "opt_intel_odcm.h"
98#include "opt_via_c7temp.h" 98#include "opt_via_c7temp.h"
99#endif 99#endif
100#endif /* defined(_KERNEL_OPT) */ 100#endif /* defined(_KERNEL_OPT) */
101 101
102#ifdef MULTIPROCESSOR 102#ifdef MULTIPROCESSOR
103extern uint32_t cpus_running; 103extern uint32_t cpus_running;
104#endif 104#endif
105 105
106int x86_ipi(int, int, int); 106int x86_ipi(int, int, int);
107void x86_self_ipi(int); 107void x86_self_ipi(int);
108int x86_ipi_init(int); 108int x86_ipi_init(int);
109int x86_ipi_startup(int, int); 109int x86_ipi_startup(int, int);
110void x86_errata(void); 110void x86_errata(void);
111 111
112void identifycpu(struct cpu_info *); 112void identifycpu(struct cpu_info *);
113void identifycpu_cpuids(struct cpu_info *); 113void identifycpu_cpuids(struct cpu_info *);
114void cpu_init(struct cpu_info *); 114void cpu_init(struct cpu_info *);
115void cpu_init_tss(struct cpu_info *); 115void cpu_init_tss(struct cpu_info *);
116void cpu_init_first(void); 116void cpu_init_first(void);
117 117
118void x86_cpu_idle_init(void); 118void x86_cpu_idle_init(void);
119void x86_cpu_idle_halt(void); 119void x86_cpu_idle_halt(void);
120void x86_cpu_idle_mwait(void); 120void x86_cpu_idle_mwait(void);
121#ifdef XEN 121#ifdef XEN
122void x86_cpu_idle_xen(void); 122void x86_cpu_idle_xen(void);
123#endif 123#endif
124 124
125#ifdef VIA_C7TEMP 125#ifdef VIA_C7TEMP
126void viac7temp_register(struct cpu_info *); 126void viac7temp_register(struct cpu_info *);
127#endif 127#endif
128 128
129#ifdef INTEL_CORETEMP 129#ifdef INTEL_CORETEMP
130void coretemp_register(struct cpu_info *); 130void coretemp_register(struct cpu_info *);
131#endif 131#endif
132 132
133#ifdef INTEL_ONDEMAND_CLOCKMOD 133#ifdef INTEL_ONDEMAND_CLOCKMOD
134void clockmod_init(void); 134void clockmod_init(void);
135#endif 135#endif
136 136
137#ifdef ENHANCED_SPEEDSTEP 137#ifdef ENHANCED_SPEEDSTEP
138void est_init(int); 138void est_init(int);
139int via_get_bus_clock(struct cpu_info *); 139int via_get_bus_clock(struct cpu_info *);
140int viac7_get_bus_clock(struct cpu_info *); 140int viac7_get_bus_clock(struct cpu_info *);
141int p3_get_bus_clock(struct cpu_info *); 141int p3_get_bus_clock(struct cpu_info *);
142int p4_get_bus_clock(struct cpu_info *); 142int p4_get_bus_clock(struct cpu_info *);
143#endif 143#endif
144 144
145extern int (*est_sysctl_get)(SYSCTLFN_PROTO); 145extern int (*cpu_freq_sysctl_get)(SYSCTLFN_PROTO);
146extern int (*est_sysctl_set)(SYSCTLFN_PROTO); 146extern int (*cpu_freq_sysctl_set)(SYSCTLFN_PROTO);
147extern int (*est_sysctl_all)(SYSCTLFN_PROTO); 147extern int (*cpu_freq_sysctl_all)(SYSCTLFN_PROTO);
148 148
149void cpu_get_tsc_freq(struct cpu_info *); 149void cpu_get_tsc_freq(struct cpu_info *);
150void pat_init(struct cpu_info *); 150void pat_init(struct cpu_info *);
151 151
152extern int cpu_vendor; 152extern int cpu_vendor;
153extern bool x86_mp_online; 153extern bool x86_mp_online;
154 154
155extern uint32_t cpu_feature[5]; 155extern uint32_t cpu_feature[5];
156 156
157#endif /* _KERNEL */ 157#endif /* _KERNEL */
158 158
159#endif /* !_X86_CPUVAR_H_ */ 159#endif /* !_X86_CPUVAR_H_ */

cvs diff -r1.74 -r1.75 src/sys/arch/x86/x86/cpu.c (switch to unified diff)

--- src/sys/arch/x86/x86/cpu.c 2010/08/04 10:02:12 1.74
+++ src/sys/arch/x86/x86/cpu.c 2010/08/09 04:18:48 1.75
@@ -1,1132 +1,1136 @@ @@ -1,1132 +1,1136 @@
1/* $NetBSD: cpu.c,v 1.74 2010/08/04 10:02:12 jruoho Exp $ */ 1/* $NetBSD: cpu.c,v 1.75 2010/08/09 04:18:48 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000, 2006, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000, 2006, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran. 8 * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1999 Stefan Grefen 33 * Copyright (c) 1999 Stefan Grefen
34 * 34 *
35 * Redistribution and use in source and binary forms, with or without 35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions 36 * modification, are permitted provided that the following conditions
37 * are met: 37 * are met:
38 * 1. Redistributions of source code must retain the above copyright 38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer. 39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright 40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the 41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution. 42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software 43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement: 44 * must display the following acknowledgement:
45 * This product includes software developed by the NetBSD 45 * This product includes software developed by the NetBSD
46 * Foundation, Inc. and its contributors. 46 * Foundation, Inc. and its contributors.
47 * 4. Neither the name of The NetBSD Foundation nor the names of its 47 * 4. Neither the name of The NetBSD Foundation nor the names of its
48 * contributors may be used to endorse or promote products derived 48 * contributors may be used to endorse or promote products derived
49 * from this software without specific prior written permission. 49 * from this software without specific prior written permission.
50 * 50 *
51 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 51 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE. 61 * SUCH DAMAGE.
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.74 2010/08/04 10:02:12 jruoho Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.75 2010/08/09 04:18:48 jruoho Exp $");
66 66
67#include "opt_ddb.h" 67#include "opt_ddb.h"
68#include "opt_mpbios.h" /* for MPDEBUG */ 68#include "opt_mpbios.h" /* for MPDEBUG */
69#include "opt_mtrr.h" 69#include "opt_mtrr.h"
70 70
71#include "lapic.h" 71#include "lapic.h"
72#include "ioapic.h" 72#include "ioapic.h"
73 73
74#ifdef i386 74#ifdef i386
75#include "npx.h" 75#include "npx.h"
76#endif 76#endif
77 77
78#include <sys/param.h> 78#include <sys/param.h>
79#include <sys/proc.h> 79#include <sys/proc.h>
80#include <sys/systm.h> 80#include <sys/systm.h>
81#include <sys/device.h> 81#include <sys/device.h>
82#include <sys/kmem.h> 82#include <sys/kmem.h>
83#include <sys/cpu.h> 83#include <sys/cpu.h>
84#include <sys/atomic.h> 84#include <sys/atomic.h>
85#include <sys/reboot.h> 85#include <sys/reboot.h>
86 86
87#include <uvm/uvm_extern.h> 87#include <uvm/uvm_extern.h>
88 88
89#include <machine/cpufunc.h> 89#include <machine/cpufunc.h>
90#include <machine/cpuvar.h> 90#include <machine/cpuvar.h>
91#include <machine/pmap.h> 91#include <machine/pmap.h>
92#include <machine/vmparam.h> 92#include <machine/vmparam.h>
93#include <machine/mpbiosvar.h> 93#include <machine/mpbiosvar.h>
94#include <machine/pcb.h> 94#include <machine/pcb.h>
95#include <machine/specialreg.h> 95#include <machine/specialreg.h>
96#include <machine/segments.h> 96#include <machine/segments.h>
97#include <machine/gdt.h> 97#include <machine/gdt.h>
98#include <machine/mtrr.h> 98#include <machine/mtrr.h>
99#include <machine/pio.h> 99#include <machine/pio.h>
100#include <machine/cpu_counter.h> 100#include <machine/cpu_counter.h>
101 101
102#ifdef i386 102#ifdef i386
103#include <machine/tlog.h> 103#include <machine/tlog.h>
104#endif 104#endif
105 105
106#include <machine/apicvar.h> 106#include <machine/apicvar.h>
107#include <machine/i82489reg.h> 107#include <machine/i82489reg.h>
108#include <machine/i82489var.h> 108#include <machine/i82489var.h>
109 109
110#include <dev/ic/mc146818reg.h> 110#include <dev/ic/mc146818reg.h>
111#include <i386/isa/nvram.h> 111#include <i386/isa/nvram.h>
112#include <dev/isa/isareg.h> 112#include <dev/isa/isareg.h>
113 113
114#include "tsc.h" 114#include "tsc.h"
115 115
116#if MAXCPUS > 32 116#if MAXCPUS > 32
117#error cpu_info contains 32bit bitmasks 117#error cpu_info contains 32bit bitmasks
118#endif 118#endif
119 119
120int cpu_match(device_t, cfdata_t, void *); 120int cpu_match(device_t, cfdata_t, void *);
121void cpu_attach(device_t, device_t, void *); 121void cpu_attach(device_t, device_t, void *);
122 122
123static bool cpu_suspend(device_t, const pmf_qual_t *); 123static bool cpu_suspend(device_t, const pmf_qual_t *);
124static bool cpu_resume(device_t, const pmf_qual_t *); 124static bool cpu_resume(device_t, const pmf_qual_t *);
125 125
126struct cpu_softc { 126struct cpu_softc {
127 device_t sc_dev; /* device tree glue */ 127 device_t sc_dev; /* device tree glue */
128 struct cpu_info *sc_info; /* pointer to CPU info */ 128 struct cpu_info *sc_info; /* pointer to CPU info */
129 bool sc_wasonline; 129 bool sc_wasonline;
130}; 130};
131 131
132int mp_cpu_start(struct cpu_info *, paddr_t);  132int mp_cpu_start(struct cpu_info *, paddr_t);
133void mp_cpu_start_cleanup(struct cpu_info *); 133void mp_cpu_start_cleanup(struct cpu_info *);
134const struct cpu_functions mp_cpu_funcs = { mp_cpu_start, NULL, 134const struct cpu_functions mp_cpu_funcs = { mp_cpu_start, NULL,
135 mp_cpu_start_cleanup }; 135 mp_cpu_start_cleanup };
136 136
137 137
138CFATTACH_DECL_NEW(cpu, sizeof(struct cpu_softc), 138CFATTACH_DECL_NEW(cpu, sizeof(struct cpu_softc),
139 cpu_match, cpu_attach, NULL, NULL); 139 cpu_match, cpu_attach, NULL, NULL);
140 140
141/* 141/*
142 * Statically-allocated CPU info for the primary CPU (or the only 142 * Statically-allocated CPU info for the primary CPU (or the only
143 * CPU, on uniprocessors). The CPU info list is initialized to 143 * CPU, on uniprocessors). The CPU info list is initialized to
144 * point at it. 144 * point at it.
145 */ 145 */
146#ifdef TRAPLOG 146#ifdef TRAPLOG
147struct tlog tlog_primary; 147struct tlog tlog_primary;
148#endif 148#endif
149struct cpu_info cpu_info_primary __aligned(CACHE_LINE_SIZE) = { 149struct cpu_info cpu_info_primary __aligned(CACHE_LINE_SIZE) = {
150 .ci_dev = 0, 150 .ci_dev = 0,
151 .ci_self = &cpu_info_primary, 151 .ci_self = &cpu_info_primary,
152 .ci_idepth = -1, 152 .ci_idepth = -1,
153 .ci_curlwp = &lwp0, 153 .ci_curlwp = &lwp0,
154 .ci_curldt = -1, 154 .ci_curldt = -1,
155#ifdef TRAPLOG 155#ifdef TRAPLOG
156 .ci_tlog_base = &tlog_primary, 156 .ci_tlog_base = &tlog_primary,
157#endif /* !TRAPLOG */ 157#endif /* !TRAPLOG */
158}; 158};
159 159
160struct cpu_info *cpu_info_list = &cpu_info_primary; 160struct cpu_info *cpu_info_list = &cpu_info_primary;
161 161
162static void cpu_set_tss_gates(struct cpu_info *); 162static void cpu_set_tss_gates(struct cpu_info *);
163 163
164#ifdef i386 164#ifdef i386
165static void tss_init(struct i386tss *, void *, void *); 165static void tss_init(struct i386tss *, void *, void *);
166#endif 166#endif
167 167
168static void cpu_init_idle_lwp(struct cpu_info *); 168static void cpu_init_idle_lwp(struct cpu_info *);
169 169
170uint32_t cpus_attached = 0; 170uint32_t cpus_attached = 0;
171uint32_t cpus_running = 0; 171uint32_t cpus_running = 0;
172 172
173uint32_t cpu_feature[5]; /* X86 CPUID feature bits 173uint32_t cpu_feature[5]; /* X86 CPUID feature bits
174 * [0] basic features %edx 174 * [0] basic features %edx
175 * [1] basic features %ecx 175 * [1] basic features %ecx
176 * [2] extended features %edx 176 * [2] extended features %edx
177 * [3] extended features %ecx 177 * [3] extended features %ecx
178 * [4] VIA padlock features 178 * [4] VIA padlock features
179 */ 179 */
180 180
181extern char x86_64_doubleflt_stack[]; 181extern char x86_64_doubleflt_stack[];
182 182
183bool x86_mp_online; 183bool x86_mp_online;
184paddr_t mp_trampoline_paddr = MP_TRAMPOLINE; 184paddr_t mp_trampoline_paddr = MP_TRAMPOLINE;
185static vaddr_t cmos_data_mapping; 185static vaddr_t cmos_data_mapping;
186struct cpu_info *cpu_starting; 186struct cpu_info *cpu_starting;
187 187
 188int (*cpu_freq_sysctl_get)(SYSCTLFN_PROTO) = NULL;
 189int (*cpu_freq_sysctl_set)(SYSCTLFN_PROTO) = NULL;
 190int (*cpu_freq_sysctl_all)(SYSCTLFN_PROTO) = NULL;
 191
188void cpu_hatch(void *); 192void cpu_hatch(void *);
189static void cpu_boot_secondary(struct cpu_info *ci); 193static void cpu_boot_secondary(struct cpu_info *ci);
190static void cpu_start_secondary(struct cpu_info *ci); 194static void cpu_start_secondary(struct cpu_info *ci);
191static void cpu_copy_trampoline(void); 195static void cpu_copy_trampoline(void);
192 196
193/* 197/*
194 * Runs once per boot once multiprocessor goo has been detected and 198 * Runs once per boot once multiprocessor goo has been detected and
195 * the local APIC on the boot processor has been mapped. 199 * the local APIC on the boot processor has been mapped.
196 * 200 *
197 * Called from lapic_boot_init() (from mpbios_scan()). 201 * Called from lapic_boot_init() (from mpbios_scan()).
198 */ 202 */
199void 203void
200cpu_init_first(void) 204cpu_init_first(void)
201{ 205{
202 206
203 cpu_info_primary.ci_cpuid = lapic_cpu_number(); 207 cpu_info_primary.ci_cpuid = lapic_cpu_number();
204 cpu_copy_trampoline(); 208 cpu_copy_trampoline();
205 209
206 cmos_data_mapping = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY); 210 cmos_data_mapping = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY);
207 if (cmos_data_mapping == 0) 211 if (cmos_data_mapping == 0)
208 panic("No KVA for page 0"); 212 panic("No KVA for page 0");
209 pmap_kenter_pa(cmos_data_mapping, 0, VM_PROT_READ|VM_PROT_WRITE, 0); 213 pmap_kenter_pa(cmos_data_mapping, 0, VM_PROT_READ|VM_PROT_WRITE, 0);
210 pmap_update(pmap_kernel()); 214 pmap_update(pmap_kernel());
211} 215}
212 216
213int 217int
214cpu_match(device_t parent, cfdata_t match, void *aux) 218cpu_match(device_t parent, cfdata_t match, void *aux)
215{ 219{
216 220
217 return 1; 221 return 1;
218} 222}
219 223
220static void 224static void
221cpu_vm_init(struct cpu_info *ci) 225cpu_vm_init(struct cpu_info *ci)
222{ 226{
223 int ncolors = 2, i; 227 int ncolors = 2, i;
224 228
225 for (i = CAI_ICACHE; i <= CAI_L2CACHE; i++) { 229 for (i = CAI_ICACHE; i <= CAI_L2CACHE; i++) {
226 struct x86_cache_info *cai; 230 struct x86_cache_info *cai;
227 int tcolors; 231 int tcolors;
228 232
229 cai = &ci->ci_cinfo[i]; 233 cai = &ci->ci_cinfo[i];
230 234
231 tcolors = atop(cai->cai_totalsize); 235 tcolors = atop(cai->cai_totalsize);
232 switch(cai->cai_associativity) { 236 switch(cai->cai_associativity) {
233 case 0xff: 237 case 0xff:
234 tcolors = 1; /* fully associative */ 238 tcolors = 1; /* fully associative */
235 break; 239 break;
236 case 0: 240 case 0:
237 case 1: 241 case 1:
238 break; 242 break;
239 default: 243 default:
240 tcolors /= cai->cai_associativity; 244 tcolors /= cai->cai_associativity;
241 } 245 }
242 ncolors = max(ncolors, tcolors); 246 ncolors = max(ncolors, tcolors);
243 /* 247 /*
244 * If the desired number of colors is not a power of 248 * If the desired number of colors is not a power of
245 * two, it won't be good. Find the greatest power of 249 * two, it won't be good. Find the greatest power of
246 * two which is an even divisor of the number of colors, 250 * two which is an even divisor of the number of colors,
247 * to preserve even coloring of pages. 251 * to preserve even coloring of pages.
248 */ 252 */
249 if (ncolors & (ncolors - 1) ) { 253 if (ncolors & (ncolors - 1) ) {
250 int try, picked = 1; 254 int try, picked = 1;
251 for (try = 1; try < ncolors; try *= 2) { 255 for (try = 1; try < ncolors; try *= 2) {
252 if (ncolors % try == 0) picked = try; 256 if (ncolors % try == 0) picked = try;
253 } 257 }
254 if (picked == 1) { 258 if (picked == 1) {
255 panic("desired number of cache colors %d is " 259 panic("desired number of cache colors %d is "
256 " > 1, but not even!", ncolors); 260 " > 1, but not even!", ncolors);
257 } 261 }
258 ncolors = picked; 262 ncolors = picked;
259 } 263 }
260 } 264 }
261 265
262 /* 266 /*
263 * Knowing the size of the largest cache on this CPU, re-color 267 * Knowing the size of the largest cache on this CPU, re-color
264 * our pages. 268 * our pages.
265 */ 269 */
266 if (ncolors <= uvmexp.ncolors) 270 if (ncolors <= uvmexp.ncolors)
267 return; 271 return;
268 aprint_debug_dev(ci->ci_dev, "%d page colors\n", ncolors); 272 aprint_debug_dev(ci->ci_dev, "%d page colors\n", ncolors);
269 uvm_page_recolor(ncolors); 273 uvm_page_recolor(ncolors);
270} 274}
271 275
272 276
273void 277void
274cpu_attach(device_t parent, device_t self, void *aux) 278cpu_attach(device_t parent, device_t self, void *aux)
275{ 279{
276 struct cpu_softc *sc = device_private(self); 280 struct cpu_softc *sc = device_private(self);
277 struct cpu_attach_args *caa = aux; 281 struct cpu_attach_args *caa = aux;
278 struct cpu_info *ci; 282 struct cpu_info *ci;
279 uintptr_t ptr; 283 uintptr_t ptr;
280 int cpunum = caa->cpu_number; 284 int cpunum = caa->cpu_number;
281 static bool again; 285 static bool again;
282 286
283 sc->sc_dev = self; 287 sc->sc_dev = self;
284 288
285 if (cpus_attached == ~0) { 289 if (cpus_attached == ~0) {
286 aprint_error(": increase MAXCPUS\n"); 290 aprint_error(": increase MAXCPUS\n");
287 return; 291 return;
288 } 292 }
289 293
290 /* 294 /*
291 * If we're an Application Processor, allocate a cpu_info 295 * If we're an Application Processor, allocate a cpu_info
292 * structure, otherwise use the primary's. 296 * structure, otherwise use the primary's.
293 */ 297 */
294 if (caa->cpu_role == CPU_ROLE_AP) { 298 if (caa->cpu_role == CPU_ROLE_AP) {
295 if ((boothowto & RB_MD1) != 0) { 299 if ((boothowto & RB_MD1) != 0) {
296 aprint_error(": multiprocessor boot disabled\n"); 300 aprint_error(": multiprocessor boot disabled\n");
297 if (!pmf_device_register(self, NULL, NULL)) 301 if (!pmf_device_register(self, NULL, NULL))
298 aprint_error_dev(self, 302 aprint_error_dev(self,
299 "couldn't establish power handler\n"); 303 "couldn't establish power handler\n");
300 return; 304 return;
301 } 305 }
302 aprint_naive(": Application Processor\n"); 306 aprint_naive(": Application Processor\n");
303 ptr = (uintptr_t)kmem_zalloc(sizeof(*ci) + CACHE_LINE_SIZE - 1, 307 ptr = (uintptr_t)kmem_zalloc(sizeof(*ci) + CACHE_LINE_SIZE - 1,
304 KM_SLEEP); 308 KM_SLEEP);
305 ci = (struct cpu_info *)roundup2(ptr, CACHE_LINE_SIZE); 309 ci = (struct cpu_info *)roundup2(ptr, CACHE_LINE_SIZE);
306 ci->ci_curldt = -1; 310 ci->ci_curldt = -1;
307#ifdef TRAPLOG 311#ifdef TRAPLOG
308 ci->ci_tlog_base = kmem_zalloc(sizeof(struct tlog), KM_SLEEP); 312 ci->ci_tlog_base = kmem_zalloc(sizeof(struct tlog), KM_SLEEP);
309#endif 313#endif
310 } else { 314 } else {
311 aprint_naive(": %s Processor\n", 315 aprint_naive(": %s Processor\n",
312 caa->cpu_role == CPU_ROLE_SP ? "Single" : "Boot"); 316 caa->cpu_role == CPU_ROLE_SP ? "Single" : "Boot");
313 ci = &cpu_info_primary; 317 ci = &cpu_info_primary;
314 if (cpunum != lapic_cpu_number()) { 318 if (cpunum != lapic_cpu_number()) {
315 /* XXX should be done earlier. */ 319 /* XXX should be done earlier. */
316 uint32_t reg; 320 uint32_t reg;
317 aprint_verbose("\n"); 321 aprint_verbose("\n");
318 aprint_verbose_dev(self, "running CPU at apic %d" 322 aprint_verbose_dev(self, "running CPU at apic %d"
319 " instead of at expected %d", lapic_cpu_number(), 323 " instead of at expected %d", lapic_cpu_number(),
320 cpunum); 324 cpunum);
321 reg = i82489_readreg(LAPIC_ID); 325 reg = i82489_readreg(LAPIC_ID);
322 i82489_writereg(LAPIC_ID, (reg & ~LAPIC_ID_MASK) | 326 i82489_writereg(LAPIC_ID, (reg & ~LAPIC_ID_MASK) |
323 (cpunum << LAPIC_ID_SHIFT)); 327 (cpunum << LAPIC_ID_SHIFT));
324 } 328 }
325 if (cpunum != lapic_cpu_number()) { 329 if (cpunum != lapic_cpu_number()) {
326 aprint_error_dev(self, "unable to reset apic id\n"); 330 aprint_error_dev(self, "unable to reset apic id\n");
327 } 331 }
328 } 332 }
329 333
330 ci->ci_self = ci; 334 ci->ci_self = ci;
331 sc->sc_info = ci; 335 sc->sc_info = ci;
332 ci->ci_dev = self; 336 ci->ci_dev = self;
333 ci->ci_acpiid = caa->cpu_id; 337 ci->ci_acpiid = caa->cpu_id;
334 ci->ci_cpuid = caa->cpu_number; 338 ci->ci_cpuid = caa->cpu_number;
335 ci->ci_func = caa->cpu_func; 339 ci->ci_func = caa->cpu_func;
336 340
337 /* Must be before mi_cpu_attach(). */ 341 /* Must be before mi_cpu_attach(). */
338 cpu_vm_init(ci); 342 cpu_vm_init(ci);
339 343
340 if (caa->cpu_role == CPU_ROLE_AP) { 344 if (caa->cpu_role == CPU_ROLE_AP) {
341 int error; 345 int error;
342 346
343 error = mi_cpu_attach(ci); 347 error = mi_cpu_attach(ci);
344 if (error != 0) { 348 if (error != 0) {
345 aprint_normal("\n"); 349 aprint_normal("\n");
346 aprint_error_dev(self, 350 aprint_error_dev(self,
347 "mi_cpu_attach failed with %d\n", error); 351 "mi_cpu_attach failed with %d\n", error);
348 return; 352 return;
349 } 353 }
350 cpu_init_tss(ci); 354 cpu_init_tss(ci);
351 } else { 355 } else {
352 KASSERT(ci->ci_data.cpu_idlelwp != NULL); 356 KASSERT(ci->ci_data.cpu_idlelwp != NULL);
353 } 357 }
354 358
355 ci->ci_cpumask = (1 << cpu_index(ci)); 359 ci->ci_cpumask = (1 << cpu_index(ci));
356 pmap_reference(pmap_kernel()); 360 pmap_reference(pmap_kernel());
357 ci->ci_pmap = pmap_kernel(); 361 ci->ci_pmap = pmap_kernel();
358 ci->ci_tlbstate = TLBSTATE_STALE; 362 ci->ci_tlbstate = TLBSTATE_STALE;
359 363
360 /* 364 /*
361 * Boot processor may not be attached first, but the below 365 * Boot processor may not be attached first, but the below
362 * must be done to allow booting other processors. 366 * must be done to allow booting other processors.
363 */ 367 */
364 if (!again) { 368 if (!again) {
365 atomic_or_32(&ci->ci_flags, CPUF_PRESENT | CPUF_PRIMARY); 369 atomic_or_32(&ci->ci_flags, CPUF_PRESENT | CPUF_PRIMARY);
366 /* Basic init. */ 370 /* Basic init. */
367 cpu_intr_init(ci); 371 cpu_intr_init(ci);
368 cpu_get_tsc_freq(ci); 372 cpu_get_tsc_freq(ci);
369 cpu_init(ci); 373 cpu_init(ci);
370 cpu_set_tss_gates(ci); 374 cpu_set_tss_gates(ci);
371 pmap_cpu_init_late(ci); 375 pmap_cpu_init_late(ci);
372 if (caa->cpu_role != CPU_ROLE_SP) { 376 if (caa->cpu_role != CPU_ROLE_SP) {
373 /* Enable lapic. */ 377 /* Enable lapic. */
374 lapic_enable(); 378 lapic_enable();
375 lapic_set_lvt(); 379 lapic_set_lvt();
376 lapic_calibrate_timer(ci); 380 lapic_calibrate_timer(ci);
377 } 381 }
378 /* Make sure DELAY() is initialized. */ 382 /* Make sure DELAY() is initialized. */
379 DELAY(1); 383 DELAY(1);
380 again = true; 384 again = true;
381 } 385 }
382 386
383 /* further PCB init done later. */ 387 /* further PCB init done later. */
384 388
385 switch (caa->cpu_role) { 389 switch (caa->cpu_role) {
386 case CPU_ROLE_SP: 390 case CPU_ROLE_SP:
387 atomic_or_32(&ci->ci_flags, CPUF_SP); 391 atomic_or_32(&ci->ci_flags, CPUF_SP);
388 cpu_identify(ci); 392 cpu_identify(ci);
389 x86_errata(); 393 x86_errata();
390 x86_cpu_idle_init(); 394 x86_cpu_idle_init();
391 break; 395 break;
392 396
393 case CPU_ROLE_BP: 397 case CPU_ROLE_BP:
394 atomic_or_32(&ci->ci_flags, CPUF_BSP); 398 atomic_or_32(&ci->ci_flags, CPUF_BSP);
395 cpu_identify(ci); 399 cpu_identify(ci);
396 x86_errata(); 400 x86_errata();
397 x86_cpu_idle_init(); 401 x86_cpu_idle_init();
398 break; 402 break;
399 403
400 case CPU_ROLE_AP: 404 case CPU_ROLE_AP:
401 /* 405 /*
402 * report on an AP 406 * report on an AP
403 */ 407 */
404 cpu_intr_init(ci); 408 cpu_intr_init(ci);
405 gdt_alloc_cpu(ci); 409 gdt_alloc_cpu(ci);
406 cpu_set_tss_gates(ci); 410 cpu_set_tss_gates(ci);
407 pmap_cpu_init_early(ci); 411 pmap_cpu_init_early(ci);
408 pmap_cpu_init_late(ci); 412 pmap_cpu_init_late(ci);
409 cpu_start_secondary(ci); 413 cpu_start_secondary(ci);
410 if (ci->ci_flags & CPUF_PRESENT) { 414 if (ci->ci_flags & CPUF_PRESENT) {
411 struct cpu_info *tmp; 415 struct cpu_info *tmp;
412 416
413 cpu_identify(ci); 417 cpu_identify(ci);
414 tmp = cpu_info_list; 418 tmp = cpu_info_list;
415 while (tmp->ci_next) 419 while (tmp->ci_next)
416 tmp = tmp->ci_next; 420 tmp = tmp->ci_next;
417 421
418 tmp->ci_next = ci; 422 tmp->ci_next = ci;
419 } 423 }
420 break; 424 break;
421 425
422 default: 426 default:
423 aprint_normal("\n"); 427 aprint_normal("\n");
424 panic("unknown processor type??\n"); 428 panic("unknown processor type??\n");
425 } 429 }
426 430
427 pat_init(ci); 431 pat_init(ci);
428 atomic_or_32(&cpus_attached, ci->ci_cpumask); 432 atomic_or_32(&cpus_attached, ci->ci_cpumask);
429 433
430 if (!pmf_device_register(self, cpu_suspend, cpu_resume)) 434 if (!pmf_device_register(self, cpu_suspend, cpu_resume))
431 aprint_error_dev(self, "couldn't establish power handler\n"); 435 aprint_error_dev(self, "couldn't establish power handler\n");
432 436
433 if (mp_verbose) { 437 if (mp_verbose) {
434 struct lwp *l = ci->ci_data.cpu_idlelwp; 438 struct lwp *l = ci->ci_data.cpu_idlelwp;
435 struct pcb *pcb = lwp_getpcb(l); 439 struct pcb *pcb = lwp_getpcb(l);
436 440
437 aprint_verbose_dev(self, 441 aprint_verbose_dev(self,
438 "idle lwp at %p, idle sp at %p\n", 442 "idle lwp at %p, idle sp at %p\n",
439 l, 443 l,
440#ifdef i386 444#ifdef i386
441 (void *)pcb->pcb_esp 445 (void *)pcb->pcb_esp
442#else 446#else
443 (void *)pcb->pcb_rsp 447 (void *)pcb->pcb_rsp
444#endif 448#endif
445 ); 449 );
446 } 450 }
447} 451}
448 452
449/* 453/*
450 * Initialize the processor appropriately. 454 * Initialize the processor appropriately.
451 */ 455 */
452 456
453void 457void
454cpu_init(struct cpu_info *ci) 458cpu_init(struct cpu_info *ci)
455{ 459{
456 460
457 lcr0(rcr0() | CR0_WP); 461 lcr0(rcr0() | CR0_WP);
458 462
459 /* 463 /*
460 * On a P6 or above, enable global TLB caching if the 464 * On a P6 or above, enable global TLB caching if the
461 * hardware supports it. 465 * hardware supports it.
462 */ 466 */
463 if (cpu_feature[0] & CPUID_PGE) 467 if (cpu_feature[0] & CPUID_PGE)
464 lcr4(rcr4() | CR4_PGE); /* enable global TLB caching */ 468 lcr4(rcr4() | CR4_PGE); /* enable global TLB caching */
465 469
466 /* 470 /*
467 * If we have FXSAVE/FXRESTOR, use them. 471 * If we have FXSAVE/FXRESTOR, use them.
468 */ 472 */
469 if (cpu_feature[0] & CPUID_FXSR) { 473 if (cpu_feature[0] & CPUID_FXSR) {
470 lcr4(rcr4() | CR4_OSFXSR); 474 lcr4(rcr4() | CR4_OSFXSR);
471 475
472 /* 476 /*
473 * If we have SSE/SSE2, enable XMM exceptions. 477 * If we have SSE/SSE2, enable XMM exceptions.
474 */ 478 */
475 if (cpu_feature[0] & (CPUID_SSE|CPUID_SSE2)) 479 if (cpu_feature[0] & (CPUID_SSE|CPUID_SSE2))
476 lcr4(rcr4() | CR4_OSXMMEXCPT); 480 lcr4(rcr4() | CR4_OSXMMEXCPT);
477 } 481 }
478 482
479#ifdef MTRR 483#ifdef MTRR
480 /* 484 /*
481 * On a P6 or above, initialize MTRR's if the hardware supports them. 485 * On a P6 or above, initialize MTRR's if the hardware supports them.
482 */ 486 */
483 if (cpu_feature[0] & CPUID_MTRR) { 487 if (cpu_feature[0] & CPUID_MTRR) {
484 if ((ci->ci_flags & CPUF_AP) == 0) 488 if ((ci->ci_flags & CPUF_AP) == 0)
485 i686_mtrr_init_first(); 489 i686_mtrr_init_first();
486 mtrr_init_cpu(ci); 490 mtrr_init_cpu(ci);
487 } 491 }
488 492
489#ifdef i386 493#ifdef i386
490 if (strcmp((char *)(ci->ci_vendor), "AuthenticAMD") == 0) { 494 if (strcmp((char *)(ci->ci_vendor), "AuthenticAMD") == 0) {
491 /* 495 /*
492 * Must be a K6-2 Step >= 7 or a K6-III. 496 * Must be a K6-2 Step >= 7 or a K6-III.
493 */ 497 */
494 if (CPUID2FAMILY(ci->ci_signature) == 5) { 498 if (CPUID2FAMILY(ci->ci_signature) == 5) {
495 if (CPUID2MODEL(ci->ci_signature) > 8 || 499 if (CPUID2MODEL(ci->ci_signature) > 8 ||
496 (CPUID2MODEL(ci->ci_signature) == 8 && 500 (CPUID2MODEL(ci->ci_signature) == 8 &&
497 CPUID2STEPPING(ci->ci_signature) >= 7)) { 501 CPUID2STEPPING(ci->ci_signature) >= 7)) {
498 mtrr_funcs = &k6_mtrr_funcs; 502 mtrr_funcs = &k6_mtrr_funcs;
499 k6_mtrr_init_first(); 503 k6_mtrr_init_first();
500 mtrr_init_cpu(ci); 504 mtrr_init_cpu(ci);
501 } 505 }
502 } 506 }
503 } 507 }
504#endif /* i386 */ 508#endif /* i386 */
505#endif /* MTRR */ 509#endif /* MTRR */
506 510
507 atomic_or_32(&cpus_running, ci->ci_cpumask); 511 atomic_or_32(&cpus_running, ci->ci_cpumask);
508 512
509 if (ci != &cpu_info_primary) { 513 if (ci != &cpu_info_primary) {
510 /* Synchronize TSC again, and check for drift. */ 514 /* Synchronize TSC again, and check for drift. */
511 wbinvd(); 515 wbinvd();
512 atomic_or_32(&ci->ci_flags, CPUF_RUNNING); 516 atomic_or_32(&ci->ci_flags, CPUF_RUNNING);
513 tsc_sync_ap(ci); 517 tsc_sync_ap(ci);
514 } else { 518 } else {
515 atomic_or_32(&ci->ci_flags, CPUF_RUNNING); 519 atomic_or_32(&ci->ci_flags, CPUF_RUNNING);
516 } 520 }
517} 521}
518 522
519void 523void
520cpu_boot_secondary_processors(void) 524cpu_boot_secondary_processors(void)
521{ 525{
522 struct cpu_info *ci; 526 struct cpu_info *ci;
523 u_long i; 527 u_long i;
524 528
525 /* Now that we know the number of CPUs, patch the text segment. */ 529 /* Now that we know the number of CPUs, patch the text segment. */
526 x86_patch(false); 530 x86_patch(false);
527 531
528 for (i=0; i < maxcpus; i++) { 532 for (i=0; i < maxcpus; i++) {
529 ci = cpu_lookup(i); 533 ci = cpu_lookup(i);
530 if (ci == NULL) 534 if (ci == NULL)
531 continue; 535 continue;
532 if (ci->ci_data.cpu_idlelwp == NULL) 536 if (ci->ci_data.cpu_idlelwp == NULL)
533 continue; 537 continue;
534 if ((ci->ci_flags & CPUF_PRESENT) == 0) 538 if ((ci->ci_flags & CPUF_PRESENT) == 0)
535 continue; 539 continue;
536 if (ci->ci_flags & (CPUF_BSP|CPUF_SP|CPUF_PRIMARY)) 540 if (ci->ci_flags & (CPUF_BSP|CPUF_SP|CPUF_PRIMARY))
537 continue; 541 continue;
538 cpu_boot_secondary(ci); 542 cpu_boot_secondary(ci);
539 } 543 }
540 544
541 x86_mp_online = true; 545 x86_mp_online = true;
542 546
543 /* Now that we know about the TSC, attach the timecounter. */ 547 /* Now that we know about the TSC, attach the timecounter. */
544 tsc_tc_init(); 548 tsc_tc_init();
545 549
546 /* Enable zeroing of pages in the idle loop if we have SSE2. */ 550 /* Enable zeroing of pages in the idle loop if we have SSE2. */
547 vm_page_zero_enable = ((cpu_feature[0] & CPUID_SSE2) != 0); 551 vm_page_zero_enable = ((cpu_feature[0] & CPUID_SSE2) != 0);
548} 552}
549 553
550static void 554static void
551cpu_init_idle_lwp(struct cpu_info *ci) 555cpu_init_idle_lwp(struct cpu_info *ci)
552{ 556{
553 struct lwp *l = ci->ci_data.cpu_idlelwp; 557 struct lwp *l = ci->ci_data.cpu_idlelwp;
554 struct pcb *pcb = lwp_getpcb(l); 558 struct pcb *pcb = lwp_getpcb(l);
555 559
556 pcb->pcb_cr0 = rcr0(); 560 pcb->pcb_cr0 = rcr0();
557} 561}
558 562
559void 563void
560cpu_init_idle_lwps(void) 564cpu_init_idle_lwps(void)
561{ 565{
562 struct cpu_info *ci; 566 struct cpu_info *ci;
563 u_long i; 567 u_long i;
564 568
565 for (i = 0; i < maxcpus; i++) { 569 for (i = 0; i < maxcpus; i++) {
566 ci = cpu_lookup(i); 570 ci = cpu_lookup(i);
567 if (ci == NULL) 571 if (ci == NULL)
568 continue; 572 continue;
569 if (ci->ci_data.cpu_idlelwp == NULL) 573 if (ci->ci_data.cpu_idlelwp == NULL)
570 continue; 574 continue;
571 if ((ci->ci_flags & CPUF_PRESENT) == 0) 575 if ((ci->ci_flags & CPUF_PRESENT) == 0)
572 continue; 576 continue;
573 cpu_init_idle_lwp(ci); 577 cpu_init_idle_lwp(ci);
574 } 578 }
575} 579}
576 580
577void 581void
578cpu_start_secondary(struct cpu_info *ci) 582cpu_start_secondary(struct cpu_info *ci)
579{ 583{
580 extern paddr_t mp_pdirpa; 584 extern paddr_t mp_pdirpa;
581 u_long psl; 585 u_long psl;
582 int i; 586 int i;
583 587
584 mp_pdirpa = pmap_init_tmp_pgtbl(mp_trampoline_paddr); 588 mp_pdirpa = pmap_init_tmp_pgtbl(mp_trampoline_paddr);
585 atomic_or_32(&ci->ci_flags, CPUF_AP); 589 atomic_or_32(&ci->ci_flags, CPUF_AP);
586 ci->ci_curlwp = ci->ci_data.cpu_idlelwp; 590 ci->ci_curlwp = ci->ci_data.cpu_idlelwp;
587 if (CPU_STARTUP(ci, mp_trampoline_paddr) != 0) { 591 if (CPU_STARTUP(ci, mp_trampoline_paddr) != 0) {
588 return; 592 return;
589 } 593 }
590 594
591 /* 595 /*
592 * Wait for it to become ready. Setting cpu_starting opens the 596 * Wait for it to become ready. Setting cpu_starting opens the
593 * initial gate and allows the AP to start soft initialization. 597 * initial gate and allows the AP to start soft initialization.
594 */ 598 */
595 KASSERT(cpu_starting == NULL); 599 KASSERT(cpu_starting == NULL);
596 cpu_starting = ci; 600 cpu_starting = ci;
597 for (i = 100000; (!(ci->ci_flags & CPUF_PRESENT)) && i > 0; i--) { 601 for (i = 100000; (!(ci->ci_flags & CPUF_PRESENT)) && i > 0; i--) {
598#ifdef MPDEBUG 602#ifdef MPDEBUG
599 extern int cpu_trace[3]; 603 extern int cpu_trace[3];
600 static int otrace[3]; 604 static int otrace[3];
601 if (memcmp(otrace, cpu_trace, sizeof(otrace)) != 0) { 605 if (memcmp(otrace, cpu_trace, sizeof(otrace)) != 0) {
602 aprint_debug_dev(ci->ci_dev, "trace %02x %02x %02x\n", 606 aprint_debug_dev(ci->ci_dev, "trace %02x %02x %02x\n",
603 cpu_trace[0], cpu_trace[1], cpu_trace[2]); 607 cpu_trace[0], cpu_trace[1], cpu_trace[2]);
604 memcpy(otrace, cpu_trace, sizeof(otrace)); 608 memcpy(otrace, cpu_trace, sizeof(otrace));
605 } 609 }
606#endif 610#endif
607 i8254_delay(10); 611 i8254_delay(10);
608 } 612 }
609 613
610 if ((ci->ci_flags & CPUF_PRESENT) == 0) { 614 if ((ci->ci_flags & CPUF_PRESENT) == 0) {
611 aprint_error_dev(ci->ci_dev, "failed to become ready\n"); 615 aprint_error_dev(ci->ci_dev, "failed to become ready\n");
612#if defined(MPDEBUG) && defined(DDB) 616#if defined(MPDEBUG) && defined(DDB)
613 printf("dropping into debugger; continue from here to resume boot\n"); 617 printf("dropping into debugger; continue from here to resume boot\n");
614 Debugger(); 618 Debugger();
615#endif 619#endif
616 } else { 620 } else {
617 /* 621 /*
618 * Synchronize time stamp counters. Invalidate cache and do 622 * Synchronize time stamp counters. Invalidate cache and do
619 * twice to try and minimize possible cache effects. Disable 623 * twice to try and minimize possible cache effects. Disable
620 * interrupts to try and rule out any external interference. 624 * interrupts to try and rule out any external interference.
621 */ 625 */
622 psl = x86_read_psl(); 626 psl = x86_read_psl();
623 x86_disable_intr(); 627 x86_disable_intr();
624 wbinvd(); 628 wbinvd();
625 tsc_sync_bp(ci); 629 tsc_sync_bp(ci);
626 x86_write_psl(psl); 630 x86_write_psl(psl);
627 } 631 }
628 632
629 CPU_START_CLEANUP(ci); 633 CPU_START_CLEANUP(ci);
630 cpu_starting = NULL; 634 cpu_starting = NULL;
631} 635}
632 636
633void 637void
634cpu_boot_secondary(struct cpu_info *ci) 638cpu_boot_secondary(struct cpu_info *ci)
635{ 639{
636 int64_t drift; 640 int64_t drift;
637 u_long psl; 641 u_long psl;
638 int i; 642 int i;
639 643
640 atomic_or_32(&ci->ci_flags, CPUF_GO); 644 atomic_or_32(&ci->ci_flags, CPUF_GO);
641 for (i = 100000; (!(ci->ci_flags & CPUF_RUNNING)) && i > 0; i--) { 645 for (i = 100000; (!(ci->ci_flags & CPUF_RUNNING)) && i > 0; i--) {
642 i8254_delay(10); 646 i8254_delay(10);
643 } 647 }
644 if ((ci->ci_flags & CPUF_RUNNING) == 0) { 648 if ((ci->ci_flags & CPUF_RUNNING) == 0) {
645 aprint_error_dev(ci->ci_dev, "failed to start\n"); 649 aprint_error_dev(ci->ci_dev, "failed to start\n");
646#if defined(MPDEBUG) && defined(DDB) 650#if defined(MPDEBUG) && defined(DDB)
647 printf("dropping into debugger; continue from here to resume boot\n"); 651 printf("dropping into debugger; continue from here to resume boot\n");
648 Debugger(); 652 Debugger();
649#endif 653#endif
650 } else { 654 } else {
651 /* Synchronize TSC again, check for drift. */ 655 /* Synchronize TSC again, check for drift. */
652 drift = ci->ci_data.cpu_cc_skew; 656 drift = ci->ci_data.cpu_cc_skew;
653 psl = x86_read_psl(); 657 psl = x86_read_psl();
654 x86_disable_intr(); 658 x86_disable_intr();
655 wbinvd(); 659 wbinvd();
656 tsc_sync_bp(ci); 660 tsc_sync_bp(ci);
657 x86_write_psl(psl); 661 x86_write_psl(psl);
658 drift -= ci->ci_data.cpu_cc_skew; 662 drift -= ci->ci_data.cpu_cc_skew;
659 aprint_debug_dev(ci->ci_dev, "TSC skew=%lld drift=%lld\n", 663 aprint_debug_dev(ci->ci_dev, "TSC skew=%lld drift=%lld\n",
660 (long long)ci->ci_data.cpu_cc_skew, (long long)drift); 664 (long long)ci->ci_data.cpu_cc_skew, (long long)drift);
661 tsc_sync_drift(drift); 665 tsc_sync_drift(drift);
662 } 666 }
663} 667}
664 668
665/* 669/*
666 * The CPU ends up here when its ready to run 670 * The CPU ends up here when its ready to run
667 * This is called from code in mptramp.s; at this point, we are running 671 * This is called from code in mptramp.s; at this point, we are running
668 * in the idle pcb/idle stack of the new CPU. When this function returns, 672 * in the idle pcb/idle stack of the new CPU. When this function returns,
669 * this processor will enter the idle loop and start looking for work. 673 * this processor will enter the idle loop and start looking for work.
670 */ 674 */
671void 675void
672cpu_hatch(void *v) 676cpu_hatch(void *v)
673{ 677{
674 struct cpu_info *ci = (struct cpu_info *)v; 678 struct cpu_info *ci = (struct cpu_info *)v;
675 struct pcb *pcb; 679 struct pcb *pcb;
676 int s, i; 680 int s, i;
677 681
678 cpu_init_msrs(ci, true); 682 cpu_init_msrs(ci, true);
679 cpu_probe(ci); 683 cpu_probe(ci);
680 684
681 ci->ci_data.cpu_cc_freq = cpu_info_primary.ci_data.cpu_cc_freq; 685 ci->ci_data.cpu_cc_freq = cpu_info_primary.ci_data.cpu_cc_freq;
682 /* cpu_get_tsc_freq(ci); */  686 /* cpu_get_tsc_freq(ci); */
683 687
684 KDASSERT((ci->ci_flags & CPUF_PRESENT) == 0); 688 KDASSERT((ci->ci_flags & CPUF_PRESENT) == 0);
685 689
686 /* 690 /*
687 * Synchronize time stamp counters. Invalidate cache and do twice 691 * Synchronize time stamp counters. Invalidate cache and do twice
688 * to try and minimize possible cache effects. Note that interrupts 692 * to try and minimize possible cache effects. Note that interrupts
689 * are off at this point. 693 * are off at this point.
690 */ 694 */
691 wbinvd(); 695 wbinvd();
692 atomic_or_32(&ci->ci_flags, CPUF_PRESENT); 696 atomic_or_32(&ci->ci_flags, CPUF_PRESENT);
693 tsc_sync_ap(ci); 697 tsc_sync_ap(ci);
694 698
695 /* 699 /*
696 * Wait to be brought online. Use 'monitor/mwait' if available, 700 * Wait to be brought online. Use 'monitor/mwait' if available,
697 * in order to make the TSC drift as much as possible. so that 701 * in order to make the TSC drift as much as possible. so that
698 * we can detect it later. If not available, try 'pause'.  702 * we can detect it later. If not available, try 'pause'.
699 * We'd like to use 'hlt', but we have interrupts off. 703 * We'd like to use 'hlt', but we have interrupts off.
700 */ 704 */
701 while ((ci->ci_flags & CPUF_GO) == 0) { 705 while ((ci->ci_flags & CPUF_GO) == 0) {
702 if ((cpu_feature[1] & CPUID2_MONITOR) != 0) { 706 if ((cpu_feature[1] & CPUID2_MONITOR) != 0) {
703 x86_monitor(&ci->ci_flags, 0, 0); 707 x86_monitor(&ci->ci_flags, 0, 0);
704 if ((ci->ci_flags & CPUF_GO) != 0) { 708 if ((ci->ci_flags & CPUF_GO) != 0) {
705 continue; 709 continue;
706 } 710 }
707 x86_mwait(0, 0); 711 x86_mwait(0, 0);
708 } else { 712 } else {
709 for (i = 10000; i != 0; i--) { 713 for (i = 10000; i != 0; i--) {
710 x86_pause(); 714 x86_pause();
711 } 715 }
712 } 716 }
713 } 717 }
714 718
715 /* Because the text may have been patched in x86_patch(). */ 719 /* Because the text may have been patched in x86_patch(). */
716 wbinvd(); 720 wbinvd();
717 x86_flush(); 721 x86_flush();
718 722
719 KASSERT((ci->ci_flags & CPUF_RUNNING) == 0); 723 KASSERT((ci->ci_flags & CPUF_RUNNING) == 0);
720 724
721#ifdef PAE 725#ifdef PAE
722 pd_entry_t * l3_pd = ci->ci_pae_l3_pdir; 726 pd_entry_t * l3_pd = ci->ci_pae_l3_pdir;
723 for (i = 0 ; i < PDP_SIZE; i++) { 727 for (i = 0 ; i < PDP_SIZE; i++) {
724 l3_pd[i] = pmap_kernel()->pm_pdirpa[i] | PG_V; 728 l3_pd[i] = pmap_kernel()->pm_pdirpa[i] | PG_V;
725 } 729 }
726 lcr3(ci->ci_pae_l3_pdirpa); 730 lcr3(ci->ci_pae_l3_pdirpa);
727#else 731#else
728 lcr3(pmap_pdirpa(pmap_kernel(), 0)); 732 lcr3(pmap_pdirpa(pmap_kernel(), 0));
729#endif 733#endif
730 734
731 pcb = lwp_getpcb(curlwp); 735 pcb = lwp_getpcb(curlwp);
732 pcb->pcb_cr3 = rcr3(); 736 pcb->pcb_cr3 = rcr3();
733 pcb = lwp_getpcb(ci->ci_data.cpu_idlelwp); 737 pcb = lwp_getpcb(ci->ci_data.cpu_idlelwp);
734 lcr0(pcb->pcb_cr0); 738 lcr0(pcb->pcb_cr0);
735 739
736 cpu_init_idt(); 740 cpu_init_idt();
737 gdt_init_cpu(ci); 741 gdt_init_cpu(ci);
738 lapic_enable(); 742 lapic_enable();
739 lapic_set_lvt(); 743 lapic_set_lvt();
740 lapic_initclocks(); 744 lapic_initclocks();
741 745
742#ifdef i386 746#ifdef i386
743#if NNPX > 0 747#if NNPX > 0
744 npxinit(ci); 748 npxinit(ci);
745#endif 749#endif
746#else 750#else
747 fpuinit(ci); 751 fpuinit(ci);
748#endif 752#endif
749 lldt(GSYSSEL(GLDT_SEL, SEL_KPL)); 753 lldt(GSYSSEL(GLDT_SEL, SEL_KPL));
750 ltr(ci->ci_tss_sel); 754 ltr(ci->ci_tss_sel);
751 755
752 cpu_init(ci); 756 cpu_init(ci);
753 cpu_get_tsc_freq(ci); 757 cpu_get_tsc_freq(ci);
754 758
755 s = splhigh(); 759 s = splhigh();
756#ifdef i386 760#ifdef i386
757 lapic_tpr = 0; 761 lapic_tpr = 0;
758#else 762#else
759 lcr8(0); 763 lcr8(0);
760#endif 764#endif
761 x86_enable_intr(); 765 x86_enable_intr();
762 splx(s); 766 splx(s);
763 x86_errata(); 767 x86_errata();
764 768
765 aprint_debug_dev(ci->ci_dev, "running\n"); 769 aprint_debug_dev(ci->ci_dev, "running\n");
766} 770}
767 771
768#if defined(DDB) 772#if defined(DDB)
769 773
770#include <ddb/db_output.h> 774#include <ddb/db_output.h>
771#include <machine/db_machdep.h> 775#include <machine/db_machdep.h>
772 776
773/* 777/*
774 * Dump CPU information from ddb. 778 * Dump CPU information from ddb.
775 */ 779 */
776void 780void
777cpu_debug_dump(void) 781cpu_debug_dump(void)
778{ 782{
779 struct cpu_info *ci; 783 struct cpu_info *ci;
780 CPU_INFO_ITERATOR cii; 784 CPU_INFO_ITERATOR cii;
781 785
782 db_printf("addr dev id flags ipis curlwp fpcurlwp\n"); 786 db_printf("addr dev id flags ipis curlwp fpcurlwp\n");
783 for (CPU_INFO_FOREACH(cii, ci)) { 787 for (CPU_INFO_FOREACH(cii, ci)) {
784 db_printf("%p %s %ld %x %x %10p %10p\n", 788 db_printf("%p %s %ld %x %x %10p %10p\n",
785 ci, 789 ci,
786 ci->ci_dev == NULL ? "BOOT" : device_xname(ci->ci_dev), 790 ci->ci_dev == NULL ? "BOOT" : device_xname(ci->ci_dev),
787 (long)ci->ci_cpuid, 791 (long)ci->ci_cpuid,
788 ci->ci_flags, ci->ci_ipis, 792 ci->ci_flags, ci->ci_ipis,
789 ci->ci_curlwp, 793 ci->ci_curlwp,
790 ci->ci_fpcurlwp); 794 ci->ci_fpcurlwp);
791 } 795 }
792} 796}
793#endif 797#endif
794 798
795static void 799static void
796cpu_copy_trampoline(void) 800cpu_copy_trampoline(void)
797{ 801{
798 /* 802 /*
799 * Copy boot code. 803 * Copy boot code.
800 */ 804 */
801 extern u_char cpu_spinup_trampoline[]; 805 extern u_char cpu_spinup_trampoline[];
802 extern u_char cpu_spinup_trampoline_end[]; 806 extern u_char cpu_spinup_trampoline_end[];
803  807
804 vaddr_t mp_trampoline_vaddr; 808 vaddr_t mp_trampoline_vaddr;
805 809
806 mp_trampoline_vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, 810 mp_trampoline_vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
807 UVM_KMF_VAONLY); 811 UVM_KMF_VAONLY);
808 812
809 pmap_kenter_pa(mp_trampoline_vaddr, mp_trampoline_paddr, 813 pmap_kenter_pa(mp_trampoline_vaddr, mp_trampoline_paddr,
810 VM_PROT_READ | VM_PROT_WRITE, 0); 814 VM_PROT_READ | VM_PROT_WRITE, 0);
811 pmap_update(pmap_kernel()); 815 pmap_update(pmap_kernel());
812 memcpy((void *)mp_trampoline_vaddr, 816 memcpy((void *)mp_trampoline_vaddr,
813 cpu_spinup_trampoline, 817 cpu_spinup_trampoline,
814 cpu_spinup_trampoline_end - cpu_spinup_trampoline); 818 cpu_spinup_trampoline_end - cpu_spinup_trampoline);
815 819
816 pmap_kremove(mp_trampoline_vaddr, PAGE_SIZE); 820 pmap_kremove(mp_trampoline_vaddr, PAGE_SIZE);
817 pmap_update(pmap_kernel()); 821 pmap_update(pmap_kernel());
818 uvm_km_free(kernel_map, mp_trampoline_vaddr, PAGE_SIZE, UVM_KMF_VAONLY); 822 uvm_km_free(kernel_map, mp_trampoline_vaddr, PAGE_SIZE, UVM_KMF_VAONLY);
819} 823}
820 824
821#ifdef i386 825#ifdef i386
822static void 826static void
823tss_init(struct i386tss *tss, void *stack, void *func) 827tss_init(struct i386tss *tss, void *stack, void *func)
824{ 828{
825 KASSERT(curcpu()->ci_pmap == pmap_kernel()); 829 KASSERT(curcpu()->ci_pmap == pmap_kernel());
826 830
827 memset(tss, 0, sizeof *tss); 831 memset(tss, 0, sizeof *tss);
828 tss->tss_esp0 = tss->tss_esp = (int)((char *)stack + USPACE - 16); 832 tss->tss_esp0 = tss->tss_esp = (int)((char *)stack + USPACE - 16);
829 tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); 833 tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
830 tss->__tss_cs = GSEL(GCODE_SEL, SEL_KPL); 834 tss->__tss_cs = GSEL(GCODE_SEL, SEL_KPL);
831 tss->tss_fs = GSEL(GCPU_SEL, SEL_KPL); 835 tss->tss_fs = GSEL(GCPU_SEL, SEL_KPL);
832 tss->tss_gs = tss->__tss_es = tss->__tss_ds = 836 tss->tss_gs = tss->__tss_es = tss->__tss_ds =
833 tss->__tss_ss = GSEL(GDATA_SEL, SEL_KPL); 837 tss->__tss_ss = GSEL(GDATA_SEL, SEL_KPL);
834 /* %cr3 contains the value associated to pmap_kernel */ 838 /* %cr3 contains the value associated to pmap_kernel */
835 tss->tss_cr3 = rcr3(); 839 tss->tss_cr3 = rcr3();
836 tss->tss_esp = (int)((char *)stack + USPACE - 16); 840 tss->tss_esp = (int)((char *)stack + USPACE - 16);
837 tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 841 tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
838 tss->__tss_eflags = PSL_MBO | PSL_NT; /* XXX not needed? */ 842 tss->__tss_eflags = PSL_MBO | PSL_NT; /* XXX not needed? */
839 tss->__tss_eip = (int)func; 843 tss->__tss_eip = (int)func;
840} 844}
841 845
842/* XXX */ 846/* XXX */
843#define IDTVEC(name) __CONCAT(X, name) 847#define IDTVEC(name) __CONCAT(X, name)
844typedef void (vector)(void); 848typedef void (vector)(void);
845extern vector IDTVEC(tss_trap08); 849extern vector IDTVEC(tss_trap08);
846#ifdef DDB 850#ifdef DDB
847extern vector Xintrddbipi; 851extern vector Xintrddbipi;
848extern int ddb_vec; 852extern int ddb_vec;
849#endif 853#endif
850 854
851static void 855static void
852cpu_set_tss_gates(struct cpu_info *ci) 856cpu_set_tss_gates(struct cpu_info *ci)
853{ 857{
854 struct segment_descriptor sd; 858 struct segment_descriptor sd;
855 859
856 ci->ci_doubleflt_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0, 860 ci->ci_doubleflt_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0,
857 UVM_KMF_WIRED); 861 UVM_KMF_WIRED);
858 tss_init(&ci->ci_doubleflt_tss, ci->ci_doubleflt_stack, 862 tss_init(&ci->ci_doubleflt_tss, ci->ci_doubleflt_stack,
859 IDTVEC(tss_trap08)); 863 IDTVEC(tss_trap08));
860 setsegment(&sd, &ci->ci_doubleflt_tss, sizeof(struct i386tss) - 1, 864 setsegment(&sd, &ci->ci_doubleflt_tss, sizeof(struct i386tss) - 1,
861 SDT_SYS386TSS, SEL_KPL, 0, 0); 865 SDT_SYS386TSS, SEL_KPL, 0, 0);
862 ci->ci_gdt[GTRAPTSS_SEL].sd = sd; 866 ci->ci_gdt[GTRAPTSS_SEL].sd = sd;
863 setgate(&idt[8], NULL, 0, SDT_SYSTASKGT, SEL_KPL, 867 setgate(&idt[8], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
864 GSEL(GTRAPTSS_SEL, SEL_KPL)); 868 GSEL(GTRAPTSS_SEL, SEL_KPL));
865 869
866#if defined(DDB) 870#if defined(DDB)
867 /* 871 /*
868 * Set up separate handler for the DDB IPI, so that it doesn't 872 * Set up separate handler for the DDB IPI, so that it doesn't
869 * stomp on a possibly corrupted stack. 873 * stomp on a possibly corrupted stack.
870 * 874 *
871 * XXX overwriting the gate set in db_machine_init. 875 * XXX overwriting the gate set in db_machine_init.
872 * Should rearrange the code so that it's set only once. 876 * Should rearrange the code so that it's set only once.
873 */ 877 */
874 ci->ci_ddbipi_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0, 878 ci->ci_ddbipi_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0,
875 UVM_KMF_WIRED); 879 UVM_KMF_WIRED);
876 tss_init(&ci->ci_ddbipi_tss, ci->ci_ddbipi_stack, Xintrddbipi); 880 tss_init(&ci->ci_ddbipi_tss, ci->ci_ddbipi_stack, Xintrddbipi);
877 881
878 setsegment(&sd, &ci->ci_ddbipi_tss, sizeof(struct i386tss) - 1, 882 setsegment(&sd, &ci->ci_ddbipi_tss, sizeof(struct i386tss) - 1,
879 SDT_SYS386TSS, SEL_KPL, 0, 0); 883 SDT_SYS386TSS, SEL_KPL, 0, 0);
880 ci->ci_gdt[GIPITSS_SEL].sd = sd; 884 ci->ci_gdt[GIPITSS_SEL].sd = sd;
881 885
882 setgate(&idt[ddb_vec], NULL, 0, SDT_SYSTASKGT, SEL_KPL, 886 setgate(&idt[ddb_vec], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
883 GSEL(GIPITSS_SEL, SEL_KPL)); 887 GSEL(GIPITSS_SEL, SEL_KPL));
884#endif 888#endif
885} 889}
886#else 890#else
887static void 891static void
888cpu_set_tss_gates(struct cpu_info *ci) 892cpu_set_tss_gates(struct cpu_info *ci)
889{ 893{
890 894
891} 895}
892#endif /* i386 */ 896#endif /* i386 */
893 897
894int 898int
895mp_cpu_start(struct cpu_info *ci, paddr_t target) 899mp_cpu_start(struct cpu_info *ci, paddr_t target)
896{ 900{
897 unsigned short dwordptr[2]; 901 unsigned short dwordptr[2];
898 int error; 902 int error;
899 903
900 /* 904 /*
901 * Bootstrap code must be addressable in real mode 905 * Bootstrap code must be addressable in real mode
902 * and it must be page aligned. 906 * and it must be page aligned.
903 */ 907 */
904 KASSERT(target < 0x10000 && target % PAGE_SIZE == 0); 908 KASSERT(target < 0x10000 && target % PAGE_SIZE == 0);
905 909
906 /* 910 /*
907 * "The BSP must initialize CMOS shutdown code to 0Ah ..." 911 * "The BSP must initialize CMOS shutdown code to 0Ah ..."
908 */ 912 */
909 913
910 outb(IO_RTC, NVRAM_RESET); 914 outb(IO_RTC, NVRAM_RESET);
911 outb(IO_RTC+1, NVRAM_RESET_JUMP); 915 outb(IO_RTC+1, NVRAM_RESET_JUMP);
912 916
913 /* 917 /*
914 * "and the warm reset vector (DWORD based at 40:67) to point 918 * "and the warm reset vector (DWORD based at 40:67) to point
915 * to the AP startup code ..." 919 * to the AP startup code ..."
916 */ 920 */
917 921
918 dwordptr[0] = 0; 922 dwordptr[0] = 0;
919 dwordptr[1] = target >> 4; 923 dwordptr[1] = target >> 4;
920 924
921 memcpy((uint8_t *)cmos_data_mapping + 0x467, dwordptr, 4); 925 memcpy((uint8_t *)cmos_data_mapping + 0x467, dwordptr, 4);
922 926
923 if ((cpu_feature[0] & CPUID_APIC) == 0) { 927 if ((cpu_feature[0] & CPUID_APIC) == 0) {
924 aprint_error("mp_cpu_start: CPU does not have APIC\n"); 928 aprint_error("mp_cpu_start: CPU does not have APIC\n");
925 return ENODEV; 929 return ENODEV;
926 } 930 }
927 931
928 /* 932 /*
929 * ... prior to executing the following sequence:". We'll also add in 933 * ... prior to executing the following sequence:". We'll also add in
930 * local cache flush, in case the BIOS has left the AP with its cache 934 * local cache flush, in case the BIOS has left the AP with its cache
931 * disabled. It may not be able to cope with MP coherency. 935 * disabled. It may not be able to cope with MP coherency.
932 */ 936 */
933 wbinvd(); 937 wbinvd();
934 938
935 if (ci->ci_flags & CPUF_AP) { 939 if (ci->ci_flags & CPUF_AP) {
936 error = x86_ipi_init(ci->ci_cpuid); 940 error = x86_ipi_init(ci->ci_cpuid);
937 if (error != 0) { 941 if (error != 0) {
938 aprint_error_dev(ci->ci_dev, "%s: IPI not taken (1)\n", 942 aprint_error_dev(ci->ci_dev, "%s: IPI not taken (1)\n",
939 __func__); 943 __func__);
940 return error; 944 return error;
941 } 945 }
942 i8254_delay(10000); 946 i8254_delay(10000);
943 947
944 error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE); 948 error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE);
945 if (error != 0) { 949 if (error != 0) {
946 aprint_error_dev(ci->ci_dev, "%s: IPI not taken (2)\n", 950 aprint_error_dev(ci->ci_dev, "%s: IPI not taken (2)\n",
947 __func__); 951 __func__);
948 return error; 952 return error;
949 } 953 }
950 i8254_delay(200); 954 i8254_delay(200);
951 955
952 error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE); 956 error = x86_ipi_startup(ci->ci_cpuid, target / PAGE_SIZE);
953 if (error != 0) { 957 if (error != 0) {
954 aprint_error_dev(ci->ci_dev, "%s: IPI not taken (3)\n", 958 aprint_error_dev(ci->ci_dev, "%s: IPI not taken (3)\n",
955 __func__); 959 __func__);
956 return error; 960 return error;
957 } 961 }
958 i8254_delay(200); 962 i8254_delay(200);
959 } 963 }
960 964
961 return 0; 965 return 0;
962} 966}
963 967
964void 968void
965mp_cpu_start_cleanup(struct cpu_info *ci) 969mp_cpu_start_cleanup(struct cpu_info *ci)
966{ 970{
967 /* 971 /*
968 * Ensure the NVRAM reset byte contains something vaguely sane. 972 * Ensure the NVRAM reset byte contains something vaguely sane.
969 */ 973 */
970 974
971 outb(IO_RTC, NVRAM_RESET); 975 outb(IO_RTC, NVRAM_RESET);
972 outb(IO_RTC+1, NVRAM_RESET_RST); 976 outb(IO_RTC+1, NVRAM_RESET_RST);
973} 977}
974 978
975#ifdef __x86_64__ 979#ifdef __x86_64__
976typedef void (vector)(void); 980typedef void (vector)(void);
977extern vector Xsyscall, Xsyscall32; 981extern vector Xsyscall, Xsyscall32;
978#endif 982#endif
979 983
980void 984void
981cpu_init_msrs(struct cpu_info *ci, bool full) 985cpu_init_msrs(struct cpu_info *ci, bool full)
982{ 986{
983#ifdef __x86_64__ 987#ifdef __x86_64__
984 wrmsr(MSR_STAR, 988 wrmsr(MSR_STAR,
985 ((uint64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) | 989 ((uint64_t)GSEL(GCODE_SEL, SEL_KPL) << 32) |
986 ((uint64_t)LSEL(LSYSRETBASE_SEL, SEL_UPL) << 48)); 990 ((uint64_t)LSEL(LSYSRETBASE_SEL, SEL_UPL) << 48));
987 wrmsr(MSR_LSTAR, (uint64_t)Xsyscall); 991 wrmsr(MSR_LSTAR, (uint64_t)Xsyscall);
988 wrmsr(MSR_CSTAR, (uint64_t)Xsyscall32); 992 wrmsr(MSR_CSTAR, (uint64_t)Xsyscall32);
989 wrmsr(MSR_SFMASK, PSL_NT|PSL_T|PSL_I|PSL_C); 993 wrmsr(MSR_SFMASK, PSL_NT|PSL_T|PSL_I|PSL_C);
990 994
991 if (full) { 995 if (full) {
992 wrmsr(MSR_FSBASE, 0); 996 wrmsr(MSR_FSBASE, 0);
993 wrmsr(MSR_GSBASE, (uint64_t)ci); 997 wrmsr(MSR_GSBASE, (uint64_t)ci);
994 wrmsr(MSR_KERNELGSBASE, 0); 998 wrmsr(MSR_KERNELGSBASE, 0);
995 } 999 }
996#endif /* __x86_64__ */ 1000#endif /* __x86_64__ */
997 1001
998 if (cpu_feature[2] & CPUID_NOX) 1002 if (cpu_feature[2] & CPUID_NOX)
999 wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE); 1003 wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NXE);
1000} 1004}
1001 1005
1002void 1006void
1003cpu_offline_md(void) 1007cpu_offline_md(void)
1004{ 1008{
1005 int s; 1009 int s;
1006 1010
1007 s = splhigh(); 1011 s = splhigh();
1008#ifdef i386 1012#ifdef i386
1009#if NNPX > 0 1013#if NNPX > 0
1010 npxsave_cpu(true); 1014 npxsave_cpu(true);
1011#endif 1015#endif
1012#else 1016#else
1013 fpusave_cpu(true); 1017 fpusave_cpu(true);
1014#endif 1018#endif
1015 splx(s); 1019 splx(s);
1016} 1020}
1017 1021
1018/* XXX joerg restructure and restart CPUs individually */ 1022/* XXX joerg restructure and restart CPUs individually */
1019static bool 1023static bool
1020cpu_suspend(device_t dv, const pmf_qual_t *qual) 1024cpu_suspend(device_t dv, const pmf_qual_t *qual)
1021{ 1025{
1022 struct cpu_softc *sc = device_private(dv); 1026 struct cpu_softc *sc = device_private(dv);
1023 struct cpu_info *ci = sc->sc_info; 1027 struct cpu_info *ci = sc->sc_info;
1024 int err; 1028 int err;
1025 1029
1026 if (ci->ci_flags & CPUF_PRIMARY) 1030 if (ci->ci_flags & CPUF_PRIMARY)
1027 return true; 1031 return true;
1028 if (ci->ci_data.cpu_idlelwp == NULL) 1032 if (ci->ci_data.cpu_idlelwp == NULL)
1029 return true; 1033 return true;
1030 if ((ci->ci_flags & CPUF_PRESENT) == 0) 1034 if ((ci->ci_flags & CPUF_PRESENT) == 0)
1031 return true; 1035 return true;
1032 1036
1033 sc->sc_wasonline = !(ci->ci_schedstate.spc_flags & SPCF_OFFLINE); 1037 sc->sc_wasonline = !(ci->ci_schedstate.spc_flags & SPCF_OFFLINE);
1034 1038
1035 if (sc->sc_wasonline) { 1039 if (sc->sc_wasonline) {
1036 mutex_enter(&cpu_lock); 1040 mutex_enter(&cpu_lock);
1037 err = cpu_setstate(ci, false); 1041 err = cpu_setstate(ci, false);
1038 mutex_exit(&cpu_lock); 1042 mutex_exit(&cpu_lock);
1039  1043
1040 if (err) 1044 if (err)
1041 return false; 1045 return false;
1042 } 1046 }
1043 1047
1044 return true; 1048 return true;
1045} 1049}
1046 1050
1047static bool 1051static bool
1048cpu_resume(device_t dv, const pmf_qual_t *qual) 1052cpu_resume(device_t dv, const pmf_qual_t *qual)
1049{ 1053{
1050 struct cpu_softc *sc = device_private(dv); 1054 struct cpu_softc *sc = device_private(dv);
1051 struct cpu_info *ci = sc->sc_info; 1055 struct cpu_info *ci = sc->sc_info;
1052 int err = 0; 1056 int err = 0;
1053 1057
1054 if (ci->ci_flags & CPUF_PRIMARY) 1058 if (ci->ci_flags & CPUF_PRIMARY)
1055 return true; 1059 return true;
1056 if (ci->ci_data.cpu_idlelwp == NULL) 1060 if (ci->ci_data.cpu_idlelwp == NULL)
1057 return true; 1061 return true;
1058 if ((ci->ci_flags & CPUF_PRESENT) == 0) 1062 if ((ci->ci_flags & CPUF_PRESENT) == 0)
1059 return true; 1063 return true;
1060 1064
1061 if (sc->sc_wasonline) { 1065 if (sc->sc_wasonline) {
1062 mutex_enter(&cpu_lock); 1066 mutex_enter(&cpu_lock);
1063 err = cpu_setstate(ci, true); 1067 err = cpu_setstate(ci, true);
1064 mutex_exit(&cpu_lock); 1068 mutex_exit(&cpu_lock);
1065 } 1069 }
1066 1070
1067 return err == 0; 1071 return err == 0;
1068} 1072}
1069 1073
1070void 1074void
1071cpu_get_tsc_freq(struct cpu_info *ci) 1075cpu_get_tsc_freq(struct cpu_info *ci)
1072{ 1076{
1073 uint64_t last_tsc; 1077 uint64_t last_tsc;
1074 1078
1075 if (cpu_hascounter()) { 1079 if (cpu_hascounter()) {
1076 last_tsc = rdmsr(MSR_TSC); 1080 last_tsc = rdmsr(MSR_TSC);
1077 i8254_delay(100000); 1081 i8254_delay(100000);
1078 ci->ci_data.cpu_cc_freq = (rdmsr(MSR_TSC) - last_tsc) * 10; 1082 ci->ci_data.cpu_cc_freq = (rdmsr(MSR_TSC) - last_tsc) * 10;
1079 } 1083 }
1080} 1084}
1081 1085
1082void 1086void
1083x86_cpu_idle_mwait(void) 1087x86_cpu_idle_mwait(void)
1084{ 1088{
1085 struct cpu_info *ci = curcpu(); 1089 struct cpu_info *ci = curcpu();
1086 1090
1087 KASSERT(ci->ci_ilevel == IPL_NONE); 1091 KASSERT(ci->ci_ilevel == IPL_NONE);
1088 1092
1089 x86_monitor(&ci->ci_want_resched, 0, 0); 1093 x86_monitor(&ci->ci_want_resched, 0, 0);
1090 if (__predict_false(ci->ci_want_resched)) { 1094 if (__predict_false(ci->ci_want_resched)) {
1091 return; 1095 return;
1092 } 1096 }
1093 x86_mwait(0, 0); 1097 x86_mwait(0, 0);
1094} 1098}
1095 1099
1096void 1100void
1097x86_cpu_idle_halt(void) 1101x86_cpu_idle_halt(void)
1098{ 1102{
1099 struct cpu_info *ci = curcpu(); 1103 struct cpu_info *ci = curcpu();
1100 1104
1101 KASSERT(ci->ci_ilevel == IPL_NONE); 1105 KASSERT(ci->ci_ilevel == IPL_NONE);
1102 1106
1103 x86_disable_intr(); 1107 x86_disable_intr();
1104 if (!__predict_false(ci->ci_want_resched)) { 1108 if (!__predict_false(ci->ci_want_resched)) {
1105 x86_stihlt(); 1109 x86_stihlt();
1106 } else { 1110 } else {
1107 x86_enable_intr(); 1111 x86_enable_intr();
1108 } 1112 }
1109} 1113}
1110 1114
1111/* 1115/*
1112 * Loads pmap for the current CPU. 1116 * Loads pmap for the current CPU.
1113 */ 1117 */
1114void 1118void
1115cpu_load_pmap(struct pmap *pmap) 1119cpu_load_pmap(struct pmap *pmap)
1116{ 1120{
1117#ifdef PAE 1121#ifdef PAE
1118 int i, s; 1122 int i, s;
1119 struct cpu_info *ci; 1123 struct cpu_info *ci;
1120 1124
1121 s = splvm(); /* just to be safe */ 1125 s = splvm(); /* just to be safe */
1122 ci = curcpu(); 1126 ci = curcpu();
1123 pd_entry_t *l3_pd = ci->ci_pae_l3_pdir; 1127 pd_entry_t *l3_pd = ci->ci_pae_l3_pdir;
1124 for (i = 0 ; i < PDP_SIZE; i++) { 1128 for (i = 0 ; i < PDP_SIZE; i++) {
1125 l3_pd[i] = pmap->pm_pdirpa[i] | PG_V; 1129 l3_pd[i] = pmap->pm_pdirpa[i] | PG_V;
1126 } 1130 }
1127 splx(s); 1131 splx(s);
1128 tlbflush(); 1132 tlbflush();
1129#else /* PAE */ 1133#else /* PAE */
1130 lcr3(pmap_pdirpa(pmap, 0)); 1134 lcr3(pmap_pdirpa(pmap, 0));
1131#endif /* PAE */ 1135#endif /* PAE */
1132} 1136}

cvs diff -r1.16 -r1.17 src/sys/arch/x86/x86/est.c (switch to unified diff)

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