xref: /netbsd-src/sys/arch/x86/x86/identcpu.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: identcpu.c,v 1.50 2016/01/01 19:46:48 tls 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 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.50 2016/01/01 19:46:48 tls Exp $");
34 
35 #include "opt_xen.h"
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #include <sys/cpu.h>
41 
42 #include <uvm/uvm_extern.h>
43 
44 #include <machine/specialreg.h>
45 #include <machine/pio.h>
46 #include <machine/cpu.h>
47 
48 #include <x86/cputypes.h>
49 #include <x86/cacheinfo.h>
50 #include <x86/cpuvar.h>
51 #include <x86/cpu_msr.h>
52 
53 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO;
54 
55 static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] =
56 	AMD_L2CACHE_INFO;
57 
58 static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] =
59 	AMD_L3CACHE_INFO;
60 
61 int cpu_vendor;
62 char cpu_brand_string[49];
63 
64 int x86_fpu_save = FPU_SAVE_FSAVE;
65 unsigned int x86_fpu_save_size = 512;
66 uint64_t x86_xsave_features = 0;
67 
68 /*
69  * Note: these are just the ones that may not have a cpuid instruction.
70  * We deal with the rest in a different way.
71  */
72 const int i386_nocpuid_cpus[] = {
73 	CPUVENDOR_INTEL, CPUCLASS_386,	/* CPU_386SX */
74 	CPUVENDOR_INTEL, CPUCLASS_386,	/* CPU_386   */
75 	CPUVENDOR_INTEL, CPUCLASS_486,	/* CPU_486SX */
76 	CPUVENDOR_INTEL, CPUCLASS_486, 	/* CPU_486   */
77 	CPUVENDOR_CYRIX, CPUCLASS_486,	/* CPU_486DLC */
78 	CPUVENDOR_CYRIX, CPUCLASS_486,	/* CPU_6x86 */
79 	CPUVENDOR_NEXGEN, CPUCLASS_386,	/* CPU_NX586 */
80 };
81 
82 static const char cpu_vendor_names[][10] = {
83 	"Unknown", "Intel", "NS/Cyrix", "NexGen", "AMD", "IDT/VIA", "Transmeta",
84 	"Vortex86"
85 };
86 
87 static const struct x86_cache_info *
88 cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc)
89 {
90 	int i;
91 
92 	for (i = 0; cai[i].cai_desc != 0; i++) {
93 		if (cai[i].cai_desc == desc)
94 			return (&cai[i]);
95 	}
96 
97 	return (NULL);
98 }
99 
100 static void
101 cpu_probe_intel_cache(struct cpu_info *ci)
102 {
103 	const struct x86_cache_info *cai;
104 	u_int descs[4];
105 	int iterations, i, j;
106 	uint8_t desc;
107 
108 	if (cpuid_level >= 2) {
109 		/* Parse the cache info from `cpuid leaf 2', if we have it. */
110 		x86_cpuid(2, descs);
111 		iterations = descs[0] & 0xff;
112 		while (iterations-- > 0) {
113 			for (i = 0; i < 4; i++) {
114 				if (descs[i] & 0x80000000)
115 					continue;
116 				for (j = 0; j < 4; j++) {
117 					if (i == 0 && j == 0)
118 						continue;
119 					desc = (descs[i] >> (j * 8)) & 0xff;
120 					if (desc == 0)
121 						continue;
122 					cai = cache_info_lookup(
123 					    intel_cpuid_cache_info, desc);
124 					if (cai != NULL) {
125 						ci->ci_cinfo[cai->cai_index] =
126 						    *cai;
127 					}
128 				}
129 			}
130 		}
131 	}
132 
133 	if (cpuid_level >= 4) {
134 		int type, level;
135 		int ways, partitions, linesize, sets;
136 		int caitype = -1;
137 		int totalsize;
138 
139 		/* Parse the cache info from `cpuid leaf 4', if we have it. */
140 		for (i = 0; ; i++) {
141 			x86_cpuid2(4, i, descs);
142 			type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE);
143 			if (type == CPUID_DCP_CACHETYPE_N)
144 				break;
145 			level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL);
146 			switch (level) {
147 			case 1:
148 				if (type == CPUID_DCP_CACHETYPE_I)
149 					caitype = CAI_ICACHE;
150 				else if (type == CPUID_DCP_CACHETYPE_D)
151 					caitype = CAI_DCACHE;
152 				else
153 					caitype = -1;
154 				break;
155 			case 2:
156 				if (type == CPUID_DCP_CACHETYPE_U)
157 					caitype = CAI_L2CACHE;
158 				else
159 					caitype = -1;
160 				break;
161 			case 3:
162 				if (type == CPUID_DCP_CACHETYPE_U)
163 					caitype = CAI_L3CACHE;
164 				else
165 					caitype = -1;
166 				break;
167 			default:
168 				caitype = -1;
169 				break;
170 			}
171 			if (caitype == -1)
172 				continue;
173 
174 			ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1;
175 			partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS)
176 			    + 1;
177 			linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE)
178 			    + 1;
179 			sets = descs[2] + 1;
180 			totalsize = ways * partitions * linesize * sets;
181 			ci->ci_cinfo[caitype].cai_totalsize = totalsize;
182 			ci->ci_cinfo[caitype].cai_associativity = ways;
183 			ci->ci_cinfo[caitype].cai_linesize = linesize;
184 		}
185 	}
186 }
187 
188 static void
189 cpu_probe_intel(struct cpu_info *ci)
190 {
191 
192 	if (cpu_vendor != CPUVENDOR_INTEL)
193 		return;
194 
195 	cpu_probe_intel_cache(ci);
196 }
197 
198 static void
199 cpu_probe_amd_cache(struct cpu_info *ci)
200 {
201 	const struct x86_cache_info *cp;
202 	struct x86_cache_info *cai;
203 	int family, model;
204 	u_int descs[4];
205 	u_int lfunc;
206 
207 	family = CPUID_TO_FAMILY(ci->ci_signature);
208 	model = CPUID_TO_MODEL(ci->ci_signature);
209 
210 	/*
211 	 * K5 model 0 has none of this info.
212 	 */
213 	if (family == 5 && model == 0)
214 		return;
215 
216 	/*
217 	 * Determine the largest extended function value.
218 	 */
219 	x86_cpuid(0x80000000, descs);
220 	lfunc = descs[0];
221 
222 	/*
223 	 * Determine L1 cache/TLB info.
224 	 */
225 	if (lfunc < 0x80000005) {
226 		/* No L1 cache info available. */
227 		return;
228 	}
229 
230 	x86_cpuid(0x80000005, descs);
231 
232 	/*
233 	 * K6-III and higher have large page TLBs.
234 	 */
235 	if ((family == 5 && model >= 9) || family >= 6) {
236 		cai = &ci->ci_cinfo[CAI_ITLB2];
237 		cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]);
238 		cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]);
239 		cai->cai_linesize = (4 * 1024 * 1024);
240 
241 		cai = &ci->ci_cinfo[CAI_DTLB2];
242 		cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]);
243 		cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]);
244 		cai->cai_linesize = (4 * 1024 * 1024);
245 	}
246 
247 	cai = &ci->ci_cinfo[CAI_ITLB];
248 	cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]);
249 	cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]);
250 	cai->cai_linesize = (4 * 1024);
251 
252 	cai = &ci->ci_cinfo[CAI_DTLB];
253 	cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]);
254 	cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]);
255 	cai->cai_linesize = (4 * 1024);
256 
257 	cai = &ci->ci_cinfo[CAI_DCACHE];
258 	cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]);
259 	cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]);
260 	cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]);
261 
262 	cai = &ci->ci_cinfo[CAI_ICACHE];
263 	cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]);
264 	cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]);
265 	cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]);
266 
267 	/*
268 	 * Determine L2 cache/TLB info.
269 	 */
270 	if (lfunc < 0x80000006) {
271 		/* No L2 cache info available. */
272 		return;
273 	}
274 
275 	x86_cpuid(0x80000006, descs);
276 
277 	cai = &ci->ci_cinfo[CAI_L2CACHE];
278 	cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]);
279 	cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]);
280 	cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]);
281 
282 	cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info,
283 	    cai->cai_associativity);
284 	if (cp != NULL)
285 		cai->cai_associativity = cp->cai_associativity;
286 	else
287 		cai->cai_associativity = 0;	/* XXX Unknown/reserved */
288 
289 	if (family < 0xf) {
290 		/* No L3 cache info available. */
291 		return;
292 	}
293 
294 	cai = &ci->ci_cinfo[CAI_L3CACHE];
295 	cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]);
296 	cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]);
297 	cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]);
298 
299 	cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info,
300 	    cai->cai_associativity);
301 	if (cp != NULL)
302 		cai->cai_associativity = cp->cai_associativity;
303 	else
304 		cai->cai_associativity = 0;	/* XXX Unknown reserved */
305 
306 	if (lfunc < 0x80000019) {
307 		/* No 1GB Page TLB */
308 		return;
309 	}
310 
311 	x86_cpuid(0x80000019, descs);
312 
313 	cai = &ci->ci_cinfo[CAI_L1_1GBDTLB];
314 	cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[1]);
315 	cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[1]);
316 	cai->cai_linesize = (1 * 1024);
317 
318 	cai = &ci->ci_cinfo[CAI_L1_1GBITLB];
319 	cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]);
320 	cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]);
321 	cai->cai_linesize = (1 * 1024);
322 
323 	cai = &ci->ci_cinfo[CAI_L2_1GBDTLB];
324 	cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]);
325 	cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]);
326 	cai->cai_linesize = (1 * 1024);
327 
328 	cai = &ci->ci_cinfo[CAI_L2_1GBITLB];
329 	cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[0]);
330 	cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[0]);
331 	cai->cai_linesize = (1 * 1024);
332 }
333 
334 static void
335 cpu_probe_k5(struct cpu_info *ci)
336 {
337 	int flag;
338 
339 	if (cpu_vendor != CPUVENDOR_AMD ||
340 	    CPUID_TO_FAMILY(ci->ci_signature) != 5)
341 		return;
342 
343 	if (CPUID_TO_MODEL(ci->ci_signature) == 0) {
344 		/*
345 		 * According to the AMD Processor Recognition App Note,
346 		 * the AMD-K5 Model 0 uses the wrong bit to indicate
347 		 * support for global PTEs, instead using bit 9 (APIC)
348 		 * rather than bit 13 (i.e. "0x200" vs. 0x2000".  Oops!).
349 		 */
350 		flag = ci->ci_feat_val[0];
351 		if ((flag & CPUID_APIC) != 0)
352 			flag = (flag & ~CPUID_APIC) | CPUID_PGE;
353 		ci->ci_feat_val[0] = flag;
354 	}
355 
356 	cpu_probe_amd_cache(ci);
357 }
358 
359 static void
360 cpu_probe_k678(struct cpu_info *ci)
361 {
362 
363 	if (cpu_vendor != CPUVENDOR_AMD ||
364 	    CPUID_TO_FAMILY(ci->ci_signature) < 6)
365 		return;
366 
367 	cpu_probe_amd_cache(ci);
368 }
369 
370 static inline uint8_t
371 cyrix_read_reg(uint8_t reg)
372 {
373 
374 	outb(0x22, reg);
375 	return inb(0x23);
376 }
377 
378 static inline void
379 cyrix_write_reg(uint8_t reg, uint8_t data)
380 {
381 
382 	outb(0x22, reg);
383 	outb(0x23, data);
384 }
385 
386 static void
387 cpu_probe_cyrix_cmn(struct cpu_info *ci)
388 {
389 	/*
390 	 * i8254 latch check routine:
391 	 *     National Geode (formerly Cyrix MediaGX) has a serious bug in
392 	 *     its built-in i8254-compatible clock module (cs5510 cs5520).
393 	 *     Set the variable 'clock_broken_latch' to indicate it.
394 	 *
395 	 * This bug is not present in the cs5530, and the flag
396 	 * is disabled again in sys/arch/i386/pci/pcib.c if this later
397 	 * model device is detected. Ideally, this work-around should not
398 	 * even be in here, it should be in there. XXX
399 	 */
400 	uint8_t c3;
401 #ifndef XEN
402 	extern int clock_broken_latch;
403 
404 	switch (ci->ci_signature) {
405 	case 0x440:     /* Cyrix MediaGX */
406 	case 0x540:     /* GXm */
407 		clock_broken_latch = 1;
408 		break;
409 	}
410 #endif
411 
412 	/* set up various cyrix registers */
413 	/*
414 	 * Enable suspend on halt (powersave mode).
415 	 * When powersave mode is enabled, the TSC stops counting
416 	 * while the CPU is halted in idle() waiting for an interrupt.
417 	 * This means we can't use the TSC for interval time in
418 	 * microtime(9), and thus it is disabled here.
419 	 *
420 	 * It still makes a perfectly good cycle counter
421 	 * for program profiling, so long as you remember you're
422 	 * counting cycles, and not time. Further, if you don't
423 	 * mind not using powersave mode, the TSC works just fine,
424 	 * so this should really be optional. XXX
425 	 */
426 	cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08);
427 
428 	/*
429 	 * Do not disable the TSC on the Geode GX, it's reported to
430 	 * work fine.
431 	 */
432 	if (ci->ci_signature != 0x552)
433 		ci->ci_feat_val[0] &= ~CPUID_TSC;
434 
435 	/* enable access to ccr4/ccr5 */
436 	c3 = cyrix_read_reg(0xC3);
437 	cyrix_write_reg(0xC3, c3 | 0x10);
438 	/* cyrix's workaround  for the "coma bug" */
439 	cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8);
440 	cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f);
441 	cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff);
442 	cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87);
443 	/* disable access to ccr4/ccr5 */
444 	cyrix_write_reg(0xC3, c3);
445 }
446 
447 static void
448 cpu_probe_cyrix(struct cpu_info *ci)
449 {
450 
451 	if (cpu_vendor != CPUVENDOR_CYRIX ||
452 	    CPUID_TO_FAMILY(ci->ci_signature) < 4 ||
453 	    CPUID_TO_FAMILY(ci->ci_signature) > 6)
454 		return;
455 
456 	cpu_probe_cyrix_cmn(ci);
457 }
458 
459 static void
460 cpu_probe_winchip(struct cpu_info *ci)
461 {
462 
463 	if (cpu_vendor != CPUVENDOR_IDT)
464 	    	return;
465 
466 	switch (CPUID_TO_FAMILY(ci->ci_signature)) {
467 	case 5:
468 		/* WinChip C6 */
469 		if (CPUID_TO_MODEL(ci->ci_signature) == 4)
470 			ci->ci_feat_val[0] &= ~CPUID_TSC;
471 		break;
472 	case 6:
473 		/*
474 		 * VIA Eden ESP
475 		 *
476 		 * Quoting from page 3-4 of: "VIA Eden ESP Processor Datasheet"
477 		 * http://www.via.com.tw/download/mainboards/6/14/Eden20v115.pdf
478 		 *
479 		 * 1. The CMPXCHG8B instruction is provided and always enabled,
480 		 *    however, it appears disabled in the corresponding CPUID
481 		 *    function bit 0 to avoid a bug in an early version of
482 		 *    Windows NT. However, this default can be changed via a
483 		 *    bit in the FCR MSR.
484 		 */
485 		ci->ci_feat_val[0] |= CPUID_CX8;
486 		wrmsr(MSR_VIA_FCR, rdmsr(MSR_VIA_FCR) | 0x00000001);
487 		break;
488 	}
489 }
490 
491 static void
492 cpu_probe_c3(struct cpu_info *ci)
493 {
494 	u_int family, model, stepping, descs[4], lfunc, msr;
495 	struct x86_cache_info *cai;
496 
497 	if (cpu_vendor != CPUVENDOR_IDT ||
498 	    CPUID_TO_FAMILY(ci->ci_signature) < 6)
499 	    	return;
500 
501 	family = CPUID_TO_FAMILY(ci->ci_signature);
502 	model = CPUID_TO_MODEL(ci->ci_signature);
503 	stepping = CPUID_TO_STEPPING(ci->ci_signature);
504 
505 	/* Determine the largest extended function value. */
506 	x86_cpuid(0x80000000, descs);
507 	lfunc = descs[0];
508 
509 	if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) {
510 		/* Nehemiah or Esther */
511 		x86_cpuid(0xc0000000, descs);
512 		lfunc = descs[0];
513 		if (lfunc >= 0xc0000001) {	/* has ACE, RNG */
514 		    int rng_enable = 0, ace_enable = 0;
515 		    x86_cpuid(0xc0000001, descs);
516 		    lfunc = descs[3];
517 		    ci->ci_feat_val[4] = lfunc;
518 		    /* Check for and enable RNG */
519 		    if (lfunc & CPUID_VIA_HAS_RNG) {
520 		    	if (!(lfunc & CPUID_VIA_DO_RNG)) {
521 			    rng_enable++;
522 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_RNG;
523 			}
524 		    }
525 		    /* Check for and enable ACE (AES-CBC) */
526 		    if (lfunc & CPUID_VIA_HAS_ACE) {
527 			if (!(lfunc & CPUID_VIA_DO_ACE)) {
528 			    ace_enable++;
529 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE;
530 			}
531 		    }
532 		    /* Check for and enable SHA */
533 		    if (lfunc & CPUID_VIA_HAS_PHE) {
534 			if (!(lfunc & CPUID_VIA_DO_PHE)) {
535 			    ace_enable++;
536 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_PHE;
537 			}
538 		    }
539 		    /* Check for and enable ACE2 (AES-CTR) */
540 		    if (lfunc & CPUID_VIA_HAS_ACE2) {
541 			if (!(lfunc & CPUID_VIA_DO_ACE2)) {
542 			    ace_enable++;
543 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE2;
544 			}
545 		    }
546 		    /* Check for and enable PMM (modmult engine) */
547 		    if (lfunc & CPUID_VIA_HAS_PMM) {
548 			if (!(lfunc & CPUID_VIA_DO_PMM)) {
549 			    ace_enable++;
550 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM;
551 			}
552 		    }
553 
554 		    /* Actually do the enables. */
555 		    if (rng_enable) {
556 			msr = rdmsr(MSR_VIA_RNG);
557 			msr |= MSR_VIA_RNG_ENABLE;
558 			/* C7 stepping 8 and subsequent CPUs have dual RNG */
559 			if (model > 0xA || (model == 0xA && stepping > 0x7)) {
560 				msr |= MSR_VIA_RNG_2NOISE;
561 			}
562 			wrmsr(MSR_VIA_RNG, msr);
563 		    }
564 
565 		    if (ace_enable) {
566 			msr = rdmsr(MSR_VIA_ACE);
567 			wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE);
568 		    }
569 
570 		}
571 	}
572 
573 	/*
574 	 * Determine L1 cache/TLB info.
575 	 */
576 	if (lfunc < 0x80000005) {
577 		/* No L1 cache info available. */
578 		return;
579 	}
580 
581 	x86_cpuid(0x80000005, descs);
582 
583 	cai = &ci->ci_cinfo[CAI_ITLB];
584 	cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]);
585 	cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]);
586 	cai->cai_linesize = (4 * 1024);
587 
588 	cai = &ci->ci_cinfo[CAI_DTLB];
589 	cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]);
590 	cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]);
591 	cai->cai_linesize = (4 * 1024);
592 
593 	cai = &ci->ci_cinfo[CAI_DCACHE];
594 	cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]);
595 	cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]);
596 	cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]);
597 	if (family == 6 && model == 9 && stepping == 8) {
598 		/* Erratum: stepping 8 reports 4 when it should be 2 */
599 		cai->cai_associativity = 2;
600 	}
601 
602 	cai = &ci->ci_cinfo[CAI_ICACHE];
603 	cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]);
604 	cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]);
605 	cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]);
606 	if (family == 6 && model == 9 && stepping == 8) {
607 		/* Erratum: stepping 8 reports 4 when it should be 2 */
608 		cai->cai_associativity = 2;
609 	}
610 
611 	/*
612 	 * Determine L2 cache/TLB info.
613 	 */
614 	if (lfunc < 0x80000006) {
615 		/* No L2 cache info available. */
616 		return;
617 	}
618 
619 	x86_cpuid(0x80000006, descs);
620 
621 	cai = &ci->ci_cinfo[CAI_L2CACHE];
622 	if (family > 6 || model >= 9) {
623 		cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
624 		cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);
625 		cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]);
626 	} else {
627 		cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
628 		cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
629 		cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
630 	}
631 }
632 
633 static void
634 cpu_probe_geode(struct cpu_info *ci)
635 {
636 
637 	if (memcmp("Geode by NSC", ci->ci_vendor, 12) != 0 ||
638 	    CPUID_TO_FAMILY(ci->ci_signature) != 5)
639 	    	return;
640 
641 	cpu_probe_cyrix_cmn(ci);
642 	cpu_probe_amd_cache(ci);
643 }
644 
645 static void
646 cpu_probe_vortex86(struct cpu_info *ci)
647 {
648 #define PCI_MODE1_ADDRESS_REG	0x0cf8
649 #define PCI_MODE1_DATA_REG	0x0cfc
650 #define PCI_MODE1_ENABLE	0x80000000UL
651 
652 	uint32_t reg;
653 
654 	if (cpu_vendor != CPUVENDOR_VORTEX86)
655 		return;
656 	/*
657 	 * CPU model available from "Customer ID register" in
658 	 * North Bridge Function 0 PCI space
659 	 * we can't use pci_conf_read() because the PCI subsystem is not
660 	 * not initialised early enough
661 	 */
662 
663 	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE | 0x90);
664 	reg = inl(PCI_MODE1_DATA_REG);
665 
666 	switch(reg) {
667 	case 0x31504d44:
668 		strcpy(cpu_brand_string, "Vortex86SX");
669 		break;
670 	case 0x32504d44:
671 		strcpy(cpu_brand_string, "Vortex86DX");
672 		break;
673 	case 0x33504d44:
674 		strcpy(cpu_brand_string, "Vortex86MX");
675 		break;
676 	case 0x37504d44:
677 		strcpy(cpu_brand_string, "Vortex86EX");
678 		break;
679 	default:
680 		strcpy(cpu_brand_string, "Unknown Vortex86");
681 		break;
682 	}
683 
684 #undef PCI_MODE1_ENABLE
685 #undef PCI_MODE1_ADDRESS_REG
686 #undef PCI_MODE1_DATA_REG
687 }
688 
689 #if !defined(__i386__) || defined(XEN)
690 #define cpu_probe_old_fpu(ci)
691 #else
692 static void
693 cpu_probe_old_fpu(struct cpu_info *ci)
694 {
695 	uint16_t control;
696 
697 	/* Check that there really is an fpu (496SX) */
698 	clts();
699 	fninit();
700 	/* Read default control word */
701 	fnstcw(&control);
702 	if (control != __INITIAL_NPXCW__) {
703 		/* Must be a 486SX, trap FP instructions */
704 		lcr0((rcr0() & ~CR0_MP) | CR0_EM);
705 		i386_fpu_present = 0;
706 		return;
707 	}
708 
709 	/* Check for 'FDIV' bug on the original Pentium */
710 	if (npx586bug1(4195835, 3145727) != 0)
711 		/* NB 120+MHz cpus are not affected */
712 		i386_fpu_fdivbug = 1;
713 
714 	stts();
715 }
716 #endif
717 
718 static void
719 cpu_probe_fpu(struct cpu_info *ci)
720 {
721 	u_int descs[4];
722 
723 #ifdef i386 /* amd64 always has fxsave, sse and sse2 */
724 	/* If we have FXSAVE/FXRESTOR, use them. */
725 	if ((ci->ci_feat_val[0] & CPUID_FXSR) == 0) {
726 		i386_use_fxsave = 0;
727 		/* Allow for no fpu even if cpuid is supported */
728 		cpu_probe_old_fpu(ci);
729 		return;
730 	}
731 
732 	i386_use_fxsave = 1;
733 	/*
734 	 * If we have SSE/SSE2, enable XMM exceptions, and
735 	 * notify userland.
736 	 */
737 	if (ci->ci_feat_val[0] & CPUID_SSE)
738 		i386_has_sse = 1;
739 	if (ci->ci_feat_val[0] & CPUID_SSE2)
740 		i386_has_sse2 = 1;
741 #else
742 	/*
743 	 * For amd64 i386_use_fxsave, i386_has_sse and i386_has_sse2 are
744 	 * #defined to 1.
745 	 */
746 #endif	/* i386 */
747 
748 	x86_fpu_save = FPU_SAVE_FXSAVE;
749 
750 	/* See if xsave (for AVX is supported) */
751 	if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0)
752 		return;
753 
754 	x86_fpu_save = FPU_SAVE_XSAVE;
755 
756 	/* xsaveopt ought to be faster than xsave */
757 	x86_cpuid2(0xd, 1, descs);
758 	if (descs[0] & CPUID_PES1_XSAVEOPT)
759 		x86_fpu_save = FPU_SAVE_XSAVEOPT;
760 
761 	/* Get features and maximum size of the save area */
762 	x86_cpuid(0xd, descs);
763 	/* XXX these probably ought to be per-cpu */
764 	if (descs[2] > 512)
765 	    x86_fpu_save_size = descs[2];
766 #ifndef XEN
767 	x86_xsave_features = (uint64_t)descs[3] << 32 | descs[0];
768 #endif
769 }
770 
771 void
772 cpu_probe(struct cpu_info *ci)
773 {
774 	u_int descs[4];
775 	int i;
776 	uint32_t miscbytes;
777 	uint32_t brand[12];
778 
779 	cpu_vendor = i386_nocpuid_cpus[cputype << 1];
780 	cpu_class = i386_nocpuid_cpus[(cputype << 1) + 1];
781 
782 	if (cpuid_level < 0) {
783 		/* cpuid instruction not supported */
784 		cpu_probe_old_fpu(ci);
785 		return;
786 	}
787 
788 	for (i = 0; i < __arraycount(ci->ci_feat_val); i++) {
789 		ci->ci_feat_val[i] = 0;
790 	}
791 
792 	x86_cpuid(0, descs);
793 	cpuid_level = descs[0];
794 	ci->ci_max_cpuid = descs[0];
795 
796 	ci->ci_vendor[0] = descs[1];
797 	ci->ci_vendor[2] = descs[2];
798 	ci->ci_vendor[1] = descs[3];
799 	ci->ci_vendor[3] = 0;
800 
801 	if (memcmp(ci->ci_vendor, "GenuineIntel", 12) == 0)
802 		cpu_vendor = CPUVENDOR_INTEL;
803 	else if (memcmp(ci->ci_vendor,  "AuthenticAMD", 12) == 0)
804 		cpu_vendor = CPUVENDOR_AMD;
805 	else if (memcmp(ci->ci_vendor,  "CyrixInstead", 12) == 0)
806 		cpu_vendor = CPUVENDOR_CYRIX;
807 	else if (memcmp(ci->ci_vendor,  "Geode by NSC", 12) == 0)
808 		cpu_vendor = CPUVENDOR_CYRIX;
809 	else if (memcmp(ci->ci_vendor, "CentaurHauls", 12) == 0)
810 		cpu_vendor = CPUVENDOR_IDT;
811 	else if (memcmp(ci->ci_vendor, "GenuineTMx86", 12) == 0)
812 		cpu_vendor = CPUVENDOR_TRANSMETA;
813 	else if (memcmp(ci->ci_vendor, "Vortex86 SoC", 12) == 0)
814 		cpu_vendor = CPUVENDOR_VORTEX86;
815 	else
816 		cpu_vendor = CPUVENDOR_UNKNOWN;
817 
818 	if (cpuid_level >= 1) {
819 		x86_cpuid(1, descs);
820 		ci->ci_signature = descs[0];
821 		miscbytes = descs[1];
822 		ci->ci_feat_val[1] = descs[2];
823 		ci->ci_feat_val[0] = descs[3];
824 
825 		/* Determine family + class. */
826 		cpu_class = CPUID_TO_FAMILY(ci->ci_signature)
827 		    + (CPUCLASS_386 - 3);
828 		if (cpu_class > CPUCLASS_686)
829 			cpu_class = CPUCLASS_686;
830 
831 		/* CLFLUSH line size is next 8 bits */
832 		if (ci->ci_feat_val[0] & CPUID_CFLUSH)
833 			ci->ci_cflush_lsize = ((miscbytes >> 8) & 0xff) << 3;
834 		ci->ci_initapicid = (miscbytes >> 24) & 0xff;
835 	}
836 
837 	/*
838 	 * Get the basic information from the extended cpuid leafs.
839 	 * These were first implemented by amd, but most of the values
840 	 * match with those generated by modern intel cpus.
841 	 */
842 	x86_cpuid(0x80000000, descs);
843 	if (descs[0] >= 0x80000000)
844 		ci->ci_max_ext_cpuid = descs[0];
845 	else
846 		ci->ci_max_ext_cpuid = 0;
847 
848 	if (ci->ci_max_ext_cpuid >= 0x80000001) {
849 		/* Determine the extended feature flags. */
850 		x86_cpuid(0x80000001, descs);
851 		ci->ci_feat_val[3] = descs[2]; /* %ecx */
852 		ci->ci_feat_val[2] = descs[3]; /* %edx */
853 	}
854 
855 	if (ci->ci_max_ext_cpuid >= 0x80000004) {
856 		x86_cpuid(0x80000002, brand);
857 		x86_cpuid(0x80000003, brand + 4);
858 		x86_cpuid(0x80000004, brand + 8);
859 		/* Skip leading spaces on brand */
860 		for (i = 0; i < 48; i++) {
861 			if (((char *) brand)[i] != ' ')
862 				break;
863 		}
864 		memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
865 	}
866 
867 	/*
868 	 * Get the structured extended features.
869 	 */
870 	if (cpuid_level >= 7) {
871 		x86_cpuid(7, descs);
872 		ci->ci_feat_val[5] = descs[1]; /* %ebx */
873 		ci->ci_feat_val[6] = descs[2]; /* %ecx */
874 	}
875 
876 	cpu_probe_intel(ci);
877 	cpu_probe_k5(ci);
878 	cpu_probe_k678(ci);
879 	cpu_probe_cyrix(ci);
880 	cpu_probe_winchip(ci);
881 	cpu_probe_c3(ci);
882 	cpu_probe_geode(ci);
883 	cpu_probe_vortex86(ci);
884 
885 	cpu_probe_fpu(ci);
886 
887 	x86_cpu_topology(ci);
888 
889 	if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) &&
890 	    (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) {
891 		/* Enable thermal monitor 1. */
892 		wrmsr(MSR_MISC_ENABLE, rdmsr(MSR_MISC_ENABLE) | (1<<3));
893 	}
894 
895 	ci->ci_feat_val[0] &= ~CPUID_FEAT_BLACKLIST;
896 	if (ci == &cpu_info_primary) {
897 		/* If first. Boot Processor is the cpu_feature reference. */
898 		for (i = 0; i < __arraycount(cpu_feature); i++) {
899 			cpu_feature[i] = ci->ci_feat_val[i];
900 		}
901 #ifndef XEN
902 		/* Early patch of text segment. */
903 		x86_patch(true);
904 #endif
905 	} else {
906 		/*
907 		 * If not first. Warn about cpu_feature mismatch for
908 		 * secondary CPUs.
909 		 */
910 		for (i = 0; i < __arraycount(cpu_feature); i++) {
911 			if (cpu_feature[i] != ci->ci_feat_val[i])
912 				aprint_error_dev(ci->ci_dev,
913 				    "feature mismatch: cpu_feature[%d] is "
914 				    "%#x, but CPU reported %#x\n",
915 				    i, cpu_feature[i], ci->ci_feat_val[i]);
916 		}
917 	}
918 }
919 
920 /* Write what we know about the cpu to the console... */
921 void
922 cpu_identify(struct cpu_info *ci)
923 {
924 
925 	cpu_setmodel("%s %d86-class",
926 	    cpu_vendor_names[cpu_vendor], cpu_class + 3);
927 	if (cpu_brand_string[0] != '\0') {
928 		aprint_normal_dev(ci->ci_dev, "%s", cpu_brand_string);
929 	} else {
930 		aprint_normal_dev(ci->ci_dev, "%s", cpu_getmodel());
931 		if (ci->ci_data.cpu_cc_freq != 0)
932 			aprint_normal(", %dMHz",
933 			    (int)(ci->ci_data.cpu_cc_freq / 1000000));
934 	}
935 	if (ci->ci_signature != 0)
936 		aprint_normal(", id 0x%x", ci->ci_signature);
937 	aprint_normal("\n");
938 
939 	if (cpu_brand_string[0] == '\0') {
940 		strlcpy(cpu_brand_string, cpu_getmodel(),
941 		    sizeof(cpu_brand_string));
942 	}
943 	if (cpu_class == CPUCLASS_386) {
944 		panic("NetBSD requires an 80486DX or later processor");
945 	}
946 	if (cputype == CPU_486DLC) {
947 		aprint_error("WARNING: BUGGY CYRIX CACHE\n");
948 	}
949 
950 #if !defined(XEN) || defined(DOM0OPS)       /* on Xen rdmsr is for Dom0 only */
951 	if (cpu_vendor == CPUVENDOR_AMD     /* check enablement of an */
952 	    && device_unit(ci->ci_dev) == 0 /* AMD feature only once */
953 	    && ((cpu_feature[3] & CPUID_SVM) == CPUID_SVM)) {
954 		uint64_t val;
955 
956 		val = rdmsr(MSR_VMCR);
957 		if (((val & VMCR_SVMED) == VMCR_SVMED)
958 		    && ((val & VMCR_LOCK) == VMCR_LOCK)) {
959 			aprint_normal_dev(ci->ci_dev,
960 				"SVM disabled by the BIOS\n");
961 		}
962 	}
963 #endif
964 
965 #ifdef i386
966 	if (i386_fpu_present == 0)
967 		aprint_normal_dev(ci->ci_dev, "no fpu\n");
968 
969 	if (i386_fpu_fdivbug == 1)
970 		aprint_normal_dev(ci->ci_dev,
971 		    "WARNING: Pentium FDIV bug detected!\n");
972 
973 	if (cpu_vendor == CPUVENDOR_TRANSMETA) {
974 		u_int descs[4];
975 		x86_cpuid(0x80860000, descs);
976 		if (descs[0] >= 0x80860007)
977 			/* Create longrun sysctls */
978 			tmx86_init_longrun();
979 	}
980 #endif	/* i386 */
981 
982 }
983