xref: /dragonfly/sys/platform/pc64/x86_64/identcpu.c (revision 2b7dbe20)
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], cpu_stdext_disable;
628 
629 	do_cpuid(0, regs);
630 	cpu_high = regs[0];
631 	((u_int *)&cpu_vendor)[0] = regs[1];
632 	((u_int *)&cpu_vendor)[1] = regs[3];
633 	((u_int *)&cpu_vendor)[2] = regs[2];
634 	cpu_vendor[12] = '\0';
635 	cpu_vendor_id = find_cpu_vendor_id();
636 
637 	do_cpuid(1, regs);
638 	cpu_id = regs[0];
639 	cpu_procinfo = regs[1];
640 	cpu_feature = regs[3];
641 	cpu_feature2 = regs[2];
642 
643 	if (cpu_high >= 5) {
644 		do_cpuid(5, regs);
645 		cpu_mwait_feature = regs[2];
646 		if (cpu_mwait_feature & CPUID_MWAIT_EXT) {
647 			cpu_mwait_extemu = regs[3];
648 			/* At least one C1 */
649 			if (CPUID_MWAIT_CX_SUBCNT(cpu_mwait_extemu, 1) == 0) {
650 				/* No C1 at all, no MWAIT EXT then */
651 				cpu_mwait_feature &= ~CPUID_MWAIT_EXT;
652 				cpu_mwait_extemu = 0;
653 			}
654 		}
655 	}
656 	if (cpu_high >= 6) {
657 		do_cpuid(6, regs);
658 		cpu_thermal_feature = regs[0];
659 	}
660 	if (cpu_high >= 7) {
661 		cpuid_count(7, 0, regs);
662 		cpu_stdext_feature = regs[1];
663 
664 		/*
665 		 * Some hypervisors fail to filter out unsupported
666 		 * extended features.  For now, disable the
667 		 * extensions, activation of which requires setting a
668 		 * bit in CR4, and which VM monitors do not support.
669 		 */
670 		if (cpu_feature2 & CPUID2_VMM) {
671 			cpu_stdext_disable = CPUID_STDEXT_FSGSBASE |
672 			    CPUID_STDEXT_SMEP;
673 		} else
674 			cpu_stdext_disable = 0;
675 		TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable);
676 		cpu_stdext_feature &= ~cpu_stdext_disable;
677 		cpu_stdext_feature2 = regs[2];
678 		cpu_stdext_feature3 = regs[3];
679 
680 		if (cpu_stdext_feature3 & CPUID_SEF_ARCH_CAP)
681 			cpu_ia32_arch_caps = rdmsr(MSR_IA32_ARCH_CAPABILITIES);
682 	}
683 
684 	if (cpu_vendor_id == CPU_VENDOR_INTEL ||
685 	    cpu_vendor_id == CPU_VENDOR_AMD ||
686 	    cpu_vendor_id == CPU_VENDOR_CENTAUR) {
687 		do_cpuid(0x80000000, regs);
688 		cpu_exthigh = regs[0];
689 	}
690 	if (cpu_exthigh >= 0x80000001) {
691 		do_cpuid(0x80000001, regs);
692 		amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
693 		amd_feature2 = regs[2];
694 	}
695 	if (cpu_exthigh >= 0x80000008) {
696 		do_cpuid(0x80000008, regs);
697 		cpu_procinfo2 = regs[2];
698 	}
699 
700 	/* XXX */
701 	cpu_type = CPU_CLAWHAMMER;
702 
703 	if (cpu_feature & CPUID_SSE2)
704 		cpu_mi_feature |= CPU_MI_BZERONT;
705 
706 	if (cpu_feature2 & CPUID2_MON)
707 		cpu_mi_feature |= CPU_MI_MONITOR;
708 
709 	/*
710 	 * We do assume that all CPUs have the same
711 	 * SSE/FXSR features
712 	 */
713 	if ((cpu_feature & CPUID_XMM) &&
714 	    (cpu_feature & CPUID_FXSR)) {
715 		npxprobemask();
716 	}
717 }
718 
719 static u_int
720 find_cpu_vendor_id(void)
721 {
722 	int	i;
723 
724 	for (i = 0; i < NELEM(cpu_vendors); i++)
725 		if (strcmp(cpu_vendor, cpu_vendors[i].vendor) == 0)
726 			return (cpu_vendors[i].vendor_id);
727 	return (0);
728 }
729 
730 static void
731 print_AMD_assoc(int i)
732 {
733 	if (i == 255)
734 		kprintf(", fully associative\n");
735 	else
736 		kprintf(", %d-way associative\n", i);
737 }
738 
739 static void
740 print_AMD_l2_assoc(int i)
741 {
742 	switch (i & 0x0f) {
743 	case 0: kprintf(", disabled/not present\n"); break;
744 	case 1: kprintf(", direct mapped\n"); break;
745 	case 2: kprintf(", 2-way associative\n"); break;
746 	case 4: kprintf(", 4-way associative\n"); break;
747 	case 6: kprintf(", 8-way associative\n"); break;
748 	case 8: kprintf(", 16-way associative\n"); break;
749 	case 15: kprintf(", fully associative\n"); break;
750 	default: kprintf(", reserved configuration\n"); break;
751 	}
752 }
753 
754 static void
755 print_AMD_info(void)
756 {
757 	u_int regs[4];
758 
759 	if (cpu_exthigh < 0x80000005)
760 		return;
761 
762 	do_cpuid(0x80000005, regs);
763 	kprintf("L1 2MB data TLB: %d entries", (regs[0] >> 16) & 0xff);
764 	print_AMD_assoc(regs[0] >> 24);
765 
766 	kprintf("L1 2MB instruction TLB: %d entries", regs[0] & 0xff);
767 	print_AMD_assoc((regs[0] >> 8) & 0xff);
768 
769 	kprintf("L1 4KB data TLB: %d entries", (regs[1] >> 16) & 0xff);
770 	print_AMD_assoc(regs[1] >> 24);
771 
772 	kprintf("L1 4KB instruction TLB: %d entries", regs[1] & 0xff);
773 	print_AMD_assoc((regs[1] >> 8) & 0xff);
774 
775 	kprintf("L1 data cache: %d kbytes", regs[2] >> 24);
776 	kprintf(", %d bytes/line", regs[2] & 0xff);
777 	kprintf(", %d lines/tag", (regs[2] >> 8) & 0xff);
778 	print_AMD_assoc((regs[2] >> 16) & 0xff);
779 
780 	kprintf("L1 instruction cache: %d kbytes", regs[3] >> 24);
781 	kprintf(", %d bytes/line", regs[3] & 0xff);
782 	kprintf(", %d lines/tag", (regs[3] >> 8) & 0xff);
783 	print_AMD_assoc((regs[3] >> 16) & 0xff);
784 
785 	if (cpu_exthigh >= 0x80000006) {
786 		do_cpuid(0x80000006, regs);
787 		if ((regs[0] >> 16) != 0) {
788 			kprintf("L2 2MB data TLB: %d entries",
789 			    (regs[0] >> 16) & 0xfff);
790 			print_AMD_l2_assoc(regs[0] >> 28);
791 			kprintf("L2 2MB instruction TLB: %d entries",
792 			    regs[0] & 0xfff);
793 			print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
794 		} else {
795 			kprintf("L2 2MB unified TLB: %d entries",
796 			    regs[0] & 0xfff);
797 			print_AMD_l2_assoc((regs[0] >> 28) & 0xf);
798 		}
799 		if ((regs[1] >> 16) != 0) {
800 			kprintf("L2 4KB data TLB: %d entries",
801 			    (regs[1] >> 16) & 0xfff);
802 			print_AMD_l2_assoc(regs[1] >> 28);
803 
804 			kprintf("L2 4KB instruction TLB: %d entries",
805 			    (regs[1] >> 16) & 0xfff);
806 			print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
807 		} else {
808 			kprintf("L2 4KB unified TLB: %d entries",
809 			    (regs[1] >> 16) & 0xfff);
810 			print_AMD_l2_assoc((regs[1] >> 28) & 0xf);
811 		}
812 		kprintf("L2 unified cache: %d kbytes", regs[2] >> 16);
813 		kprintf(", %d bytes/line", regs[2] & 0xff);
814 		kprintf(", %d lines/tag", (regs[2] >> 8) & 0x0f);
815 		print_AMD_l2_assoc((regs[2] >> 12) & 0x0f);
816 	}
817 }
818 
819 static void
820 print_via_padlock_info(void)
821 {
822 	u_int regs[4];
823 
824 	/* Check for supported models. */
825 	switch (cpu_id & 0xff0) {
826 	case 0x690:
827 		if ((cpu_id & 0xf) < 3)
828 			return;
829 	case 0x6a0:
830 	case 0x6d0:
831 	case 0x6f0:
832 		break;
833 	default:
834 		return;
835 	}
836 
837 	do_cpuid(0xc0000000, regs);
838 	if (regs[0] >= 0xc0000001)
839 		do_cpuid(0xc0000001, regs);
840 	else
841 		return;
842 
843 	kprintf("\n  VIA Padlock Features=0x%pb%i",
844 	"\020"
845 	"\003RNG"		/* RNG */
846 	"\007AES"		/* ACE */
847 	"\011AES-CTR"		/* ACE2 */
848 	"\013SHA1,SHA256"	/* PHE */
849 	"\015RSA"		/* PMM */
850 	, regs[3]);
851 }
852