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