xref: /netbsd-src/sys/arch/x86/x86/identcpu.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: identcpu.c,v 1.79 2018/07/04 07:55:57 maya 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.79 2018/07/04 07:55:57 maya 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 #include <x86/fpu.h>
53 
54 #include <x86/x86/vmtreg.h>	/* for vmt_hvcall() */
55 #include <x86/x86/vmtvar.h>	/* for vmt_hvcall() */
56 
57 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO;
58 
59 static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] =
60 	AMD_L2CACHE_INFO;
61 
62 static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] =
63 	AMD_L3CACHE_INFO;
64 
65 int cpu_vendor;
66 char cpu_brand_string[49];
67 
68 int x86_fpu_save __read_mostly;
69 unsigned int x86_fpu_save_size __read_mostly = sizeof(struct save87);
70 uint64_t x86_xsave_features __read_mostly = 0;
71 
72 /*
73  * Note: these are just the ones that may not have a cpuid instruction.
74  * We deal with the rest in a different way.
75  */
76 const int i386_nocpuid_cpus[] = {
77 	CPUVENDOR_INTEL, CPUCLASS_386,	/* CPU_386SX */
78 	CPUVENDOR_INTEL, CPUCLASS_386,	/* CPU_386   */
79 	CPUVENDOR_INTEL, CPUCLASS_486,	/* CPU_486SX */
80 	CPUVENDOR_INTEL, CPUCLASS_486, 	/* CPU_486   */
81 	CPUVENDOR_CYRIX, CPUCLASS_486,	/* CPU_486DLC */
82 	CPUVENDOR_CYRIX, CPUCLASS_486,	/* CPU_6x86 */
83 	CPUVENDOR_NEXGEN, CPUCLASS_386,	/* CPU_NX586 */
84 };
85 
86 static const char cpu_vendor_names[][10] = {
87 	"Unknown", "Intel", "NS/Cyrix", "NexGen", "AMD", "IDT/VIA", "Transmeta",
88 	"Vortex86"
89 };
90 
91 static const struct x86_cache_info *
92 cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc)
93 {
94 	int i;
95 
96 	for (i = 0; cai[i].cai_desc != 0; i++) {
97 		if (cai[i].cai_desc == desc)
98 			return (&cai[i]);
99 	}
100 
101 	return (NULL);
102 }
103 
104 static void
105 cpu_probe_intel_cache(struct cpu_info *ci)
106 {
107 	const struct x86_cache_info *cai;
108 	u_int descs[4];
109 	int iterations, i, j;
110 	uint8_t desc;
111 
112 	if (cpuid_level >= 2) {
113 		/* Parse the cache info from `cpuid leaf 2', if we have it. */
114 		x86_cpuid(2, descs);
115 		iterations = descs[0] & 0xff;
116 		while (iterations-- > 0) {
117 			for (i = 0; i < 4; i++) {
118 				if (descs[i] & 0x80000000)
119 					continue;
120 				for (j = 0; j < 4; j++) {
121 					if (i == 0 && j == 0)
122 						continue;
123 					desc = (descs[i] >> (j * 8)) & 0xff;
124 					if (desc == 0)
125 						continue;
126 					cai = cache_info_lookup(
127 					    intel_cpuid_cache_info, desc);
128 					if (cai != NULL) {
129 						ci->ci_cinfo[cai->cai_index] =
130 						    *cai;
131 					}
132 				}
133 			}
134 		}
135 	}
136 
137 	if (cpuid_level >= 4) {
138 		int type, level;
139 		int ways, partitions, linesize, sets;
140 		int caitype = -1;
141 		int totalsize;
142 
143 		/* Parse the cache info from `cpuid leaf 4', if we have it. */
144 		for (i = 0; ; i++) {
145 			x86_cpuid2(4, i, descs);
146 			type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE);
147 			if (type == CPUID_DCP_CACHETYPE_N)
148 				break;
149 			level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL);
150 			switch (level) {
151 			case 1:
152 				if (type == CPUID_DCP_CACHETYPE_I)
153 					caitype = CAI_ICACHE;
154 				else if (type == CPUID_DCP_CACHETYPE_D)
155 					caitype = CAI_DCACHE;
156 				else
157 					caitype = -1;
158 				break;
159 			case 2:
160 				if (type == CPUID_DCP_CACHETYPE_U)
161 					caitype = CAI_L2CACHE;
162 				else
163 					caitype = -1;
164 				break;
165 			case 3:
166 				if (type == CPUID_DCP_CACHETYPE_U)
167 					caitype = CAI_L3CACHE;
168 				else
169 					caitype = -1;
170 				break;
171 			default:
172 				caitype = -1;
173 				break;
174 			}
175 			if (caitype == -1)
176 				continue;
177 
178 			ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1;
179 			partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS)
180 			    + 1;
181 			linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE)
182 			    + 1;
183 			sets = descs[2] + 1;
184 			totalsize = ways * partitions * linesize * sets;
185 			ci->ci_cinfo[caitype].cai_totalsize = totalsize;
186 			ci->ci_cinfo[caitype].cai_associativity = ways;
187 			ci->ci_cinfo[caitype].cai_linesize = linesize;
188 		}
189 	}
190 }
191 
192 static void
193 cpu_probe_intel_errata(struct cpu_info *ci)
194 {
195 	u_int family, model, stepping;
196 
197 	family = CPUID_TO_FAMILY(ci->ci_signature);
198 	model = CPUID_TO_MODEL(ci->ci_signature);
199 	stepping = CPUID_TO_STEPPING(ci->ci_signature);
200 
201 	if (family == 0x6 && model == 0x5C && stepping == 0x9) { /* Apollo Lake */
202 		wrmsr(MSR_MISC_ENABLE,
203 		    rdmsr(MSR_MISC_ENABLE) & ~IA32_MISC_MWAIT_EN);
204 
205 		cpu_feature[1] &= ~CPUID2_MONITOR;
206 		ci->ci_feat_val[1] &= ~CPUID2_MONITOR;
207 	}
208 }
209 
210 static void
211 cpu_probe_intel(struct cpu_info *ci)
212 {
213 
214 	if (cpu_vendor != CPUVENDOR_INTEL)
215 		return;
216 
217 	cpu_probe_intel_cache(ci);
218 	cpu_probe_intel_errata(ci);
219 }
220 
221 static void
222 cpu_probe_amd_cache(struct cpu_info *ci)
223 {
224 	const struct x86_cache_info *cp;
225 	struct x86_cache_info *cai;
226 	int family, model;
227 	u_int descs[4];
228 	u_int lfunc;
229 
230 	family = CPUID_TO_FAMILY(ci->ci_signature);
231 	model = CPUID_TO_MODEL(ci->ci_signature);
232 
233 	/*
234 	 * K5 model 0 has none of this info.
235 	 */
236 	if (family == 5 && model == 0)
237 		return;
238 
239 	/*
240 	 * Determine the largest extended function value.
241 	 */
242 	x86_cpuid(0x80000000, descs);
243 	lfunc = descs[0];
244 
245 	/*
246 	 * Determine L1 cache/TLB info.
247 	 */
248 	if (lfunc < 0x80000005) {
249 		/* No L1 cache info available. */
250 		return;
251 	}
252 
253 	x86_cpuid(0x80000005, descs);
254 
255 	/*
256 	 * K6-III and higher have large page TLBs.
257 	 */
258 	if ((family == 5 && model >= 9) || family >= 6) {
259 		cai = &ci->ci_cinfo[CAI_ITLB2];
260 		cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]);
261 		cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]);
262 		cai->cai_linesize = (4 * 1024 * 1024);
263 
264 		cai = &ci->ci_cinfo[CAI_DTLB2];
265 		cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]);
266 		cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]);
267 		cai->cai_linesize = (4 * 1024 * 1024);
268 	}
269 
270 	cai = &ci->ci_cinfo[CAI_ITLB];
271 	cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]);
272 	cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]);
273 	cai->cai_linesize = (4 * 1024);
274 
275 	cai = &ci->ci_cinfo[CAI_DTLB];
276 	cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]);
277 	cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]);
278 	cai->cai_linesize = (4 * 1024);
279 
280 	cai = &ci->ci_cinfo[CAI_DCACHE];
281 	cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]);
282 	cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]);
283 	cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]);
284 
285 	cai = &ci->ci_cinfo[CAI_ICACHE];
286 	cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]);
287 	cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]);
288 	cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]);
289 
290 	/*
291 	 * Determine L2 cache/TLB info.
292 	 */
293 	if (lfunc < 0x80000006) {
294 		/* No L2 cache info available. */
295 		return;
296 	}
297 
298 	x86_cpuid(0x80000006, descs);
299 
300 	cai = &ci->ci_cinfo[CAI_L2CACHE];
301 	cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]);
302 	cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]);
303 	cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]);
304 
305 	cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info,
306 	    cai->cai_associativity);
307 	if (cp != NULL)
308 		cai->cai_associativity = cp->cai_associativity;
309 	else
310 		cai->cai_associativity = 0;	/* XXX Unknown/reserved */
311 
312 	if (family < 0xf) {
313 		/* No L3 cache info available. */
314 		return;
315 	}
316 
317 	cai = &ci->ci_cinfo[CAI_L3CACHE];
318 	cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]);
319 	cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]);
320 	cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]);
321 
322 	cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info,
323 	    cai->cai_associativity);
324 	if (cp != NULL)
325 		cai->cai_associativity = cp->cai_associativity;
326 	else
327 		cai->cai_associativity = 0;	/* XXX Unknown reserved */
328 
329 	if (lfunc < 0x80000019) {
330 		/* No 1GB Page TLB */
331 		return;
332 	}
333 
334 	x86_cpuid(0x80000019, descs);
335 
336 	cai = &ci->ci_cinfo[CAI_L1_1GBDTLB];
337 	cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[1]);
338 	cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[1]);
339 	cai->cai_linesize = (1 * 1024);
340 
341 	cai = &ci->ci_cinfo[CAI_L1_1GBITLB];
342 	cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]);
343 	cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]);
344 	cai->cai_linesize = (1 * 1024);
345 
346 	cai = &ci->ci_cinfo[CAI_L2_1GBDTLB];
347 	cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]);
348 	cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]);
349 	cai->cai_linesize = (1 * 1024);
350 
351 	cai = &ci->ci_cinfo[CAI_L2_1GBITLB];
352 	cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[0]);
353 	cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[0]);
354 	cai->cai_linesize = (1 * 1024);
355 }
356 
357 static void
358 cpu_probe_k5(struct cpu_info *ci)
359 {
360 	int flag;
361 
362 	if (cpu_vendor != CPUVENDOR_AMD ||
363 	    CPUID_TO_FAMILY(ci->ci_signature) != 5)
364 		return;
365 
366 	if (CPUID_TO_MODEL(ci->ci_signature) == 0) {
367 		/*
368 		 * According to the AMD Processor Recognition App Note,
369 		 * the AMD-K5 Model 0 uses the wrong bit to indicate
370 		 * support for global PTEs, instead using bit 9 (APIC)
371 		 * rather than bit 13 (i.e. "0x200" vs. 0x2000".  Oops!).
372 		 */
373 		flag = ci->ci_feat_val[0];
374 		if ((flag & CPUID_APIC) != 0)
375 			flag = (flag & ~CPUID_APIC) | CPUID_PGE;
376 		ci->ci_feat_val[0] = flag;
377 	}
378 
379 	cpu_probe_amd_cache(ci);
380 }
381 
382 static void
383 cpu_probe_k678(struct cpu_info *ci)
384 {
385 
386 	if (cpu_vendor != CPUVENDOR_AMD ||
387 	    CPUID_TO_FAMILY(ci->ci_signature) < 6)
388 		return;
389 
390 	cpu_probe_amd_cache(ci);
391 }
392 
393 static inline uint8_t
394 cyrix_read_reg(uint8_t reg)
395 {
396 
397 	outb(0x22, reg);
398 	return inb(0x23);
399 }
400 
401 static inline void
402 cyrix_write_reg(uint8_t reg, uint8_t data)
403 {
404 
405 	outb(0x22, reg);
406 	outb(0x23, data);
407 }
408 
409 static void
410 cpu_probe_cyrix_cmn(struct cpu_info *ci)
411 {
412 	/*
413 	 * i8254 latch check routine:
414 	 *     National Geode (formerly Cyrix MediaGX) has a serious bug in
415 	 *     its built-in i8254-compatible clock module (cs5510 cs5520).
416 	 *     Set the variable 'clock_broken_latch' to indicate it.
417 	 *
418 	 * This bug is not present in the cs5530, and the flag
419 	 * is disabled again in sys/arch/i386/pci/pcib.c if this later
420 	 * model device is detected. Ideally, this work-around should not
421 	 * even be in here, it should be in there. XXX
422 	 */
423 	uint8_t c3;
424 #ifndef XEN
425 	extern int clock_broken_latch;
426 
427 	switch (ci->ci_signature) {
428 	case 0x440:     /* Cyrix MediaGX */
429 	case 0x540:     /* GXm */
430 		clock_broken_latch = 1;
431 		break;
432 	}
433 #endif
434 
435 	/* set up various cyrix registers */
436 	/*
437 	 * Enable suspend on halt (powersave mode).
438 	 * When powersave mode is enabled, the TSC stops counting
439 	 * while the CPU is halted in idle() waiting for an interrupt.
440 	 * This means we can't use the TSC for interval time in
441 	 * microtime(9), and thus it is disabled here.
442 	 *
443 	 * It still makes a perfectly good cycle counter
444 	 * for program profiling, so long as you remember you're
445 	 * counting cycles, and not time. Further, if you don't
446 	 * mind not using powersave mode, the TSC works just fine,
447 	 * so this should really be optional. XXX
448 	 */
449 	cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08);
450 
451 	/*
452 	 * Do not disable the TSC on the Geode GX, it's reported to
453 	 * work fine.
454 	 */
455 	if (ci->ci_signature != 0x552)
456 		ci->ci_feat_val[0] &= ~CPUID_TSC;
457 
458 	/* enable access to ccr4/ccr5 */
459 	c3 = cyrix_read_reg(0xC3);
460 	cyrix_write_reg(0xC3, c3 | 0x10);
461 	/* cyrix's workaround  for the "coma bug" */
462 	cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8);
463 	cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f);
464 	cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff);
465 	cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87);
466 	/* disable access to ccr4/ccr5 */
467 	cyrix_write_reg(0xC3, c3);
468 }
469 
470 static void
471 cpu_probe_cyrix(struct cpu_info *ci)
472 {
473 
474 	if (cpu_vendor != CPUVENDOR_CYRIX ||
475 	    CPUID_TO_FAMILY(ci->ci_signature) < 4 ||
476 	    CPUID_TO_FAMILY(ci->ci_signature) > 6)
477 		return;
478 
479 	cpu_probe_cyrix_cmn(ci);
480 }
481 
482 static void
483 cpu_probe_winchip(struct cpu_info *ci)
484 {
485 
486 	if (cpu_vendor != CPUVENDOR_IDT)
487 	    	return;
488 
489 	switch (CPUID_TO_FAMILY(ci->ci_signature)) {
490 	case 5:
491 		/* WinChip C6 */
492 		if (CPUID_TO_MODEL(ci->ci_signature) == 4)
493 			ci->ci_feat_val[0] &= ~CPUID_TSC;
494 		break;
495 	case 6:
496 		/*
497 		 * VIA Eden ESP
498 		 *
499 		 * Quoting from page 3-4 of: "VIA Eden ESP Processor Datasheet"
500 		 * http://www.via.com.tw/download/mainboards/6/14/Eden20v115.pdf
501 		 *
502 		 * 1. The CMPXCHG8B instruction is provided and always enabled,
503 		 *    however, it appears disabled in the corresponding CPUID
504 		 *    function bit 0 to avoid a bug in an early version of
505 		 *    Windows NT. However, this default can be changed via a
506 		 *    bit in the FCR MSR.
507 		 */
508 		ci->ci_feat_val[0] |= CPUID_CX8;
509 		wrmsr(MSR_VIA_FCR, rdmsr(MSR_VIA_FCR) | 0x00000001);
510 		break;
511 	}
512 }
513 
514 static void
515 cpu_probe_c3(struct cpu_info *ci)
516 {
517 	u_int family, model, stepping, descs[4], lfunc, msr;
518 	struct x86_cache_info *cai;
519 
520 	if (cpu_vendor != CPUVENDOR_IDT ||
521 	    CPUID_TO_FAMILY(ci->ci_signature) < 6)
522 	    	return;
523 
524 	family = CPUID_TO_FAMILY(ci->ci_signature);
525 	model = CPUID_TO_MODEL(ci->ci_signature);
526 	stepping = CPUID_TO_STEPPING(ci->ci_signature);
527 
528 	/* Determine the largest extended function value. */
529 	x86_cpuid(0x80000000, descs);
530 	lfunc = descs[0];
531 
532 	if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) {
533 		/* Nehemiah or Esther */
534 		x86_cpuid(0xc0000000, descs);
535 		lfunc = descs[0];
536 		if (lfunc >= 0xc0000001) {	/* has ACE, RNG */
537 		    int rng_enable = 0, ace_enable = 0;
538 		    x86_cpuid(0xc0000001, descs);
539 		    lfunc = descs[3];
540 		    ci->ci_feat_val[4] = lfunc;
541 		    /* Check for and enable RNG */
542 		    if (lfunc & CPUID_VIA_HAS_RNG) {
543 		    	if (!(lfunc & CPUID_VIA_DO_RNG)) {
544 			    rng_enable++;
545 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_RNG;
546 			}
547 		    }
548 		    /* Check for and enable ACE (AES-CBC) */
549 		    if (lfunc & CPUID_VIA_HAS_ACE) {
550 			if (!(lfunc & CPUID_VIA_DO_ACE)) {
551 			    ace_enable++;
552 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE;
553 			}
554 		    }
555 		    /* Check for and enable SHA */
556 		    if (lfunc & CPUID_VIA_HAS_PHE) {
557 			if (!(lfunc & CPUID_VIA_DO_PHE)) {
558 			    ace_enable++;
559 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_PHE;
560 			}
561 		    }
562 		    /* Check for and enable ACE2 (AES-CTR) */
563 		    if (lfunc & CPUID_VIA_HAS_ACE2) {
564 			if (!(lfunc & CPUID_VIA_DO_ACE2)) {
565 			    ace_enable++;
566 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE2;
567 			}
568 		    }
569 		    /* Check for and enable PMM (modmult engine) */
570 		    if (lfunc & CPUID_VIA_HAS_PMM) {
571 			if (!(lfunc & CPUID_VIA_DO_PMM)) {
572 			    ace_enable++;
573 			    ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM;
574 			}
575 		    }
576 
577 		    /*
578 		     * Actually do the enables.  It's a little gross,
579 		     * but per the PadLock programming guide, "Enabling
580 		     * PadLock", condition 3, we must enable SSE too or
581 		     * else the first use of RNG or ACE instructions
582 		     * will generate a trap.
583 		     *
584 		     * We must do this early because of kernel RNG
585 		     * initialization but it is safe without the full
586 		     * FPU-detect as all these CPUs have SSE.
587 		     */
588 		    lcr4(rcr4() | CR4_OSFXSR);
589 
590 		    if (rng_enable) {
591 			msr = rdmsr(MSR_VIA_RNG);
592 			msr |= MSR_VIA_RNG_ENABLE;
593 			/* C7 stepping 8 and subsequent CPUs have dual RNG */
594 			if (model > 0xA || (model == 0xA && stepping > 0x7)) {
595 				msr |= MSR_VIA_RNG_2NOISE;
596 			}
597 			wrmsr(MSR_VIA_RNG, msr);
598 		    }
599 
600 		    if (ace_enable) {
601 			msr = rdmsr(MSR_VIA_ACE);
602 			wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE);
603 		    }
604 
605 		}
606 	}
607 
608 	/*
609 	 * Determine L1 cache/TLB info.
610 	 */
611 	if (lfunc < 0x80000005) {
612 		/* No L1 cache info available. */
613 		return;
614 	}
615 
616 	x86_cpuid(0x80000005, descs);
617 
618 	cai = &ci->ci_cinfo[CAI_ITLB];
619 	cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]);
620 	cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]);
621 	cai->cai_linesize = (4 * 1024);
622 
623 	cai = &ci->ci_cinfo[CAI_DTLB];
624 	cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]);
625 	cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]);
626 	cai->cai_linesize = (4 * 1024);
627 
628 	cai = &ci->ci_cinfo[CAI_DCACHE];
629 	cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]);
630 	cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]);
631 	cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]);
632 	if (family == 6 && model == 9 && stepping == 8) {
633 		/* Erratum: stepping 8 reports 4 when it should be 2 */
634 		cai->cai_associativity = 2;
635 	}
636 
637 	cai = &ci->ci_cinfo[CAI_ICACHE];
638 	cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]);
639 	cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]);
640 	cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]);
641 	if (family == 6 && model == 9 && stepping == 8) {
642 		/* Erratum: stepping 8 reports 4 when it should be 2 */
643 		cai->cai_associativity = 2;
644 	}
645 
646 	/*
647 	 * Determine L2 cache/TLB info.
648 	 */
649 	if (lfunc < 0x80000006) {
650 		/* No L2 cache info available. */
651 		return;
652 	}
653 
654 	x86_cpuid(0x80000006, descs);
655 
656 	cai = &ci->ci_cinfo[CAI_L2CACHE];
657 	if (family > 6 || model >= 9) {
658 		cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
659 		cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);
660 		cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]);
661 	} else {
662 		cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
663 		cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
664 		cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
665 	}
666 }
667 
668 static void
669 cpu_probe_geode(struct cpu_info *ci)
670 {
671 
672 	if (memcmp("Geode by NSC", ci->ci_vendor, 12) != 0 ||
673 	    CPUID_TO_FAMILY(ci->ci_signature) != 5)
674 	    	return;
675 
676 	cpu_probe_cyrix_cmn(ci);
677 	cpu_probe_amd_cache(ci);
678 }
679 
680 static void
681 cpu_probe_vortex86(struct cpu_info *ci)
682 {
683 #define PCI_MODE1_ADDRESS_REG	0x0cf8
684 #define PCI_MODE1_DATA_REG	0x0cfc
685 #define PCI_MODE1_ENABLE	0x80000000UL
686 
687 	uint32_t reg;
688 
689 	if (cpu_vendor != CPUVENDOR_VORTEX86)
690 		return;
691 	/*
692 	 * CPU model available from "Customer ID register" in
693 	 * North Bridge Function 0 PCI space
694 	 * we can't use pci_conf_read() because the PCI subsystem is not
695 	 * not initialised early enough
696 	 */
697 
698 	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE | 0x90);
699 	reg = inl(PCI_MODE1_DATA_REG);
700 
701 	if ((reg & 0xf8ffffff) != 0x30504d44) {
702 		reg = 0;
703 	} else {
704 		reg = (reg >> 24) & 7;
705 	}
706 
707 	static const char *cpu_vortex86_flavor[] = {
708 	    "??", "SX", "DX", "MX", "DX2", "MX+", "DX3", "EX",
709 	};
710 	snprintf(cpu_brand_string, sizeof(cpu_brand_string), "Vortex86%s",
711 	    cpu_vortex86_flavor[reg]);
712 
713 #undef PCI_MODE1_ENABLE
714 #undef PCI_MODE1_ADDRESS_REG
715 #undef PCI_MODE1_DATA_REG
716 }
717 
718 static void
719 cpu_probe_old_fpu(struct cpu_info *ci)
720 {
721 #if defined(__i386__) && !defined(XEN)
722 
723 	clts();
724 	fninit();
725 
726 	/* Check for 'FDIV' bug on the original Pentium */
727 	if (npx586bug1(4195835, 3145727) != 0)
728 		/* NB 120+MHz cpus are not affected */
729 		i386_fpu_fdivbug = 1;
730 
731 	stts();
732 #endif
733 }
734 
735 #ifndef XEN
736 static void
737 cpu_probe_fpu_leak(struct cpu_info *ci)
738 {
739 	/*
740 	 * INTEL-SA-00145. Affected CPUs are from Family 6.
741 	 */
742 	if (cpu_vendor != CPUVENDOR_INTEL) {
743 		return;
744 	}
745 	if (CPUID_TO_FAMILY(ci->ci_signature) != 6) {
746 		return;
747 	}
748 
749 	switch (CPUID_TO_MODEL(ci->ci_signature)) {
750 	/* Atom CPUs are not vulnerable. */
751 	case 0x1c: /* Pineview */
752 	case 0x26: /* Lincroft */
753 	case 0x27: /* Penwell */
754 	case 0x35: /* Cloverview */
755 	case 0x36: /* Cedarview */
756 	case 0x37: /* Baytrail / Valleyview (Silvermont) */
757 	case 0x4d: /* Avaton / Rangely (Silvermont) */
758 	case 0x4c: /* Cherrytrail / Brasswell */
759 	case 0x4a: /* Merrifield */
760 	case 0x5a: /* Moorefield */
761 	case 0x5c: /* Goldmont */
762 	case 0x5f: /* Denverton */
763 	case 0x7a: /* Gemini Lake */
764 		break;
765 
766 	/* Knights CPUs are not vulnerable. */
767 	case 0x57: /* Knights Landing */
768 	case 0x85: /* Knights Mill */
769 		break;
770 
771 	/* The rest is vulnerable. */
772 	default:
773 		x86_fpu_eager = true;
774 		break;
775 	}
776 }
777 #endif
778 
779 static void
780 cpu_probe_fpu(struct cpu_info *ci)
781 {
782 	u_int descs[4];
783 
784 #ifndef XEN
785 	cpu_probe_fpu_leak(ci);
786 #endif
787 
788 	x86_fpu_save = FPU_SAVE_FSAVE;
789 
790 #ifdef i386
791 	/* If we have FXSAVE/FXRESTOR, use them. */
792 	if ((ci->ci_feat_val[0] & CPUID_FXSR) == 0) {
793 		i386_use_fxsave = 0;
794 		/* Allow for no fpu even if cpuid is supported */
795 		cpu_probe_old_fpu(ci);
796 		return;
797 	}
798 
799 	i386_use_fxsave = 1;
800 	/*
801 	 * If we have SSE/SSE2, enable XMM exceptions, and
802 	 * notify userland.
803 	 */
804 	if (ci->ci_feat_val[0] & CPUID_SSE)
805 		i386_has_sse = 1;
806 	if (ci->ci_feat_val[0] & CPUID_SSE2)
807 		i386_has_sse2 = 1;
808 #else
809 	/*
810 	 * For amd64 i386_use_fxsave, i386_has_sse and i386_has_sse2 are
811 	 * #defined to 1, because fxsave/sse/sse2 are always present.
812 	 */
813 #endif
814 
815 	x86_fpu_save = FPU_SAVE_FXSAVE;
816 	x86_fpu_save_size = sizeof(struct fxsave);
817 
818 	/* See if xsave (for AVX) is supported */
819 	if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0)
820 		return;
821 
822 #ifdef XEN
823 	/*
824 	 * Xen kernel can disable XSAVE via "no-xsave" option, in that case
825 	 * XSAVE instructions like xrstor become privileged and trigger
826 	 * supervisor trap. OSXSAVE flag seems to be reliably set according
827 	 * to whether XSAVE is actually available.
828 	 */
829 #ifdef XEN_USE_XSAVE
830 	if ((ci->ci_feat_val[1] & CPUID2_OSXSAVE) == 0)
831 #endif
832 		return;
833 #endif
834 
835 	x86_fpu_save = FPU_SAVE_XSAVE;
836 
837 #if 0 /* XXX PR 52966 */
838 	x86_cpuid2(0xd, 1, descs);
839 	if (descs[0] & CPUID_PES1_XSAVEOPT)
840 		x86_fpu_save = FPU_SAVE_XSAVEOPT;
841 #endif
842 
843 	/* Get features and maximum size of the save area */
844 	x86_cpuid(0xd, descs);
845 	if (descs[2] > sizeof(struct fxsave))
846 		x86_fpu_save_size = descs[2];
847 
848 	x86_xsave_features = (uint64_t)descs[3] << 32 | descs[0];
849 }
850 
851 void
852 cpu_probe(struct cpu_info *ci)
853 {
854 	u_int descs[4];
855 	int i;
856 	uint32_t miscbytes;
857 	uint32_t brand[12];
858 
859 	cpu_vendor = i386_nocpuid_cpus[cputype << 1];
860 	cpu_class = i386_nocpuid_cpus[(cputype << 1) + 1];
861 
862 	if (cpuid_level < 0) {
863 		/* cpuid instruction not supported */
864 		cpu_probe_old_fpu(ci);
865 		return;
866 	}
867 
868 	for (i = 0; i < __arraycount(ci->ci_feat_val); i++) {
869 		ci->ci_feat_val[i] = 0;
870 	}
871 
872 	x86_cpuid(0, descs);
873 	cpuid_level = descs[0];
874 	ci->ci_max_cpuid = descs[0];
875 
876 	ci->ci_vendor[0] = descs[1];
877 	ci->ci_vendor[2] = descs[2];
878 	ci->ci_vendor[1] = descs[3];
879 	ci->ci_vendor[3] = 0;
880 
881 	if (memcmp(ci->ci_vendor, "GenuineIntel", 12) == 0)
882 		cpu_vendor = CPUVENDOR_INTEL;
883 	else if (memcmp(ci->ci_vendor,  "AuthenticAMD", 12) == 0)
884 		cpu_vendor = CPUVENDOR_AMD;
885 	else if (memcmp(ci->ci_vendor,  "CyrixInstead", 12) == 0)
886 		cpu_vendor = CPUVENDOR_CYRIX;
887 	else if (memcmp(ci->ci_vendor,  "Geode by NSC", 12) == 0)
888 		cpu_vendor = CPUVENDOR_CYRIX;
889 	else if (memcmp(ci->ci_vendor, "CentaurHauls", 12) == 0)
890 		cpu_vendor = CPUVENDOR_IDT;
891 	else if (memcmp(ci->ci_vendor, "GenuineTMx86", 12) == 0)
892 		cpu_vendor = CPUVENDOR_TRANSMETA;
893 	else if (memcmp(ci->ci_vendor, "Vortex86 SoC", 12) == 0)
894 		cpu_vendor = CPUVENDOR_VORTEX86;
895 	else
896 		cpu_vendor = CPUVENDOR_UNKNOWN;
897 
898 	if (cpuid_level >= 1) {
899 		x86_cpuid(1, descs);
900 		ci->ci_signature = descs[0];
901 		miscbytes = descs[1];
902 		ci->ci_feat_val[1] = descs[2];
903 		ci->ci_feat_val[0] = descs[3];
904 
905 		/* Determine family + class. */
906 		cpu_class = CPUID_TO_FAMILY(ci->ci_signature)
907 		    + (CPUCLASS_386 - 3);
908 		if (cpu_class > CPUCLASS_686)
909 			cpu_class = CPUCLASS_686;
910 
911 		/* CLFLUSH line size is next 8 bits */
912 		if (ci->ci_feat_val[0] & CPUID_CFLUSH)
913 			ci->ci_cflush_lsize
914 			    = __SHIFTOUT(miscbytes, CPUID_CLFLUSH_SIZE) << 3;
915 		ci->ci_initapicid = __SHIFTOUT(miscbytes, CPUID_LOCAL_APIC_ID);
916 	}
917 
918 	/*
919 	 * Get the basic information from the extended cpuid leafs.
920 	 * These were first implemented by amd, but most of the values
921 	 * match with those generated by modern intel cpus.
922 	 */
923 	x86_cpuid(0x80000000, descs);
924 	if (descs[0] >= 0x80000000)
925 		ci->ci_max_ext_cpuid = descs[0];
926 	else
927 		ci->ci_max_ext_cpuid = 0;
928 
929 	if (ci->ci_max_ext_cpuid >= 0x80000001) {
930 		/* Determine the extended feature flags. */
931 		x86_cpuid(0x80000001, descs);
932 		ci->ci_feat_val[3] = descs[2]; /* %ecx */
933 		ci->ci_feat_val[2] = descs[3]; /* %edx */
934 	}
935 
936 	if (ci->ci_max_ext_cpuid >= 0x80000004) {
937 		x86_cpuid(0x80000002, brand);
938 		x86_cpuid(0x80000003, brand + 4);
939 		x86_cpuid(0x80000004, brand + 8);
940 		/* Skip leading spaces on brand */
941 		for (i = 0; i < 48; i++) {
942 			if (((char *) brand)[i] != ' ')
943 				break;
944 		}
945 		memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
946 	}
947 
948 	/*
949 	 * Get the structured extended features.
950 	 */
951 	if (cpuid_level >= 7) {
952 		x86_cpuid(7, descs);
953 		ci->ci_feat_val[5] = descs[1]; /* %ebx */
954 		ci->ci_feat_val[6] = descs[2]; /* %ecx */
955 		ci->ci_feat_val[7] = descs[3]; /* %edx */
956 	}
957 
958 	cpu_probe_intel(ci);
959 	cpu_probe_k5(ci);
960 	cpu_probe_k678(ci);
961 	cpu_probe_cyrix(ci);
962 	cpu_probe_winchip(ci);
963 	cpu_probe_c3(ci);
964 	cpu_probe_geode(ci);
965 	cpu_probe_vortex86(ci);
966 
967 	cpu_probe_fpu(ci);
968 
969 	x86_cpu_topology(ci);
970 
971 	if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) &&
972 	    (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) {
973 		/* Enable thermal monitor 1. */
974 		wrmsr(MSR_MISC_ENABLE, rdmsr(MSR_MISC_ENABLE) | (1<<3));
975 	}
976 
977 	ci->ci_feat_val[0] &= ~CPUID_FEAT_BLACKLIST;
978 	if (ci == &cpu_info_primary) {
979 		/* If first. Boot Processor is the cpu_feature reference. */
980 		for (i = 0; i < __arraycount(cpu_feature); i++) {
981 			cpu_feature[i] = ci->ci_feat_val[i];
982 		}
983 		identify_hypervisor();
984 #ifndef XEN
985 		/* Early patch of text segment. */
986 		x86_patch(true);
987 #endif
988 	} else {
989 		/*
990 		 * If not first. Warn about cpu_feature mismatch for
991 		 * secondary CPUs.
992 		 */
993 		for (i = 0; i < __arraycount(cpu_feature); i++) {
994 			if (cpu_feature[i] != ci->ci_feat_val[i])
995 				aprint_error_dev(ci->ci_dev,
996 				    "feature mismatch: cpu_feature[%d] is "
997 				    "%#x, but CPU reported %#x\n",
998 				    i, cpu_feature[i], ci->ci_feat_val[i]);
999 		}
1000 	}
1001 }
1002 
1003 /* Write what we know about the cpu to the console... */
1004 void
1005 cpu_identify(struct cpu_info *ci)
1006 {
1007 
1008 	cpu_setmodel("%s %d86-class",
1009 	    cpu_vendor_names[cpu_vendor], cpu_class + 3);
1010 	if (cpu_brand_string[0] != '\0') {
1011 		aprint_normal_dev(ci->ci_dev, "%s", cpu_brand_string);
1012 	} else {
1013 		aprint_normal_dev(ci->ci_dev, "%s", cpu_getmodel());
1014 		if (ci->ci_data.cpu_cc_freq != 0)
1015 			aprint_normal(", %dMHz",
1016 			    (int)(ci->ci_data.cpu_cc_freq / 1000000));
1017 	}
1018 	if (ci->ci_signature != 0)
1019 		aprint_normal(", id 0x%x", ci->ci_signature);
1020 	aprint_normal("\n");
1021 	aprint_normal_dev(ci->ci_dev, "package %lu, core %lu, smt %lu\n",
1022 	    ci->ci_package_id, ci->ci_core_id, ci->ci_smt_id);
1023 	if (cpu_brand_string[0] == '\0') {
1024 		strlcpy(cpu_brand_string, cpu_getmodel(),
1025 		    sizeof(cpu_brand_string));
1026 	}
1027 	if (cpu_class == CPUCLASS_386) {
1028 		panic("NetBSD requires an 80486DX or later processor");
1029 	}
1030 	if (cputype == CPU_486DLC) {
1031 		aprint_error("WARNING: BUGGY CYRIX CACHE\n");
1032 	}
1033 
1034 #if !defined(XEN) || defined(DOM0OPS)       /* on Xen rdmsr is for Dom0 only */
1035 	if (cpu_vendor == CPUVENDOR_AMD     /* check enablement of an */
1036 	    && device_unit(ci->ci_dev) == 0 /* AMD feature only once */
1037 	    && ((cpu_feature[3] & CPUID_SVM) == CPUID_SVM)) {
1038 		uint64_t val;
1039 
1040 		val = rdmsr(MSR_VMCR);
1041 		if (((val & VMCR_SVMED) == VMCR_SVMED)
1042 		    && ((val & VMCR_LOCK) == VMCR_LOCK)) {
1043 			aprint_normal_dev(ci->ci_dev,
1044 				"SVM disabled by the BIOS\n");
1045 		}
1046 	}
1047 #endif
1048 
1049 #ifdef i386
1050 	if (i386_fpu_fdivbug == 1)
1051 		aprint_normal_dev(ci->ci_dev,
1052 		    "WARNING: Pentium FDIV bug detected!\n");
1053 
1054 	if (cpu_vendor == CPUVENDOR_TRANSMETA) {
1055 		u_int descs[4];
1056 		x86_cpuid(0x80860000, descs);
1057 		if (descs[0] >= 0x80860007)
1058 			/* Create longrun sysctls */
1059 			tmx86_init_longrun();
1060 	}
1061 #endif	/* i386 */
1062 
1063 }
1064 
1065 /*
1066  * Hypervisor
1067  */
1068 vm_guest_t vm_guest = VM_GUEST_NO;
1069 
1070 static const char * const vm_bios_vendors[] = {
1071 	"QEMU",				/* QEMU */
1072 	"Plex86",			/* Plex86 */
1073 	"Bochs",			/* Bochs */
1074 	"Xen",				/* Xen */
1075 	"BHYVE",			/* bhyve */
1076 	"Seabios",			/* KVM */
1077 };
1078 
1079 static const char * const vm_system_products[] = {
1080 	"VMware Virtual Platform",	/* VMWare VM */
1081 	"Virtual Machine",		/* Microsoft VirtualPC */
1082 	"VirtualBox",			/* Sun xVM VirtualBox */
1083 	"Parallels Virtual Platform",	/* Parallels VM */
1084 	"KVM",				/* KVM */
1085 };
1086 
1087 void
1088 identify_hypervisor(void)
1089 {
1090 	u_int regs[6];
1091 	char hv_vendor[12];
1092 	const char *p;
1093 	int i;
1094 
1095 	if (vm_guest != VM_GUEST_NO)
1096 		return;
1097 
1098 	/*
1099 	 * [RFC] CPUID usage for interaction between Hypervisors and Linux.
1100 	 * http://lkml.org/lkml/2008/10/1/246
1101 	 *
1102 	 * KB1009458: Mechanisms to determine if software is running in
1103 	 * a VMware virtual machine
1104 	 * http://kb.vmware.com/kb/1009458
1105 	 */
1106 	if (ISSET(cpu_feature[1], CPUID2_RAZ)) {
1107 		vm_guest = VM_GUEST_VM;
1108 		x86_cpuid(0x40000000, regs);
1109 		if (regs[0] >= 0x40000000) {
1110 			memcpy(&hv_vendor[0], &regs[1], sizeof(*regs));
1111 			memcpy(&hv_vendor[4], &regs[2], sizeof(*regs));
1112 			memcpy(&hv_vendor[8], &regs[3], sizeof(*regs));
1113 			if (memcmp(hv_vendor, "VMwareVMware", 12) == 0)
1114 				vm_guest = VM_GUEST_VMWARE;
1115 			else if (memcmp(hv_vendor, "Microsoft Hv", 12) == 0)
1116 				vm_guest = VM_GUEST_HV;
1117 			else if (memcmp(hv_vendor, "KVMKVMKVM\0\0\0", 12) == 0)
1118 				vm_guest = VM_GUEST_KVM;
1119 			/* FreeBSD bhyve: "bhyve bhyve " */
1120 			/* OpenBSD vmm:   "OpenBSDVMM58" */
1121 		}
1122 		return;
1123 	}
1124 
1125 	/*
1126 	 * Examine SMBIOS strings for older hypervisors.
1127 	 */
1128 	p = pmf_get_platform("system-serial");
1129 	if (p != NULL) {
1130 		if (strncmp(p, "VMware-", 7) == 0 || strncmp(p, "VMW", 3) == 0) {
1131 			vmt_hvcall(VM_CMD_GET_VERSION, regs);
1132 			if (regs[1] == VM_MAGIC) {
1133 				vm_guest = VM_GUEST_VMWARE;
1134 				return;
1135 			}
1136 		}
1137 	}
1138 	p = pmf_get_platform("bios-vendor");
1139 	if (p != NULL) {
1140 		for (i = 0; i < __arraycount(vm_bios_vendors); i++) {
1141 			if (strcmp(p, vm_bios_vendors[i]) == 0) {
1142 				vm_guest = VM_GUEST_VM;
1143 				return;
1144 			}
1145 		}
1146 	}
1147 	p = pmf_get_platform("system-product");
1148 	if (p != NULL) {
1149 		for (i = 0; i < __arraycount(vm_system_products); i++) {
1150 			if (strcmp(p, vm_system_products[i]) == 0) {
1151 				vm_guest = VM_GUEST_VM;
1152 				return;
1153 			}
1154 		}
1155 	}
1156 }
1157