i386.c revision 1.18 1 1.18 pgoyette /* $NetBSD: i386.c,v 1.18 2009/05/13 22:25:51 pgoyette Exp $ */
2 1.1 ad
3 1.1 ad /*-
4 1.1 ad * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
5 1.1 ad * All rights reserved.
6 1.1 ad *
7 1.1 ad * This code is derived from software contributed to The NetBSD Foundation
8 1.1 ad * by Frank van der Linden, and by Jason R. Thorpe.
9 1.1 ad *
10 1.1 ad * Redistribution and use in source and binary forms, with or without
11 1.1 ad * modification, are permitted provided that the following conditions
12 1.1 ad * are met:
13 1.1 ad * 1. Redistributions of source code must retain the above copyright
14 1.1 ad * notice, this list of conditions and the following disclaimer.
15 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 ad * notice, this list of conditions and the following disclaimer in the
17 1.1 ad * documentation and/or other materials provided with the distribution.
18 1.1 ad *
19 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 ad * POSSIBILITY OF SUCH DAMAGE.
30 1.1 ad */
31 1.1 ad
32 1.1 ad /*-
33 1.1 ad * Copyright (c)2008 YAMAMOTO Takashi,
34 1.1 ad * All rights reserved.
35 1.1 ad *
36 1.1 ad * Redistribution and use in source and binary forms, with or without
37 1.1 ad * modification, are permitted provided that the following conditions
38 1.1 ad * are met:
39 1.1 ad * 1. Redistributions of source code must retain the above copyright
40 1.1 ad * notice, this list of conditions and the following disclaimer.
41 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright
42 1.1 ad * notice, this list of conditions and the following disclaimer in the
43 1.1 ad * documentation and/or other materials provided with the distribution.
44 1.1 ad *
45 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46 1.1 ad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 1.1 ad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 1.1 ad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 1.1 ad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 1.1 ad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 1.1 ad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 1.1 ad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 1.1 ad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 1.1 ad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 1.1 ad * SUCH DAMAGE.
56 1.1 ad */
57 1.1 ad
58 1.1 ad #include <sys/cdefs.h>
59 1.1 ad #ifndef lint
60 1.18 pgoyette __RCSID("$NetBSD: i386.c,v 1.18 2009/05/13 22:25:51 pgoyette Exp $");
61 1.1 ad #endif /* not lint */
62 1.1 ad
63 1.1 ad #include <sys/types.h>
64 1.1 ad #include <sys/param.h>
65 1.1 ad #include <sys/bitops.h>
66 1.1 ad #include <sys/sysctl.h>
67 1.1 ad
68 1.1 ad #include <string.h>
69 1.1 ad #include <stdio.h>
70 1.1 ad #include <stdlib.h>
71 1.1 ad #include <err.h>
72 1.1 ad #include <assert.h>
73 1.1 ad #include <math.h>
74 1.14 christos #include <util.h>
75 1.1 ad
76 1.1 ad #include <machine/specialreg.h>
77 1.1 ad #include <machine/cpu.h>
78 1.1 ad
79 1.1 ad #include <x86/cpuvar.h>
80 1.1 ad #include <x86/cputypes.h>
81 1.6 christos #include <x86/cacheinfo.h>
82 1.1 ad
83 1.1 ad #include "../cpuctl.h"
84 1.1 ad
85 1.7 christos /* Size of buffer for printing humanized numbers */
86 1.16 tsutsui #define HUMAN_BUFSIZE sizeof("999KB")
87 1.7 christos
88 1.1 ad #define x86_cpuid(a,b) x86_cpuid2((a),0,(b))
89 1.1 ad
90 1.1 ad void x86_cpuid2(uint32_t, uint32_t, uint32_t *);
91 1.1 ad void x86_identify(void);
92 1.1 ad
93 1.1 ad struct cpu_info {
94 1.1 ad const char *ci_dev;
95 1.1 ad int32_t ci_cpuid_level;
96 1.1 ad uint32_t ci_signature; /* X86 cpuid type */
97 1.18 pgoyette uint32_t ci_feat_val[5]; /* X86 CPUID feature bits
98 1.18 pgoyette * [0] basic features %edx
99 1.18 pgoyette * [1] basic features %ecx
100 1.18 pgoyette * [2] extended features %edx
101 1.18 pgoyette * [3] extended features %ecx
102 1.18 pgoyette * [4] VIA padlock features
103 1.18 pgoyette */
104 1.1 ad uint32_t ci_cpu_class; /* CPU class */
105 1.1 ad uint32_t ci_brand_id; /* Intel brand id */
106 1.1 ad uint32_t ci_vendor[4]; /* vendor string */
107 1.1 ad uint32_t ci_cpu_serial[3]; /* PIII serial number */
108 1.1 ad uint64_t ci_tsc_freq; /* cpu cycles/second */
109 1.1 ad uint8_t ci_packageid;
110 1.1 ad uint8_t ci_coreid;
111 1.1 ad uint8_t ci_smtid;
112 1.1 ad uint32_t ci_initapicid;
113 1.1 ad struct x86_cache_info ci_cinfo[CAI_COUNT];
114 1.1 ad void (*ci_info)(struct cpu_info *);
115 1.1 ad };
116 1.1 ad
117 1.1 ad struct cpu_nocpuid_nameclass {
118 1.1 ad int cpu_vendor;
119 1.1 ad const char *cpu_vendorname;
120 1.1 ad const char *cpu_name;
121 1.1 ad int cpu_class;
122 1.1 ad void (*cpu_setup)(struct cpu_info *);
123 1.1 ad void (*cpu_cacheinfo)(struct cpu_info *);
124 1.1 ad void (*cpu_info)(struct cpu_info *);
125 1.1 ad };
126 1.1 ad
127 1.18 pgoyette struct cpu_extend_nameclass {
128 1.18 pgoyette int ext_model;
129 1.18 pgoyette const char *cpu_models[CPU_MAXMODEL+1];
130 1.18 pgoyette };
131 1.1 ad
132 1.1 ad struct cpu_cpuid_nameclass {
133 1.1 ad const char *cpu_id;
134 1.1 ad int cpu_vendor;
135 1.1 ad const char *cpu_vendorname;
136 1.1 ad struct cpu_cpuid_family {
137 1.1 ad int cpu_class;
138 1.1 ad const char *cpu_models[CPU_MAXMODEL+2];
139 1.1 ad void (*cpu_setup)(struct cpu_info *);
140 1.1 ad void (*cpu_probe)(struct cpu_info *);
141 1.1 ad void (*cpu_info)(struct cpu_info *);
142 1.18 pgoyette struct cpu_extend_nameclass *cpu_extended_names;
143 1.1 ad } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
144 1.1 ad };
145 1.1 ad
146 1.7 christos static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO;
147 1.1 ad
148 1.1 ad /*
149 1.1 ad * Map Brand ID from cpuid instruction to brand name.
150 1.1 ad * Source: Intel Processor Identification and the CPUID Instruction, AP-485
151 1.1 ad */
152 1.1 ad static const char * const i386_intel_brand[] = {
153 1.1 ad "", /* Unsupported */
154 1.1 ad "Celeron", /* Intel (R) Celeron (TM) processor */
155 1.1 ad "Pentium III", /* Intel (R) Pentium (R) III processor */
156 1.1 ad "Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */
157 1.1 ad "Pentium III", /* Intel (R) Pentium (R) III processor */
158 1.1 ad "", /* Reserved */
159 1.1 ad "Mobile Pentium III", /* Mobile Intel (R) Pentium (R) III processor-M */
160 1.1 ad "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */
161 1.1 ad "Pentium 4", /* Intel (R) Pentium (R) 4 processor */
162 1.1 ad "Pentium 4", /* Intel (R) Pentium (R) 4 processor */
163 1.1 ad "Celeron", /* Intel (R) Celeron (TM) processor */
164 1.1 ad "Xeon", /* Intel (R) Xeon (TM) processor */
165 1.1 ad "Xeon MP", /* Intel (R) Xeon (TM) processor MP */
166 1.1 ad "", /* Reserved */
167 1.1 ad "Mobile Pentium 4", /* Mobile Intel (R) Pentium (R) 4 processor-M */
168 1.1 ad "Mobile Celeron", /* Mobile Intel (R) Celeron (R) processor */
169 1.1 ad };
170 1.1 ad
171 1.1 ad /*
172 1.1 ad * AMD processors don't have Brand IDs, so we need these names for probe.
173 1.1 ad */
174 1.1 ad static const char * const amd_brand[] = {
175 1.1 ad "",
176 1.1 ad "Duron", /* AMD Duron(tm) */
177 1.1 ad "MP", /* AMD Athlon(tm) MP */
178 1.1 ad "XP", /* AMD Athlon(tm) XP */
179 1.1 ad "4" /* AMD Athlon(tm) 4 */
180 1.1 ad };
181 1.1 ad
182 1.1 ad static int cpu_vendor;
183 1.1 ad static char cpu_brand_string[49];
184 1.1 ad static char amd_brand_name[48];
185 1.1 ad
186 1.1 ad static void via_cpu_probe(struct cpu_info *);
187 1.1 ad static void amd_family6_probe(struct cpu_info *);
188 1.1 ad static void intel_family_new_probe(struct cpu_info *);
189 1.1 ad static const char *intel_family6_name(struct cpu_info *);
190 1.1 ad static const char *amd_amd64_name(struct cpu_info *);
191 1.1 ad static void amd_family5_setup(struct cpu_info *);
192 1.1 ad static void transmeta_cpu_info(struct cpu_info *);
193 1.1 ad static const char *print_cache_config(struct cpu_info *, int, const char *,
194 1.1 ad const char *);
195 1.1 ad static const char *print_tlb_config(struct cpu_info *, int, const char *,
196 1.1 ad const char *);
197 1.1 ad static void amd_cpu_cacheinfo(struct cpu_info *);
198 1.1 ad static void via_cpu_cacheinfo(struct cpu_info *);
199 1.1 ad static void x86_print_cacheinfo(struct cpu_info *);
200 1.1 ad static const struct x86_cache_info *cache_info_lookup(
201 1.1 ad const struct x86_cache_info *, uint8_t);
202 1.1 ad static void cyrix6x86_cpu_setup(struct cpu_info *);
203 1.1 ad static void winchip_cpu_setup(struct cpu_info *);
204 1.1 ad static void amd_family5_setup(struct cpu_info *);
205 1.5 ad static void powernow_probe(struct cpu_info *);
206 1.1 ad
207 1.1 ad /*
208 1.1 ad * Info for CTL_HW
209 1.1 ad */
210 1.1 ad static char cpu_model[120];
211 1.1 ad
212 1.1 ad /*
213 1.1 ad * Note: these are just the ones that may not have a cpuid instruction.
214 1.1 ad * We deal with the rest in a different way.
215 1.1 ad */
216 1.1 ad const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = {
217 1.1 ad { CPUVENDOR_INTEL, "Intel", "386SX", CPUCLASS_386,
218 1.1 ad NULL, NULL, NULL }, /* CPU_386SX */
219 1.1 ad { CPUVENDOR_INTEL, "Intel", "386DX", CPUCLASS_386,
220 1.1 ad NULL, NULL, NULL }, /* CPU_386 */
221 1.1 ad { CPUVENDOR_INTEL, "Intel", "486SX", CPUCLASS_486,
222 1.1 ad NULL, NULL, NULL }, /* CPU_486SX */
223 1.1 ad { CPUVENDOR_INTEL, "Intel", "486DX", CPUCLASS_486,
224 1.1 ad NULL, NULL, NULL }, /* CPU_486 */
225 1.1 ad { CPUVENDOR_CYRIX, "Cyrix", "486DLC", CPUCLASS_486,
226 1.1 ad NULL, NULL, NULL }, /* CPU_486DLC */
227 1.1 ad { CPUVENDOR_CYRIX, "Cyrix", "6x86", CPUCLASS_486,
228 1.1 ad NULL, NULL, NULL }, /* CPU_6x86 */
229 1.1 ad { CPUVENDOR_NEXGEN,"NexGen","586", CPUCLASS_386,
230 1.1 ad NULL, NULL, NULL }, /* CPU_NX586 */
231 1.1 ad };
232 1.1 ad
233 1.1 ad const char *classnames[] = {
234 1.1 ad "386",
235 1.1 ad "486",
236 1.1 ad "586",
237 1.1 ad "686"
238 1.1 ad };
239 1.1 ad
240 1.1 ad const char *modifiers[] = {
241 1.1 ad "",
242 1.1 ad "OverDrive",
243 1.1 ad "Dual",
244 1.1 ad ""
245 1.1 ad };
246 1.1 ad
247 1.18 pgoyette struct cpu_extend_nameclass intel_family6_ext_models[] = {
248 1.18 pgoyette { /* Extended models 1x */
249 1.18 pgoyette 0x01, { NULL, NULL,
250 1.18 pgoyette NULL, NULL,
251 1.18 pgoyette NULL, NULL,
252 1.18 pgoyette NULL, NULL,
253 1.18 pgoyette NULL, NULL,
254 1.18 pgoyette "Core i7 (Nehalem)", NULL,
255 1.18 pgoyette "Atom", "XeonMP (Nehalem)",
256 1.18 pgoyette NULL, NULL} },
257 1.18 pgoyette { /* End of list */
258 1.18 pgoyette 0x00, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
259 1.18 pgoyette NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
260 1.18 pgoyette };
261 1.18 pgoyette
262 1.1 ad const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
263 1.1 ad {
264 1.1 ad "GenuineIntel",
265 1.1 ad CPUVENDOR_INTEL,
266 1.1 ad "Intel",
267 1.1 ad /* Family 4 */
268 1.1 ad { {
269 1.1 ad CPUCLASS_486,
270 1.1 ad {
271 1.1 ad "486DX", "486DX", "486SX", "486DX2", "486SL",
272 1.1 ad "486SX2", 0, "486DX2 W/B Enhanced",
273 1.1 ad "486DX4", 0, 0, 0, 0, 0, 0, 0,
274 1.1 ad "486" /* Default */
275 1.1 ad },
276 1.1 ad NULL,
277 1.1 ad NULL,
278 1.1 ad NULL,
279 1.18 pgoyette NULL,
280 1.1 ad },
281 1.1 ad /* Family 5 */
282 1.1 ad {
283 1.1 ad CPUCLASS_586,
284 1.1 ad {
285 1.1 ad "Pentium (P5 A-step)", "Pentium (P5)",
286 1.1 ad "Pentium (P54C)", "Pentium (P24T)",
287 1.1 ad "Pentium/MMX", "Pentium", 0,
288 1.1 ad "Pentium (P54C)", "Pentium/MMX (Tillamook)",
289 1.1 ad 0, 0, 0, 0, 0, 0, 0,
290 1.1 ad "Pentium" /* Default */
291 1.1 ad },
292 1.1 ad NULL,
293 1.1 ad NULL,
294 1.1 ad NULL,
295 1.18 pgoyette NULL,
296 1.1 ad },
297 1.1 ad /* Family 6 */
298 1.1 ad {
299 1.1 ad CPUCLASS_686,
300 1.1 ad {
301 1.1 ad "Pentium Pro (A-step)", "Pentium Pro", 0,
302 1.1 ad "Pentium II (Klamath)", "Pentium Pro",
303 1.1 ad "Pentium II/Celeron (Deschutes)",
304 1.1 ad "Celeron (Mendocino)",
305 1.1 ad "Pentium III (Katmai)",
306 1.1 ad "Pentium III (Coppermine)",
307 1.1 ad "Pentium M (Banias)",
308 1.1 ad "Pentium III Xeon (Cascades)",
309 1.1 ad "Pentium III (Tualatin)", 0,
310 1.1 ad "Pentium M (Dothan)",
311 1.1 ad "Pentium M (Yonah)",
312 1.1 ad "Core 2 (Merom)",
313 1.1 ad "Pentium Pro, II or III" /* Default */
314 1.1 ad },
315 1.1 ad NULL,
316 1.1 ad intel_family_new_probe,
317 1.1 ad NULL,
318 1.18 pgoyette &intel_family6_ext_models[0],
319 1.1 ad },
320 1.1 ad /* Family > 6 */
321 1.1 ad {
322 1.1 ad CPUCLASS_686,
323 1.1 ad {
324 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
325 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
326 1.1 ad "Pentium 4" /* Default */
327 1.1 ad },
328 1.1 ad NULL,
329 1.1 ad intel_family_new_probe,
330 1.1 ad NULL,
331 1.18 pgoyette NULL,
332 1.1 ad } }
333 1.1 ad },
334 1.1 ad {
335 1.1 ad "AuthenticAMD",
336 1.1 ad CPUVENDOR_AMD,
337 1.1 ad "AMD",
338 1.1 ad /* Family 4 */
339 1.1 ad { {
340 1.1 ad CPUCLASS_486,
341 1.1 ad {
342 1.1 ad 0, 0, 0, "Am486DX2 W/T",
343 1.1 ad 0, 0, 0, "Am486DX2 W/B",
344 1.1 ad "Am486DX4 W/T or Am5x86 W/T 150",
345 1.1 ad "Am486DX4 W/B or Am5x86 W/B 150", 0, 0,
346 1.1 ad 0, 0, "Am5x86 W/T 133/160",
347 1.1 ad "Am5x86 W/B 133/160",
348 1.1 ad "Am486 or Am5x86" /* Default */
349 1.1 ad },
350 1.1 ad NULL,
351 1.1 ad NULL,
352 1.1 ad NULL,
353 1.18 pgoyette NULL,
354 1.1 ad },
355 1.1 ad /* Family 5 */
356 1.1 ad {
357 1.1 ad CPUCLASS_586,
358 1.1 ad {
359 1.1 ad "K5", "K5", "K5", "K5", 0, 0, "K6",
360 1.1 ad "K6", "K6-2", "K6-III", "Geode LX", 0, 0,
361 1.1 ad "K6-2+/III+", 0, 0,
362 1.1 ad "K5 or K6" /* Default */
363 1.1 ad },
364 1.1 ad amd_family5_setup,
365 1.1 ad NULL,
366 1.1 ad amd_cpu_cacheinfo,
367 1.18 pgoyette NULL,
368 1.1 ad },
369 1.1 ad /* Family 6 */
370 1.1 ad {
371 1.1 ad CPUCLASS_686,
372 1.1 ad {
373 1.1 ad 0, "Athlon Model 1", "Athlon Model 2",
374 1.1 ad "Duron", "Athlon Model 4 (Thunderbird)",
375 1.1 ad 0, "Athlon", "Duron", "Athlon", 0,
376 1.1 ad "Athlon", 0, 0, 0, 0, 0,
377 1.1 ad "K7 (Athlon)" /* Default */
378 1.1 ad },
379 1.1 ad NULL,
380 1.1 ad amd_family6_probe,
381 1.1 ad amd_cpu_cacheinfo,
382 1.18 pgoyette NULL,
383 1.1 ad },
384 1.1 ad /* Family > 6 */
385 1.1 ad {
386 1.1 ad CPUCLASS_686,
387 1.1 ad {
388 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
389 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
390 1.1 ad "Unknown K8 (Athlon)" /* Default */
391 1.1 ad },
392 1.1 ad NULL,
393 1.1 ad amd_family6_probe,
394 1.1 ad amd_cpu_cacheinfo,
395 1.18 pgoyette NULL,
396 1.1 ad } }
397 1.1 ad },
398 1.1 ad {
399 1.1 ad "CyrixInstead",
400 1.1 ad CPUVENDOR_CYRIX,
401 1.1 ad "Cyrix",
402 1.1 ad /* Family 4 */
403 1.1 ad { {
404 1.1 ad CPUCLASS_486,
405 1.1 ad {
406 1.1 ad 0, 0, 0,
407 1.1 ad "MediaGX",
408 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
409 1.1 ad "486" /* Default */
410 1.1 ad },
411 1.1 ad cyrix6x86_cpu_setup, /* XXX ?? */
412 1.1 ad NULL,
413 1.1 ad NULL,
414 1.18 pgoyette NULL,
415 1.1 ad },
416 1.1 ad /* Family 5 */
417 1.1 ad {
418 1.1 ad CPUCLASS_586,
419 1.1 ad {
420 1.1 ad 0, 0, "6x86", 0,
421 1.1 ad "MMX-enhanced MediaGX (GXm)", /* or Geode? */
422 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
423 1.1 ad "6x86" /* Default */
424 1.1 ad },
425 1.1 ad cyrix6x86_cpu_setup,
426 1.1 ad NULL,
427 1.1 ad NULL,
428 1.18 pgoyette NULL,
429 1.1 ad },
430 1.1 ad /* Family 6 */
431 1.1 ad {
432 1.1 ad CPUCLASS_686,
433 1.1 ad {
434 1.1 ad "6x86MX", 0, 0, 0, 0, 0, 0, 0,
435 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
436 1.1 ad "6x86MX" /* Default */
437 1.1 ad },
438 1.1 ad cyrix6x86_cpu_setup,
439 1.1 ad NULL,
440 1.1 ad NULL,
441 1.18 pgoyette NULL,
442 1.1 ad },
443 1.1 ad /* Family > 6 */
444 1.1 ad {
445 1.1 ad CPUCLASS_686,
446 1.1 ad {
447 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
448 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
449 1.1 ad "Unknown 6x86MX" /* Default */
450 1.1 ad },
451 1.1 ad NULL,
452 1.1 ad NULL,
453 1.1 ad NULL,
454 1.18 pgoyette NULL,
455 1.1 ad } }
456 1.1 ad },
457 1.1 ad { /* MediaGX is now owned by National Semiconductor */
458 1.1 ad "Geode by NSC",
459 1.1 ad CPUVENDOR_CYRIX, /* XXX */
460 1.1 ad "National Semiconductor",
461 1.1 ad /* Family 4, NSC never had any of these */
462 1.1 ad { {
463 1.1 ad CPUCLASS_486,
464 1.1 ad {
465 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
466 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
467 1.1 ad "486 compatible" /* Default */
468 1.1 ad },
469 1.1 ad NULL,
470 1.1 ad NULL,
471 1.1 ad NULL,
472 1.18 pgoyette NULL,
473 1.1 ad },
474 1.1 ad /* Family 5: Geode family, formerly MediaGX */
475 1.1 ad {
476 1.1 ad CPUCLASS_586,
477 1.1 ad {
478 1.1 ad 0, 0, 0, 0,
479 1.1 ad "Geode GX1",
480 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
481 1.1 ad "Geode" /* Default */
482 1.1 ad },
483 1.1 ad cyrix6x86_cpu_setup,
484 1.1 ad NULL,
485 1.1 ad amd_cpu_cacheinfo,
486 1.18 pgoyette NULL,
487 1.1 ad },
488 1.1 ad /* Family 6, not yet available from NSC */
489 1.1 ad {
490 1.1 ad CPUCLASS_686,
491 1.1 ad {
492 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
493 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
494 1.1 ad "Pentium Pro compatible" /* Default */
495 1.1 ad },
496 1.1 ad NULL,
497 1.1 ad NULL,
498 1.1 ad NULL,
499 1.18 pgoyette NULL,
500 1.1 ad },
501 1.1 ad /* Family > 6, not yet available from NSC */
502 1.1 ad {
503 1.1 ad CPUCLASS_686,
504 1.1 ad {
505 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
506 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
507 1.1 ad "Pentium Pro compatible" /* Default */
508 1.1 ad },
509 1.1 ad NULL,
510 1.1 ad NULL,
511 1.1 ad NULL,
512 1.18 pgoyette NULL,
513 1.1 ad } }
514 1.1 ad },
515 1.1 ad {
516 1.1 ad "CentaurHauls",
517 1.1 ad CPUVENDOR_IDT,
518 1.1 ad "IDT",
519 1.1 ad /* Family 4, IDT never had any of these */
520 1.1 ad { {
521 1.1 ad CPUCLASS_486,
522 1.1 ad {
523 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
524 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
525 1.1 ad "486 compatible" /* Default */
526 1.1 ad },
527 1.1 ad NULL,
528 1.1 ad NULL,
529 1.1 ad NULL,
530 1.18 pgoyette NULL,
531 1.1 ad },
532 1.1 ad /* Family 5 */
533 1.1 ad {
534 1.1 ad CPUCLASS_586,
535 1.1 ad {
536 1.1 ad 0, 0, 0, 0, "WinChip C6", 0, 0, 0,
537 1.1 ad "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0,
538 1.1 ad "WinChip" /* Default */
539 1.1 ad },
540 1.1 ad winchip_cpu_setup,
541 1.1 ad NULL,
542 1.1 ad NULL,
543 1.18 pgoyette NULL,
544 1.1 ad },
545 1.1 ad /* Family 6, VIA acquired IDT Centaur design subsidiary */
546 1.1 ad {
547 1.1 ad CPUCLASS_686,
548 1.1 ad {
549 1.1 ad 0, 0, 0, 0, 0, 0, "C3 Samuel",
550 1.1 ad "C3 Samuel 2/Ezra", "C3 Ezra-T",
551 1.1 ad "C3 Nehemiah", "C7 Esther", 0, 0, 0, 0, 0,
552 1.1 ad "C3" /* Default */
553 1.1 ad },
554 1.1 ad NULL,
555 1.1 ad via_cpu_probe,
556 1.1 ad via_cpu_cacheinfo,
557 1.18 pgoyette NULL,
558 1.1 ad },
559 1.1 ad /* Family > 6, not yet available from VIA */
560 1.1 ad {
561 1.1 ad CPUCLASS_686,
562 1.1 ad {
563 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
564 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
565 1.1 ad "Pentium Pro compatible" /* Default */
566 1.1 ad },
567 1.1 ad NULL,
568 1.1 ad NULL,
569 1.1 ad NULL,
570 1.18 pgoyette NULL,
571 1.1 ad } }
572 1.1 ad },
573 1.1 ad {
574 1.1 ad "GenuineTMx86",
575 1.1 ad CPUVENDOR_TRANSMETA,
576 1.1 ad "Transmeta",
577 1.1 ad /* Family 4, Transmeta never had any of these */
578 1.1 ad { {
579 1.1 ad CPUCLASS_486,
580 1.1 ad {
581 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
582 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
583 1.1 ad "486 compatible" /* Default */
584 1.1 ad },
585 1.1 ad NULL,
586 1.1 ad NULL,
587 1.1 ad NULL,
588 1.18 pgoyette NULL,
589 1.1 ad },
590 1.1 ad /* Family 5 */
591 1.1 ad {
592 1.1 ad CPUCLASS_586,
593 1.1 ad {
594 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
595 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
596 1.1 ad "Crusoe" /* Default */
597 1.1 ad },
598 1.1 ad NULL,
599 1.1 ad NULL,
600 1.1 ad transmeta_cpu_info,
601 1.18 pgoyette NULL,
602 1.1 ad },
603 1.1 ad /* Family 6, not yet available from Transmeta */
604 1.1 ad {
605 1.1 ad CPUCLASS_686,
606 1.1 ad {
607 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
608 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
609 1.1 ad "Pentium Pro compatible" /* Default */
610 1.1 ad },
611 1.1 ad NULL,
612 1.1 ad NULL,
613 1.1 ad NULL,
614 1.18 pgoyette NULL,
615 1.1 ad },
616 1.1 ad /* Family > 6, not yet available from Transmeta */
617 1.1 ad {
618 1.1 ad CPUCLASS_686,
619 1.1 ad {
620 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
621 1.1 ad 0, 0, 0, 0, 0, 0, 0, 0,
622 1.1 ad "Pentium Pro compatible" /* Default */
623 1.1 ad },
624 1.1 ad NULL,
625 1.1 ad NULL,
626 1.1 ad NULL,
627 1.18 pgoyette NULL,
628 1.1 ad } }
629 1.1 ad }
630 1.1 ad };
631 1.1 ad
632 1.1 ad /*
633 1.1 ad * disable the TSC such that we don't use the TSC in microtime(9)
634 1.1 ad * because some CPUs got the implementation wrong.
635 1.1 ad */
636 1.1 ad static void
637 1.1 ad disable_tsc(struct cpu_info *ci)
638 1.1 ad {
639 1.18 pgoyette if (ci->ci_feat_val[0] & CPUID_TSC) {
640 1.18 pgoyette ci->ci_feat_val[0] &= ~CPUID_TSC;
641 1.1 ad aprint_error("WARNING: broken TSC disabled\n");
642 1.1 ad }
643 1.1 ad }
644 1.1 ad
645 1.1 ad static void
646 1.1 ad cyrix6x86_cpu_setup(struct cpu_info *ci)
647 1.1 ad {
648 1.1 ad
649 1.1 ad /*
650 1.1 ad * Do not disable the TSC on the Geode GX, it's reported to
651 1.1 ad * work fine.
652 1.1 ad */
653 1.1 ad if (ci->ci_signature != 0x552)
654 1.1 ad disable_tsc(ci);
655 1.1 ad }
656 1.1 ad
657 1.1 ad void
658 1.1 ad winchip_cpu_setup(struct cpu_info *ci)
659 1.1 ad {
660 1.1 ad switch (CPUID2MODEL(ci->ci_signature)) { /* model */
661 1.1 ad case 4: /* WinChip C6 */
662 1.1 ad disable_tsc(ci);
663 1.1 ad }
664 1.1 ad }
665 1.1 ad
666 1.1 ad
667 1.1 ad static void
668 1.1 ad identifycpu_cpuids(struct cpu_info *ci)
669 1.1 ad {
670 1.1 ad const char *cpuname = ci->ci_dev;
671 1.1 ad u_int lp_max = 1; /* logical processors per package */
672 1.1 ad u_int smt_max; /* smt per core */
673 1.1 ad u_int core_max = 1; /* core per package */
674 1.17 christos u_int smt_bits, core_bits;
675 1.1 ad uint32_t descs[4];
676 1.1 ad
677 1.1 ad aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid);
678 1.1 ad ci->ci_packageid = ci->ci_initapicid;
679 1.1 ad ci->ci_coreid = 0;
680 1.1 ad ci->ci_smtid = 0;
681 1.1 ad if (cpu_vendor != CPUVENDOR_INTEL) {
682 1.1 ad return;
683 1.1 ad }
684 1.1 ad
685 1.1 ad /*
686 1.1 ad * 253668.pdf 7.10.2
687 1.1 ad */
688 1.1 ad
689 1.18 pgoyette if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
690 1.1 ad x86_cpuid(1, descs);
691 1.1 ad lp_max = (descs[1] >> 16) & 0xff;
692 1.1 ad }
693 1.1 ad x86_cpuid(0, descs);
694 1.1 ad if (descs[0] >= 4) {
695 1.1 ad x86_cpuid2(4, 0, descs);
696 1.1 ad core_max = (descs[0] >> 26) + 1;
697 1.1 ad }
698 1.1 ad assert(lp_max >= core_max);
699 1.1 ad smt_max = lp_max / core_max;
700 1.1 ad smt_bits = ilog2(smt_max - 1) + 1;
701 1.1 ad core_bits = ilog2(core_max - 1) + 1;
702 1.1 ad if (smt_bits + core_bits) {
703 1.1 ad ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits);
704 1.1 ad }
705 1.1 ad aprint_verbose("%s: Cluster/Package ID %u\n", cpuname,
706 1.1 ad ci->ci_packageid);
707 1.1 ad if (core_bits) {
708 1.1 ad u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1);
709 1.1 ad
710 1.1 ad ci->ci_coreid =
711 1.1 ad __SHIFTOUT(ci->ci_initapicid, core_mask);
712 1.1 ad aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid);
713 1.1 ad }
714 1.1 ad if (smt_bits) {
715 1.17 christos u_int smt_mask = __BITS((int)0, (int)(smt_bits - 1));
716 1.1 ad
717 1.1 ad ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, smt_mask);
718 1.1 ad aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid);
719 1.1 ad }
720 1.1 ad }
721 1.1 ad
722 1.1 ad static void
723 1.1 ad via_cpu_probe(struct cpu_info *ci)
724 1.1 ad {
725 1.1 ad u_int model = CPUID2MODEL(ci->ci_signature);
726 1.1 ad u_int stepping = CPUID2STEPPING(ci->ci_signature);
727 1.1 ad u_int descs[4];
728 1.1 ad u_int lfunc;
729 1.1 ad
730 1.1 ad /*
731 1.1 ad * Determine the largest extended function value.
732 1.1 ad */
733 1.1 ad x86_cpuid(0x80000000, descs);
734 1.1 ad lfunc = descs[0];
735 1.1 ad
736 1.1 ad /*
737 1.1 ad * Determine the extended feature flags.
738 1.1 ad */
739 1.1 ad if (lfunc >= 0x80000001) {
740 1.1 ad x86_cpuid(0x80000001, descs);
741 1.18 pgoyette ci->ci_feat_val[2] |= descs[3];
742 1.1 ad }
743 1.1 ad
744 1.1 ad if (model < 0x9)
745 1.1 ad return;
746 1.1 ad
747 1.1 ad /* Nehemiah or Esther */
748 1.1 ad x86_cpuid(0xc0000000, descs);
749 1.1 ad lfunc = descs[0];
750 1.1 ad if (lfunc < 0xc0000001) /* no ACE, no RNG */
751 1.1 ad return;
752 1.1 ad
753 1.1 ad x86_cpuid(0xc0000001, descs);
754 1.1 ad lfunc = descs[3];
755 1.1 ad if (model > 0x9 || stepping >= 8) { /* ACE */
756 1.1 ad if (lfunc & CPUID_VIA_HAS_ACE) {
757 1.18 pgoyette ci->ci_feat_val[4] = lfunc;
758 1.1 ad }
759 1.1 ad }
760 1.1 ad }
761 1.1 ad
762 1.1 ad static const char *
763 1.1 ad intel_family6_name(struct cpu_info *ci)
764 1.1 ad {
765 1.1 ad int model = CPUID2MODEL(ci->ci_signature);
766 1.1 ad const char *ret = NULL;
767 1.1 ad u_int l2cache = ci->ci_cinfo[CAI_L2CACHE].cai_totalsize;
768 1.1 ad
769 1.1 ad if (model == 5) {
770 1.1 ad switch (l2cache) {
771 1.1 ad case 0:
772 1.1 ad case 128 * 1024:
773 1.1 ad ret = "Celeron (Covington)";
774 1.1 ad break;
775 1.1 ad case 256 * 1024:
776 1.1 ad ret = "Mobile Pentium II (Dixon)";
777 1.1 ad break;
778 1.1 ad case 512 * 1024:
779 1.1 ad ret = "Pentium II";
780 1.1 ad break;
781 1.1 ad case 1 * 1024 * 1024:
782 1.1 ad case 2 * 1024 * 1024:
783 1.1 ad ret = "Pentium II Xeon";
784 1.1 ad break;
785 1.1 ad }
786 1.1 ad } else if (model == 6) {
787 1.1 ad switch (l2cache) {
788 1.1 ad case 256 * 1024:
789 1.1 ad case 512 * 1024:
790 1.1 ad ret = "Mobile Pentium II";
791 1.1 ad break;
792 1.1 ad }
793 1.1 ad } else if (model == 7) {
794 1.1 ad switch (l2cache) {
795 1.1 ad case 512 * 1024:
796 1.1 ad ret = "Pentium III";
797 1.1 ad break;
798 1.1 ad case 1 * 1024 * 1024:
799 1.1 ad case 2 * 1024 * 1024:
800 1.1 ad ret = "Pentium III Xeon";
801 1.1 ad break;
802 1.1 ad }
803 1.1 ad } else if (model >= 8) {
804 1.1 ad if (ci->ci_brand_id && ci->ci_brand_id < 0x10) {
805 1.1 ad switch (ci->ci_brand_id) {
806 1.1 ad case 0x3:
807 1.1 ad if (ci->ci_signature == 0x6B1)
808 1.1 ad ret = "Celeron";
809 1.1 ad break;
810 1.1 ad case 0x8:
811 1.1 ad if (ci->ci_signature >= 0xF13)
812 1.1 ad ret = "genuine processor";
813 1.1 ad break;
814 1.1 ad case 0xB:
815 1.1 ad if (ci->ci_signature >= 0xF13)
816 1.1 ad ret = "Xeon MP";
817 1.1 ad break;
818 1.1 ad case 0xE:
819 1.1 ad if (ci->ci_signature < 0xF13)
820 1.1 ad ret = "Xeon";
821 1.1 ad break;
822 1.1 ad }
823 1.1 ad if (ret == NULL)
824 1.1 ad ret = i386_intel_brand[ci->ci_brand_id];
825 1.1 ad }
826 1.1 ad }
827 1.1 ad
828 1.1 ad return ret;
829 1.1 ad }
830 1.1 ad
831 1.1 ad /*
832 1.1 ad * Identify AMD64 CPU names from cpuid.
833 1.1 ad *
834 1.1 ad * Based on:
835 1.1 ad * "Revision Guide for AMD Athlon 64 and AMD Opteron Processors"
836 1.1 ad * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf
837 1.1 ad * "Revision Guide for AMD NPT Family 0Fh Processors"
838 1.1 ad * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf
839 1.1 ad * and other miscellaneous reports.
840 1.1 ad */
841 1.1 ad static const char *
842 1.1 ad amd_amd64_name(struct cpu_info *ci)
843 1.1 ad {
844 1.1 ad int extfamily, extmodel, model;
845 1.1 ad const char *ret = NULL;
846 1.1 ad
847 1.1 ad model = CPUID2MODEL(ci->ci_signature);
848 1.1 ad extfamily = CPUID2EXTFAMILY(ci->ci_signature);
849 1.1 ad extmodel = CPUID2EXTMODEL(ci->ci_signature);
850 1.1 ad
851 1.7 christos switch (extfamily) {
852 1.7 christos case 0x00:
853 1.1 ad switch (model) {
854 1.1 ad case 0x1:
855 1.1 ad switch (extmodel) {
856 1.1 ad case 0x2: /* rev JH-E1/E6 */
857 1.1 ad case 0x4: /* rev JH-F2 */
858 1.1 ad ret = "Dual-Core Opteron";
859 1.1 ad break;
860 1.1 ad }
861 1.1 ad break;
862 1.1 ad case 0x3:
863 1.1 ad switch (extmodel) {
864 1.1 ad case 0x2: /* rev JH-E6 (Toledo) */
865 1.1 ad ret = "Dual-Core Opteron or Athlon 64 X2";
866 1.1 ad break;
867 1.1 ad case 0x4: /* rev JH-F2 (Windsor) */
868 1.1 ad ret = "Athlon 64 FX or Athlon 64 X2";
869 1.1 ad break;
870 1.1 ad }
871 1.1 ad break;
872 1.1 ad case 0x4:
873 1.1 ad switch (extmodel) {
874 1.1 ad case 0x0: /* rev SH-B0/C0/CG (ClawHammer) */
875 1.1 ad case 0x1: /* rev SH-D0 */
876 1.1 ad ret = "Athlon 64";
877 1.1 ad break;
878 1.1 ad case 0x2: /* rev SH-E5 (Lancaster?) */
879 1.1 ad ret = "Mobile Athlon 64 or Turion 64";
880 1.1 ad break;
881 1.1 ad }
882 1.1 ad break;
883 1.1 ad case 0x5:
884 1.1 ad switch (extmodel) {
885 1.1 ad case 0x0: /* rev SH-B0/B3/C0/CG (SledgeHammer?) */
886 1.1 ad ret = "Opteron or Athlon 64 FX";
887 1.1 ad break;
888 1.1 ad case 0x1: /* rev SH-D0 */
889 1.1 ad case 0x2: /* rev SH-E4 */
890 1.1 ad ret = "Opteron";
891 1.1 ad break;
892 1.1 ad }
893 1.1 ad break;
894 1.1 ad case 0x7:
895 1.1 ad switch (extmodel) {
896 1.1 ad case 0x0: /* rev SH-CG (ClawHammer) */
897 1.1 ad case 0x1: /* rev SH-D0 */
898 1.1 ad ret = "Athlon 64";
899 1.1 ad break;
900 1.1 ad case 0x2: /* rev DH-E4, SH-E4 */
901 1.1 ad ret = "Athlon 64 or Athlon 64 FX or Opteron";
902 1.1 ad break;
903 1.1 ad }
904 1.1 ad break;
905 1.1 ad case 0x8:
906 1.1 ad switch (extmodel) {
907 1.1 ad case 0x0: /* rev CH-CG */
908 1.1 ad case 0x1: /* rev CH-D0 */
909 1.1 ad ret = "Athlon 64 or Sempron";
910 1.1 ad break;
911 1.1 ad case 0x4: /* rev BH-F2 */
912 1.1 ad ret = "Turion 64 X2";
913 1.1 ad break;
914 1.1 ad }
915 1.1 ad break;
916 1.1 ad case 0xb:
917 1.1 ad switch (extmodel) {
918 1.1 ad case 0x0: /* rev CH-CG */
919 1.1 ad case 0x1: /* rev CH-D0 */
920 1.1 ad ret = "Athlon 64";
921 1.1 ad break;
922 1.1 ad case 0x2: /* rev BH-E4 (Manchester) */
923 1.1 ad case 0x4: /* rev BH-F2 (Windsor) */
924 1.1 ad ret = "Athlon 64 X2";
925 1.1 ad break;
926 1.1 ad case 0x6: /* rev BH-G1 (Brisbane) */
927 1.1 ad ret = "Athlon X2 or Athlon 64 X2";
928 1.1 ad break;
929 1.1 ad }
930 1.1 ad break;
931 1.1 ad case 0xc:
932 1.1 ad switch (extmodel) {
933 1.1 ad case 0x0: /* rev DH-CG (Newcastle) */
934 1.1 ad case 0x1: /* rev DH-D0 (Winchester) */
935 1.1 ad case 0x2: /* rev DH-E3/E6 */
936 1.1 ad ret = "Athlon 64 or Sempron";
937 1.1 ad break;
938 1.1 ad }
939 1.1 ad break;
940 1.1 ad case 0xe:
941 1.1 ad switch (extmodel) {
942 1.1 ad case 0x0: /* rev DH-CG (Newcastle?) */
943 1.1 ad ret = "Athlon 64 or Sempron";
944 1.1 ad break;
945 1.1 ad }
946 1.1 ad break;
947 1.1 ad case 0xf:
948 1.1 ad switch (extmodel) {
949 1.1 ad case 0x0: /* rev DH-CG (Newcastle/Paris) */
950 1.1 ad case 0x1: /* rev DH-D0 (Winchester/Victoria) */
951 1.1 ad case 0x2: /* rev DH-E3/E6 (Venice/Palermo) */
952 1.1 ad case 0x4: /* rev DH-F2 (Orleans/Manila) */
953 1.1 ad case 0x5: /* rev DH-F2 (Orleans/Manila) */
954 1.1 ad case 0x6: /* rev DH-G1 */
955 1.1 ad ret = "Athlon 64 or Sempron";
956 1.1 ad break;
957 1.1 ad }
958 1.1 ad break;
959 1.1 ad default:
960 1.1 ad ret = "Unknown AMD64 CPU";
961 1.1 ad }
962 1.7 christos break;
963 1.7 christos case 0x01:
964 1.7 christos switch (model) {
965 1.7 christos case 0x02:
966 1.7 christos ret = "Family 10h";
967 1.7 christos break;
968 1.7 christos default:
969 1.7 christos ret = "Unknown AMD64 CPU";
970 1.7 christos break;
971 1.7 christos }
972 1.7 christos break;
973 1.1 ad }
974 1.1 ad
975 1.1 ad return ret;
976 1.1 ad }
977 1.1 ad
978 1.1 ad static void
979 1.1 ad cpu_probe_base_features(struct cpu_info *ci)
980 1.1 ad {
981 1.1 ad const struct x86_cache_info *cai;
982 1.1 ad u_int descs[4];
983 1.1 ad int iterations, i, j;
984 1.1 ad uint8_t desc;
985 1.1 ad uint32_t miscbytes;
986 1.1 ad uint32_t brand[12];
987 1.1 ad
988 1.1 ad if (ci->ci_cpuid_level < 0)
989 1.1 ad return;
990 1.1 ad
991 1.1 ad x86_cpuid(0, descs);
992 1.1 ad ci->ci_cpuid_level = descs[0];
993 1.1 ad ci->ci_vendor[0] = descs[1];
994 1.1 ad ci->ci_vendor[2] = descs[2];
995 1.1 ad ci->ci_vendor[1] = descs[3];
996 1.1 ad ci->ci_vendor[3] = 0;
997 1.1 ad
998 1.1 ad x86_cpuid(0x80000000, brand);
999 1.1 ad if (brand[0] >= 0x80000004) {
1000 1.1 ad x86_cpuid(0x80000002, brand);
1001 1.1 ad x86_cpuid(0x80000003, brand + 4);
1002 1.1 ad x86_cpuid(0x80000004, brand + 8);
1003 1.1 ad for (i = 0; i < 48; i++)
1004 1.1 ad if (((char *) brand)[i] != ' ')
1005 1.1 ad break;
1006 1.1 ad memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
1007 1.1 ad }
1008 1.1 ad
1009 1.1 ad if (ci->ci_cpuid_level < 1)
1010 1.1 ad return;
1011 1.1 ad
1012 1.1 ad x86_cpuid(1, descs);
1013 1.1 ad ci->ci_signature = descs[0];
1014 1.1 ad miscbytes = descs[1];
1015 1.18 pgoyette ci->ci_feat_val[1] = descs[2];
1016 1.18 pgoyette ci->ci_feat_val[0] = descs[3];
1017 1.1 ad
1018 1.1 ad /* Brand is low order 8 bits of ebx */
1019 1.1 ad ci->ci_brand_id = miscbytes & 0xff;
1020 1.1 ad ci->ci_initapicid = (miscbytes >> 24) & 0xff;
1021 1.1 ad if (ci->ci_cpuid_level < 2)
1022 1.1 ad return;
1023 1.1 ad
1024 1.1 ad /*
1025 1.1 ad * Parse the cache info from `cpuid', if we have it.
1026 1.1 ad * XXX This is kinda ugly, but hey, so is the architecture...
1027 1.1 ad */
1028 1.1 ad
1029 1.1 ad x86_cpuid(2, descs);
1030 1.1 ad
1031 1.1 ad iterations = descs[0] & 0xff;
1032 1.1 ad while (iterations-- > 0) {
1033 1.1 ad for (i = 0; i < 4; i++) {
1034 1.1 ad if (descs[i] & 0x80000000)
1035 1.1 ad continue;
1036 1.1 ad for (j = 0; j < 4; j++) {
1037 1.1 ad if (i == 0 && j == 0)
1038 1.1 ad continue;
1039 1.1 ad desc = (descs[i] >> (j * 8)) & 0xff;
1040 1.1 ad if (desc == 0)
1041 1.1 ad continue;
1042 1.1 ad cai = cache_info_lookup(intel_cpuid_cache_info,
1043 1.1 ad desc);
1044 1.1 ad if (cai != NULL)
1045 1.1 ad ci->ci_cinfo[cai->cai_index] = *cai;
1046 1.1 ad }
1047 1.1 ad }
1048 1.1 ad x86_cpuid(2, descs);
1049 1.1 ad }
1050 1.1 ad
1051 1.1 ad if (ci->ci_cpuid_level < 3)
1052 1.1 ad return;
1053 1.1 ad
1054 1.1 ad /*
1055 1.1 ad * If the processor serial number misfeature is present and supported,
1056 1.1 ad * extract it here.
1057 1.1 ad */
1058 1.18 pgoyette if ((ci->ci_feat_val[0] & CPUID_PN) != 0) {
1059 1.1 ad ci->ci_cpu_serial[0] = ci->ci_signature;
1060 1.1 ad x86_cpuid(3, descs);
1061 1.1 ad ci->ci_cpu_serial[2] = descs[2];
1062 1.1 ad ci->ci_cpu_serial[1] = descs[3];
1063 1.1 ad }
1064 1.1 ad }
1065 1.1 ad
1066 1.1 ad static void
1067 1.1 ad cpu_probe_features(struct cpu_info *ci)
1068 1.1 ad {
1069 1.1 ad const struct cpu_cpuid_nameclass *cpup = NULL;
1070 1.1 ad int i, xmax, family;
1071 1.1 ad
1072 1.1 ad cpu_probe_base_features(ci);
1073 1.1 ad
1074 1.1 ad if (ci->ci_cpuid_level < 1)
1075 1.1 ad return;
1076 1.1 ad
1077 1.3 chris xmax = __arraycount(i386_cpuid_cpus);
1078 1.1 ad for (i = 0; i < xmax; i++) {
1079 1.1 ad if (!strncmp((char *)ci->ci_vendor,
1080 1.1 ad i386_cpuid_cpus[i].cpu_id, 12)) {
1081 1.1 ad cpup = &i386_cpuid_cpus[i];
1082 1.1 ad break;
1083 1.1 ad }
1084 1.1 ad }
1085 1.1 ad
1086 1.1 ad if (cpup == NULL)
1087 1.1 ad return;
1088 1.1 ad
1089 1.1 ad family = (ci->ci_signature >> 8) & 0xf;
1090 1.1 ad
1091 1.1 ad if (family > CPU_MAXFAMILY) {
1092 1.1 ad family = CPU_MAXFAMILY;
1093 1.1 ad }
1094 1.1 ad i = family - CPU_MINFAMILY;
1095 1.1 ad
1096 1.1 ad if (cpup->cpu_family[i].cpu_probe == NULL)
1097 1.1 ad return;
1098 1.1 ad
1099 1.1 ad (*cpup->cpu_family[i].cpu_probe)(ci);
1100 1.1 ad }
1101 1.1 ad
1102 1.1 ad static void
1103 1.1 ad intel_family_new_probe(struct cpu_info *ci)
1104 1.1 ad {
1105 1.1 ad uint32_t descs[4];
1106 1.1 ad
1107 1.1 ad x86_cpuid(0x80000000, descs);
1108 1.1 ad
1109 1.1 ad /*
1110 1.1 ad * Determine extended feature flags.
1111 1.1 ad */
1112 1.1 ad if (descs[0] >= 0x80000001) {
1113 1.1 ad x86_cpuid(0x80000001, descs);
1114 1.18 pgoyette ci->ci_feat_val[2] |= descs[3];
1115 1.18 pgoyette ci->ci_feat_val[3] |= descs[2];
1116 1.1 ad }
1117 1.1 ad }
1118 1.1 ad
1119 1.1 ad static void
1120 1.1 ad amd_family6_probe(struct cpu_info *ci)
1121 1.1 ad {
1122 1.1 ad uint32_t descs[4];
1123 1.1 ad char *p;
1124 1.17 christos size_t i;
1125 1.1 ad
1126 1.1 ad x86_cpuid(0x80000000, descs);
1127 1.1 ad
1128 1.1 ad /*
1129 1.1 ad * Determine the extended feature flags.
1130 1.1 ad */
1131 1.1 ad if (descs[0] >= 0x80000001) {
1132 1.1 ad x86_cpuid(0x80000001, descs);
1133 1.18 pgoyette ci->ci_feat_val[2] |= descs[3]; /* %edx */
1134 1.18 pgoyette ci->ci_feat_val[3] = descs[2]; /* %ecx */
1135 1.1 ad }
1136 1.1 ad
1137 1.1 ad if (*cpu_brand_string == '\0')
1138 1.1 ad return;
1139 1.1 ad
1140 1.3 chris for (i = 1; i < __arraycount(amd_brand); i++)
1141 1.1 ad if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) {
1142 1.1 ad ci->ci_brand_id = i;
1143 1.1 ad strlcpy(amd_brand_name, p, sizeof(amd_brand_name));
1144 1.1 ad break;
1145 1.1 ad }
1146 1.1 ad }
1147 1.1 ad
1148 1.1 ad static void
1149 1.1 ad amd_family5_setup(struct cpu_info *ci)
1150 1.1 ad {
1151 1.1 ad
1152 1.1 ad switch (CPUID2MODEL(ci->ci_signature)) {
1153 1.1 ad case 0: /* AMD-K5 Model 0 */
1154 1.1 ad /*
1155 1.1 ad * According to the AMD Processor Recognition App Note,
1156 1.1 ad * the AMD-K5 Model 0 uses the wrong bit to indicate
1157 1.1 ad * support for global PTEs, instead using bit 9 (APIC)
1158 1.1 ad * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!).
1159 1.1 ad */
1160 1.18 pgoyette if (ci->ci_feat_val[0] & CPUID_APIC)
1161 1.18 pgoyette ci->ci_feat_val[0] =
1162 1.18 pgoyette (ci->ci_feat_val[0] & ~CPUID_APIC) | CPUID_PGE;
1163 1.1 ad /*
1164 1.1 ad * XXX But pmap_pg_g is already initialized -- need to kick
1165 1.1 ad * XXX the pmap somehow. How does the MP branch do this?
1166 1.1 ad */
1167 1.1 ad break;
1168 1.1 ad }
1169 1.1 ad }
1170 1.1 ad
1171 1.1 ad static void
1172 1.1 ad tmx86_get_longrun_status(u_int *frequency, u_int *voltage, u_int *percentage)
1173 1.1 ad {
1174 1.1 ad u_int descs[4];
1175 1.1 ad
1176 1.1 ad x86_cpuid(0x80860007, descs);
1177 1.1 ad *frequency = descs[0];
1178 1.1 ad *voltage = descs[1];
1179 1.1 ad *percentage = descs[2];
1180 1.1 ad }
1181 1.1 ad
1182 1.1 ad static void
1183 1.1 ad transmeta_cpu_info(struct cpu_info *ci)
1184 1.1 ad {
1185 1.1 ad u_int descs[4], nreg;
1186 1.1 ad u_int frequency, voltage, percentage;
1187 1.1 ad
1188 1.1 ad x86_cpuid(0x80860000, descs);
1189 1.1 ad nreg = descs[0];
1190 1.1 ad if (nreg >= 0x80860001) {
1191 1.1 ad x86_cpuid(0x80860001, descs);
1192 1.1 ad aprint_verbose_dev(ci->ci_dev, "Processor revision %u.%u.%u.%u\n",
1193 1.1 ad (descs[1] >> 24) & 0xff,
1194 1.1 ad (descs[1] >> 16) & 0xff,
1195 1.1 ad (descs[1] >> 8) & 0xff,
1196 1.1 ad descs[1] & 0xff);
1197 1.1 ad }
1198 1.1 ad if (nreg >= 0x80860002) {
1199 1.1 ad x86_cpuid(0x80860002, descs);
1200 1.1 ad aprint_verbose_dev(ci->ci_dev, "Code Morphing Software Rev: %u.%u.%u-%u-%u\n",
1201 1.1 ad (descs[1] >> 24) & 0xff,
1202 1.1 ad (descs[1] >> 16) & 0xff,
1203 1.1 ad (descs[1] >> 8) & 0xff,
1204 1.1 ad descs[1] & 0xff,
1205 1.1 ad descs[2]);
1206 1.1 ad }
1207 1.1 ad if (nreg >= 0x80860006) {
1208 1.1 ad union {
1209 1.1 ad char text[65];
1210 1.1 ad u_int descs[4][4];
1211 1.1 ad } info;
1212 1.1 ad int i;
1213 1.1 ad
1214 1.1 ad for (i=0; i<4; i++) {
1215 1.1 ad x86_cpuid(0x80860003 + i, info.descs[i]);
1216 1.1 ad }
1217 1.1 ad info.text[64] = '\0';
1218 1.1 ad aprint_verbose_dev(ci->ci_dev, "%s\n", info.text);
1219 1.1 ad }
1220 1.1 ad
1221 1.1 ad if (nreg >= 0x80860007) {
1222 1.1 ad tmx86_get_longrun_status(&frequency,
1223 1.1 ad &voltage, &percentage);
1224 1.1 ad aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n",
1225 1.1 ad frequency, voltage, percentage);
1226 1.1 ad }
1227 1.1 ad }
1228 1.1 ad
1229 1.1 ad void
1230 1.1 ad identifycpu(const char *cpuname)
1231 1.1 ad {
1232 1.18 pgoyette const char *name = "", *modifier, *vendorname, *brand = "";
1233 1.1 ad int class = CPUCLASS_386, i, xmax;
1234 1.18 pgoyette int modif, family, model, ext_model;
1235 1.18 pgoyette const struct cpu_extend_nameclass *modlist;
1236 1.1 ad const struct cpu_cpuid_nameclass *cpup = NULL;
1237 1.1 ad const struct cpu_cpuid_family *cpufam;
1238 1.12 cegger const char *feature_str[5];
1239 1.1 ad struct cpu_info *ci, cistore;
1240 1.1 ad extern int cpu;
1241 1.1 ad extern int cpu_info_level;
1242 1.1 ad size_t sz;
1243 1.18 pgoyette char buf[512];
1244 1.18 pgoyette char *bp;
1245 1.1 ad
1246 1.1 ad ci = &cistore;
1247 1.1 ad memset(ci, 0, sizeof(*ci));
1248 1.1 ad ci->ci_dev = cpuname;
1249 1.1 ad
1250 1.1 ad x86_identify();
1251 1.1 ad ci->ci_cpuid_level = cpu_info_level;
1252 1.1 ad cpu_probe_features(ci);
1253 1.1 ad
1254 1.1 ad if (ci->ci_cpuid_level == -1) {
1255 1.17 christos if ((size_t)cpu >= __arraycount(i386_nocpuid_cpus))
1256 1.1 ad errx(1, "unknown cpu type %d", cpu);
1257 1.1 ad name = i386_nocpuid_cpus[cpu].cpu_name;
1258 1.1 ad cpu_vendor = i386_nocpuid_cpus[cpu].cpu_vendor;
1259 1.1 ad vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname;
1260 1.1 ad class = i386_nocpuid_cpus[cpu].cpu_class;
1261 1.1 ad ci->ci_info = i386_nocpuid_cpus[cpu].cpu_info;
1262 1.1 ad modifier = "";
1263 1.1 ad } else {
1264 1.1 ad xmax = __arraycount(i386_cpuid_cpus);
1265 1.1 ad modif = (ci->ci_signature >> 12) & 0x3;
1266 1.1 ad family = CPUID2FAMILY(ci->ci_signature);
1267 1.1 ad if (family < CPU_MINFAMILY)
1268 1.1 ad errx(1, "identifycpu: strange family value");
1269 1.1 ad model = CPUID2MODEL(ci->ci_signature);
1270 1.18 pgoyette ext_model = CPUID2EXTMODEL(ci->ci_signature);
1271 1.1 ad
1272 1.1 ad for (i = 0; i < xmax; i++) {
1273 1.1 ad if (!strncmp((char *)ci->ci_vendor,
1274 1.1 ad i386_cpuid_cpus[i].cpu_id, 12)) {
1275 1.1 ad cpup = &i386_cpuid_cpus[i];
1276 1.1 ad break;
1277 1.1 ad }
1278 1.1 ad }
1279 1.1 ad
1280 1.1 ad if (cpup == NULL) {
1281 1.1 ad cpu_vendor = CPUVENDOR_UNKNOWN;
1282 1.1 ad if (ci->ci_vendor[0] != '\0')
1283 1.1 ad vendorname = (char *)&ci->ci_vendor[0];
1284 1.1 ad else
1285 1.1 ad vendorname = "Unknown";
1286 1.1 ad if (family >= CPU_MAXFAMILY)
1287 1.1 ad family = CPU_MINFAMILY;
1288 1.1 ad class = family - 3;
1289 1.1 ad modifier = "";
1290 1.1 ad name = "";
1291 1.1 ad ci->ci_info = NULL;
1292 1.1 ad } else {
1293 1.1 ad cpu_vendor = cpup->cpu_vendor;
1294 1.1 ad vendorname = cpup->cpu_vendorname;
1295 1.1 ad modifier = modifiers[modif];
1296 1.1 ad if (family > CPU_MAXFAMILY) {
1297 1.1 ad family = CPU_MAXFAMILY;
1298 1.1 ad model = CPU_DEFMODEL;
1299 1.18 pgoyette } else if (model > CPU_MAXMODEL) {
1300 1.1 ad model = CPU_DEFMODEL;
1301 1.18 pgoyette ext_model = 0;
1302 1.18 pgoyette }
1303 1.1 ad cpufam = &cpup->cpu_family[family - CPU_MINFAMILY];
1304 1.18 pgoyette if (cpufam->cpu_extended_names == NULL ||
1305 1.18 pgoyette ext_model == 0)
1306 1.18 pgoyette name = cpufam->cpu_models[model];
1307 1.18 pgoyette else {
1308 1.18 pgoyette /*
1309 1.18 pgoyette * Scan list(s) of extended model names
1310 1.18 pgoyette */
1311 1.18 pgoyette modlist = cpufam->cpu_extended_names;
1312 1.18 pgoyette while (modlist->ext_model != 0) {
1313 1.18 pgoyette if (modlist->ext_model == ext_model) {
1314 1.18 pgoyette name =
1315 1.18 pgoyette modlist->cpu_models[model];
1316 1.18 pgoyette break;
1317 1.18 pgoyette }
1318 1.18 pgoyette modlist++;
1319 1.18 pgoyette }
1320 1.18 pgoyette }
1321 1.18 pgoyette if (name == NULL || *name == '\0')
1322 1.1 ad name = cpufam->cpu_models[CPU_DEFMODEL];
1323 1.1 ad class = cpufam->cpu_class;
1324 1.1 ad ci->ci_info = cpufam->cpu_info;
1325 1.1 ad
1326 1.1 ad if (cpu_vendor == CPUVENDOR_INTEL) {
1327 1.1 ad if (family == 6 && model >= 5) {
1328 1.1 ad const char *tmp;
1329 1.1 ad tmp = intel_family6_name(ci);
1330 1.1 ad if (tmp != NULL)
1331 1.1 ad name = tmp;
1332 1.1 ad }
1333 1.1 ad if (family == CPU_MAXFAMILY &&
1334 1.1 ad ci->ci_brand_id <
1335 1.1 ad __arraycount(i386_intel_brand) &&
1336 1.1 ad i386_intel_brand[ci->ci_brand_id])
1337 1.1 ad name =
1338 1.1 ad i386_intel_brand[ci->ci_brand_id];
1339 1.1 ad }
1340 1.1 ad
1341 1.1 ad if (cpu_vendor == CPUVENDOR_AMD) {
1342 1.1 ad if (family == 6 && model >= 6) {
1343 1.1 ad if (ci->ci_brand_id == 1)
1344 1.1 ad /*
1345 1.1 ad * It's Duron. We override the
1346 1.1 ad * name, since it might have
1347 1.1 ad * been misidentified as Athlon.
1348 1.1 ad */
1349 1.1 ad name =
1350 1.1 ad amd_brand[ci->ci_brand_id];
1351 1.1 ad else
1352 1.1 ad brand = amd_brand_name;
1353 1.1 ad }
1354 1.1 ad if (CPUID2FAMILY(ci->ci_signature) == 0xf) {
1355 1.1 ad /*
1356 1.1 ad * Identify AMD64 CPU names.
1357 1.1 ad * Note family value is clipped by
1358 1.1 ad * CPU_MAXFAMILY.
1359 1.1 ad */
1360 1.1 ad const char *tmp;
1361 1.1 ad tmp = amd_amd64_name(ci);
1362 1.1 ad if (tmp != NULL)
1363 1.1 ad name = tmp;
1364 1.1 ad }
1365 1.1 ad }
1366 1.1 ad
1367 1.1 ad if (cpu_vendor == CPUVENDOR_IDT && family >= 6)
1368 1.1 ad vendorname = "VIA";
1369 1.1 ad }
1370 1.1 ad }
1371 1.1 ad
1372 1.1 ad ci->ci_cpu_class = class;
1373 1.1 ad
1374 1.1 ad sz = sizeof(ci->ci_tsc_freq);
1375 1.1 ad (void)sysctlbyname("machdep.tsc_freq", &ci->ci_tsc_freq, &sz, NULL, 0);
1376 1.1 ad
1377 1.1 ad snprintf(cpu_model, sizeof(cpu_model), "%s%s%s%s%s%s%s (%s-class)",
1378 1.1 ad vendorname,
1379 1.1 ad *modifier ? " " : "", modifier,
1380 1.1 ad *name ? " " : "", name,
1381 1.1 ad *brand ? " " : "", brand,
1382 1.1 ad classnames[class]);
1383 1.1 ad aprint_normal("%s: %s", cpuname, cpu_model);
1384 1.1 ad
1385 1.1 ad if (ci->ci_tsc_freq != 0)
1386 1.1 ad aprint_normal(", %qd.%02qd MHz",
1387 1.1 ad (ci->ci_tsc_freq + 4999) / 1000000,
1388 1.1 ad ((ci->ci_tsc_freq + 4999) / 10000) % 100);
1389 1.1 ad if (ci->ci_signature != 0)
1390 1.1 ad aprint_normal(", id 0x%x", ci->ci_signature);
1391 1.1 ad aprint_normal("\n");
1392 1.1 ad
1393 1.1 ad if (ci->ci_info)
1394 1.1 ad (*ci->ci_info)(ci);
1395 1.1 ad
1396 1.18 pgoyette /*
1397 1.18 pgoyette * display CPU feature flags
1398 1.18 pgoyette */
1399 1.18 pgoyette
1400 1.18 pgoyette #define MAX_FEATURE_LEN 60 /* XXX Need to find a better way to set this */
1401 1.18 pgoyette
1402 1.10 pgoyette feature_str[0] = CPUID_FLAGS1;
1403 1.18 pgoyette feature_str[1] = CPUID2_FLAGS1;
1404 1.18 pgoyette feature_str[2] = CPUID_EXT_FLAGS;
1405 1.18 pgoyette feature_str[3] = NULL;
1406 1.18 pgoyette feature_str[4] = NULL;
1407 1.12 cegger
1408 1.12 cegger switch (cpu_vendor) {
1409 1.12 cegger case CPUVENDOR_AMD:
1410 1.18 pgoyette feature_str[3] = CPUID_AMD_FLAGS4;
1411 1.12 cegger break;
1412 1.12 cegger case CPUVENDOR_INTEL:
1413 1.18 pgoyette feature_str[2] = CPUID_INTEL_EXT_FLAGS;
1414 1.11 cegger feature_str[3] = CPUID_INTEL_FLAGS4;
1415 1.12 cegger break;
1416 1.18 pgoyette case CPUVENDOR_CYRIX:
1417 1.18 pgoyette feature_str[4] = CPUID_FLAGS_PADLOCK;
1418 1.18 pgoyette /* FALLTHRU */
1419 1.12 cegger default:
1420 1.12 cegger break;
1421 1.12 cegger }
1422 1.1 ad
1423 1.18 pgoyette for (i = 0; i <= 4; i++) {
1424 1.18 pgoyette if (ci->ci_feat_val[i] && feature_str[i] != NULL) {
1425 1.18 pgoyette snprintb_m(buf, sizeof(buf), feature_str[i],
1426 1.18 pgoyette ci->ci_feat_val[i], MAX_FEATURE_LEN);
1427 1.18 pgoyette bp = buf;
1428 1.18 pgoyette while (*bp != '\0') {
1429 1.18 pgoyette aprint_verbose("%s: %sfeatures%c %s\n",
1430 1.18 pgoyette cpuname, (i == 4)?"padlock ":"",
1431 1.18 pgoyette (i == 4 || i == 0)?' ':'1' + i, bp);
1432 1.18 pgoyette bp += strlen(bp) + 1;
1433 1.18 pgoyette }
1434 1.1 ad }
1435 1.1 ad }
1436 1.1 ad
1437 1.1 ad if (*cpu_brand_string != '\0')
1438 1.1 ad aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string);
1439 1.1 ad
1440 1.1 ad x86_print_cacheinfo(ci);
1441 1.1 ad
1442 1.18 pgoyette if (ci->ci_cpuid_level >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) {
1443 1.1 ad aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n",
1444 1.1 ad cpuname,
1445 1.1 ad ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536,
1446 1.1 ad ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536,
1447 1.1 ad ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536);
1448 1.1 ad }
1449 1.1 ad
1450 1.1 ad if (ci->ci_cpu_class == CPUCLASS_386) {
1451 1.1 ad errx(1, "NetBSD requires an 80486 or later processor");
1452 1.1 ad }
1453 1.1 ad
1454 1.1 ad if (cpu == CPU_486DLC) {
1455 1.1 ad #ifndef CYRIX_CACHE_WORKS
1456 1.1 ad aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n");
1457 1.1 ad #else
1458 1.1 ad #ifndef CYRIX_CACHE_REALLY_WORKS
1459 1.1 ad aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n");
1460 1.1 ad #else
1461 1.1 ad aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED.\n");
1462 1.1 ad #endif
1463 1.1 ad #endif
1464 1.1 ad }
1465 1.1 ad
1466 1.1 ad /*
1467 1.1 ad * Everything past this point requires a Pentium or later.
1468 1.1 ad */
1469 1.1 ad if (ci->ci_cpuid_level < 0)
1470 1.1 ad return;
1471 1.1 ad
1472 1.1 ad identifycpu_cpuids(ci);
1473 1.1 ad
1474 1.1 ad #ifdef INTEL_CORETEMP
1475 1.1 ad if (cpu_vendor == CPUVENDOR_INTEL && ci->ci_cpuid_level >= 0x06)
1476 1.1 ad coretemp_register(ci);
1477 1.1 ad #endif
1478 1.1 ad
1479 1.5 ad if (cpu_vendor == CPUVENDOR_AMD) {
1480 1.5 ad powernow_probe(ci);
1481 1.15 yamt
1482 1.18 pgoyette if ((ci->ci_feat_val[3] & CPUID_SVM) != 0) {
1483 1.15 yamt uint32_t data[4];
1484 1.15 yamt
1485 1.15 yamt x86_cpuid(0x8000000a, data);
1486 1.15 yamt aprint_verbose("%s: SVM Rev. %d\n", cpuname,
1487 1.15 yamt data[0] & 0xf);
1488 1.15 yamt aprint_verbose("%s: SVM NASID %d\n", cpuname, data[1]);
1489 1.15 yamt snprintb(buf, sizeof(buf), CPUID_AMD_SVM_FLAGS,
1490 1.15 yamt data[3]);
1491 1.15 yamt aprint_verbose("%s: SVM features %s\n", cpuname, buf);
1492 1.15 yamt }
1493 1.1 ad }
1494 1.1 ad
1495 1.1 ad #ifdef INTEL_ONDEMAND_CLOCKMOD
1496 1.1 ad clockmod_init();
1497 1.1 ad #endif
1498 1.2 ad
1499 1.2 ad aprint_normal_dev(ci->ci_dev, "family %02x model %02x "
1500 1.2 ad "extfamily %02x extmodel %02x\n", CPUID2FAMILY(ci->ci_signature),
1501 1.2 ad CPUID2MODEL(ci->ci_signature), CPUID2EXTFAMILY(ci->ci_signature),
1502 1.2 ad CPUID2EXTMODEL(ci->ci_signature));
1503 1.1 ad }
1504 1.1 ad
1505 1.1 ad static const char *
1506 1.1 ad print_cache_config(struct cpu_info *ci, int cache_tag, const char *name,
1507 1.1 ad const char *sep)
1508 1.1 ad {
1509 1.1 ad struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
1510 1.7 christos char human_num[HUMAN_BUFSIZE];
1511 1.1 ad
1512 1.1 ad if (cai->cai_totalsize == 0)
1513 1.1 ad return sep;
1514 1.1 ad
1515 1.1 ad if (sep == NULL)
1516 1.1 ad aprint_verbose_dev(ci->ci_dev, "");
1517 1.1 ad else
1518 1.1 ad aprint_verbose("%s", sep);
1519 1.1 ad if (name != NULL)
1520 1.1 ad aprint_verbose("%s ", name);
1521 1.1 ad
1522 1.1 ad if (cai->cai_string != NULL) {
1523 1.1 ad aprint_verbose("%s ", cai->cai_string);
1524 1.1 ad } else {
1525 1.8 christos (void)humanize_number(human_num, sizeof(human_num),
1526 1.7 christos cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE);
1527 1.7 christos aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize);
1528 1.1 ad }
1529 1.1 ad switch (cai->cai_associativity) {
1530 1.1 ad case 0:
1531 1.1 ad aprint_verbose("disabled");
1532 1.1 ad break;
1533 1.1 ad case 1:
1534 1.1 ad aprint_verbose("direct-mapped");
1535 1.1 ad break;
1536 1.1 ad case 0xff:
1537 1.1 ad aprint_verbose("fully associative");
1538 1.1 ad break;
1539 1.1 ad default:
1540 1.1 ad aprint_verbose("%d-way", cai->cai_associativity);
1541 1.1 ad break;
1542 1.1 ad }
1543 1.1 ad return ", ";
1544 1.1 ad }
1545 1.1 ad
1546 1.1 ad static const char *
1547 1.1 ad print_tlb_config(struct cpu_info *ci, int cache_tag, const char *name,
1548 1.1 ad const char *sep)
1549 1.1 ad {
1550 1.1 ad struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
1551 1.7 christos char human_num[HUMAN_BUFSIZE];
1552 1.1 ad
1553 1.1 ad if (cai->cai_totalsize == 0)
1554 1.1 ad return sep;
1555 1.1 ad
1556 1.1 ad if (sep == NULL)
1557 1.1 ad aprint_verbose_dev(ci->ci_dev, "");
1558 1.1 ad else
1559 1.1 ad aprint_verbose("%s", sep);
1560 1.1 ad if (name != NULL)
1561 1.1 ad aprint_verbose("%s ", name);
1562 1.1 ad
1563 1.1 ad if (cai->cai_string != NULL) {
1564 1.1 ad aprint_verbose("%s", cai->cai_string);
1565 1.1 ad } else {
1566 1.7 christos (void)humanize_number(human_num, sizeof(human_num),
1567 1.7 christos cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE);
1568 1.7 christos aprint_verbose("%d %s entries ", cai->cai_totalsize,
1569 1.7 christos human_num);
1570 1.1 ad switch (cai->cai_associativity) {
1571 1.1 ad case 0:
1572 1.1 ad aprint_verbose("disabled");
1573 1.1 ad break;
1574 1.1 ad case 1:
1575 1.1 ad aprint_verbose("direct-mapped");
1576 1.1 ad break;
1577 1.1 ad case 0xff:
1578 1.1 ad aprint_verbose("fully associative");
1579 1.1 ad break;
1580 1.1 ad default:
1581 1.1 ad aprint_verbose("%d-way", cai->cai_associativity);
1582 1.1 ad break;
1583 1.1 ad }
1584 1.1 ad }
1585 1.1 ad return ", ";
1586 1.1 ad }
1587 1.1 ad
1588 1.1 ad static const struct x86_cache_info *
1589 1.1 ad cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc)
1590 1.1 ad {
1591 1.1 ad int i;
1592 1.1 ad
1593 1.1 ad for (i = 0; cai[i].cai_desc != 0; i++) {
1594 1.1 ad if (cai[i].cai_desc == desc)
1595 1.1 ad return (&cai[i]);
1596 1.1 ad }
1597 1.1 ad
1598 1.1 ad return (NULL);
1599 1.1 ad }
1600 1.1 ad
1601 1.7 christos static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] =
1602 1.7 christos AMD_L2CACHE_INFO;
1603 1.1 ad
1604 1.7 christos static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] =
1605 1.7 christos AMD_L3CACHE_INFO;
1606 1.1 ad
1607 1.1 ad static void
1608 1.1 ad amd_cpu_cacheinfo(struct cpu_info *ci)
1609 1.1 ad {
1610 1.1 ad const struct x86_cache_info *cp;
1611 1.1 ad struct x86_cache_info *cai;
1612 1.1 ad int family, model;
1613 1.1 ad u_int descs[4];
1614 1.1 ad u_int lfunc;
1615 1.1 ad
1616 1.1 ad family = (ci->ci_signature >> 8) & 15;
1617 1.1 ad model = CPUID2MODEL(ci->ci_signature);
1618 1.1 ad
1619 1.1 ad /*
1620 1.1 ad * K5 model 0 has none of this info.
1621 1.1 ad */
1622 1.1 ad if (family == 5 && model == 0)
1623 1.1 ad return;
1624 1.1 ad
1625 1.1 ad /*
1626 1.1 ad * Get extended values for K8 and up.
1627 1.1 ad */
1628 1.1 ad if (family == 0xf) {
1629 1.1 ad family += CPUID2EXTFAMILY(ci->ci_signature);
1630 1.1 ad model += CPUID2EXTMODEL(ci->ci_signature);
1631 1.1 ad }
1632 1.1 ad
1633 1.1 ad /*
1634 1.1 ad * Determine the largest extended function value.
1635 1.1 ad */
1636 1.1 ad x86_cpuid(0x80000000, descs);
1637 1.1 ad lfunc = descs[0];
1638 1.1 ad
1639 1.1 ad /*
1640 1.1 ad * Determine L1 cache/TLB info.
1641 1.1 ad */
1642 1.1 ad if (lfunc < 0x80000005) {
1643 1.1 ad /* No L1 cache info available. */
1644 1.1 ad return;
1645 1.1 ad }
1646 1.1 ad
1647 1.1 ad x86_cpuid(0x80000005, descs);
1648 1.1 ad
1649 1.1 ad /*
1650 1.1 ad * K6-III and higher have large page TLBs.
1651 1.1 ad */
1652 1.1 ad if ((family == 5 && model >= 9) || family >= 6) {
1653 1.1 ad cai = &ci->ci_cinfo[CAI_ITLB2];
1654 1.1 ad cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]);
1655 1.1 ad cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]);
1656 1.1 ad cai->cai_linesize = (4 * 1024 * 1024);
1657 1.1 ad
1658 1.1 ad cai = &ci->ci_cinfo[CAI_DTLB2];
1659 1.1 ad cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]);
1660 1.1 ad cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]);
1661 1.1 ad cai->cai_linesize = (4 * 1024 * 1024);
1662 1.1 ad }
1663 1.1 ad
1664 1.1 ad cai = &ci->ci_cinfo[CAI_ITLB];
1665 1.1 ad cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]);
1666 1.1 ad cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]);
1667 1.1 ad cai->cai_linesize = (4 * 1024);
1668 1.1 ad
1669 1.1 ad cai = &ci->ci_cinfo[CAI_DTLB];
1670 1.1 ad cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]);
1671 1.1 ad cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]);
1672 1.1 ad cai->cai_linesize = (4 * 1024);
1673 1.1 ad
1674 1.1 ad cai = &ci->ci_cinfo[CAI_DCACHE];
1675 1.1 ad cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]);
1676 1.1 ad cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]);
1677 1.1 ad cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[2]);
1678 1.1 ad
1679 1.1 ad cai = &ci->ci_cinfo[CAI_ICACHE];
1680 1.1 ad cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]);
1681 1.1 ad cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]);
1682 1.1 ad cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]);
1683 1.1 ad
1684 1.1 ad /*
1685 1.1 ad * Determine L2 cache/TLB info.
1686 1.1 ad */
1687 1.1 ad if (lfunc < 0x80000006) {
1688 1.1 ad /* No L2 cache info available. */
1689 1.1 ad return;
1690 1.1 ad }
1691 1.1 ad
1692 1.1 ad x86_cpuid(0x80000006, descs);
1693 1.1 ad
1694 1.1 ad cai = &ci->ci_cinfo[CAI_L2CACHE];
1695 1.1 ad cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]);
1696 1.1 ad cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]);
1697 1.1 ad cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]);
1698 1.1 ad
1699 1.1 ad cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info,
1700 1.1 ad cai->cai_associativity);
1701 1.1 ad if (cp != NULL)
1702 1.1 ad cai->cai_associativity = cp->cai_associativity;
1703 1.1 ad else
1704 1.1 ad cai->cai_associativity = 0; /* XXX Unknown/reserved */
1705 1.7 christos
1706 1.7 christos /*
1707 1.7 christos * Determine L3 cache info on AMD Family 10h processors
1708 1.7 christos */
1709 1.7 christos if (family == 0x10) {
1710 1.7 christos cai = &ci->ci_cinfo[CAI_L3CACHE];
1711 1.7 christos cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]);
1712 1.7 christos cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]);
1713 1.7 christos cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]);
1714 1.7 christos
1715 1.7 christos cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info,
1716 1.7 christos cai->cai_associativity);
1717 1.7 christos if (cp != NULL)
1718 1.7 christos cai->cai_associativity = cp->cai_associativity;
1719 1.7 christos else
1720 1.7 christos cai->cai_associativity = 0; /* XXX Unkn/Rsvd */
1721 1.7 christos }
1722 1.1 ad }
1723 1.1 ad
1724 1.1 ad static void
1725 1.1 ad via_cpu_cacheinfo(struct cpu_info *ci)
1726 1.1 ad {
1727 1.1 ad struct x86_cache_info *cai;
1728 1.1 ad int family, model, stepping;
1729 1.1 ad u_int descs[4];
1730 1.1 ad u_int lfunc;
1731 1.1 ad
1732 1.1 ad family = (ci->ci_signature >> 8) & 15;
1733 1.1 ad model = CPUID2MODEL(ci->ci_signature);
1734 1.1 ad stepping = CPUID2STEPPING(ci->ci_signature);
1735 1.1 ad
1736 1.1 ad /*
1737 1.1 ad * Determine the largest extended function value.
1738 1.1 ad */
1739 1.1 ad x86_cpuid(0x80000000, descs);
1740 1.1 ad lfunc = descs[0];
1741 1.1 ad
1742 1.1 ad /*
1743 1.1 ad * Determine L1 cache/TLB info.
1744 1.1 ad */
1745 1.1 ad if (lfunc < 0x80000005) {
1746 1.1 ad /* No L1 cache info available. */
1747 1.1 ad return;
1748 1.1 ad }
1749 1.1 ad
1750 1.1 ad x86_cpuid(0x80000005, descs);
1751 1.1 ad
1752 1.1 ad cai = &ci->ci_cinfo[CAI_ITLB];
1753 1.1 ad cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]);
1754 1.1 ad cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]);
1755 1.1 ad cai->cai_linesize = (4 * 1024);
1756 1.1 ad
1757 1.1 ad cai = &ci->ci_cinfo[CAI_DTLB];
1758 1.1 ad cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]);
1759 1.1 ad cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]);
1760 1.1 ad cai->cai_linesize = (4 * 1024);
1761 1.1 ad
1762 1.1 ad cai = &ci->ci_cinfo[CAI_DCACHE];
1763 1.1 ad cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]);
1764 1.1 ad cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]);
1765 1.1 ad cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]);
1766 1.1 ad if (model == 9 && stepping == 8) {
1767 1.1 ad /* Erratum: stepping 8 reports 4 when it should be 2 */
1768 1.1 ad cai->cai_associativity = 2;
1769 1.1 ad }
1770 1.1 ad
1771 1.1 ad cai = &ci->ci_cinfo[CAI_ICACHE];
1772 1.1 ad cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]);
1773 1.1 ad cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]);
1774 1.1 ad cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]);
1775 1.1 ad if (model == 9 && stepping == 8) {
1776 1.1 ad /* Erratum: stepping 8 reports 4 when it should be 2 */
1777 1.1 ad cai->cai_associativity = 2;
1778 1.1 ad }
1779 1.1 ad
1780 1.1 ad /*
1781 1.1 ad * Determine L2 cache/TLB info.
1782 1.1 ad */
1783 1.1 ad if (lfunc < 0x80000006) {
1784 1.1 ad /* No L2 cache info available. */
1785 1.1 ad return;
1786 1.1 ad }
1787 1.1 ad
1788 1.1 ad x86_cpuid(0x80000006, descs);
1789 1.1 ad
1790 1.1 ad cai = &ci->ci_cinfo[CAI_L2CACHE];
1791 1.1 ad if (model >= 9) {
1792 1.1 ad cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
1793 1.1 ad cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);
1794 1.1 ad cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]);
1795 1.1 ad } else {
1796 1.1 ad cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
1797 1.1 ad cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
1798 1.1 ad cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
1799 1.1 ad }
1800 1.1 ad }
1801 1.1 ad
1802 1.1 ad static void
1803 1.1 ad x86_print_cacheinfo(struct cpu_info *ci)
1804 1.1 ad {
1805 1.1 ad const char *sep;
1806 1.1 ad
1807 1.1 ad if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 ||
1808 1.1 ad ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) {
1809 1.1 ad sep = print_cache_config(ci, CAI_ICACHE, "I-cache", NULL);
1810 1.1 ad sep = print_cache_config(ci, CAI_DCACHE, "D-cache", sep);
1811 1.1 ad if (sep != NULL)
1812 1.1 ad aprint_verbose("\n");
1813 1.1 ad }
1814 1.1 ad if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize != 0) {
1815 1.1 ad sep = print_cache_config(ci, CAI_L2CACHE, "L2 cache", NULL);
1816 1.1 ad if (sep != NULL)
1817 1.1 ad aprint_verbose("\n");
1818 1.1 ad }
1819 1.1 ad if (ci->ci_cinfo[CAI_ITLB].cai_totalsize != 0) {
1820 1.1 ad sep = print_tlb_config(ci, CAI_ITLB, "ITLB", NULL);
1821 1.1 ad sep = print_tlb_config(ci, CAI_ITLB2, NULL, sep);
1822 1.1 ad if (sep != NULL)
1823 1.1 ad aprint_verbose("\n");
1824 1.1 ad }
1825 1.1 ad if (ci->ci_cinfo[CAI_DTLB].cai_totalsize != 0) {
1826 1.1 ad sep = print_tlb_config(ci, CAI_DTLB, "DTLB", NULL);
1827 1.1 ad sep = print_tlb_config(ci, CAI_DTLB2, NULL, sep);
1828 1.1 ad if (sep != NULL)
1829 1.1 ad aprint_verbose("\n");
1830 1.1 ad }
1831 1.7 christos if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) {
1832 1.7 christos sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL);
1833 1.7 christos if (sep != NULL)
1834 1.7 christos aprint_verbose("\n");
1835 1.7 christos }
1836 1.1 ad }
1837 1.5 ad
1838 1.5 ad static void
1839 1.5 ad powernow_probe(struct cpu_info *ci)
1840 1.5 ad {
1841 1.5 ad uint32_t regs[4];
1842 1.14 christos char buf[256];
1843 1.5 ad
1844 1.5 ad x86_cpuid(0x80000000, regs);
1845 1.5 ad
1846 1.5 ad /* We need CPUID(0x80000007) */
1847 1.5 ad if (regs[0] < 0x80000007)
1848 1.5 ad return;
1849 1.5 ad x86_cpuid(0x80000007, regs);
1850 1.5 ad
1851 1.14 christos snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]);
1852 1.5 ad aprint_normal_dev(ci->ci_dev, "AMD Power Management features: %s\n",
1853 1.14 christos buf);
1854 1.5 ad }
1855