1 /*        $NetBSD: i386.c,v 1.147 2024/10/19 16:43:46 msaitoh Exp $   */
2 
3 /*-
4  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Frank van der Linden,  and by Jason R. Thorpe.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*-
33  * Copyright (c)2008 YAMAMOTO Takashi,
34  * All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  *
45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55  * SUCH DAMAGE.
56  */
57 
58 #include <sys/cdefs.h>
59 #ifndef lint
60 __RCSID("$NetBSD: i386.c,v 1.147 2024/10/19 16:43:46 msaitoh Exp $");
61 #endif /* not lint */
62 
63 #include <sys/types.h>
64 #include <sys/param.h>
65 #include <sys/bitops.h>
66 #include <sys/sysctl.h>
67 #include <sys/ioctl.h>
68 #include <sys/cpuio.h>
69 
70 #include <errno.h>
71 #include <string.h>
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <err.h>
75 #include <assert.h>
76 #include <math.h>
77 #include <util.h>
78 
79 #include <machine/specialreg.h>
80 #include <machine/cpu.h>
81 
82 #include <x86/cpuvar.h>
83 #include <x86/cputypes.h>
84 #include <x86/cpu_ucode.h>
85 
86 #include "../cpuctl.h"
87 #include "cpuctl_i386.h"
88 
89 /* Size of buffer for printing humanized numbers */
90 #define HUMAN_BUFSIZE sizeof("999KB")
91 
92 struct cpu_nocpuid_nameclass {
93           int cpu_vendor;
94           const char *cpu_vendorname;
95           const char *cpu_name;
96           int cpu_class;
97           void (*cpu_setup)(struct cpu_info *);
98           void (*cpu_cacheinfo)(struct cpu_info *);
99           void (*cpu_info)(struct cpu_info *);
100 };
101 
102 struct cpu_cpuid_nameclass {
103           const char *cpu_id;
104           int cpu_vendor;
105           const char *cpu_vendorname;
106           struct cpu_cpuid_family {
107                     int cpu_class;
108                     const char *cpu_models[256];
109                     const char *cpu_model_default;
110                     void (*cpu_setup)(struct cpu_info *);
111                     void (*cpu_probe)(struct cpu_info *);
112                     void (*cpu_info)(struct cpu_info *);
113           } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
114 };
115 
116 static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO;
117 
118 /*
119  * Map Brand ID from cpuid instruction to brand name.
120  * Source: Table 3-24, Mapping of Brand Indices; and Intel 64 and IA-32
121  * Processor Brand Strings, Chapter 3 in "Intel (R) 64 and IA-32
122  * Architectures Software Developer's Manual, Volume 2A".
123  */
124 static const char * const i386_intel_brand[] = {
125           "",                     /* Unsupported */
126           "Celeron",              /* Intel (R) Celeron (TM) processor */
127           "Pentium III",          /* Intel (R) Pentium (R) III processor */
128           "Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */
129           "Pentium III",          /* Intel (R) Pentium (R) III processor */
130           "",                     /* 0x05: Reserved */
131           "Mobile Pentium III",/* Mobile Intel (R) Pentium (R) III processor-M */
132           "Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
133           "Pentium 4",            /* Intel (R) Pentium (R) 4 processor */
134           "Pentium 4",            /* Intel (R) Pentium (R) 4 processor */
135           "Celeron",              /* Intel (R) Celeron (TM) processor */
136           "Xeon",                 /* Intel (R) Xeon (TM) processor */
137           "Xeon MP",              /* Intel (R) Xeon (TM) processor MP */
138           "",                     /* 0x0d: Reserved */
139           "Mobile Pentium 4", /* Mobile Intel (R) Pentium (R) 4 processor-M */
140           "Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
141           "",                     /* 0x10: Reserved */
142           "Mobile Genuine",   /* Mobile Genuine Intel (R) processor */
143           "Celeron M",            /* Intel (R) Celeron (R) M processor */
144           "Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
145           "Celeron",              /* Intel (R) Celeron (R) processor */
146           "Mobile Genuine",   /* Mobile Genuine Intel (R) processor */
147           "Pentium M",            /* Intel (R) Pentium (R) M processor */
148           "Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
149 };
150 
151 /*
152  * AMD processors don't have Brand IDs, so we need these names for probe.
153  */
154 static const char * const amd_brand[] = {
155           "",
156           "Duron",  /* AMD Duron(tm) */
157           "MP",               /* AMD Athlon(tm) MP */
158           "XP",               /* AMD Athlon(tm) XP */
159           "4"                 /* AMD Athlon(tm) 4 */
160 };
161 
162 int cpu_vendor;
163 static char cpu_brand_string[49];
164 static char amd_brand_name[48];
165 static int use_pae, largepagesize;
166 
167 /* Setup functions */
168 static void         disable_tsc(struct cpu_info *);
169 static void         amd_family5_setup(struct cpu_info *);
170 static void         cyrix6x86_cpu_setup(struct cpu_info *);
171 static void         winchip_cpu_setup(struct cpu_info *);
172 /* Brand/Model name functions */
173 static const char *intel_family6_name(struct cpu_info *);
174 static const char *amd_amd64_name(struct cpu_info *);
175 /* Probe functions */
176 static void         amd_family6_probe(struct cpu_info *);
177 static void         powernow_probe(struct cpu_info *);
178 static void         intel_family_new_probe(struct cpu_info *);
179 static void         via_cpu_probe(struct cpu_info *);
180 /* (Cache) Info functions */
181 static void         intel_cpu_cacheinfo(struct cpu_info *);
182 static void         amd_cpu_cacheinfo(struct cpu_info *);
183 static void         via_cpu_cacheinfo(struct cpu_info *);
184 static void         tmx86_get_longrun_status(u_int *, u_int *, u_int *);
185 static void         transmeta_cpu_info(struct cpu_info *);
186 /* Common functions */
187 static void         cpu_probe_base_features(struct cpu_info *, const char *);
188 static void         cpu_probe_hv_features(struct cpu_info *, const char *);
189 static void         cpu_probe_features(struct cpu_info *);
190 static void         print_bits(const char *, const char *, const char *, uint32_t);
191 static void         identifycpu_cpuids(struct cpu_info *);
192 static const char *print_cache_config(struct cpu_info *, int, const char *,
193     const char *);
194 static const char *print_tlb_config(struct cpu_info *, int, const char *,
195     const char *);
196 static void         x86_print_cache_and_tlb_info(struct cpu_info *);
197 
198 /*
199  * Note: these are just the ones that may not have a cpuid instruction.
200  * We deal with the rest in a different way.
201  */
202 const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = {
203           { CPUVENDOR_INTEL, "Intel", "386SX",    CPUCLASS_386,
204             NULL, NULL, NULL },                             /* CPU_386SX */
205           { CPUVENDOR_INTEL, "Intel", "386DX",    CPUCLASS_386,
206             NULL, NULL, NULL },                             /* CPU_386   */
207           { CPUVENDOR_INTEL, "Intel", "486SX",    CPUCLASS_486,
208             NULL, NULL, NULL },                             /* CPU_486SX */
209           { CPUVENDOR_INTEL, "Intel", "486DX",    CPUCLASS_486,
210             NULL, NULL, NULL },                             /* CPU_486   */
211           { CPUVENDOR_CYRIX, "Cyrix", "486DLC",   CPUCLASS_486,
212             NULL, NULL, NULL },                             /* CPU_486DLC */
213           { CPUVENDOR_CYRIX, "Cyrix", "6x86",     CPUCLASS_486,
214             NULL, NULL, NULL },                   /* CPU_6x86 */
215           { CPUVENDOR_NEXGEN,"NexGen","586",      CPUCLASS_386,
216             NULL, NULL, NULL },                             /* CPU_NX586 */
217 };
218 
219 const char *classnames[] = {
220           "386",
221           "486",
222           "586",
223           "686"
224 };
225 
226 const char *modifiers[] = {
227           "",
228           "OverDrive",
229           "Dual",
230           ""
231 };
232 
233 const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
234           {
235                     /*
236                      * For Intel processors, check Chapter 35Model-specific
237                      * registers (MSRS), in "Intel (R) 64 and IA-32 Architectures
238                      * Software Developer's Manual, Volume 3C".
239                      */
240                     "GenuineIntel",
241                     CPUVENDOR_INTEL,
242                     "Intel",
243                     /* Family 4 */
244                     { {
245                               CPUCLASS_486,
246                               {
247                                         "486DX", "486DX", "486SX", "486DX2", "486SL",
248                                         "486SX2", 0, "486DX2 W/B Enhanced",
249                                         "486DX4", 0, 0, 0, 0, 0, 0, 0,
250                               },
251                               "486",              /* Default */
252                               NULL,
253                               NULL,
254                               intel_cpu_cacheinfo,
255                     },
256                     /* Family 5 */
257                     {
258                               CPUCLASS_586,
259                               {
260                                         "Pentium (P5 A-step)", "Pentium (P5)",
261                                         "Pentium (P54C)", "Pentium (P24T)",
262                                         "Pentium/MMX", "Pentium", 0,
263                                         "Pentium (P54C)", "Pentium/MMX (Tillamook)",
264                                         "Quark X1000", 0, 0, 0, 0, 0, 0,
265                               },
266                               "Pentium",          /* Default */
267                               NULL,
268                               NULL,
269                               intel_cpu_cacheinfo,
270                     },
271                     /* Family 6 */
272                     {
273                               CPUCLASS_686,
274                               {
275                                         [0x00] = "Pentium Pro (A-step)",
276                                         [0x01] = "Pentium Pro",
277                                         [0x03] = "Pentium II (Klamath)",
278                                         [0x04] = "Pentium Pro",
279                                         [0x05] = "Pentium II/Celeron (Deschutes)",
280                                         [0x06] = "Celeron (Mendocino)",
281                                         [0x07] = "Pentium III (Katmai)",
282                                         [0x08] = "Pentium III (Coppermine)",
283                                         [0x09] = "Pentium M (Banias)",
284                                         [0x0a] = "Pentium III Xeon (Cascades)",
285                                         [0x0b] = "Pentium III (Tualatin)",
286                                         [0x0d] = "Pentium M (Dothan)",
287                                         [0x0e] = "Pentium Core Duo, Core solo",
288                                         [0x0f] = "Xeon 30xx, 32xx, 51xx, 53xx, 73xx, "
289                                                    "Core 2 Quad 6xxx, "
290                                                    "Core 2 Extreme 6xxx, "
291                                                    "Core 2 Duo 4xxx, 5xxx, 6xxx, 7xxx "
292                                                    "and Pentium DC",
293                                         [0x15] = "EP80579 Integrated Processor",
294                                         [0x16] = "Celeron (45nm)",
295                                         [0x17] = "Xeon 31xx, 33xx, 52xx, 54xx, "
296                                                    "Core 2 Quad 8xxx and 9xxx",
297                                         [0x1a] = "Core i7, Xeon 34xx, 35xx and 55xx "
298                                                    "(Nehalem)",
299                                         [0x1c] = "45nm Atom Family",
300                                         [0x1d] = "XeonMP 74xx (Nehalem)",
301                                         [0x1e] = "Core i7 and i5",
302                                         [0x1f] = "Core i7 and i5",
303                                         [0x25] = "Xeon 36xx & 56xx, i7, i5 and i3",
304                                         [0x26] = "Atom Family",
305                                         [0x27] = "Atom Family",
306                                         [0x2a] = "Xeon E3-12xx, 2nd gen i7, i5, "
307                                                    "i3 2xxx",
308                                         [0x2c] = "Xeon 36xx & 56xx, i7, i5 and i3",
309                                         [0x2d] = "Xeon E5 Sandy Bridge family, "
310                                                    "Core i7-39xx Extreme",
311                                         [0x2e] = "Xeon 75xx & 65xx",
312                                         [0x2f] = "Xeon E7 family",
313                                         [0x35] = "Atom Family",
314                                         [0x36] = "Atom S1000",
315                                         [0x37] = "Atom E3000, Z3[67]00",
316                                         [0x3a] = "Xeon E3-1200v2 and 3rd gen core, "
317                                                    "Ivy Bridge",
318                                         [0x3c] = "4th gen Core, Xeon E3-12xx v3 "
319                                                    "(Haswell)",
320                                         [0x3d] = "Core M-5xxx, 5th gen Core (Broadwell)",
321                                         [0x3e] = "Xeon E5/E7 v2 (Ivy Bridge-E), "
322                                                    "Core i7-49xx Extreme",
323                                         [0x3f] = "Xeon E5-4600/2600/1600 v3, Xeon E7 v3 (Haswell-E), "
324                                                    "Core i7-59xx Extreme",
325                                         [0x45] = "4th gen Core, Xeon E3-12xx v3 "
326                                                    "(Haswell)",
327                                         [0x46] = "4th gen Core, Xeon E3-12xx v3 "
328                                                    "(Haswell)",
329                                         [0x47] = "5th gen Core, Xeon E3-1200 v4 (Broadwell)",
330                                         [0x4a] = "Atom Z3400",
331                                         [0x4c] = "Atom X[57]-Z8000 (Airmont)",
332                                         [0x4d] = "Atom C2000",
333                                         [0x4e] = "6th gen Core, Xeon E3-1[25]00 v5 (Skylake)",
334                                         [0x4f] = "Xeon E[57] v4 (Broadwell), Core i7-69xx Extreme",
335                                         [0x55] = "Xeon Scalable (Skylake, Cascade Lake, Copper Lake)",
336                                         [0x56] = "Xeon D-1500 (Broadwell)",
337                                         [0x57] = "Xeon Phi [357]200 (Knights Landing)",
338                                         [0x5a] = "Atom Z3500",
339                                         [0x5c] = "Atom (Goldmont)",
340                                         [0x5d] = "Atom X3-C3000 (Silvermont)",
341                                         [0x5e] = "6th gen Core, Xeon E3-1[25]00 v5 (Skylake)",
342                                         [0x5f] = "Atom (Goldmont, Denverton)",
343                                         [0x66] = "8th gen Core i3 (Cannon Lake)",
344                                         [0x6a] = "3rd gen Xeon Scalable (Ice Lake)",
345                                         [0x6c] = "3rd gen Xeon Scalable (Ice Lake)",
346                                         [0x7a] = "Atom (Goldmont Plus)",
347                                         [0x7d] = "10th gen Core (Ice Lake)",
348                                         [0x7e] = "10th gen Core (Ice Lake)",
349                                         [0x85] = "Xeon Phi 7215, 7285, 7295 (Knights Mill)",
350                                         [0x86] = "Atom (Tremont)",
351                                         [0x8c] = "11th gen Core (Tiger Lake)",
352                                         [0x8d] = "11th gen Core (Tiger Lake)",
353                                         [0x8e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)",
354                                         [0x8f] = "4th gen Xeon Scalable (Sapphire Rapids)",
355                                         [0x96] = "Atom x6000E (Elkhart Lake)",
356                                         [0x97] = "12th gen Core (Alder Lake)",
357                                         [0x9a] = "12th gen Core (Alder Lake)",
358                                         [0x9c] = "Pentium Silver N6xxx, Celeron N45xx, Celeron N51xx (Jasper Lake)",
359                                         [0x9e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)",
360                                         [0xa5] = "10th gen Core (Comet Lake)",
361                                         [0xa6] = "10th gen Core (Comet Lake)",
362                                         [0xa7] = "11th gen Core (Rocket Lake)",
363                                         [0xa8] = "11th gen Core (Rocket Lake)",
364                                         [0xaa] = "Core Ultra 7 (Meteor Lake)",
365                                         [0xb7] = "13th gen Core (Raptor Lake)",
366                                         [0xba] = "13th gen Core (Raptor Lake)",
367                                         [0xbe] = "Core i3-N3xx N[12]xx Nxx Atom x7xxxE (Alder Lake-N)",
368                                         [0xbf] = "13th gen Core (Raptor Lake)",
369                                         [0xcf] = "5th gen Xeon Scalable (Emerald Rapids)",
370                               },
371                               "Pentium Pro, II or III",     /* Default */
372                               NULL,
373                               intel_family_new_probe,
374                               intel_cpu_cacheinfo,
375                     },
376                     /* Family > 6 */
377                     {
378                               CPUCLASS_686,
379                               {
380                                         0, 0, 0, 0, 0, 0, 0, 0,
381                                         0, 0, 0, 0, 0, 0, 0, 0,
382                               },
383                               "Pentium 4",        /* Default */
384                               NULL,
385                               intel_family_new_probe,
386                               intel_cpu_cacheinfo,
387                     } }
388           },
389           {
390                     "AuthenticAMD",
391                     CPUVENDOR_AMD,
392                     "AMD",
393                     /* Family 4 */
394                     { {
395                               CPUCLASS_486,
396                               {
397                                         0, 0, 0, "Am486DX2 W/T",
398                                         0, 0, 0, "Am486DX2 W/B",
399                                         "Am486DX4 W/T or Am5x86 W/T 150",
400                                         "Am486DX4 W/B or Am5x86 W/B 150", 0, 0,
401                                         0, 0, "Am5x86 W/T 133/160",
402                                         "Am5x86 W/B 133/160",
403                               },
404                               "Am486 or Am5x86",  /* Default */
405                               NULL,
406                               NULL,
407                               NULL,
408                     },
409                     /* Family 5 */
410                     {
411                               CPUCLASS_586,
412                               {
413                                         "K5", "K5", "K5", "K5", 0, 0, "K6",
414                                         "K6", "K6-2", "K6-III", "Geode LX", 0, 0,
415                                         "K6-2+/III+", 0, 0,
416                               },
417                               "K5 or K6",                   /* Default */
418                               amd_family5_setup,
419                               NULL,
420                               amd_cpu_cacheinfo,
421                     },
422                     /* Family 6 */
423                     {
424                               CPUCLASS_686,
425                               {
426                                         0, "Athlon Model 1", "Athlon Model 2",
427                                         "Duron", "Athlon Model 4 (Thunderbird)",
428                                         0, "Athlon", "Duron", "Athlon", 0,
429                                         "Athlon", 0, 0, 0, 0, 0,
430                               },
431                               "K7 (Athlon)",      /* Default */
432                               NULL,
433                               amd_family6_probe,
434                               amd_cpu_cacheinfo,
435                     },
436                     /* Family > 6 */
437                     {
438                               CPUCLASS_686,
439                               {
440                                         0, 0, 0, 0, 0, 0, 0, 0,
441                                         0, 0, 0, 0, 0, 0, 0, 0,
442                               },
443                               "Unknown K8 (Athlon)",        /* Default */
444                               NULL,
445                               amd_family6_probe,
446                               amd_cpu_cacheinfo,
447                     } }
448           },
449           {
450                     "CyrixInstead",
451                     CPUVENDOR_CYRIX,
452                     "Cyrix",
453                     /* Family 4 */
454                     { {
455                               CPUCLASS_486,
456                               {
457                                         0, 0, 0,
458                                         "MediaGX",
459                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
460                               },
461                               "486",              /* Default */
462                               cyrix6x86_cpu_setup, /* XXX ?? */
463                               NULL,
464                               NULL,
465                     },
466                     /* Family 5 */
467                     {
468                               CPUCLASS_586,
469                               {
470                                         0, 0, "6x86", 0,
471                                         "MMX-enhanced MediaGX (GXm)", /* or Geode? */
472                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
473                               },
474                               "6x86",             /* Default */
475                               cyrix6x86_cpu_setup,
476                               NULL,
477                               NULL,
478                     },
479                     /* Family 6 */
480                     {
481                               CPUCLASS_686,
482                               {
483                                         "6x86MX", 0, 0, 0, 0, 0, 0, 0,
484                                         0, 0, 0, 0, 0, 0, 0, 0,
485                               },
486                               "6x86MX",           /* Default */
487                               cyrix6x86_cpu_setup,
488                               NULL,
489                               NULL,
490                     },
491                     /* Family > 6 */
492                     {
493                               CPUCLASS_686,
494                               {
495                                         0, 0, 0, 0, 0, 0, 0, 0,
496                                         0, 0, 0, 0, 0, 0, 0, 0,
497                               },
498                               "Unknown 6x86MX",             /* Default */
499                               NULL,
500                               NULL,
501                               NULL,
502                     } }
503           },
504           {         /* MediaGX is now owned by National Semiconductor */
505                     "Geode by NSC",
506                     CPUVENDOR_CYRIX, /* XXX */
507                     "National Semiconductor",
508                     /* Family 4, NSC never had any of these */
509                     { {
510                               CPUCLASS_486,
511                               {
512                                         0, 0, 0, 0, 0, 0, 0, 0,
513                                         0, 0, 0, 0, 0, 0, 0, 0,
514                               },
515                               "486 compatible",   /* Default */
516                               NULL,
517                               NULL,
518                               NULL,
519                     },
520                     /* Family 5: Geode family, formerly MediaGX */
521                     {
522                               CPUCLASS_586,
523                               {
524                                         0, 0, 0, 0,
525                                         "Geode GX1",
526                                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
527                               },
528                               "Geode",            /* Default */
529                               cyrix6x86_cpu_setup,
530                               NULL,
531                               amd_cpu_cacheinfo,
532                     },
533                     /* Family 6, not yet available from NSC */
534                     {
535                               CPUCLASS_686,
536                               {
537                                         0, 0, 0, 0, 0, 0, 0, 0,
538                                         0, 0, 0, 0, 0, 0, 0, 0,
539                               },
540                               "Pentium Pro compatible", /* Default */
541                               NULL,
542                               NULL,
543                               NULL,
544                     },
545                     /* Family > 6, not yet available from NSC */
546                     {
547                               CPUCLASS_686,
548                               {
549                                         0, 0, 0, 0, 0, 0, 0, 0,
550                                         0, 0, 0, 0, 0, 0, 0, 0,
551                               },
552                               "Pentium Pro compatible",     /* Default */
553                               NULL,
554                               NULL,
555                               NULL,
556                     } }
557           },
558           {
559                     "CentaurHauls",
560                     CPUVENDOR_IDT,
561                     "IDT",
562                     /* Family 4, IDT never had any of these */
563                     { {
564                               CPUCLASS_486,
565                               {
566                                         0, 0, 0, 0, 0, 0, 0, 0,
567                                         0, 0, 0, 0, 0, 0, 0, 0,
568                               },
569                               "486 compatible",   /* Default */
570                               NULL,
571                               NULL,
572                               NULL,
573                     },
574                     /* Family 5 */
575                     {
576                               CPUCLASS_586,
577                               {
578                                         0, 0, 0, 0, "WinChip C6", 0, 0, 0,
579                                         "WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0,
580                               },
581                               "WinChip",                    /* Default */
582                               winchip_cpu_setup,
583                               NULL,
584                               NULL,
585                     },
586                     /* Family 6, VIA acquired IDT Centaur design subsidiary */
587                     {
588                               CPUCLASS_686,
589                               {
590                                         0, 0, 0, 0, 0, 0, "C3 Samuel",
591                                         "C3 Samuel 2/Ezra", "C3 Ezra-T",
592                                         "C3 Nehemiah", "C7 Esther", 0, 0, "C7 Esther",
593                                         0, "VIA Nano",
594                               },
595                               "Unknown VIA/IDT",  /* Default */
596                               NULL,
597                               via_cpu_probe,
598                               via_cpu_cacheinfo,
599                     },
600                     /* Family > 6, not yet available from VIA */
601                     {
602                               CPUCLASS_686,
603                               {
604                                         0, 0, 0, 0, 0, 0, 0, 0,
605                                         0, 0, 0, 0, 0, 0, 0, 0,
606                               },
607                               "Pentium Pro compatible",     /* Default */
608                               NULL,
609                               NULL,
610                               NULL,
611                     } }
612           },
613           {
614                     "GenuineTMx86",
615                     CPUVENDOR_TRANSMETA,
616                     "Transmeta",
617                     /* Family 4, Transmeta never had any of these */
618                     { {
619                               CPUCLASS_486,
620                               {
621                                         0, 0, 0, 0, 0, 0, 0, 0,
622                                         0, 0, 0, 0, 0, 0, 0, 0,
623                               },
624                               "486 compatible",   /* Default */
625                               NULL,
626                               NULL,
627                               NULL,
628                     },
629                     /* Family 5 */
630                     {
631                               CPUCLASS_586,
632                               {
633                                         0, 0, 0, 0, 0, 0, 0, 0,
634                                         0, 0, 0, 0, 0, 0, 0, 0,
635                               },
636                               "Crusoe",           /* Default */
637                               NULL,
638                               NULL,
639                               transmeta_cpu_info,
640                     },
641                     /* Family 6, not yet available from Transmeta */
642                     {
643                               CPUCLASS_686,
644                               {
645                                         0, 0, 0, 0, 0, 0, 0, 0,
646                                         0, 0, 0, 0, 0, 0, 0, 0,
647                               },
648                               "Pentium Pro compatible",     /* Default */
649                               NULL,
650                               NULL,
651                               NULL,
652                     },
653                     /* Family > 6, not yet available from Transmeta */
654                     {
655                               CPUCLASS_686,
656                               {
657                                         0, 0, 0, 0, 0, 0, 0, 0,
658                                         0, 0, 0, 0, 0, 0, 0, 0,
659                               },
660                               "Pentium Pro compatible",     /* Default */
661                               NULL,
662                               NULL,
663                               NULL,
664                     } }
665           }
666 };
667 
668 /*
669  * disable the TSC such that we don't use the TSC in microtime(9)
670  * because some CPUs got the implementation wrong.
671  */
672 static void
disable_tsc(struct cpu_info * ci)673 disable_tsc(struct cpu_info *ci)
674 {
675           if (ci->ci_feat_val[0] & CPUID_TSC) {
676                     ci->ci_feat_val[0] &= ~CPUID_TSC;
677                     aprint_error("WARNING: broken TSC disabled\n");
678           }
679 }
680 
681 static void
amd_family5_setup(struct cpu_info * ci)682 amd_family5_setup(struct cpu_info *ci)
683 {
684 
685           switch (ci->ci_model) {
686           case 0:             /* AMD-K5 Model 0 */
687                     /*
688                      * According to the AMD Processor Recognition App Note,
689                      * the AMD-K5 Model 0 uses the wrong bit to indicate
690                      * support for global PTEs, instead using bit 9 (APIC)
691                      * rather than bit 13 (i.e. "0x200" vs. 0x2000".  Oops!).
692                      */
693                     if (ci->ci_feat_val[0] & CPUID_APIC)
694                               ci->ci_feat_val[0] =
695                                   (ci->ci_feat_val[0] & ~CPUID_APIC) | CPUID_PGE;
696                     /*
697                      * XXX But pmap_pg_g is already initialized -- need to kick
698                      * XXX the pmap somehow.  How does the MP branch do this?
699                      */
700                     break;
701           }
702 }
703 
704 static void
cyrix6x86_cpu_setup(struct cpu_info * ci)705 cyrix6x86_cpu_setup(struct cpu_info *ci)
706 {
707 
708           /*
709            * Do not disable the TSC on the Geode GX, it's reported to
710            * work fine.
711            */
712           if (ci->ci_signature != 0x552)
713                     disable_tsc(ci);
714 }
715 
716 static void
winchip_cpu_setup(struct cpu_info * ci)717 winchip_cpu_setup(struct cpu_info *ci)
718 {
719           switch (ci->ci_model) {
720           case 4:   /* WinChip C6 */
721                     disable_tsc(ci);
722           }
723 }
724 
725 
726 static const char *
intel_family6_name(struct cpu_info * ci)727 intel_family6_name(struct cpu_info *ci)
728 {
729           const char *ret = NULL;
730           u_int l2cache = ci->ci_cinfo[CAI_L2CACHE].cai_totalsize;
731 
732           if (ci->ci_model == 5) {
733                     switch (l2cache) {
734                     case 0:
735                     case 128 * 1024:
736                               ret = "Celeron (Covington)";
737                               break;
738                     case 256 * 1024:
739                               ret = "Mobile Pentium II (Dixon)";
740                               break;
741                     case 512 * 1024:
742                               ret = "Pentium II";
743                               break;
744                     case 1 * 1024 * 1024:
745                     case 2 * 1024 * 1024:
746                               ret = "Pentium II Xeon";
747                               break;
748                     }
749           } else if (ci->ci_model == 6) {
750                     switch (l2cache) {
751                     case 256 * 1024:
752                     case 512 * 1024:
753                               ret = "Mobile Pentium II";
754                               break;
755                     }
756           } else if (ci->ci_model == 7) {
757                     switch (l2cache) {
758                     case 512 * 1024:
759                               ret = "Pentium III";
760                               break;
761                     case 1 * 1024 * 1024:
762                     case 2 * 1024 * 1024:
763                               ret = "Pentium III Xeon";
764                               break;
765                     }
766           } else if (ci->ci_model >= 8) {
767                     if (ci->ci_brand_id && ci->ci_brand_id < 0x10) {
768                               switch (ci->ci_brand_id) {
769                               case 0x3:
770                                         if (ci->ci_signature == 0x6B1)
771                                                   ret = "Celeron";
772                                         break;
773                               case 0x8:
774                                         if (ci->ci_signature >= 0xF13)
775                                                   ret = "genuine processor";
776                                         break;
777                               case 0xB:
778                                         if (ci->ci_signature >= 0xF13)
779                                                   ret = "Xeon MP";
780                                         break;
781                               case 0xE:
782                                         if (ci->ci_signature < 0xF13)
783                                                   ret = "Xeon";
784                                         break;
785                               }
786                               if (ret == NULL)
787                                         ret = i386_intel_brand[ci->ci_brand_id];
788                     }
789           }
790 
791           return ret;
792 }
793 
794 /*
795  * Identify AMD64 CPU names from cpuid.
796  *
797  * Based on:
798  * "Revision Guide for AMD Athlon 64 and AMD Opteron Processors"
799  * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf
800  * "Revision Guide for AMD NPT Family 0Fh Processors"
801  * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf
802  * and other miscellaneous reports.
803  *
804  * This is all rather pointless, these are cross 'brand' since the raw
805  * silicon is shared.
806  */
807 static const char *
amd_amd64_name(struct cpu_info * ci)808 amd_amd64_name(struct cpu_info *ci)
809 {
810           static char family_str[32];
811 
812           /* Only called if family >= 15 */
813 
814           switch (ci->ci_family) {
815           case 15:
816                     switch (ci->ci_model) {
817                     case 0x21:          /* rev JH-E1/E6 */
818                     case 0x41:          /* rev JH-F2 */
819                               return "Dual-Core Opteron";
820                     case 0x23:          /* rev JH-E6 (Toledo) */
821                               return "Dual-Core Opteron or Athlon 64 X2";
822                     case 0x43:          /* rev JH-F2 (Windsor) */
823                               return "Athlon 64 FX or Athlon 64 X2";
824                     case 0x24:          /* rev SH-E5 (Lancaster?) */
825                               return "Mobile Athlon 64 or Turion 64";
826                     case 0x05:          /* rev SH-B0/B3/C0/CG (SledgeHammer?) */
827                               return "Opteron or Athlon 64 FX";
828                     case 0x15:          /* rev SH-D0 */
829                     case 0x25:          /* rev SH-E4 */
830                               return "Opteron";
831                     case 0x27:          /* rev DH-E4, SH-E4 */
832                               return "Athlon 64 or Athlon 64 FX or Opteron";
833                     case 0x48:          /* rev BH-F2 */
834                               return "Turion 64 X2";
835                     case 0x04:          /* rev SH-B0/C0/CG (ClawHammer) */
836                     case 0x07:          /* rev SH-CG (ClawHammer) */
837                     case 0x0b:          /* rev CH-CG */
838                     case 0x14:          /* rev SH-D0 */
839                     case 0x17:          /* rev SH-D0 */
840                     case 0x1b:          /* rev CH-D0 */
841                               return "Athlon 64";
842                     case 0x2b:          /* rev BH-E4 (Manchester) */
843                     case 0x4b:          /* rev BH-F2 (Windsor) */
844                               return "Athlon 64 X2";
845                     case 0x6b:          /* rev BH-G1 (Brisbane) */
846                               return "Athlon X2 or Athlon 64 X2";
847                     case 0x08:          /* rev CH-CG */
848                     case 0x0c:          /* rev DH-CG (Newcastle) */
849                     case 0x0e:          /* rev DH-CG (Newcastle?) */
850                     case 0x0f:          /* rev DH-CG (Newcastle/Paris) */
851                     case 0x18:          /* rev CH-D0 */
852                     case 0x1c:          /* rev DH-D0 (Winchester) */
853                     case 0x1f:          /* rev DH-D0 (Winchester/Victoria) */
854                     case 0x2c:          /* rev DH-E3/E6 */
855                     case 0x2f:          /* rev DH-E3/E6 (Venice/Palermo) */
856                     case 0x4f:          /* rev DH-F2 (Orleans/Manila) */
857                     case 0x5f:          /* rev DH-F2 (Orleans/Manila) */
858                     case 0x6f:          /* rev DH-G1 */
859                               return "Athlon 64 or Sempron";
860                     default:
861                               break;
862                     }
863                     return "Unknown AMD64 CPU";
864 
865 #if 0
866           case 16:
867                     return "Family 10h";
868           case 17:
869                     return "Family 11h";
870           case 18:
871                     return "Family 12h";
872           case 19:
873                     return "Family 14h";
874           case 20:
875                     return "Family 15h";
876 #endif
877 
878           default:
879                     break;
880           }
881 
882           snprintf(family_str, sizeof family_str, "Family %xh", ci->ci_family);
883           return family_str;
884 }
885 
886 static void
intel_family_new_probe(struct cpu_info * ci)887 intel_family_new_probe(struct cpu_info *ci)
888 {
889           uint32_t descs[4];
890 
891           x86_cpuid(0x80000000, descs);
892 
893           /*
894            * Determine extended feature flags.
895            */
896           if (descs[0] >= 0x80000001) {
897                     x86_cpuid(0x80000001, descs);
898                     ci->ci_feat_val[2] |= descs[3];
899                     ci->ci_feat_val[3] |= descs[2];
900           }
901 }
902 
903 static void
via_cpu_probe(struct cpu_info * ci)904 via_cpu_probe(struct cpu_info *ci)
905 {
906           u_int stepping = CPUID_TO_STEPPING(ci->ci_signature);
907           u_int descs[4];
908           u_int lfunc;
909 
910           /*
911            * Determine the largest extended function value.
912            */
913           x86_cpuid(0x80000000, descs);
914           lfunc = descs[0];
915 
916           /*
917            * Determine the extended feature flags.
918            */
919           if (lfunc >= 0x80000001) {
920                     x86_cpuid(0x80000001, descs);
921                     ci->ci_feat_val[2] |= descs[3];
922           }
923 
924           if (ci->ci_model < 0x9 || (ci->ci_model == 0x9 && stepping < 3))
925                     return;
926 
927           /* Nehemiah or Esther */
928           x86_cpuid(0xc0000000, descs);
929           lfunc = descs[0];
930           if (lfunc < 0xc0000001)       /* no ACE, no RNG */
931                     return;
932 
933           x86_cpuid(0xc0000001, descs);
934           lfunc = descs[3];
935           ci->ci_feat_val[4] = lfunc;
936 }
937 
938 static void
amd_family6_probe(struct cpu_info * ci)939 amd_family6_probe(struct cpu_info *ci)
940 {
941           uint32_t descs[4];
942           char *p;
943           size_t i;
944 
945           x86_cpuid(0x80000000, descs);
946 
947           /*
948            * Determine the extended feature flags.
949            */
950           if (descs[0] >= 0x80000001) {
951                     x86_cpuid(0x80000001, descs);
952                     ci->ci_feat_val[2] |= descs[3]; /* %edx */
953                     ci->ci_feat_val[3] = descs[2]; /* %ecx */
954           }
955 
956           if (*cpu_brand_string == '\0')
957                     return;
958 
959           for (i = 1; i < __arraycount(amd_brand); i++)
960                     if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) {
961                               ci->ci_brand_id = i;
962                               strlcpy(amd_brand_name, p, sizeof(amd_brand_name));
963                               break;
964                     }
965 }
966 
967 static void
intel_cpu_cacheinfo(struct cpu_info * ci)968 intel_cpu_cacheinfo(struct cpu_info *ci)
969 {
970           const struct x86_cache_info *cai;
971           u_int descs[4];
972           int iterations, i, j;
973           int type, level, ways, linesize, sets;
974           int caitype = -1;
975           uint8_t desc;
976 
977           /* Return if the cpu is old pre-cpuid instruction cpu */
978           if (ci->ci_cpu_type >= 0)
979                     return;
980 
981           if (ci->ci_max_cpuid < 2)
982                     return;
983 
984           /*
985            * Parse the cache info from `cpuid leaf 2', if we have it.
986            * XXX This is kinda ugly, but hey, so is the architecture...
987            */
988           x86_cpuid(2, descs);
989           iterations = descs[0] & 0xff;
990           while (iterations-- > 0) {
991                     for (i = 0; i < 4; i++) {
992                               if (descs[i] & 0x80000000)
993                                         continue;
994                               for (j = 0; j < 4; j++) {
995                                         /*
996                                          * The least significant byte in EAX
997                                          * ((desc[0] >> 0) & 0xff) is always 0x01 and
998                                          * it should be ignored.
999                                          */
1000                                         if (i == 0 && j == 0)
1001                                                   continue;
1002                                         desc = (descs[i] >> (j * 8)) & 0xff;
1003                                         if (desc == 0)
1004                                                   continue;
1005                                         cai = cpu_cacheinfo_lookup(
1006                                                   intel_cpuid_cache_info, desc);
1007                                         if (cai != NULL)
1008                                                   ci->ci_cinfo[cai->cai_index] = *cai;
1009                                         else if ((verbose != 0) && (desc != 0xff)
1010                                             && (desc != 0xfe))
1011                                                   aprint_error_dev(ci->ci_dev, "error:"
1012                                                       " Unknown cacheinfo desc %02x\n",
1013                                                       desc);
1014                               }
1015                     }
1016                     x86_cpuid(2, descs);
1017           }
1018 
1019           if (ci->ci_max_cpuid < 4)
1020                     return;
1021 
1022           /* Parse the cache info from `cpuid leaf 4', if we have it. */
1023           cpu_dcp_cacheinfo(ci, 4);
1024 
1025           if (ci->ci_max_cpuid < 0x18)
1026                     return;
1027           /* Parse the TLB info from `cpuid leaf 18H', if we have it. */
1028           x86_cpuid(0x18, descs);
1029           iterations = descs[0];
1030           for (i = 0; i <= iterations; i++) {
1031                     uint32_t pgsize;
1032                     bool full;
1033 
1034                     x86_cpuid2(0x18, i, descs);
1035                     type = __SHIFTOUT(descs[3], CPUID_DATP_TCTYPE);
1036                     if (type == CPUID_DATP_TCTYPE_N)
1037                               continue;
1038                     level = __SHIFTOUT(descs[3], CPUID_DATP_TCLEVEL);
1039                     pgsize = __SHIFTOUT(descs[1], CPUID_DATP_PGSIZE);
1040                     switch (level) {
1041                     case 1:
1042                               if (type == CPUID_DATP_TCTYPE_I) {
1043                                         switch (pgsize) {
1044                                         case CPUID_DATP_PGSIZE_4KB:
1045                                                   caitype = CAI_ITLB;
1046                                                   break;
1047                                         case CPUID_DATP_PGSIZE_2MB
1048                                             | CPUID_DATP_PGSIZE_4MB:
1049                                                   caitype = CAI_ITLB2;
1050                                                   break;
1051                                         case CPUID_DATP_PGSIZE_1GB:
1052                                                   caitype = CAI_L1_1GBITLB;
1053                                                   break;
1054                                         default:
1055                                                   aprint_error_dev(ci->ci_dev,
1056                                                       "error: unknown ITLB size (%d)\n",
1057                                                       pgsize);
1058                                                   caitype = CAI_ITLB;
1059                                                   break;
1060                                         }
1061                               } else if (type == CPUID_DATP_TCTYPE_D) {
1062                                         switch (pgsize) {
1063                                         case CPUID_DATP_PGSIZE_4KB:
1064                                                   caitype = CAI_DTLB;
1065                                                   break;
1066                                         case CPUID_DATP_PGSIZE_2MB
1067                                             | CPUID_DATP_PGSIZE_4MB:
1068                                                   caitype = CAI_DTLB2;
1069                                                   break;
1070                                         case CPUID_DATP_PGSIZE_1GB:
1071                                                   caitype = CAI_L1_1GBDTLB;
1072                                                   break;
1073                                         default:
1074                                                   aprint_error_dev(ci->ci_dev,
1075                                                       "error: unknown DTLB size (%d)\n",
1076                                                       pgsize);
1077                                                   caitype = CAI_DTLB;
1078                                                   break;
1079                                         }
1080                               } else if (type == CPUID_DATP_TCTYPE_L)
1081                                         caitype = CAI_L1_LD_TLB;
1082                               else if (type == CPUID_DATP_TCTYPE_S)
1083                                         caitype = CAI_L1_ST_TLB;
1084                               else
1085                                         caitype = -1;
1086                               break;
1087                     case 2:
1088                               if (type == CPUID_DATP_TCTYPE_I)
1089                                         caitype = CAI_L2_ITLB;
1090                               else if (type == CPUID_DATP_TCTYPE_D)
1091                                         caitype = CAI_L2_DTLB;
1092                               else if (type == CPUID_DATP_TCTYPE_U) {
1093                                         if (pgsize == CPUID_DATP_PGSIZE_4KB)
1094                                                   caitype = CAI_L2_STLB;
1095                                         else if (pgsize == (CPUID_DATP_PGSIZE_4KB
1096                                                   | CPUID_DATP_PGSIZE_2MB))
1097                                                   caitype = CAI_L2_STLB2;
1098                                         else if (pgsize == (CPUID_DATP_PGSIZE_2MB
1099                                                   | CPUID_DATP_PGSIZE_4MB))
1100                                                   caitype = CAI_L2_STLB3;
1101                                         else if ((pgsize & CPUID_DATP_PGSIZE_1GB)
1102                                             != 0) {
1103                                                   /* FIXME: 1GB max TLB */
1104                                                   caitype = CAI_L2_STLB3;
1105                                                   linesize = 1024 * 1024 * 1024;
1106                                         } else if ((pgsize & CPUID_DATP_PGSIZE_4MB)
1107                                             != 0) {
1108                                                   /* FIXME: 4MB max TLB */
1109                                                   caitype = CAI_L2_STLB3;
1110                                                   linesize = 4 * 1024 * 1024;
1111                                         } else if ((pgsize & CPUID_DATP_PGSIZE_2MB)
1112                                             != 0) {
1113                                                   /* FIXME: 2MB max TLB */
1114                                                   caitype = CAI_L2_STLB2;
1115                                                   linesize = 2 * 1024 * 1024;
1116                                         } else {
1117                                                   aprint_error_dev(ci->ci_dev, "error: "
1118                                                       "unknown L2 STLB size (%d)\n",
1119                                                       pgsize);
1120                                                   caitype = CAI_L2_STLB;
1121                                                   linesize = 4 * 1024;
1122                                         }
1123                               } else
1124                                         caitype = -1;
1125                               break;
1126                     case 3:
1127                               /* XXX need work for L3 TLB */
1128                               caitype = CAI_L3CACHE;
1129                               break;
1130                     default:
1131                               caitype = -1;
1132                               break;
1133                     }
1134                     if (caitype == -1) {
1135                               aprint_error_dev(ci->ci_dev,
1136                                   "error: unknown TLB level&type (%d & %d)\n",
1137                                   level, type);
1138                               continue;
1139                     }
1140                     switch (pgsize) {
1141                     case CPUID_DATP_PGSIZE_4KB:
1142                               linesize = 4 * 1024;
1143                               break;
1144                     case CPUID_DATP_PGSIZE_2MB:
1145                               linesize = 2 * 1024 * 1024;
1146                               break;
1147                     case CPUID_DATP_PGSIZE_4MB:
1148                               linesize = 4 * 1024 * 1024;
1149                               break;
1150                     case CPUID_DATP_PGSIZE_1GB:
1151                               linesize = 1024 * 1024 * 1024;
1152                               break;
1153                     default:
1154                               if ((pgsize & CPUID_DATP_PGSIZE_1GB) != 0)
1155                                         linesize = 1024 * 1024 * 1024; /* MAX 1G */
1156                               else if ((pgsize & CPUID_DATP_PGSIZE_4MB) != 0)
1157                                         linesize = 4 * 1024 * 1024; /* MAX 4M */
1158                               else if ((pgsize & CPUID_DATP_PGSIZE_2MB) != 0)
1159                                         linesize = 2 * 1024 * 1024; /* MAX 2M */
1160                               else
1161                                         linesize = 4 * 1024;          /* XXX default to 4K */
1162                               aprint_error_dev(ci->ci_dev, "WARNING: Currently "
1163                                   "this info can't print correctly "
1164                                   "(level = %d, pgsize = %d)\n",
1165                                   level, pgsize);
1166                               break;
1167                     }
1168                     ways = __SHIFTOUT(descs[1], CPUID_DATP_WAYS);
1169                     sets = descs[2];
1170                     full = descs[3] & CPUID_DATP_FULLASSOC;
1171                     ci->ci_cinfo[caitype].cai_totalsize
1172                         = ways * sets; /* entries */
1173                     ci->ci_cinfo[caitype].cai_associativity
1174                         = full ? 0xff : ways;
1175                     ci->ci_cinfo[caitype].cai_linesize = linesize; /* pg size */
1176           }
1177 }
1178 
1179 static const struct x86_cache_info amd_cpuid_l2l3cache_assoc_info[] =
1180     AMD_L2L3CACHE_INFO;
1181 
1182 static void
amd_cpu_cacheinfo(struct cpu_info * ci)1183 amd_cpu_cacheinfo(struct cpu_info *ci)
1184 {
1185           const struct x86_cache_info *cp;
1186           struct x86_cache_info *cai;
1187           u_int descs[4];
1188           u_int lfunc;
1189           bool l2tlbx32 = false;
1190 
1191           /* K5 model 0 has none of this info. */
1192           if (ci->ci_family == 5 && ci->ci_model == 0)
1193                     return;
1194 
1195           /* Determine the largest extended function value. */
1196           x86_cpuid(0x80000000, descs);
1197           lfunc = descs[0];
1198 
1199           if (lfunc < 0x80000005)
1200                     return;
1201 
1202           /* Determine L1 cache/TLB info. */
1203           x86_cpuid(0x80000005, descs);
1204 
1205           /* K6-III and higher have large page TLBs. */
1206           if ((ci->ci_family == 5 && ci->ci_model >= 9) || ci->ci_family >= 6) {
1207                     cai = &ci->ci_cinfo[CAI_ITLB2];
1208                     cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]);
1209                     cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]);
1210                     cai->cai_linesize = largepagesize;
1211 
1212                     cai = &ci->ci_cinfo[CAI_DTLB2];
1213                     cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]);
1214                     cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]);
1215                     cai->cai_linesize = largepagesize;
1216           }
1217 
1218           cai = &ci->ci_cinfo[CAI_ITLB];
1219           cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]);
1220           cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]);
1221           cai->cai_linesize = (4 * 1024);
1222 
1223           cai = &ci->ci_cinfo[CAI_DTLB];
1224           cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]);
1225           cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]);
1226           cai->cai_linesize = (4 * 1024);
1227 
1228           cai = &ci->ci_cinfo[CAI_DCACHE];
1229           cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]);
1230           cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]);
1231           cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]);
1232 
1233           cai = &ci->ci_cinfo[CAI_ICACHE];
1234           cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]);
1235           cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]);
1236           cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]);
1237 
1238           if (lfunc < 0x80000006)
1239                     return;
1240 
1241           /* Determine L2 cache/TLB info. */
1242           if (lfunc >= 0x80000021) {
1243                      x86_cpuid(0x80000021, descs);
1244                      l2tlbx32 = descs[0] & CPUID_AMDEXT2_L2TLBSIZEX32;
1245           }
1246           x86_cpuid(0x80000006, descs);
1247 
1248           cai = &ci->ci_cinfo[CAI_L2_ITLB];
1249           cai->cai_totalsize =
1250               AMD_L2_EBX_IUTLB_ENTRIES(descs[1]) * (l2tlbx32 ? 32 : 1);
1251           cai->cai_associativity = AMD_L2_EBX_IUTLB_ASSOC(descs[1]);
1252           cai->cai_linesize = (4 * 1024);
1253           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1254               cai->cai_associativity);
1255           if (cp != NULL)
1256                     cai->cai_associativity = cp->cai_associativity;
1257           else
1258                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1259 
1260           cai = &ci->ci_cinfo[CAI_L2_ITLB2];
1261           cai->cai_totalsize =
1262               AMD_L2_EAX_IUTLB_ENTRIES(descs[0]) * (l2tlbx32 ? 32 : 1);
1263           cai->cai_associativity = AMD_L2_EAX_IUTLB_ASSOC(descs[0]);
1264           cai->cai_linesize = largepagesize;
1265           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1266               cai->cai_associativity);
1267           if (cp != NULL)
1268                     cai->cai_associativity = cp->cai_associativity;
1269           else
1270                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1271 
1272           cai = &ci->ci_cinfo[CAI_L2_DTLB];
1273           cai->cai_totalsize =
1274               AMD_L2_EBX_DTLB_ENTRIES(descs[1]) * (l2tlbx32 ? 32 : 1);
1275           cai->cai_associativity = AMD_L2_EBX_DTLB_ASSOC(descs[1]);
1276           cai->cai_linesize = (4 * 1024);
1277           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1278               cai->cai_associativity);
1279           if (cp != NULL)
1280                     cai->cai_associativity = cp->cai_associativity;
1281           else
1282                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1283 
1284           cai = &ci->ci_cinfo[CAI_L2_DTLB2];
1285           cai->cai_totalsize =
1286               AMD_L2_EAX_DTLB_ENTRIES(descs[0]) * (l2tlbx32 ? 32 : 1);
1287           cai->cai_associativity = AMD_L2_EAX_DTLB_ASSOC(descs[0]);
1288           cai->cai_linesize = largepagesize;
1289           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1290               cai->cai_associativity);
1291           if (cp != NULL)
1292                     cai->cai_associativity = cp->cai_associativity;
1293           else
1294                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1295 
1296           cai = &ci->ci_cinfo[CAI_L2CACHE];
1297           cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]);
1298           cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]);
1299           cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]);
1300 
1301           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1302               cai->cai_associativity);
1303           if (cp != NULL)
1304                     cai->cai_associativity = cp->cai_associativity;
1305           else
1306                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1307 
1308           /* Determine L3 cache info on AMD Family 10h and newer processors */
1309           if (ci->ci_family >= 0x10) {
1310                     cai = &ci->ci_cinfo[CAI_L3CACHE];
1311                     cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]);
1312                     cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]);
1313                     cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]);
1314 
1315                     cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1316                         cai->cai_associativity);
1317                     if (cp != NULL)
1318                               cai->cai_associativity = cp->cai_associativity;
1319                     else
1320                               cai->cai_associativity = 0;   /* XXX Unkn/Rsvd */
1321           }
1322 
1323           if (lfunc < 0x80000019)
1324                     return;
1325 
1326           /* Determine 1GB TLB info. */
1327           x86_cpuid(0x80000019, descs);
1328 
1329           cai = &ci->ci_cinfo[CAI_L1_1GBITLB];
1330           cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]);
1331           cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]);
1332           cai->cai_linesize = (1024 * 1024 * 1024);
1333           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1334               cai->cai_associativity);
1335           if (cp != NULL)
1336                     cai->cai_associativity = cp->cai_associativity;
1337           else
1338                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1339 
1340           cai = &ci->ci_cinfo[CAI_L1_1GBDTLB];
1341           cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[0]);
1342           cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[0]);
1343           cai->cai_linesize = (1024 * 1024 * 1024);
1344           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1345               cai->cai_associativity);
1346           if (cp != NULL)
1347                     cai->cai_associativity = cp->cai_associativity;
1348           else
1349                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1350 
1351           cai = &ci->ci_cinfo[CAI_L2_1GBITLB];
1352           cai->cai_totalsize =
1353               AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[1])  * (l2tlbx32 ? 32 : 1);
1354           cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[1]);
1355           cai->cai_linesize = (1024 * 1024 * 1024);
1356           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1357               cai->cai_associativity);
1358           if (cp != NULL)
1359                     cai->cai_associativity = cp->cai_associativity;
1360           else
1361                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1362 
1363           cai = &ci->ci_cinfo[CAI_L2_1GBDTLB];
1364           cai->cai_totalsize =
1365               AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]) * (l2tlbx32 ? 32 : 1);
1366           cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]);
1367           cai->cai_linesize = (1024 * 1024 * 1024);
1368           cp = cpu_cacheinfo_lookup(amd_cpuid_l2l3cache_assoc_info,
1369               cai->cai_associativity);
1370           if (cp != NULL)
1371                     cai->cai_associativity = cp->cai_associativity;
1372           else
1373                     cai->cai_associativity = 0;   /* XXX Unknown/reserved */
1374 
1375           if (lfunc < 0x8000001d)
1376                     return;
1377 
1378           if (ci->ci_feat_val[3] & CPUID_TOPOEXT)
1379                     cpu_dcp_cacheinfo(ci, 0x8000001d);
1380 }
1381 
1382 static void
via_cpu_cacheinfo(struct cpu_info * ci)1383 via_cpu_cacheinfo(struct cpu_info *ci)
1384 {
1385           struct x86_cache_info *cai;
1386           int stepping;
1387           u_int descs[4];
1388           u_int lfunc;
1389 
1390           stepping = CPUID_TO_STEPPING(ci->ci_signature);
1391 
1392           /*
1393            * Determine the largest extended function value.
1394            */
1395           x86_cpuid(0x80000000, descs);
1396           lfunc = descs[0];
1397 
1398           /*
1399            * Determine L1 cache/TLB info.
1400            */
1401           if (lfunc < 0x80000005) {
1402                     /* No L1 cache info available. */
1403                     return;
1404           }
1405 
1406           x86_cpuid(0x80000005, descs);
1407 
1408           cai = &ci->ci_cinfo[CAI_ITLB];
1409           cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]);
1410           cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]);
1411           cai->cai_linesize = (4 * 1024);
1412 
1413           cai = &ci->ci_cinfo[CAI_DTLB];
1414           cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]);
1415           cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]);
1416           cai->cai_linesize = (4 * 1024);
1417 
1418           cai = &ci->ci_cinfo[CAI_DCACHE];
1419           cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]);
1420           cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]);
1421           cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]);
1422           if (ci->ci_model == 9 && stepping == 8) {
1423                     /* Erratum: stepping 8 reports 4 when it should be 2 */
1424                     cai->cai_associativity = 2;
1425           }
1426 
1427           cai = &ci->ci_cinfo[CAI_ICACHE];
1428           cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]);
1429           cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]);
1430           cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]);
1431           if (ci->ci_model == 9 && stepping == 8) {
1432                     /* Erratum: stepping 8 reports 4 when it should be 2 */
1433                     cai->cai_associativity = 2;
1434           }
1435 
1436           /*
1437            * Determine L2 cache/TLB info.
1438            */
1439           if (lfunc < 0x80000006) {
1440                     /* No L2 cache info available. */
1441                     return;
1442           }
1443 
1444           x86_cpuid(0x80000006, descs);
1445 
1446           cai = &ci->ci_cinfo[CAI_L2CACHE];
1447           if (ci->ci_model >= 9) {
1448                     cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
1449                     cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);
1450                     cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]);
1451           } else {
1452                     cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
1453                     cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
1454                     cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
1455           }
1456 }
1457 
1458 static void
tmx86_get_longrun_status(u_int * frequency,u_int * voltage,u_int * percentage)1459 tmx86_get_longrun_status(u_int *frequency, u_int *voltage, u_int *percentage)
1460 {
1461           u_int descs[4];
1462 
1463           x86_cpuid(0x80860007, descs);
1464           *frequency = descs[0];
1465           *voltage = descs[1];
1466           *percentage = descs[2];
1467 }
1468 
1469 static void
transmeta_cpu_info(struct cpu_info * ci)1470 transmeta_cpu_info(struct cpu_info *ci)
1471 {
1472           u_int descs[4], nreg;
1473           u_int frequency, voltage, percentage;
1474 
1475           x86_cpuid(0x80860000, descs);
1476           nreg = descs[0];
1477           if (nreg >= 0x80860001) {
1478                     x86_cpuid(0x80860001, descs);
1479                     aprint_verbose_dev(ci->ci_dev, "Processor revision %u.%u.%u.%u\n",
1480                         (descs[1] >> 24) & 0xff,
1481                         (descs[1] >> 16) & 0xff,
1482                         (descs[1] >> 8) & 0xff,
1483                         descs[1] & 0xff);
1484           }
1485           if (nreg >= 0x80860002) {
1486                     x86_cpuid(0x80860002, descs);
1487                     aprint_verbose_dev(ci->ci_dev, "Code Morphing Software Rev: %u.%u.%u-%u-%u\n",
1488                         (descs[1] >> 24) & 0xff,
1489                         (descs[1] >> 16) & 0xff,
1490                         (descs[1] >> 8) & 0xff,
1491                         descs[1] & 0xff,
1492                         descs[2]);
1493           }
1494           if (nreg >= 0x80860006) {
1495                     union {
1496                               char text[65];
1497                               u_int descs[4][4];
1498                     } info;
1499                     int i;
1500 
1501                     for (i=0; i<4; i++) {
1502                               x86_cpuid(0x80860003 + i, info.descs[i]);
1503                     }
1504                     info.text[64] = '\0';
1505                     aprint_verbose_dev(ci->ci_dev, "%s\n", info.text);
1506           }
1507 
1508           if (nreg >= 0x80860007) {
1509                     tmx86_get_longrun_status(&frequency,
1510                         &voltage, &percentage);
1511                     aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n",
1512                         frequency, voltage, percentage);
1513           }
1514 }
1515 
1516 static void
cpu_probe_base_features(struct cpu_info * ci,const char * cpuname)1517 cpu_probe_base_features(struct cpu_info *ci, const char *cpuname)
1518 {
1519           u_int descs[4];
1520           int i;
1521           uint32_t brand[12];
1522 
1523           memset(ci, 0, sizeof(*ci));
1524           ci->ci_dev = cpuname;
1525 
1526           ci->ci_cpu_type = x86_identify();
1527           if (ci->ci_cpu_type >= 0) {
1528                     /* Old pre-cpuid instruction cpu */
1529                     ci->ci_max_cpuid = -1;
1530                     return;
1531           }
1532 
1533           /*
1534            * This CPU supports cpuid instruction, so we can call x86_cpuid()
1535            * function.
1536            */
1537 
1538           /*
1539            * Fn0000_0000:
1540            * - Save cpuid max level.
1541            * - Save vendor string.
1542            */
1543           x86_cpuid(0, descs);
1544           ci->ci_max_cpuid = descs[0];
1545           /* Save vendor string */
1546           ci->ci_vendor[0] = descs[1];
1547           ci->ci_vendor[2] = descs[2];
1548           ci->ci_vendor[1] = descs[3];
1549           ci->ci_vendor[3] = 0;
1550 
1551           /*
1552            * Fn8000_0000:
1553            * - Get cpuid extended function's max level.
1554            */
1555           x86_cpuid(0x80000000, descs);
1556           if (descs[0] >= 0x80000000)
1557                     ci->ci_max_ext_cpuid = descs[0];
1558           else {
1559                     /* Set lower value than 0x80000000 */
1560                     ci->ci_max_ext_cpuid = 0;
1561           }
1562 
1563           /*
1564            * Fn8000_000[2-4]:
1565            * - Save brand string.
1566            */
1567           if (ci->ci_max_ext_cpuid >= 0x80000004) {
1568                     x86_cpuid(0x80000002, brand);
1569                     x86_cpuid(0x80000003, brand + 4);
1570                     x86_cpuid(0x80000004, brand + 8);
1571                     for (i = 0; i < 48; i++)
1572                               if (((char *) brand)[i] != ' ')
1573                                         break;
1574                     memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
1575           }
1576 
1577           if (ci->ci_max_cpuid < 1)
1578                     return;
1579 
1580           /*
1581            * Fn0000_0001:
1582            * - Get CPU family, model and stepping (from eax).
1583            * - Initial local APIC ID and brand ID (from ebx)
1584            * - CPUID2 (from ecx)
1585            * - CPUID (from edx)
1586            */
1587           x86_cpuid(1, descs);
1588           ci->ci_signature = descs[0];
1589 
1590           /* Extract full family/model values */
1591           ci->ci_family = CPUID_TO_FAMILY(ci->ci_signature);
1592           ci->ci_model = CPUID_TO_MODEL(ci->ci_signature);
1593 
1594           /* Brand is low order 8 bits of ebx */
1595           ci->ci_brand_id = __SHIFTOUT(descs[1], CPUID_BRAND_INDEX);
1596           /* Initial local APIC ID */
1597           ci->ci_initapicid = __SHIFTOUT(descs[1], CPUID_LOCAL_APIC_ID);
1598 
1599           ci->ci_feat_val[1] = descs[2];
1600           ci->ci_feat_val[0] = descs[3];
1601 
1602           if (ci->ci_max_cpuid < 3)
1603                     return;
1604 
1605           /*
1606            * If the processor serial number misfeature is present and supported,
1607            * extract it here.
1608            */
1609           if ((ci->ci_feat_val[0] & CPUID_PSN) != 0) {
1610                     ci->ci_cpu_serial[0] = ci->ci_signature;
1611                     x86_cpuid(3, descs);
1612                     ci->ci_cpu_serial[2] = descs[2];
1613                     ci->ci_cpu_serial[1] = descs[3];
1614           }
1615 
1616           if (ci->ci_max_cpuid < 0x7)
1617                     return;
1618 
1619           x86_cpuid(7, descs);
1620           ci->ci_feat_val[5] = descs[1];
1621           ci->ci_feat_val[6] = descs[2];
1622           ci->ci_feat_val[7] = descs[3];
1623 
1624           if (ci->ci_max_cpuid < 0xd)
1625                     return;
1626 
1627           /* Get support XCR0 bits */
1628           x86_cpuid2(0xd, 0, descs);
1629           ci->ci_feat_val[8] = descs[0];          /* Actually 64 bits */
1630           ci->ci_cur_xsave = descs[1];
1631           ci->ci_max_xsave = descs[2];
1632 
1633           /* Additional flags (eg xsaveopt support) */
1634           x86_cpuid2(0xd, 1, descs);
1635           ci->ci_feat_val[9] = descs[0];           /* Actually 64 bits */
1636 }
1637 
1638 static void
cpu_probe_hv_features(struct cpu_info * ci,const char * cpuname)1639 cpu_probe_hv_features(struct cpu_info *ci, const char *cpuname)
1640 {
1641           uint32_t descs[4];
1642           char hv_sig[13];
1643           char *p;
1644           const char *hv_name;
1645           int i;
1646 
1647           /*
1648            * [RFC] CPUID usage for interaction between Hypervisors and Linux.
1649            * http://lkml.org/lkml/2008/10/1/246
1650            *
1651            * KB1009458: Mechanisms to determine if software is running in
1652            * a VMware virtual machine
1653            * http://kb.vmware.com/kb/1009458
1654            */
1655           if ((ci->ci_feat_val[1] & CPUID2_RAZ) != 0) {
1656                     x86_cpuid(0x40000000, descs);
1657                     for (i = 1, p = hv_sig; i < 4; i++, p += sizeof(descs) / 4)
1658                               memcpy(p, &descs[i], sizeof(descs[i]));
1659                     *p = '\0';
1660                     /*
1661                      * HV vendor        ID string
1662                      * ------------+--------------
1663                      * HAXM             "HAXMHAXMHAXM"
1664                      * KVM              "KVMKVMKVM"
1665                      * Microsoft        "Microsoft Hv"
1666                      * QEMU(TCG)        "TCGTCGTCGTCG"
1667                      * VMware "VMwareVMware"
1668                      * Xen              "XenVMMXenVMM"
1669                      * NetBSD "___ NVMM ___"
1670                      */
1671                     if (strncmp(hv_sig, "HAXMHAXMHAXM", 12) == 0)
1672                               hv_name = "HAXM";
1673                     else if (strncmp(hv_sig, "KVMKVMKVM", 9) == 0)
1674                               hv_name = "KVM";
1675                     else if (strncmp(hv_sig, "Microsoft Hv", 12) == 0)
1676                               hv_name = "Hyper-V";
1677                     else if (strncmp(hv_sig, "TCGTCGTCGTCG", 12) == 0)
1678                               hv_name = "QEMU(TCG)";
1679                     else if (strncmp(hv_sig, "VMwareVMware", 12) == 0)
1680                               hv_name = "VMware";
1681                     else if (strncmp(hv_sig, "XenVMMXenVMM", 12) == 0)
1682                               hv_name = "Xen";
1683                     else if (strncmp(hv_sig, "___ NVMM ___", 12) == 0)
1684                               hv_name = "NVMM";
1685                     else
1686                               hv_name = "unknown";
1687 
1688                     printf("%s: Running on hypervisor: %s\n", cpuname, hv_name);
1689           }
1690 }
1691 
1692 static void
cpu_probe_features(struct cpu_info * ci)1693 cpu_probe_features(struct cpu_info *ci)
1694 {
1695           const struct cpu_cpuid_nameclass *cpup = NULL;
1696           unsigned int i;
1697 
1698           if (ci->ci_max_cpuid < 1)
1699                     return;
1700 
1701           for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) {
1702                     if (!strncmp((char *)ci->ci_vendor,
1703                         i386_cpuid_cpus[i].cpu_id, 12)) {
1704                               cpup = &i386_cpuid_cpus[i];
1705                               break;
1706                     }
1707           }
1708 
1709           if (cpup == NULL)
1710                     return;
1711 
1712           i = ci->ci_family - CPU_MINFAMILY;
1713 
1714           if (i >= __arraycount(cpup->cpu_family))
1715                     i = __arraycount(cpup->cpu_family) - 1;
1716 
1717           if (cpup->cpu_family[i].cpu_probe == NULL)
1718                     return;
1719 
1720           (*cpup->cpu_family[i].cpu_probe)(ci);
1721 }
1722 
1723 static void
print_bits(const char * cpuname,const char * hdr,const char * fmt,uint32_t val)1724 print_bits(const char *cpuname, const char *hdr, const char *fmt, uint32_t val)
1725 {
1726           char buf[32 * 16];
1727           char *bp;
1728 
1729 #define   MAX_LINE_LEN        79        /* get from command arg or 'stty cols' ? */
1730 
1731           if (val == 0 || fmt == NULL)
1732                     return;
1733 
1734           snprintb_m(buf, sizeof(buf), fmt, val,
1735               MAX_LINE_LEN - strlen(cpuname) - 2 - strlen(hdr) - 1);
1736           bp = buf;
1737           while (*bp != '\0') {
1738                     aprint_verbose("%s: %s %s\n", cpuname, hdr, bp);
1739                     bp += strlen(bp) + 1;
1740           }
1741 }
1742 #ifdef lint
1743 #define print_bits(cpuname, hdr, fmt, val) \
1744           do {      \
1745                     print_bits(cpuname, hdr, fmt, val); \
1746                     snprintb(NULL, 0, fmt, val); \
1747           } while (0)
1748 #endif
1749 
1750 static void
dump_descs(uint32_t leafstart,uint32_t leafend,const char * cpuname,const char * blockname)1751 dump_descs(uint32_t leafstart, uint32_t leafend, const char *cpuname,
1752     const char *blockname)
1753 {
1754           uint32_t descs[4];
1755           uint32_t leaf;
1756 
1757           aprint_verbose("%s: highest %s info %08x\n", cpuname, blockname,
1758               leafend);
1759 
1760           if (verbose) {
1761                     for (leaf = leafstart; leaf <= leafend; leaf++) {
1762                               x86_cpuid(leaf, descs);
1763                               printf("%s: %08x: %08x %08x %08x %08x\n", cpuname,
1764                                   leaf, descs[0], descs[1], descs[2], descs[3]);
1765                     }
1766           }
1767 }
1768 
1769 static void
identifycpu_cpuids_intel_0x04(struct cpu_info * ci)1770 identifycpu_cpuids_intel_0x04(struct cpu_info *ci)
1771 {
1772           u_int lp_max = 1;   /* logical processors per package */
1773           u_int smt_max;                /* smt per core */
1774           u_int core_max = 1; /* core per package */
1775           u_int smt_bits, core_bits;
1776           uint32_t descs[4];
1777 
1778           /*
1779            * 253668.pdf 7.10.2
1780            */
1781 
1782           if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
1783                     x86_cpuid(1, descs);
1784                     lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES);
1785           }
1786           x86_cpuid2(4, 0, descs);
1787           core_max = __SHIFTOUT(descs[0], CPUID_DCP_CORE_P_PKG) + 1;
1788 
1789           assert(lp_max >= core_max);
1790           smt_max = lp_max / core_max;
1791           smt_bits = ilog2(smt_max - 1) + 1;
1792           core_bits = ilog2(core_max - 1) + 1;
1793 
1794           if (smt_bits + core_bits)
1795                     ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits);
1796 
1797           if (core_bits)
1798                     ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid,
1799                         __BITS(smt_bits, smt_bits + core_bits - 1));
1800 
1801           if (smt_bits)
1802                     ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid,
1803                         __BITS((int)0, (int)(smt_bits - 1)));
1804 }
1805 
1806 static void
identifycpu_cpuids_intel_0x0b(struct cpu_info * ci)1807 identifycpu_cpuids_intel_0x0b(struct cpu_info *ci)
1808 {
1809           const char *cpuname = ci->ci_dev;
1810           u_int smt_bits, core_bits, core_shift = 0, pkg_shift = 0;
1811           uint32_t descs[4];
1812           int i;
1813 
1814           x86_cpuid(0x0b, descs);
1815           if (descs[1] == 0) {
1816                     identifycpu_cpuids_intel_0x04(ci);
1817                     return;
1818           }
1819 
1820           for (i = 0; ; i++) {
1821                     unsigned int shiftnum, lvltype;
1822                     x86_cpuid2(0x0b, i, descs);
1823 
1824                     /* On invalid level, (EAX and) EBX return 0 */
1825                     if (descs[1] == 0)
1826                               break;
1827 
1828                     shiftnum = __SHIFTOUT(descs[0], CPUID_TOP_SHIFTNUM);
1829                     lvltype = __SHIFTOUT(descs[2], CPUID_TOP_LVLTYPE);
1830                     switch (lvltype) {
1831                     case CPUID_TOP_LVLTYPE_SMT:
1832                               core_shift = shiftnum;
1833                               break;
1834                     case CPUID_TOP_LVLTYPE_CORE:
1835                               pkg_shift = shiftnum;
1836                               break;
1837                     case CPUID_TOP_LVLTYPE_INVAL:
1838                               aprint_verbose("%s: Invalid level type\n", cpuname);
1839                               break;
1840                     default:
1841                               aprint_verbose("%s: Unknown level type(%d) \n",
1842                                   cpuname, lvltype);
1843                               break;
1844                     }
1845           }
1846 
1847           assert(pkg_shift >= core_shift);
1848           smt_bits = core_shift;
1849           core_bits = pkg_shift - core_shift;
1850 
1851           ci->ci_packageid = ci->ci_initapicid >> pkg_shift;
1852 
1853           if (core_bits)
1854                     ci->ci_coreid = __SHIFTOUT(ci->ci_initapicid,
1855                         __BITS(core_shift, pkg_shift - 1));
1856 
1857           if (smt_bits)
1858                     ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid,
1859                         __BITS((int)0, core_shift - 1));
1860 }
1861 
1862 static void
identifycpu_cpuids_intel(struct cpu_info * ci)1863 identifycpu_cpuids_intel(struct cpu_info *ci)
1864 {
1865           const char *cpuname = ci->ci_dev;
1866 
1867           if (ci->ci_max_cpuid >= 0x0b)
1868                     identifycpu_cpuids_intel_0x0b(ci);
1869           else if (ci->ci_max_cpuid >= 4)
1870                     identifycpu_cpuids_intel_0x04(ci);
1871 
1872           aprint_verbose("%s: Cluster/Package ID %u\n", cpuname,
1873               ci->ci_packageid);
1874           aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid);
1875           aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid);
1876 }
1877 
1878 static void
identifycpu_cpuids_amd(struct cpu_info * ci)1879 identifycpu_cpuids_amd(struct cpu_info *ci)
1880 {
1881           const char *cpuname = ci->ci_dev;
1882           u_int lp_max, core_max;
1883           int n, cpu_family, apic_id, smt_bits, core_bits = 0;
1884           uint32_t descs[4];
1885 
1886           apic_id = ci->ci_initapicid;
1887           cpu_family = CPUID_TO_FAMILY(ci->ci_signature);
1888 
1889           if (cpu_family < 0xf)
1890                     return;
1891 
1892           if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
1893                     x86_cpuid(1, descs);
1894                     lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES);
1895 
1896                     if (cpu_family >= 0x10 && ci->ci_max_ext_cpuid >= 0x8000008) {
1897                               x86_cpuid(0x8000008, descs);
1898                               core_max = (descs[2] & 0xff) + 1;
1899                               n = (descs[2] >> 12) & 0x0f;
1900                               if (n != 0)
1901                                         core_bits = n;
1902                     }
1903           } else {
1904                     lp_max = 1;
1905           }
1906           core_max = lp_max;
1907 
1908           smt_bits = ilog2((lp_max / core_max) - 1) + 1;
1909           if (core_bits == 0)
1910                     core_bits = ilog2(core_max - 1) + 1;
1911 
1912 #if 0 /* MSRs need kernel mode */
1913           if (cpu_family < 0x11) {
1914                     const uint64_t reg = rdmsr(MSR_NB_CFG);
1915                     if ((reg & NB_CFG_INITAPICCPUIDLO) == 0) {
1916                               const u_int node_id = apic_id & __BITS(0, 2);
1917                               apic_id = (cpu_family == 0xf) ?
1918                                         (apic_id >> core_bits) | (node_id << core_bits) :
1919                                         (apic_id >> 5) | (node_id << 2);
1920                     }
1921           }
1922 #endif
1923 
1924           if (cpu_family >= 0x17) {
1925                     x86_cpuid(0x8000001e, descs);
1926                     const u_int threads = ((descs[1] >> 8) & 0xff) + 1;
1927                     smt_bits = ilog2(threads);
1928                     core_bits -= smt_bits;
1929           }
1930 
1931           if (smt_bits + core_bits) {
1932                     if (smt_bits + core_bits < 32)
1933                               ci->ci_packageid = 0;
1934           }
1935           if (core_bits) {
1936                     u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1);
1937                     ci->ci_coreid = __SHIFTOUT(apic_id, core_mask);
1938           }
1939           if (smt_bits) {
1940                     u_int smt_mask = __BITS(0, smt_bits - 1);
1941                     ci->ci_smtid = __SHIFTOUT(apic_id, smt_mask);
1942           }
1943 
1944           aprint_verbose("%s: Cluster/Package ID %u\n", cpuname,
1945               ci->ci_packageid);
1946           aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid);
1947           aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid);
1948 }
1949 
1950 static void
identifycpu_cpuids(struct cpu_info * ci)1951 identifycpu_cpuids(struct cpu_info *ci)
1952 {
1953           const char *cpuname = ci->ci_dev;
1954 
1955           aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid);
1956           ci->ci_packageid = ci->ci_initapicid;
1957           ci->ci_coreid = 0;
1958           ci->ci_smtid = 0;
1959 
1960           if (cpu_vendor == CPUVENDOR_INTEL)
1961                     identifycpu_cpuids_intel(ci);
1962           else if (cpu_vendor == CPUVENDOR_AMD)
1963                     identifycpu_cpuids_amd(ci);
1964 }
1965 
1966 void
identifycpu(int fd,const char * cpuname)1967 identifycpu(int fd, const char *cpuname)
1968 {
1969           const char *name = "", *modifier, *vendorname, *brand = "";
1970           int class = CPUCLASS_386;
1971           unsigned int i;
1972           int modif, family;
1973           const struct cpu_cpuid_nameclass *cpup = NULL;
1974           const struct cpu_cpuid_family *cpufam;
1975           struct cpu_info *ci, cistore;
1976           u_int descs[4];
1977           size_t sz;
1978           struct cpu_ucode_version ucode;
1979           union {
1980                     struct cpu_ucode_version_amd amd;
1981                     struct cpu_ucode_version_intel1 intel1;
1982           } ucvers;
1983 
1984           ci = &cistore;
1985           cpu_probe_base_features(ci, cpuname);
1986           dump_descs(0x00000000, ci->ci_max_cpuid, cpuname, "basic");
1987           if ((ci->ci_feat_val[1] & CPUID2_RAZ) != 0) {
1988                     x86_cpuid(0x40000000, descs);
1989                     dump_descs(0x40000000, descs[0], cpuname, "hypervisor");
1990           }
1991           dump_descs(0x80000000, ci->ci_max_ext_cpuid, cpuname, "extended");
1992 
1993           cpu_probe_hv_features(ci, cpuname);
1994           cpu_probe_features(ci);
1995 
1996           if (ci->ci_cpu_type >= 0) {
1997                     /* Old pre-cpuid instruction cpu */
1998                     if (ci->ci_cpu_type >= (int)__arraycount(i386_nocpuid_cpus))
1999                               errx(1, "unknown cpu type %d", ci->ci_cpu_type);
2000                     name = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_name;
2001                     cpu_vendor = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendor;
2002                     vendorname = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendorname;
2003                     class = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_class;
2004                     ci->ci_info = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_info;
2005                     modifier = "";
2006           } else {
2007                     /* CPU which support cpuid instruction */
2008                     modif = (ci->ci_signature >> 12) & 0x3;
2009                     family = ci->ci_family;
2010                     if (family < CPU_MINFAMILY)
2011                               errx(1, "identifycpu: strange family value");
2012                     if (family > CPU_MAXFAMILY)
2013                               family = CPU_MAXFAMILY;
2014 
2015                     for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) {
2016                               if (!strncmp((char *)ci->ci_vendor,
2017                                   i386_cpuid_cpus[i].cpu_id, 12)) {
2018                                         cpup = &i386_cpuid_cpus[i];
2019                                         break;
2020                               }
2021                     }
2022 
2023                     if (cpup == NULL) {
2024                               cpu_vendor = CPUVENDOR_UNKNOWN;
2025                               if (ci->ci_vendor[0] != '\0')
2026                                         vendorname = (char *)&ci->ci_vendor[0];
2027                               else
2028                                         vendorname = "Unknown";
2029                               class = family - 3;
2030                               modifier = "";
2031                               name = "";
2032                               ci->ci_info = NULL;
2033                     } else {
2034                               cpu_vendor = cpup->cpu_vendor;
2035                               vendorname = cpup->cpu_vendorname;
2036                               modifier = modifiers[modif];
2037                               cpufam = &cpup->cpu_family[family - CPU_MINFAMILY];
2038                               name = cpufam->cpu_models[ci->ci_model];
2039                               if (name == NULL || *name == '\0')
2040                                         name = cpufam->cpu_model_default;
2041                               class = cpufam->cpu_class;
2042                               ci->ci_info = cpufam->cpu_info;
2043 
2044                               if (cpu_vendor == CPUVENDOR_INTEL) {
2045                                         if (ci->ci_family == 6 && ci->ci_model >= 5) {
2046                                                   const char *tmp;
2047                                                   tmp = intel_family6_name(ci);
2048                                                   if (tmp != NULL)
2049                                                             name = tmp;
2050                                         }
2051                                         if (ci->ci_family == 15 &&
2052                                             ci->ci_brand_id <
2053                                             __arraycount(i386_intel_brand) &&
2054                                             i386_intel_brand[ci->ci_brand_id])
2055                                                   name =
2056                                                       i386_intel_brand[ci->ci_brand_id];
2057                               }
2058 
2059                               if (cpu_vendor == CPUVENDOR_AMD) {
2060                                         if (ci->ci_family == 6 && ci->ci_model >= 6) {
2061                                                   if (ci->ci_brand_id == 1)
2062                                                             /*
2063                                                              * It's Duron. We override the
2064                                                              * name, since it might have
2065                                                              * been misidentified as Athlon.
2066                                                              */
2067                                                             name =
2068                                                                 amd_brand[ci->ci_brand_id];
2069                                                   else
2070                                                             brand = amd_brand_name;
2071                                         }
2072                                         if (CPUID_TO_BASEFAMILY(ci->ci_signature)
2073                                             == 0xf) {
2074                                                   /* Identify AMD64 CPU names.  */
2075                                                   const char *tmp;
2076                                                   tmp = amd_amd64_name(ci);
2077                                                   if (tmp != NULL)
2078                                                             name = tmp;
2079                                         }
2080                               }
2081 
2082                               if (cpu_vendor == CPUVENDOR_IDT && ci->ci_family >= 6)
2083                                         vendorname = "VIA";
2084                     }
2085           }
2086 
2087           ci->ci_cpu_class = class;
2088 
2089           sz = sizeof(ci->ci_tsc_freq);
2090           (void)sysctlbyname("machdep.tsc_freq", &ci->ci_tsc_freq, &sz, NULL, 0);
2091           sz = sizeof(use_pae);
2092           (void)sysctlbyname("machdep.pae", &use_pae, &sz, NULL, 0);
2093           largepagesize = (use_pae ? 2 * 1024 * 1024 : 4 * 1024 * 1024);
2094 
2095           /*
2096            * The 'cpu_brand_string' is much more useful than the 'cpu_model'
2097            * we try to determine from the family/model values.
2098            */
2099           if (*cpu_brand_string != '\0')
2100                     aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string);
2101 
2102           aprint_normal("%s: %s", cpuname, vendorname);
2103           if (*modifier)
2104                     aprint_normal(" %s", modifier);
2105           if (*name)
2106                     aprint_normal(" %s", name);
2107           if (*brand)
2108                     aprint_normal(" %s", brand);
2109           aprint_normal(" (%s-class)", classnames[class]);
2110 
2111           if (ci->ci_tsc_freq != 0)
2112                     aprint_normal(", %ju.%02ju MHz",
2113                         ((uintmax_t)ci->ci_tsc_freq + 4999) / 1000000,
2114                         (((uintmax_t)ci->ci_tsc_freq + 4999) / 10000) % 100);
2115           aprint_normal("\n");
2116 
2117           (void)cpu_tsc_freq_cpuid(ci);
2118 
2119           aprint_normal_dev(ci->ci_dev, "family %#x model %#x stepping %#x",
2120               ci->ci_family, ci->ci_model, CPUID_TO_STEPPING(ci->ci_signature));
2121           if (ci->ci_signature != 0)
2122                     aprint_normal(" (id %#x)", ci->ci_signature);
2123           aprint_normal("\n");
2124 
2125           if (ci->ci_info)
2126                     (*ci->ci_info)(ci);
2127 
2128           /*
2129            * display CPU feature flags
2130            */
2131 
2132           print_bits(cpuname, "features", CPUID_FLAGS1, ci->ci_feat_val[0]);
2133           print_bits(cpuname, "features1", CPUID2_FLAGS1, ci->ci_feat_val[1]);
2134 
2135           /* These next two are actually common definitions! */
2136           print_bits(cpuname, "features2",
2137               cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_EXT_FLAGS
2138                     : CPUID_EXT_FLAGS, ci->ci_feat_val[2]);
2139           print_bits(cpuname, "features3",
2140               cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_FLAGS4
2141                     : CPUID_AMD_FLAGS4, ci->ci_feat_val[3]);
2142 
2143           print_bits(cpuname, "padloack features", CPUID_FLAGS_PADLOCK,
2144               ci->ci_feat_val[4]);
2145           if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD))
2146                     print_bits(cpuname, "features5", CPUID_SEF_FLAGS,
2147                         ci->ci_feat_val[5]);
2148           if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD))
2149                     print_bits(cpuname, "features6", CPUID_SEF_FLAGS1,
2150                         ci->ci_feat_val[6]);
2151 
2152           if (cpu_vendor == CPUVENDOR_INTEL)
2153                     print_bits(cpuname, "features7", CPUID_SEF_FLAGS2,
2154                         ci->ci_feat_val[7]);
2155 
2156           print_bits(cpuname, "xsave features", XCR0_FLAGS1, ci->ci_feat_val[8]);
2157           print_bits(cpuname, "xsave instructions", CPUID_PES1_FLAGS,
2158               ci->ci_feat_val[9]);
2159 
2160           if (ci->ci_max_xsave != 0) {
2161                     aprint_normal("%s: xsave area size: current %d, maximum %d",
2162                         cpuname, ci->ci_cur_xsave, ci->ci_max_xsave);
2163                     aprint_normal(", xgetbv %sabled\n",
2164                         ci->ci_feat_val[1] & CPUID2_OSXSAVE ? "en" : "dis");
2165                     if (ci->ci_feat_val[1] & CPUID2_OSXSAVE)
2166                               print_bits(cpuname, "enabled xsave", XCR0_FLAGS1,
2167                                   x86_xgetbv());
2168           }
2169 
2170           x86_print_cache_and_tlb_info(ci);
2171 
2172           if (ci->ci_max_cpuid >= 3 && (ci->ci_feat_val[0] & CPUID_PSN)) {
2173                     aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n",
2174                         cpuname,
2175                         ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536,
2176                         ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536,
2177                         ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536);
2178           }
2179 
2180           if (ci->ci_cpu_class == CPUCLASS_386)
2181                     errx(1, "NetBSD requires an 80486 or later processor");
2182 
2183           if (ci->ci_cpu_type == CPU_486DLC) {
2184 #ifndef CYRIX_CACHE_WORKS
2185                     aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n");
2186 #else
2187 #ifndef CYRIX_CACHE_REALLY_WORKS
2188                     aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n");
2189 #else
2190                     aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED.\n");
2191 #endif
2192 #endif
2193           }
2194 
2195           /*
2196            * Everything past this point requires a Pentium or later.
2197            */
2198           if (ci->ci_max_cpuid < 0)
2199                     return;
2200 
2201           identifycpu_cpuids(ci);
2202 
2203           if ((ci->ci_max_cpuid >= 5)
2204               && ((cpu_vendor == CPUVENDOR_INTEL)
2205                     || (cpu_vendor == CPUVENDOR_AMD))) {
2206                     uint16_t lmin, lmax;
2207                     x86_cpuid(5, descs);
2208 
2209                     print_bits(cpuname, "MONITOR/MWAIT extensions",
2210                         CPUID_MON_FLAGS, descs[2]);
2211                     lmin = __SHIFTOUT(descs[0], CPUID_MON_MINSIZE);
2212                     lmax = __SHIFTOUT(descs[1], CPUID_MON_MAXSIZE);
2213                     aprint_normal("%s: monitor-line size %hu", cpuname, lmin);
2214                     if (lmin != lmax)
2215                               aprint_normal("-%hu", lmax);
2216                     aprint_normal("\n");
2217 
2218                     for (i = 0; i <= 7; i++) {
2219                               unsigned int num = CPUID_MON_SUBSTATE(descs[3], i);
2220 
2221                               if (num != 0)
2222                                         aprint_normal("%s: C%u substates %u\n",
2223                                             cpuname, i, num);
2224                     }
2225           }
2226           if ((ci->ci_max_cpuid >= 6)
2227               && ((cpu_vendor == CPUVENDOR_INTEL)
2228                     || (cpu_vendor == CPUVENDOR_AMD))) {
2229                     x86_cpuid(6, descs);
2230                     print_bits(cpuname, "DSPM-eax", CPUID_DSPM_FLAGS, descs[0]);
2231                     print_bits(cpuname, "DSPM-ecx", CPUID_DSPM_FLAGS1, descs[2]);
2232           }
2233           if ((ci->ci_max_cpuid >= 7)
2234               && ((cpu_vendor == CPUVENDOR_INTEL)
2235                     || (cpu_vendor == CPUVENDOR_AMD))) {
2236                     unsigned int maxsubleaf;
2237 
2238                     x86_cpuid(7, descs);
2239                     maxsubleaf = descs[0];
2240                     aprint_verbose("%s: SEF highest subleaf %08x\n",
2241                         cpuname, maxsubleaf);
2242                     if (maxsubleaf >= 1) {
2243                               x86_cpuid2(7, 1, descs);
2244                               print_bits(cpuname, "SEF-subleaf1-eax",
2245                                   CPUID_SEF1_FLAGS_A, descs[0]);
2246                               print_bits(cpuname, "SEF-subleaf1-ebx",
2247                                   CPUID_SEF1_FLAGS_B, descs[1]);
2248                               print_bits(cpuname, "SEF-subleaf1-edx",
2249                                   CPUID_SEF1_FLAGS_D, descs[3]);
2250                     }
2251                     if (maxsubleaf >= 2) {
2252                               x86_cpuid2(7, 2, descs);
2253                               print_bits(cpuname, "SEF-subleaf2-edx",
2254                                   CPUID_SEF2_FLAGS_D, descs[3]);
2255                     }
2256           }
2257 
2258           if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD)) {
2259                     if (ci->ci_max_ext_cpuid >= 0x80000007)
2260                               powernow_probe(ci);
2261 
2262                     if (ci->ci_max_ext_cpuid >= 0x80000008) {
2263                               x86_cpuid(0x80000008, descs);
2264                               print_bits(cpuname, "AMD Extended features",
2265                                   CPUID_CAPEX_FLAGS, descs[1]);
2266                     }
2267           }
2268 
2269           if (cpu_vendor == CPUVENDOR_AMD) {
2270                     if (ci->ci_max_ext_cpuid >= 0x80000021) {
2271                               x86_cpuid(0x80000021, descs);
2272                               print_bits(cpuname, "AMD Extended features2",
2273                                   CPUID_AMDEXT2_FLAGS, descs[0]);
2274                     }
2275 
2276                     if (ci->ci_max_ext_cpuid >= 0x80000007) {
2277                               x86_cpuid(0x80000007, descs);
2278                               print_bits(cpuname, "RAS features",
2279                                   CPUID_RAS_FLAGS, descs[1]);
2280                     }
2281                     if ((ci->ci_max_ext_cpuid >= 0x8000000a)
2282                         && (ci->ci_feat_val[3] & CPUID_SVM) != 0) {
2283                               x86_cpuid(0x8000000a, descs);
2284                               aprint_verbose("%s: SVM Rev. %d\n", cpuname,
2285                                   descs[0] & 0xf);
2286                               aprint_verbose("%s: SVM NASID %d\n", cpuname,
2287                                   descs[1]);
2288                               print_bits(cpuname, "SVM features",
2289                                   CPUID_AMD_SVM_FLAGS, descs[3]);
2290                     }
2291                     if (ci->ci_max_ext_cpuid >= 0x8000001b) {
2292                               x86_cpuid(0x8000001b, descs);
2293                               print_bits(cpuname, "IBS features",
2294                                   CPUID_IBS_FLAGS, descs[0]);
2295                     }
2296                     if (ci->ci_max_ext_cpuid >= 0x8000001f) {
2297                               x86_cpuid(0x8000001f, descs);
2298                               print_bits(cpuname, "Encrypted Memory features",
2299                                   CPUID_AMD_ENCMEM_FLAGS, descs[0]);
2300                     }
2301                     if (ci->ci_max_ext_cpuid >= 0x80000022) {
2302                               uint8_t ncore, nnb, numc, nlbrs;
2303 
2304                               x86_cpuid(0x80000022, descs);
2305                               print_bits(cpuname, "Perfmon:",
2306                                   CPUID_AXPERF_FLAGS, descs[0]);
2307 
2308                               ncore = __SHIFTOUT(descs[1], CPUID_AXPERF_NCPC);
2309                               nnb = __SHIFTOUT(descs[1], CPUID_AXPERF_NNBPC);
2310                               numc = __SHIFTOUT(descs[1], CPUID_AXPERF_NUMCPC);
2311                               nlbrs = __SHIFTOUT(descs[1], CPUID_AXPERF_NLBRSTACK);
2312                               aprint_verbose("%s: Perfmon: counters: "
2313                                   "Core %hhu, Northbridge %hhu, UMC %hhu\n", cpuname,
2314                                   ncore, nnb, numc);
2315                               aprint_verbose("%s: Perfmon: LBR Stack %hhu entries\n",
2316                                   cpuname, nlbrs);
2317                     }
2318                     if (ci->ci_max_ext_cpuid >= 0x80000027) {
2319                               uint8_t classes;
2320 
2321                               x86_cpuid(0x80000027, descs);
2322                               classes = __SHIFTOUT(descs[0], CPUID_HWC_NWC);
2323                               aprint_verbose("%s: Hetero workload class: "
2324                                   "%hhu classes\n", cpuname, classes);
2325                     }
2326           } else if (cpu_vendor == CPUVENDOR_INTEL) {
2327                     if (ci->ci_max_cpuid >= 0x0a) {
2328                               unsigned int pmcver, ncounter, veclen;
2329 
2330                               x86_cpuid(0x0a, descs);
2331                               pmcver = __SHIFTOUT(descs[0], CPUID_PERF_VERSION);
2332                               ncounter = __SHIFTOUT(descs[0], CPUID_PERF_NGPPC);
2333                               veclen = __SHIFTOUT(descs[0], CPUID_PERF_BVECLEN);
2334                               aprint_verbose("%s: Perfmon: Ver. %u",
2335                                   cpuname, pmcver);
2336                               if (((pmcver >= 3) && (pmcver <= 4)) ||
2337                                   ((pmcver >= 5) &&
2338                                         (descs[3] & CPUID_PERF_ANYTHREADDEPR) == 0))
2339                                         aprint_verbose(" <ANYTHREAD>\n");
2340                               else
2341                                         aprint_verbose("\n");
2342 
2343                               aprint_verbose("%s: Perfmon: General: "
2344                                   "bitwidth %u, %u counters\n", cpuname,
2345                                   (uint32_t)__SHIFTOUT(descs[0], CPUID_PERF_NBWGPPC),
2346                                   ncounter);
2347                               /* Invert logic for the output */
2348                               descs[1] ^= __BITS(veclen - 1, 0);
2349                               /*
2350                                * Mask unrelated bits. An hypervisor reduces the
2351                                * vector and set bit(s) out of the vector.
2352                                */
2353                               descs[1] &= __BITS(veclen - 1, 0);
2354                               print_bits(cpuname, "Perfmon: General: avail",
2355                                   CPUID_PERF_FLAGS1, descs[1]);
2356 
2357                               if (pmcver >= 2) {
2358                                         ncounter = __SHIFTOUT(descs[3],
2359                                             CPUID_PERF_NFFPC);
2360                                         aprint_verbose("%s: Perfmon: Fixed: "
2361                                             "bitwidth %u, %u counters\n", cpuname,
2362                                             (uint32_t)__SHIFTOUT(descs[3],
2363                                                   CPUID_PERF_NBWFFPC),
2364                                             ncounter);
2365                                         if (pmcver <= 4)
2366                                                   descs[2] = __BITS(ncounter - 1, 0);
2367                                         print_bits(cpuname, "Perfmon: Fixed: avail",
2368                                             CPUID_PERF_FLAGS2, descs[2]);
2369                               }
2370                     }
2371                     if (ci->ci_max_cpuid >= 0x1a) {
2372                               x86_cpuid(0x1a, descs);
2373                               if (descs[0] != 0) {
2374                                         aprint_verbose("%s: Hybrid: Core type %02x, "
2375                                             "Native Model ID %07x\n",
2376                                             cpuname,
2377                                             (uint8_t)__SHIFTOUT(descs[0],
2378                                                   CPUID_HYBRID_CORETYPE),
2379                                             (uint32_t)__SHIFTOUT(descs[0],
2380                                                   CPUID_HYBRID_NATIVEID));
2381                               }
2382                     }
2383           }
2384 
2385 #ifdef INTEL_ONDEMAND_CLOCKMOD
2386           clockmod_init();
2387 #endif
2388 
2389           if (cpu_vendor == CPUVENDOR_AMD)
2390                     ucode.loader_version = CPU_UCODE_LOADER_AMD;
2391           else if (cpu_vendor == CPUVENDOR_INTEL)
2392                     ucode.loader_version = CPU_UCODE_LOADER_INTEL1;
2393           else
2394                     return;
2395 
2396           ucode.data = &ucvers;
2397           if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &ucode) < 0) {
2398 #ifdef __i386__
2399                     struct cpu_ucode_version_64 ucode_64;
2400                     if (errno != ENOTTY)
2401                               return;
2402                     /* Try the 64 bit ioctl */
2403                     memset(&ucode_64, 0, sizeof ucode_64);
2404                     ucode_64.data = &ucvers;
2405                     ucode_64.loader_version = ucode.loader_version;
2406                     if (ioctl(fd, IOC_CPU_UCODE_GET_VERSION_64, &ucode_64) < 0)
2407                               return;
2408 #else
2409                     return;
2410 #endif
2411           }
2412 
2413           if (cpu_vendor == CPUVENDOR_AMD)
2414                     printf("%s: UCode version: 0x%"PRIx64"\n", cpuname, ucvers.amd.version);
2415           else if (cpu_vendor == CPUVENDOR_INTEL)
2416                     printf("%s: microcode version 0x%x, platform ID %d\n", cpuname,
2417                         ucvers.intel1.ucodeversion, ucvers.intel1.platformid);
2418 }
2419 
2420 static const char *
print_cache_config(struct cpu_info * ci,int cache_tag,const char * name,const char * sep)2421 print_cache_config(struct cpu_info *ci, int cache_tag, const char *name,
2422     const char *sep)
2423 {
2424           struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
2425           char human_num[HUMAN_BUFSIZE];
2426 
2427           if (cai->cai_totalsize == 0)
2428                     return sep;
2429 
2430           if (sep == NULL)
2431                     aprint_verbose_dev(ci->ci_dev, "");
2432           else
2433                     aprint_verbose("%s", sep);
2434           if (name != NULL)
2435                     aprint_verbose("%s ", name);
2436 
2437           if (cai->cai_string != NULL) {
2438                     aprint_verbose("%s ", cai->cai_string);
2439           } else {
2440                     (void)humanize_number(human_num, sizeof(human_num),
2441                         cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE);
2442                     aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize);
2443           }
2444           switch (cai->cai_associativity) {
2445           case      0:
2446                     aprint_verbose("disabled");
2447                     break;
2448           case      1:
2449                     aprint_verbose("direct-mapped");
2450                     break;
2451           case 0xff:
2452                     aprint_verbose("fully associative");
2453                     break;
2454           default:
2455                     aprint_verbose("%d-way", cai->cai_associativity);
2456                     break;
2457           }
2458           return ", ";
2459 }
2460 
2461 static const char *
print_tlb_config(struct cpu_info * ci,int cache_tag,const char * name,const char * sep)2462 print_tlb_config(struct cpu_info *ci, int cache_tag, const char *name,
2463     const char *sep)
2464 {
2465           struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
2466           char human_num[HUMAN_BUFSIZE];
2467 
2468           if (cai->cai_totalsize == 0)
2469                     return sep;
2470 
2471           if (sep == NULL)
2472                     aprint_verbose_dev(ci->ci_dev, "");
2473           else
2474                     aprint_verbose("%s", sep);
2475           if ((name != NULL) && (sep == NULL))
2476                     aprint_verbose("%s ", name);
2477 
2478           if (cai->cai_string != NULL) {
2479                     aprint_verbose("%s", cai->cai_string);
2480           } else {
2481                     (void)humanize_number(human_num, sizeof(human_num),
2482                         cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE);
2483                     aprint_verbose("%d %s entries ", cai->cai_totalsize,
2484                         human_num);
2485                     switch (cai->cai_associativity) {
2486                     case 0:
2487                               aprint_verbose("disabled");
2488                               break;
2489                     case 1:
2490                               aprint_verbose("direct-mapped");
2491                               break;
2492                     case 0xff:
2493                               aprint_verbose("fully associative");
2494                               break;
2495                     default:
2496                               aprint_verbose("%d-way", cai->cai_associativity);
2497                               break;
2498                     }
2499           }
2500           return ", ";
2501 }
2502 
2503 static void
x86_print_cache_and_tlb_info(struct cpu_info * ci)2504 x86_print_cache_and_tlb_info(struct cpu_info *ci)
2505 {
2506           const char *sep = NULL;
2507 
2508           if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 ||
2509               ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) {
2510                     sep = print_cache_config(ci, CAI_ICACHE, "I-cache:", NULL);
2511                     sep = print_cache_config(ci, CAI_DCACHE, "D-cache:", sep);
2512                     if (sep != NULL)
2513                               aprint_verbose("\n");
2514           }
2515           if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize != 0) {
2516                     sep = print_cache_config(ci, CAI_L2CACHE, "L2 cache:", NULL);
2517                     if (sep != NULL)
2518                               aprint_verbose("\n");
2519           }
2520           if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) {
2521                     sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache:", NULL);
2522                     if (sep != NULL)
2523                               aprint_verbose("\n");
2524           }
2525           if (ci->ci_cinfo[CAI_PREFETCH].cai_linesize != 0) {
2526                     aprint_verbose_dev(ci->ci_dev, "%dB prefetching",
2527                         ci->ci_cinfo[CAI_PREFETCH].cai_linesize);
2528                     if (sep != NULL)
2529                               aprint_verbose("\n");
2530           }
2531 
2532           sep = print_tlb_config(ci, CAI_ITLB, "ITLB:", NULL);
2533           sep = print_tlb_config(ci, CAI_ITLB2, "ITLB:", sep);
2534           sep = print_tlb_config(ci, CAI_L1_1GBITLB, "ITLB:", sep);
2535           if (sep != NULL)
2536                     aprint_verbose("\n");
2537 
2538           sep = print_tlb_config(ci, CAI_DTLB, "DTLB:", NULL);
2539           sep = print_tlb_config(ci, CAI_DTLB2, "DTLB:", sep);
2540           sep = print_tlb_config(ci, CAI_L1_1GBDTLB, "DTLB:", sep);
2541           if (sep != NULL)
2542                     aprint_verbose("\n");
2543 
2544           sep = print_tlb_config(ci, CAI_L1_LD_TLB, "Load only TLB:", NULL);
2545           if (sep != NULL)
2546                     aprint_verbose("\n");
2547 
2548           sep = print_tlb_config(ci, CAI_L1_ST_TLB, "Store only TLB:", NULL);
2549           if (sep != NULL)
2550                     aprint_verbose("\n");
2551 
2552           sep = print_tlb_config(ci, CAI_L2_ITLB, "L2 ITLB:", NULL);
2553           sep = print_tlb_config(ci, CAI_L2_ITLB2, "L2 ITLB:", sep);
2554           sep = print_tlb_config(ci, CAI_L2_1GBITLB, "L2 ITLB:", sep);
2555           if (sep != NULL)
2556                     aprint_verbose("\n");
2557 
2558           sep = print_tlb_config(ci, CAI_L2_DTLB, "L2 DTLB:", NULL);
2559           sep = print_tlb_config(ci, CAI_L2_DTLB2, "L2 DTLB:", sep);
2560           sep = print_tlb_config(ci, CAI_L2_1GBDTLB, "L2 DTLB:", sep);
2561           if (sep != NULL)
2562                     aprint_verbose("\n");
2563 
2564           sep = print_tlb_config(ci, CAI_L2_STLB, "L2 STLB:", NULL);
2565           sep = print_tlb_config(ci, CAI_L2_STLB2, "L2 STLB:", sep);
2566           sep = print_tlb_config(ci, CAI_L2_STLB3, "L2 STLB:", sep);
2567           if (sep != NULL)
2568                     aprint_verbose("\n");
2569 }
2570 
2571 static void
powernow_probe(struct cpu_info * ci)2572 powernow_probe(struct cpu_info *ci)
2573 {
2574           uint32_t regs[4];
2575           char buf[256];
2576 
2577           x86_cpuid(0x80000007, regs);
2578 
2579           snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]);
2580           aprint_normal_dev(ci->ci_dev, "Power Management features: %s\n", buf);
2581 }
2582 
2583 bool
identifycpu_bind(void)2584 identifycpu_bind(void)
2585 {
2586 
2587           return true;
2588 }
2589 
2590 int
ucodeupdate_check(int fd,struct cpu_ucode * uc)2591 ucodeupdate_check(int fd, struct cpu_ucode *uc)
2592 {
2593           struct cpu_info ci;
2594           int loader_version, res;
2595           struct cpu_ucode_version versreq;
2596 
2597           cpu_probe_base_features(&ci, "unknown");
2598 
2599           if (!strcmp((char *)ci.ci_vendor, "AuthenticAMD"))
2600                     loader_version = CPU_UCODE_LOADER_AMD;
2601           else if (!strcmp((char *)ci.ci_vendor, "GenuineIntel"))
2602                     loader_version = CPU_UCODE_LOADER_INTEL1;
2603           else
2604                     return -1;
2605 
2606           /* check whether the kernel understands this loader version */
2607           versreq.loader_version = loader_version;
2608           versreq.data = 0;
2609           res = ioctl(fd, IOC_CPU_UCODE_GET_VERSION, &versreq);
2610           if (res)
2611                     return -1;
2612 
2613           switch (loader_version) {
2614           case CPU_UCODE_LOADER_AMD:
2615                   if (uc->cpu_nr != -1) {
2616                           warnx("ucode updates on AMD can only be done on all CPUs at once");
2617                               return -1;
2618                     }
2619                     uc->cpu_nr = CPU_UCODE_ALL_CPUS;
2620                     break;
2621           case CPU_UCODE_LOADER_INTEL1:
2622                     if (uc->cpu_nr == -1)
2623                               uc->cpu_nr = CPU_UCODE_ALL_CPUS; /* for Xen */
2624                     else
2625                               uc->cpu_nr = CPU_UCODE_CURRENT_CPU;
2626                     break;
2627           default: /* can't happen */
2628                     return -1;
2629           }
2630           uc->loader_version = loader_version;
2631           return 0;
2632 }
2633