xref: /dragonfly/sys/platform/pc64/x86_64/identcpu.c (revision 655933d6)
1 /*-
2  * Copyright (c) 1992 Terrence R. Lambert.
3  * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
4  * Copyright (c) 1997 KATO Takenori.
5  * Copyright (c) 2008 The DragonFly Project.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * William Jolitz.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the University of
22  *	California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  * from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
40  */
41 
42 #include "opt_cpu.h"
43 
44 #include <sys/param.h>
45 #include <sys/bus.h>
46 #include <sys/eventhandler.h>
47 #include <sys/systm.h>
48 #include <sys/kernel.h>
49 #include <sys/sysctl.h>
50 #include <sys/power.h>
51 
52 #include <machine/asmacros.h>
53 #include <machine/clock.h>
54 #include <machine/cputypes.h>
55 #include <machine/frame.h>
56 #include <machine/segments.h>
57 #include <machine/specialreg.h>
58 #include <machine/md_var.h>
59 #include <machine/npx.h>
60 
61 /* XXX - should be in header file: */
62 void printcpuinfo(void);
63 void identify_cpu(void);
64 void earlysetcpuclass(void);
65 void panicifcpuunsupported(void);
66 
67 static u_int find_cpu_vendor_id(void);
68 static void print_AMD_info(void);
69 static void print_AMD_assoc(int i);
70 static void print_via_padlock_info(void);
71 
72 int	cpu_class;
73 char machine[] = "x86_64";
74 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD,
75     machine, 0, "Machine class");
76 
77 static char cpu_model[128];
78 SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD,
79     cpu_model, 0, "Machine model");
80 
81 static int hw_clockrate;
82 SYSCTL_INT(_hw, OID_AUTO, clockrate, CTLFLAG_RD,
83     &hw_clockrate, 0, "CPU instruction clock rate");
84 
85 static char cpu_brand[48];
86 
87 static struct {
88 	char	*cpu_name;
89 	int	cpu_class;
90 } x86_64_cpus[] = {
91 	{ "Clawhammer",		CPUCLASS_K8 },		/* CPU_CLAWHAMMER */
92 	{ "Sledgehammer",	CPUCLASS_K8 },		/* CPU_SLEDGEHAMMER */
93 };
94 
95 static struct {
96 	char	*vendor;
97 	u_int	vendor_id;
98 } cpu_vendors[] = {
99 	{ INTEL_VENDOR_ID,	CPU_VENDOR_INTEL },	/* GenuineIntel */
100 	{ AMD_VENDOR_ID,	CPU_VENDOR_AMD },	/* AuthenticAMD */
101 	{ CENTAUR_VENDOR_ID,	CPU_VENDOR_CENTAUR },	/* CentaurHauls */
102 };
103 
104 #ifdef foo
105 static int cpu_cores;
106 static int cpu_logical;
107 #endif
108 
109 void
110 printcpuinfo(void)
111 {
112 	u_int regs[4], i;
113 	char *brand;
114 
115 	cpu_class = x86_64_cpus[cpu_type].cpu_class;
116 	kprintf("CPU: ");
117 	strncpy(cpu_model, x86_64_cpus[cpu_type].cpu_name, sizeof (cpu_model));
118 
119 	/* Check for extended CPUID information and a processor name. */
120 	if (cpu_exthigh >= 0x80000004) {
121 		brand = cpu_brand;
122 		for (i = 0x80000002; i < 0x80000005; i++) {
123 			do_cpuid(i, regs);
124 			memcpy(brand, regs, sizeof(regs));
125 			brand += sizeof(regs);
126 		}
127 	}
128 
129 	switch (cpu_vendor_id) {
130 	case CPU_VENDOR_INTEL:
131 		/* Please make up your mind folks! */
132 		strcat(cpu_model, "EM64T");
133 		break;
134 	case CPU_VENDOR_AMD:
135 		/*
136 		 * Values taken from AMD Processor Recognition
137 		 * http://www.amd.com/K6/k6docs/pdf/20734g.pdf
138 		 * (also describes ``Features'' encodings.
139 		 */
140 		strcpy(cpu_model, "AMD ");
141 		if ((cpu_id & 0xf00) == 0xf00)
142 			strcat(cpu_model, "AMD64 Processor");
143 		else
144 			strcat(cpu_model, "Unknown");
145 		break;
146 	case CPU_VENDOR_CENTAUR:
147 		strcpy(cpu_model, "VIA ");
148 		if ((cpu_id & 0xff0) == 0x6f0)
149 			strcat(cpu_model, "Nano Processor");
150 		else
151 			strcat(cpu_model, "Unknown");
152 		break;
153 	default:
154 		strcat(cpu_model, "Unknown");
155 		break;
156 	}
157 
158 	/*
159 	 * Replace cpu_model with cpu_brand minus leading spaces if
160 	 * we have one.
161 	 */
162 	brand = cpu_brand;
163 	while (*brand == ' ')
164 		++brand;
165 	if (*brand != '\0')
166 		strcpy(cpu_model, brand);
167 
168 	kprintf("%s (", cpu_model);
169 	switch(cpu_class) {
170 	case CPUCLASS_K8:
171 		hw_clockrate = (tsc_frequency + 5000) / 1000000;
172 		kprintf("%jd.%02d-MHz ",
173 		       (intmax_t)(tsc_frequency + 4999) / 1000000,
174 		       (u_int)((tsc_frequency + 4999) / 10000) % 100);
175 		kprintf("K8");
176 		break;
177 	default:
178 		kprintf("Unknown");	/* will panic below... */
179 	}
180 	kprintf("-class CPU)\n");
181 	if (*cpu_vendor)
182 		kprintf("  Origin = \"%s\"", cpu_vendor);
183 	if (cpu_id)
184 		kprintf("  Id = 0x%x", cpu_id);
185 
186 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
187 	    cpu_vendor_id == CPU_VENDOR_AMD ||
188 	    cpu_vendor_id == CPU_VENDOR_CENTAUR) {
189 		kprintf("  Stepping = %u", cpu_id & 0xf);
190 		if (cpu_high > 0) {
191 #if 0
192 			u_int cmp = 1, htt = 1;
193 #endif
194 
195 			/*
196 			 * Here we should probably set up flags indicating
197 			 * whether or not various features are available.
198 			 * The interesting ones are probably VME, PSE, PAE,
199 			 * and PGE.  The code already assumes without bothering
200 			 * to check that all CPUs >= Pentium have a TSC and
201 			 * MSRs.
202 			 */
203 			kprintf("\n  Features=0x%pb%i",
204 			"\020"
205 			"\001FPU"	/* Integral FPU */
206 			"\002VME"	/* Extended VM86 mode support */
207 			"\003DE"	/* Debugging Extensions (CR4.DE) */
208 			"\004PSE"	/* 4MByte page tables */
209 			"\005TSC"	/* Timestamp counter */
210 			"\006MSR"	/* Machine specific registers */
211 			"\007PAE"	/* Physical address extension */
212 			"\010MCE"	/* Machine Check support */
213 			"\011CX8"	/* CMPEXCH8 instruction */
214 			"\012APIC"	/* SMP local APIC */
215 			"\013oldMTRR"	/* Previous implementation of MTRR */
216 			"\014SEP"	/* Fast System Call */
217 			"\015MTRR"	/* Memory Type Range Registers */
218 			"\016PGE"	/* PG_G (global bit) support */
219 			"\017MCA"	/* Machine Check Architecture */
220 			"\020CMOV"	/* CMOV instruction */
221 			"\021PAT"	/* Page attributes table */
222 			"\022PSE36"	/* 36 bit address space support */
223 			"\023PN"	/* Processor Serial number */
224 			"\024CLFLUSH"	/* Has the CLFLUSH instruction */
225 			"\025<b20>"
226 			"\026DTS"	/* Debug Trace Store */
227 			"\027ACPI"	/* ACPI support */
228 			"\030MMX"	/* MMX instructions */
229 			"\031FXSR"	/* FXSAVE/FXRSTOR */
230 			"\032SSE"	/* Streaming SIMD Extensions */
231 			"\033SSE2"	/* Streaming SIMD Extensions #2 */
232 			"\034SS"	/* Self snoop */
233 			"\035HTT"	/* Hyperthreading (see EBX bit 16-23) */
234 			"\036TM"	/* Thermal Monitor clock slowdown */
235 			"\037IA64"	/* CPU can execute IA64 instructions */
236 			"\040PBE"	/* Pending Break Enable */
237 			, cpu_feature);
238 
239 			if (cpu_feature2 != 0) {
240 				kprintf("\n  Features2=0x%pb%i",
241 				"\020"
242 				"\001SSE3"	/* SSE3 */
243 				"\002PCLMULQDQ"	/* Carry-Less Mul Quadword */
244 				"\003DTES64"	/* 64-bit Debug Trace */
245 				"\004MON"	/* MONITOR/MWAIT Instructions */
246 				"\005DS_CPL"	/* CPL Qualified Debug Store */
247 				"\006VMX"	/* Virtual Machine Extensions */
248 				"\007SMX"	/* Safer Mode Extensions */
249 				"\010EST"	/* Enhanced SpeedStep */
250 				"\011TM2"	/* Thermal Monitor 2 */
251 				"\012SSSE3"	/* SSSE3 */
252 				"\013CNXT-ID"	/* L1 context ID available */
253 				"\014SDBG"	/* IA-32 silicon debug */
254 				"\015FMA"	/* Fused Multiply Add */
255 				"\016CX16"	/* CMPXCHG16B Instruction */
256 				"\017xTPR"	/* Send Task Priority Messages */
257 				"\020PDCM"	/* Perf/Debug Capability MSR */
258 				"\021<b16>"
259 				"\022PCID"	/* Process-context Identifiers */
260 				"\023DCA"	/* Direct Cache Access */
261 				"\024SSE4.1"	/* SSE 4.1 */
262 				"\025SSE4.2"	/* SSE 4.2 */
263 				"\026x2APIC"	/* xAPIC Extensions */
264 				"\027MOVBE"	/* MOVBE Instruction */
265 				"\030POPCNT"	/* POPCNT Instruction */
266 				"\031TSCDLT"	/* TSC-Deadline Timer */
267 				"\032AESNI"	/* AES Crypto */
268 				"\033XSAVE"	/* XSAVE/XRSTOR States */
269 				"\034OSXSAVE"	/* OS-Enabled State Management */
270 				"\035AVX"	/* Advanced Vector Extensions */
271 				"\036F16C"	/* Half-precision conversions */
272 				"\037RDRND"	/* RDRAND RNG function */
273 				"\040VMM"	/*  Running on a hypervisor */
274 				, cpu_feature2);
275 			}
276 
277 			if (cpu_ia32_arch_caps != 0) {
278 				kprintf("\n  IA32_ARCH_CAPS=0x%pb%i",
279 				       "\020"
280 				       "\001RDCL_NO"
281 				       "\002IBRS_ALL"
282 				       "\003RSBA"
283 				       "\004SKIP_L1DFL_VME"
284 				       "\005SSB_NO"
285 				       "\006MDS_NO"
286 				       "\010TSX_CTRL"
287 				       "\011TAA_NO",
288 				       (u_int)cpu_ia32_arch_caps
289 				);
290 			}
291 
292 			/*
293 			 * AMD64 Architecture Programmer's Manual Volume 3:
294 			 * General-Purpose and System Instructions
295 			 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf
296 			 *
297 			 * IA-32 Intel Architecture Software Developer's Manual,
298 			 * Volume 2A: Instruction Set Reference, A-M
299 			 * ftp://download.intel.com/design/Pentium4/manuals/25366617.pdf
300 			 */
301 			if (amd_feature != 0) {
302 				kprintf("\n  AMD Features=0x%pb%i",
303 				"\020"		/* in hex */
304 				"\001<s0>"	/* Same */
305 				"\002<s1>"	/* Same */
306 				"\003<s2>"	/* Same */
307 				"\004<s3>"	/* Same */
308 				"\005<s4>"	/* Same */
309 				"\006<s5>"	/* Same */
310 				"\007<s6>"	/* Same */
311 				"\010<s7>"	/* Same */
312 				"\011<s8>"	/* Same */
313 				"\012<s9>"	/* Same */
314 				"\013<b10>"	/* Undefined */
315 				"\014SYSCALL"	/* Have SYSCALL/SYSRET */
316 				"\015<s12>"	/* Same */
317 				"\016<s13>"	/* Same */
318 				"\017<s14>"	/* Same */
319 				"\020<s15>"	/* Same */
320 				"\021<s16>"	/* Same */
321 				"\022<s17>"	/* Same */
322 				"\023<b18>"	/* Reserved, unknown */
323 				"\024MP"	/* Multiprocessor Capable */
324 				"\025NX"	/* Has EFER.NXE, NX */
325 				"\026<b21>"	/* Undefined */
326 				"\027MMX+"	/* AMD MMX Extensions */
327 				"\030<s23>"	/* Same */
328 				"\031<s24>"	/* Same */
329 				"\032FFXSR"	/* Fast FXSAVE/FXRSTOR */
330 				"\033Page1GB"	/* 1-GB large page support */
331 				"\034RDTSCP"	/* RDTSCP */
332 				"\035<b28>"	/* Undefined */
333 				"\036LM"	/* 64 bit long mode */
334 				"\0373DNow!+"	/* AMD 3DNow! Extensions */
335 				"\0403DNow!"	/* AMD 3DNow! */
336 				, amd_feature);
337 			}
338 
339 			if (amd_feature2 != 0) {
340 				kprintf("\n  AMD Features2=0x%pb%i",
341 				"\020"
342 				"\001LAHF"	/* LAHF/SAHF in long mode */
343 				"\002CMP"	/* CMP legacy */
344 				"\003SVM"	/* Secure Virtual Mode */
345 				"\004ExtAPIC"	/* Extended APIC register */
346 				"\005CR8"	/* CR8 in legacy mode */
347 				"\006ABM"	/* LZCNT instruction */
348 				"\007SSE4A"	/* SSE4A */
349 				"\010MAS"	/* Misaligned SSE mode */
350 				"\011Prefetch"	/* 3DNow! Prefetch/PrefetchW */
351 				"\012OSVW"	/* OS visible workaround */
352 				"\013IBS"	/* Instruction based sampling */
353 				"\014XOP"	/* XOP extended instructions */
354 				"\015SKINIT"	/* SKINIT/STGI */
355 				"\016WDT"	/* Watchdog timer */
356 				"\017<b14>"
357 				"\020LWP"	/* Lightweight Profiling */
358 				"\021FMA4"	/* 4-operand FMA instructions */
359 				"\022TCE"       /* Translation Cache Extension */
360 				"\023<b18>"
361 				"\024NodeId"	/* NodeId MSR support */
362 				"\025<b20>"
363 				"\026TBM"	/* Trailing Bit Manipulation */
364 				"\027Topology"	/* Topology Extensions */
365 				"\030PCX_CORE"  /* Core Performance Counter */
366 				"\031PCX_NB"    /* NB Performance Counter */
367 				"\032SPM"	/* Streaming Perf Monitor */
368 				"\033DBE"	/* Data Breakpoint Extension */
369 				"\034PTSC"	/* Performance TSC */
370 				"\035PCX_L2I"	/* L2I Performance Counter */
371 		       	        "\036MWAITX"	/* MONITORX/MWAITX instructions */
372 				"\037ADMSKX"
373 				"\040<b31>"
374 				, amd_feature2);
375 			}
376 
377 			if (cpu_stdext_feature != 0) {
378 				kprintf("\n  Structured Extended "
379 					"Features=0x%pb%i",
380 				        "\020"
381 				        /*RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE*/
382 				        "\001GSFSBASE"
383 				        "\002TSCADJ"
384 				        /* Bit Manipulation Instructions */
385 				        "\004BMI1"
386 				        /* Hardware Lock Elision */
387 				        "\005HLE"
388 				        /* Advanced Vector Instructions 2 */
389 				        "\006AVX2"
390 				        /* Supervisor Mode Execution Prot. */
391 				        "\010SMEP"
392 				        /* Bit Manipulation Instructions */
393 				        "\011BMI2"
394 				        "\012ENHMOVSB"
395 				       /* Invalidate Processor Context ID */
396 				        "\013INVPCID"
397 				        /* Restricted Transactional Memory */
398 				        "\014RTM"
399 				        "\015PQM"
400 				        "\016NFPUSG"
401 				        /* Intel Memory Protection Extensions */
402 				        "\017MPX"
403 				        "\020PQE"
404 				        /* AVX512 Foundation */
405 				        "\021AVX512F"
406 				        "\022AVX512DQ"
407 				        /* Enhanced NRBG */
408 				        "\023RDSEED"
409 				        /* ADCX + ADOX */
410 				        "\024ADX"
411 				        /* Supervisor Mode Access Prevention */
412 				        "\025SMAP"
413 				        "\026AVX512IFMA"
414 				        /* Formerly PCOMMIT */
415 				        "\027<b22>"
416 				        "\030CLFLUSHOPT"
417 				        "\031CLWB"
418 				        "\032PROCTRACE"
419 				        "\033AVX512PF"
420 				        "\034AVX512ER"
421 				        "\035AVX512CD"
422 				        "\036SHA"
423 				        "\037AVX512BW"
424 				        "\040AVX512VL",
425 				        cpu_stdext_feature
426 				);
427 			}
428 
429 			if (cpu_stdext_feature2 != 0) {
430 				kprintf("\n  Structured Extended "
431 					"Features2=0x%pb%i",
432 				        "\020"
433 				        "\001PREFETCHWT1"
434 				        "\002AVX512VBMI"
435 				        "\003UMIP"
436 				        "\004PKU"
437 				        "\005OSPKE"
438 				        "\006WAITPKG"
439 				        "\007AVX512VBMI2"
440 				        "\011GFNI"
441 				        "\012VAES"
442 				        "\013VPCLMULQDQ"
443 				        "\014AVX512VNNI"
444 				        "\015AVX512BITALG"
445 				        "\016TME"
446 				        "\017AVX512VPOPCNTDQ"
447 				        "\021LA57"
448 				        "\027RDPID"
449 				        "\032CLDEMOTE"
450 				        "\034MOVDIRI"
451 				        "\035MOVDIR64B"
452 				        "\036ENQCMD"
453 				        "\037SGXLC",
454 				        cpu_stdext_feature2
455 			       );
456 			}
457 
458 			if (cpu_stdext_feature3 != 0) {
459 				kprintf("\n  Structured Extended "
460 					"Features3=0x%pb%i",
461 				        "\020"
462 				        "\003AVX512_4VNNIW"
463 				        "\004AVX512_4FMAPS"
464 				        "\005FSRM"
465 				        "\011AVX512VP2INTERSECT"
466 				        "\012MCUOPT"
467 				        "\013MD_CLEAR"
468 				        "\016TSXFA"
469 				        "\023PCONFIG"
470 				        "\025IBT"
471 				        "\033IBPB"
472 				        "\034STIBP"
473 				        "\035L1DFL"
474 				        "\036ARCH_CAP"
475 				        "\037CORE_CAP"
476 				        "\040SSBD",
477 				        cpu_stdext_feature3
478 			       );
479 			}
480 
481 			if (cpu_thermal_feature != 0) {
482 				kprintf("\n  Thermal and PM Features=0x%pb%i",
483 				    "\020"
484 				    /* Digital temperature sensor */
485 				    "\001SENSOR"
486 				    /* Turbo boost */
487 				    "\002TURBO"
488 				    /* APIC-Timer-always-running */
489 				    "\003ARAT"
490 				    /* Power limit notification controls */
491 				    "\005PLN"
492 				    /* Clock modulation duty cycle extension */
493 				    "\006ECMD"
494 				    /* Package thermal management */
495 				    "\007PTM"
496 				    /* Hardware P-states */
497 				    "\010HWP"
498 				    , cpu_thermal_feature);
499 			}
500 
501 			if (cpu_mwait_feature != 0) {
502 				kprintf("\n  MONITOR/MWAIT Features=0x%pb%i",
503 				    "\020"
504 				    /* Enumeration of Monitor-Mwait extension */
505 				    "\001CST"
506 				    /*  interrupts as break-event for MWAIT */
507 				    "\002INTBRK"
508 				    , cpu_mwait_feature);
509 			}
510 
511 			if (cpu_vendor_id == CPU_VENDOR_CENTAUR)
512 				print_via_padlock_info();
513 			/*
514 			 * INVALID CPU TOPOLOGY INFORMATION PRINT
515 			 * DEPRECATED - CPU_TOPOLOGY_DETECTION moved to
516 			 * - sys/platform/pc64/x86_64/mp_machdep.c
517 			 * - sys/kern/subr_cpu_topology
518 			 */
519 
520 #if 0
521 			if ((cpu_feature & CPUID_HTT) &&
522 			    cpu_vendor_id == CPU_VENDOR_AMD)
523 				cpu_feature &= ~CPUID_HTT;
524 #endif
525 
526 			/*
527 			 * If this CPU supports HTT or CMP then mention the
528 			 * number of physical/logical cores it contains.
529 			 */
530 #if 0
531 			if (cpu_feature & CPUID_HTT)
532 				htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
533 			if (cpu_vendor_id == CPU_VENDOR_AMD &&
534 			    (amd_feature2 & AMDID2_CMP))
535 				cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
536 			else if (cpu_vendor_id == CPU_VENDOR_INTEL &&
537 			    (cpu_high >= 4)) {
538 				cpuid_count(4, 0, regs);
539 				if ((regs[0] & 0x1f) != 0)
540 					cmp = ((regs[0] >> 26) & 0x3f) + 1;
541 			}
542 #endif
543 #ifdef foo
544 			/*
545 			 * XXX For Intel CPUs, this is max number of cores per
546 			 * package, not the actual cores per package.
547 			 */
548 #if 0
549 			cpu_cores = cmp;
550 			cpu_logical = htt / cmp;
551 
552 			if (cpu_cores > 1)
553 				kprintf("\n  Cores per package: %d", cpu_cores);
554 			if (cpu_logical > 1) {
555 				kprintf("\n  Logical CPUs per core: %d",
556 				    cpu_logical);
557 			}
558 #endif
559 #endif
560 		}
561 	}
562 	/* Avoid ugly blank lines: only print newline when we have to. */
563 	if (*cpu_vendor || cpu_id)
564 		kprintf("\n");
565 
566 	if (cpu_stdext_feature & (CPUID_STDEXT_SMAP | CPUID_STDEXT_SMEP)) {
567 		kprintf("CPU Special Features Installed:");
568 		if (cpu_stdext_feature & CPUID_STDEXT_SMAP)
569 			kprintf(" SMAP");
570 		if (cpu_stdext_feature & CPUID_STDEXT_SMEP)
571 			kprintf(" SMEP");
572 		kprintf("\n");
573 	}
574 
575 	if (bootverbose) {
576 		if (cpu_vendor_id == CPU_VENDOR_AMD)
577 			print_AMD_info();
578 	}
579 }
580 
581 void
582 panicifcpuunsupported(void)
583 {
584 
585 #ifndef HAMMER_CPU
586 #error "You need to specify a cpu type"
587 #endif
588 	/*
589 	 * Now that we have told the user what they have,
590 	 * let them know if that machine type isn't configured.
591 	 */
592 	switch (cpu_class) {
593 	case CPUCLASS_X86:
594 #ifndef HAMMER_CPU
595 	case CPUCLASS_K8:
596 #endif
597 		panic("CPU class not configured");
598 	default:
599 		break;
600 	}
601 }
602 
603 
604 #if 0 /* JG */
605 /* Update TSC freq with the value indicated by the caller. */
606 static void
607 tsc_freq_changed(void *arg, const struct cf_level *level, int status)
608 {
609 	/* If there was an error during the transition, don't do anything. */
610 	if (status != 0)
611 		return;
612 
613 	/* Total setting for this level gives the new frequency in MHz. */
614 	hw_clockrate = level->total_set.freq;
615 }
616 
617 EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
618     EVENTHANDLER_PRI_ANY);
619 #endif
620 
621 /*
622  * Final stage of CPU identification.
623  */
624 void
625 identify_cpu(void)
626 {
627 	u_int regs[4];
628 	u_int cpu_stdext_disable;
629 
630 	do_cpuid(0, regs);
631 	cpu_high = regs[0];
632 	((u_int *)&cpu_vendor)[0] = regs[1];
633 	((u_int *)&cpu_vendor)[1] = regs[3];
634 	((u_int *)&cpu_vendor)[2] = regs[2];
635 	cpu_vendor[12] = '\0';
636 	cpu_vendor_id = find_cpu_vendor_id();
637 
638 	do_cpuid(1, regs);
639 	cpu_id = regs[0];
640 	cpu_procinfo = regs[1];
641 	cpu_feature = regs[3];
642 	cpu_feature2 = regs[2];
643 
644 	if (cpu_high >= 5) {
645 		do_cpuid(5, regs);
646 		cpu_mwait_feature = regs[2];
647 		if (cpu_mwait_feature & CPUID_MWAIT_EXT) {
648 			cpu_mwait_extemu = regs[3];
649 			/* At least one C1 */
650 			if (CPUID_MWAIT_CX_SUBCNT(cpu_mwait_extemu, 1) == 0) {
651 				/* No C1 at all, no MWAIT EXT then */
652 				cpu_mwait_feature &= ~CPUID_MWAIT_EXT;
653 				cpu_mwait_extemu = 0;
654 			}
655 		}
656 	}
657 	if (cpu_high >= 6) {
658 		do_cpuid(6, regs);
659 		cpu_thermal_feature = regs[0];
660 	}
661 	if (cpu_high >= 7) {
662 		cpuid_count(7, 0, regs);
663 		cpu_stdext_feature = regs[1];
664 
665 		/*
666 		 * Some hypervisors fail to filter out unsupported
667 		 * extended features.  For now, disable the
668 		 * extensions, activation of which requires setting a
669 		 * bit in CR4, and which VM monitors do not support.
670 		 */
671 		if (cpu_feature2 & CPUID2_VMM) {
672 			cpu_stdext_disable = CPUID_STDEXT_FSGSBASE |
673 					     CPUID_STDEXT_SMEP;
674 		} else {
675 			cpu_stdext_disable = 0;
676 		}
677 		TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable);
678 
679 		/*
680 		 * Some hypervisors fail to implement
681 		 * MSR_IA32_ARCH_CAPABILITIES, catch any problems.
682 		 */
683 		cpu_stdext_feature &= ~cpu_stdext_disable;
684 		cpu_stdext_feature2 = regs[2];
685 		cpu_stdext_feature3 = regs[3];
686 		if (cpu_stdext_feature3 & CPUID_STDEXT3_ARCH_CAP) {
687 			if (rdmsr_safe(MSR_IA32_ARCH_CAPABILITIES,
688 				       &cpu_ia32_arch_caps))
689 			{
690 				kprintf("Warning: MSR_IA32_ARCH_CAPABILITIES "
691 					"cannot be accessed\n");
692 			}
693 		}
694 	}
695 
696 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
697 	    cpu_vendor_id == CPU_VENDOR_AMD ||
698 	    cpu_vendor_id == CPU_VENDOR_CENTAUR) {
699 		do_cpuid(0x80000000, regs);
700 		cpu_exthigh = regs[0];
701 	}
702 	if (cpu_exthigh >= 0x80000001) {
703 		do_cpuid(0x80000001, regs);
704 		amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
705 		amd_feature2 = regs[2];
706 	}
707 	if (cpu_exthigh >= 0x80000008) {
708 		do_cpuid(0x80000008, regs);
709 		cpu_procinfo2 = regs[2];
710 	}
711 
712 	/* XXX */
713 	cpu_type = CPU_CLAWHAMMER;
714 
715 	if (cpu_feature & CPUID_SSE2)
716 		cpu_mi_feature |= CPU_MI_BZERONT;
717 
718 	if (cpu_feature2 & CPUID2_MON)
719 		cpu_mi_feature |= CPU_MI_MONITOR;
720 
721 	/*
722 	 * We do assume that all CPUs have the same
723 	 * SSE/FXSR features
724 	 */
725 	if ((cpu_feature & CPUID_SSE) && (cpu_feature & CPUID_FXSR))
726 		npxprobemask();
727 }
728 
729 static u_int
730 find_cpu_vendor_id(void)
731 {
732 	int	i;
733 
734 	for (i = 0; i < NELEM(cpu_vendors); i++)
735 		if (strcmp(cpu_vendor, cpu_vendors[i].vendor) == 0)
736 			return (cpu_vendors[i].vendor_id);
737 	return (0);
738 }
739 
740 static void
741 print_AMD_assoc(int i)
742 {
743 	if (i == 255)
744 		kprintf(", fully associative\n");
745 	else
746 		kprintf(", %d-way associative\n", i);
747 }
748 
749 static void
750 print_AMD_l2_assoc(int i)
751 {
752 	switch (i & 0x0f) {
753 	case 0: kprintf(", disabled/not present\n"); break;
754 	case 1: kprintf(", direct mapped\n"); break;
755 	case 2: kprintf(", 2-way associative\n"); break;
756 	case 4: kprintf(", 4-way associative\n"); break;
757 	case 6: kprintf(", 8-way associative\n"); break;
758 	case 8: kprintf(", 16-way associative\n"); break;
759 	case 15: kprintf(", fully associative\n"); break;
760 	default: kprintf(", reserved configuration\n"); break;
761 	}
762 }
763 
764 static void
765 print_AMD_info(void)
766 {
767 	u_int regs[4];
768 
769 	if (cpu_exthigh < 0x80000005)
770 		return;
771 
772 	do_cpuid(0x80000005, regs);
773 	kprintf("L1 2MB data TLB: %d entries", (regs[0] >> 16) & 0xff);
774 	print_AMD_assoc(regs[0] >> 24);
775 
776 	kprintf("L1 2MB instruction TLB: %d entries", regs[0] & 0xff);
777 	print_AMD_assoc((regs[0] >> 8) & 0xff);
778 
779 	kprintf("L1 4KB data TLB: %d entries", (regs[1] >> 16) & 0xff);
780 	print_AMD_assoc(regs[1] >> 24);
781 
782 	kprintf("L1 4KB instruction TLB: %d entries", regs[1] & 0xff);
783 	print_AMD_assoc((regs[1] >> 8) & 0xff);
784 
785 	kprintf("L1 data cache: %d kbytes", regs[2] >> 24);
786 	kprintf(", %d bytes/line", regs[2] & 0xff);
787 	kprintf(", %d lines/tag", (regs[2] >> 8) & 0xff);
788 	print_AMD_assoc((regs[2] >> 16) & 0xff);
789 
790 	kprintf("L1 instruction cache: %d kbytes", regs[3] >> 24);
791 	kprintf(", %d bytes/line", regs[3] & 0xff);
792 	kprintf(", %d lines/tag", (regs[3] >> 8) & 0xff);
793 	print_AMD_assoc((regs[3] >> 16) & 0xff);
794 
795 	if (cpu_exthigh >= 0x80000006) {
796 		do_cpuid(0x80000006, regs);
797 		if ((regs[0] >> 16) != 0) {
798 			kprintf("L2 2MB data TLB: %d entries",
799 			    (regs[0] >> 16) & 0xfff);
800 			print_AMD_l2_assoc(regs[0] >> 28);
801 			kprintf("L2 2MB instruction TLB: %d entries",
802 			    regs[0] & 0xfff);
803 			print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
804 		} else {
805 			kprintf("L2 2MB unified TLB: %d entries",
806 			    regs[0] & 0xfff);
807 			print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
808 		}
809 		if ((regs[1] >> 16) != 0) {
810 			kprintf("L2 4KB data TLB: %d entries",
811 			    (regs[1] >> 16) & 0xfff);
812 			print_AMD_l2_assoc(regs[1] >> 28);
813 
814 			kprintf("L2 4KB instruction TLB: %d entries",
815 			    (regs[1] >> 16) & 0xfff);
816 			print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
817 		} else {
818 			kprintf("L2 4KB unified TLB: %d entries",
819 			    (regs[1] >> 16) & 0xfff);
820 			print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
821 		}
822 		kprintf("L2 unified cache: %d kbytes", regs[2] >> 16);
823 		kprintf(", %d bytes/line", regs[2] & 0xff);
824 		kprintf(", %d lines/tag", (regs[2] >> 8) & 0x0f);
825 		print_AMD_l2_assoc((regs[2] >> 12) & 0x0f);
826 	}
827 }
828 
829 static void
830 print_via_padlock_info(void)
831 {
832 	u_int regs[4];
833 
834 	/* Check for supported models. */
835 	switch (cpu_id & 0xff0) {
836 	case 0x690:
837 		if ((cpu_id & 0xf) < 3)
838 			return;
839 	case 0x6a0:
840 	case 0x6d0:
841 	case 0x6f0:
842 		break;
843 	default:
844 		return;
845 	}
846 
847 	do_cpuid(0xc0000000, regs);
848 	if (regs[0] >= 0xc0000001)
849 		do_cpuid(0xc0000001, regs);
850 	else
851 		return;
852 
853 	kprintf("\n  VIA Padlock Features=0x%pb%i",
854 	"\020"
855 	"\003RNG"		/* RNG */
856 	"\007AES"		/* ACE */
857 	"\011AES-CTR"		/* ACE2 */
858 	"\013SHA1,SHA256"	/* PHE */
859 	"\015RSA"		/* PMM */
860 	, regs[3]);
861 }
862