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