1/* $NetBSD: identcpu.c,v 1.50 2016/01/01 19:46:48 tls Exp $ */
2
3/*-
4 * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden, and by Jason R. Thorpe.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.50 2016/01/01 19:46:48 tls Exp $");
34
35#include "opt_xen.h"
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/device.h>
40#include <sys/cpu.h>
41
42#include <uvm/uvm_extern.h>
43
44#include <machine/specialreg.h>
45#include <machine/pio.h>
46#include <machine/cpu.h>
47
48#include <x86/cputypes.h>
49#include <x86/cacheinfo.h>
50#include <x86/cpuvar.h>
51#include <x86/cpu_msr.h>
52
53static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO;
54
55static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] =
56 AMD_L2CACHE_INFO;
57
58static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] =
59 AMD_L3CACHE_INFO;
60
61int cpu_vendor;
62char cpu_brand_string[49];
63
64int x86_fpu_save = FPU_SAVE_FSAVE;
65unsigned int x86_fpu_save_size = 512;
66uint64_t x86_xsave_features = 0;
67
68/*
69 * Note: these are just the ones that may not have a cpuid instruction.
70 * We deal with the rest in a different way.
71 */
72const int i386_nocpuid_cpus[] = {
73 CPUVENDOR_INTEL, CPUCLASS_386, /* CPU_386SX */
74 CPUVENDOR_INTEL, CPUCLASS_386, /* CPU_386 */
75 CPUVENDOR_INTEL, CPUCLASS_486, /* CPU_486SX */
76 CPUVENDOR_INTEL, CPUCLASS_486, /* CPU_486 */
77 CPUVENDOR_CYRIX, CPUCLASS_486, /* CPU_486DLC */
78 CPUVENDOR_CYRIX, CPUCLASS_486, /* CPU_6x86 */
79 CPUVENDOR_NEXGEN, CPUCLASS_386, /* CPU_NX586 */
80};
81
82static const char cpu_vendor_names[][10] = {
83 "Unknown", "Intel", "NS/Cyrix", "NexGen", "AMD", "IDT/VIA", "Transmeta",
84 "Vortex86"
85};
86
87static const struct x86_cache_info *
88cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc)
89{
90 int i;
91
92 for (i = 0; cai[i].cai_desc != 0; i++) {
93 if (cai[i].cai_desc == desc)
94 return (&cai[i]);
95 }
96
97 return (NULL);
98}
99
100static void
101cpu_probe_intel_cache(struct cpu_info *ci)
102{
103 const struct x86_cache_info *cai;
104 u_int descs[4];
105 int iterations, i, j;
106 uint8_t desc;
107
108 if (cpuid_level >= 2) {
109 /* Parse the cache info from `cpuid leaf 2', if we have it. */
110 x86_cpuid(2, descs);
111 iterations = descs[0] & 0xff;
112 while (iterations-- > 0) {
113 for (i = 0; i < 4; i++) {
114 if (descs[i] & 0x80000000)
115 continue;
116 for (j = 0; j < 4; j++) {
117 if (i == 0 && j == 0)
118 continue;
119 desc = (descs[i] >> (j * 8)) & 0xff;
120 if (desc == 0)
121 continue;
122 cai = cache_info_lookup(
123 intel_cpuid_cache_info, desc);
124 if (cai != NULL) {
125 ci->ci_cinfo[cai->cai_index] =
126 *cai;
127 }
128 }
129 }
130 }
131 }
132
133 if (cpuid_level >= 4) {
134 int type, level;
135 int ways, partitions, linesize, sets;
136 int caitype = -1;
137 int totalsize;
138
139 /* Parse the cache info from `cpuid leaf 4', if we have it. */
140 for (i = 0; ; i++) {
141 x86_cpuid2(4, i, descs);
142 type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE);
143 if (type == CPUID_DCP_CACHETYPE_N)
144 break;
145 level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL);
146 switch (level) {
147 case 1:
148 if (type == CPUID_DCP_CACHETYPE_I)
149 caitype = CAI_ICACHE;
150 else if (type == CPUID_DCP_CACHETYPE_D)
151 caitype = CAI_DCACHE;
152 else
153 caitype = -1;
154 break;
155 case 2:
156 if (type == CPUID_DCP_CACHETYPE_U)
157 caitype = CAI_L2CACHE;
158 else
159 caitype = -1;
160 break;
161 case 3:
162 if (type == CPUID_DCP_CACHETYPE_U)
163 caitype = CAI_L3CACHE;
164 else
165 caitype = -1;
166 break;
167 default:
168 caitype = -1;
169 break;
170 }
171 if (caitype == -1)
172 continue;
173
174 ways = __SHIFTOUT(descs[1], CPUID_DCP_WAYS) + 1;
175 partitions =__SHIFTOUT(descs[1], CPUID_DCP_PARTITIONS)
176 + 1;
177 linesize = __SHIFTOUT(descs[1], CPUID_DCP_LINESIZE)
178 + 1;
179 sets = descs[2] + 1;
180 totalsize = ways * partitions * linesize * sets;
181 ci->ci_cinfo[caitype].cai_totalsize = totalsize;
182 ci->ci_cinfo[caitype].cai_associativity = ways;
183 ci->ci_cinfo[caitype].cai_linesize = linesize;
184 }
185 }
186}
187
188static void
189cpu_probe_intel(struct cpu_info *ci)
190{
191
192 if (cpu_vendor != CPUVENDOR_INTEL)
193 return;
194
195 cpu_probe_intel_cache(ci);
196}
197
198static void
199cpu_probe_amd_cache(struct cpu_info *ci)
200{
201 const struct x86_cache_info *cp;
202 struct x86_cache_info *cai;
203 int family, model;
204 u_int descs[4];
205 u_int lfunc;
206
207 family = CPUID_TO_FAMILY(ci->ci_signature);
208 model = CPUID_TO_MODEL(ci->ci_signature);
209
210 /*
211 * K5 model 0 has none of this info.
212 */
213 if (family == 5 && model == 0)
214 return;
215
216 /*
217 * Determine the largest extended function value.
218 */
219 x86_cpuid(0x80000000, descs);
220 lfunc = descs[0];
221
222 /*
223 * Determine L1 cache/TLB info.
224 */
225 if (lfunc < 0x80000005) {
226 /* No L1 cache info available. */
227 return;
228 }
229
230 x86_cpuid(0x80000005, descs);
231
232 /*
233 * K6-III and higher have large page TLBs.
234 */
235 if ((family == 5 && model >= 9) || family >= 6) {
236 cai = &ci->ci_cinfo[CAI_ITLB2];
237 cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]);
238 cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]);
239 cai->cai_linesize = (4 * 1024 * 1024);
240
241 cai = &ci->ci_cinfo[CAI_DTLB2];
242 cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]);
243 cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]);
244 cai->cai_linesize = (4 * 1024 * 1024);
245 }
246
247 cai = &ci->ci_cinfo[CAI_ITLB];
248 cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]);
249 cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]);
250 cai->cai_linesize = (4 * 1024);
251
252 cai = &ci->ci_cinfo[CAI_DTLB];
253 cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]);
254 cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]);
255 cai->cai_linesize = (4 * 1024);
256
257 cai = &ci->ci_cinfo[CAI_DCACHE];
258 cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]);
259 cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]);
260 cai->cai_linesize = AMD_L1_ECX_DC_LS(descs[2]);
261
262 cai = &ci->ci_cinfo[CAI_ICACHE];
263 cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]);
264 cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]);
265 cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]);
266
267 /*
268 * Determine L2 cache/TLB info.
269 */
270 if (lfunc < 0x80000006) {
271 /* No L2 cache info available. */
272 return;
273 }
274
275 x86_cpuid(0x80000006, descs);
276
277 cai = &ci->ci_cinfo[CAI_L2CACHE];
278 cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]);
279 cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]);
280 cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]);
281
282 cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info,
283 cai->cai_associativity);
284 if (cp != NULL)
285 cai->cai_associativity = cp->cai_associativity;
286 else
287 cai->cai_associativity = 0; /* XXX Unknown/reserved */
288
289 if (family < 0xf) {
290 /* No L3 cache info available. */
291 return;
292 }
293
294 cai = &ci->ci_cinfo[CAI_L3CACHE];
295 cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]);
296 cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]);
297 cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]);
298
299 cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info,
300 cai->cai_associativity);
301 if (cp != NULL)
302 cai->cai_associativity = cp->cai_associativity;
303 else
304 cai->cai_associativity = 0; /* XXX Unknown reserved */
305
306 if (lfunc < 0x80000019) {
307 /* No 1GB Page TLB */
308 return;
309 }
310
311 x86_cpuid(0x80000019, descs);
312
313 cai = &ci->ci_cinfo[CAI_L1_1GBDTLB];
314 cai->cai_totalsize = AMD_L1_1GB_EAX_DTLB_ENTRIES(descs[1]);
315 cai->cai_associativity = AMD_L1_1GB_EAX_DTLB_ASSOC(descs[1]);
316 cai->cai_linesize = (1 * 1024);
317
318 cai = &ci->ci_cinfo[CAI_L1_1GBITLB];
319 cai->cai_totalsize = AMD_L1_1GB_EAX_IUTLB_ENTRIES(descs[0]);
320 cai->cai_associativity = AMD_L1_1GB_EAX_IUTLB_ASSOC(descs[0]);
321 cai->cai_linesize = (1 * 1024);
322
323 cai = &ci->ci_cinfo[CAI_L2_1GBDTLB];
324 cai->cai_totalsize = AMD_L2_1GB_EBX_DUTLB_ENTRIES(descs[1]);
325 cai->cai_associativity = AMD_L2_1GB_EBX_DUTLB_ASSOC(descs[1]);
326 cai->cai_linesize = (1 * 1024);
327
328 cai = &ci->ci_cinfo[CAI_L2_1GBITLB];
329 cai->cai_totalsize = AMD_L2_1GB_EBX_IUTLB_ENTRIES(descs[0]);
330 cai->cai_associativity = AMD_L2_1GB_EBX_IUTLB_ASSOC(descs[0]);
331 cai->cai_linesize = (1 * 1024);
332}
333
334static void
335cpu_probe_k5(struct cpu_info *ci)
336{
337 int flag;
338
339 if (cpu_vendor != CPUVENDOR_AMD ||
340 CPUID_TO_FAMILY(ci->ci_signature) != 5)
341 return;
342
343 if (CPUID_TO_MODEL(ci->ci_signature) == 0) {
344 /*
345 * According to the AMD Processor Recognition App Note,
346 * the AMD-K5 Model 0 uses the wrong bit to indicate
347 * support for global PTEs, instead using bit 9 (APIC)
348 * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!).
349 */
350 flag = ci->ci_feat_val[0];
351 if ((flag & CPUID_APIC) != 0)
352 flag = (flag & ~CPUID_APIC) | CPUID_PGE;
353 ci->ci_feat_val[0] = flag;
354 }
355
356 cpu_probe_amd_cache(ci);
357}
358
359static void
360cpu_probe_k678(struct cpu_info *ci)
361{
362
363 if (cpu_vendor != CPUVENDOR_AMD ||
364 CPUID_TO_FAMILY(ci->ci_signature) < 6)
365 return;
366
367 cpu_probe_amd_cache(ci);
368}
369
370static inline uint8_t
371cyrix_read_reg(uint8_t reg)
372{
373
374 outb(0x22, reg);
375 return inb(0x23);
376}
377
378static inline void
379cyrix_write_reg(uint8_t reg, uint8_t data)
380{
381
382 outb(0x22, reg);
383 outb(0x23, data);
384}
385
386static void
387cpu_probe_cyrix_cmn(struct cpu_info *ci)
388{
389 /*
390 * i8254 latch check routine:
391 * National Geode (formerly Cyrix MediaGX) has a serious bug in
392 * its built-in i8254-compatible clock module (cs5510 cs5520).
393 * Set the variable 'clock_broken_latch' to indicate it.
394 *
395 * This bug is not present in the cs5530, and the flag
396 * is disabled again in sys/arch/i386/pci/pcib.c if this later
397 * model device is detected. Ideally, this work-around should not
398 * even be in here, it should be in there. XXX
399 */
400 uint8_t c3;
401#ifndef XEN
402 extern int clock_broken_latch;
403
404 switch (ci->ci_signature) {
405 case 0x440: /* Cyrix MediaGX */
406 case 0x540: /* GXm */
407 clock_broken_latch = 1;
408 break;
409 }
410#endif
411
412 /* set up various cyrix registers */
413 /*
414 * Enable suspend on halt (powersave mode).
415 * When powersave mode is enabled, the TSC stops counting
416 * while the CPU is halted in idle() waiting for an interrupt.
417 * This means we can't use the TSC for interval time in
418 * microtime(9), and thus it is disabled here.
419 *
420 * It still makes a perfectly good cycle counter
421 * for program profiling, so long as you remember you're
422 * counting cycles, and not time. Further, if you don't
423 * mind not using powersave mode, the TSC works just fine,
424 * so this should really be optional. XXX
425 */
426 cyrix_write_reg(0xc2, cyrix_read_reg(0xc2) | 0x08);
427
428 /*
429 * Do not disable the TSC on the Geode GX, it's reported to
430 * work fine.
431 */
432 if (ci->ci_signature != 0x552)
433 ci->ci_feat_val[0] &= ~CPUID_TSC;
434
435 /* enable access to ccr4/ccr5 */
436 c3 = cyrix_read_reg(0xC3);
437 cyrix_write_reg(0xC3, c3 | 0x10);
438 /* cyrix's workaround for the "coma bug" */
439 cyrix_write_reg(0x31, cyrix_read_reg(0x31) | 0xf8);
440 cyrix_write_reg(0x32, cyrix_read_reg(0x32) | 0x7f);
441 cyrix_write_reg(0x33, cyrix_read_reg(0x33) & ~0xff);
442 cyrix_write_reg(0x3c, cyrix_read_reg(0x3c) | 0x87);
443 /* disable access to ccr4/ccr5 */
444 cyrix_write_reg(0xC3, c3);
445}
446
447static void
448cpu_probe_cyrix(struct cpu_info *ci)
449{
450
451 if (cpu_vendor != CPUVENDOR_CYRIX ||
452 CPUID_TO_FAMILY(ci->ci_signature) < 4 ||
453 CPUID_TO_FAMILY(ci->ci_signature) > 6)
454 return;
455
456 cpu_probe_cyrix_cmn(ci);
457}
458
459static void
460cpu_probe_winchip(struct cpu_info *ci)
461{
462
463 if (cpu_vendor != CPUVENDOR_IDT)
464 return;
465
466 switch (CPUID_TO_FAMILY(ci->ci_signature)) {
467 case 5:
468 /* WinChip C6 */
469 if (CPUID_TO_MODEL(ci->ci_signature) == 4)
470 ci->ci_feat_val[0] &= ~CPUID_TSC;
471 break;
472 case 6:
473 /*
474 * VIA Eden ESP
475 *
476 * Quoting from page 3-4 of: "VIA Eden ESP Processor Datasheet"
477 * http://www.via.com.tw/download/mainboards/6/14/Eden20v115.pdf
478 *
479 * 1. The CMPXCHG8B instruction is provided and always enabled,
480 * however, it appears disabled in the corresponding CPUID
481 * function bit 0 to avoid a bug in an early version of
482 * Windows NT. However, this default can be changed via a
483 * bit in the FCR MSR.
484 */
485 ci->ci_feat_val[0] |= CPUID_CX8;
486 wrmsr(MSR_VIA_FCR, rdmsr(MSR_VIA_FCR) | 0x00000001);
487 break;
488 }
489}
490
491static void
492cpu_probe_c3(struct cpu_info *ci)
493{
494 u_int family, model, stepping, descs[4], lfunc, msr;
495 struct x86_cache_info *cai;
496
497 if (cpu_vendor != CPUVENDOR_IDT ||
498 CPUID_TO_FAMILY(ci->ci_signature) < 6)
499 return;
500
501 family = CPUID_TO_FAMILY(ci->ci_signature);
502 model = CPUID_TO_MODEL(ci->ci_signature);
503 stepping = CPUID_TO_STEPPING(ci->ci_signature);
504
505 /* Determine the largest extended function value. */
506 x86_cpuid(0x80000000, descs);
507 lfunc = descs[0];
508
509 if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) {
510 /* Nehemiah or Esther */
511 x86_cpuid(0xc0000000, descs);
512 lfunc = descs[0];
513 if (lfunc >= 0xc0000001) { /* has ACE, RNG */
514 int rng_enable = 0, ace_enable = 0;
515 x86_cpuid(0xc0000001, descs);
516 lfunc = descs[3];
517 ci->ci_feat_val[4] = lfunc;
518 /* Check for and enable RNG */
519 if (lfunc & CPUID_VIA_HAS_RNG) {
520 if (!(lfunc & CPUID_VIA_DO_RNG)) {
521 rng_enable++;
522 ci->ci_feat_val[4] |= CPUID_VIA_DO_RNG;
523 }
524 }
525 /* Check for and enable ACE (AES-CBC) */
526 if (lfunc & CPUID_VIA_HAS_ACE) {
527 if (!(lfunc & CPUID_VIA_DO_ACE)) {
528 ace_enable++;
529 ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE;
530 }
531 }
532 /* Check for and enable SHA */
533 if (lfunc & CPUID_VIA_HAS_PHE) {
534 if (!(lfunc & CPUID_VIA_DO_PHE)) {
535 ace_enable++;
536 ci->ci_feat_val[4] |= CPUID_VIA_DO_PHE;
537 }
538 }
539 /* Check for and enable ACE2 (AES-CTR) */
540 if (lfunc & CPUID_VIA_HAS_ACE2) {
541 if (!(lfunc & CPUID_VIA_DO_ACE2)) {
542 ace_enable++;
543 ci->ci_feat_val[4] |= CPUID_VIA_DO_ACE2;
544 }
545 }
546 /* Check for and enable PMM (modmult engine) */
547 if (lfunc & CPUID_VIA_HAS_PMM) {
548 if (!(lfunc & CPUID_VIA_DO_PMM)) {
549 ace_enable++;
550 ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM;
551 }
552 }
553
554 /* Actually do the enables. */
555 if (rng_enable) {
556 msr = rdmsr(MSR_VIA_RNG);
557 msr |= MSR_VIA_RNG_ENABLE;
558 /* C7 stepping 8 and subsequent CPUs have dual RNG */
559 if (model > 0xA || (model == 0xA && stepping > 0x7)) {
560 msr |= MSR_VIA_RNG_2NOISE;
561 }
562 wrmsr(MSR_VIA_RNG, msr);
563 }
564
565 if (ace_enable) {
566 msr = rdmsr(MSR_VIA_ACE);
567 wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE);
568 }
569
570 }
571 }
572
573 /*
574 * Determine L1 cache/TLB info.
575 */
576 if (lfunc < 0x80000005) {
577 /* No L1 cache info available. */
578 return;
579 }
580
581 x86_cpuid(0x80000005, descs);
582
583 cai = &ci->ci_cinfo[CAI_ITLB];
584 cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]);
585 cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]);
586 cai->cai_linesize = (4 * 1024);
587
588 cai = &ci->ci_cinfo[CAI_DTLB];
589 cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]);
590 cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]);
591 cai->cai_linesize = (4 * 1024);
592
593 cai = &ci->ci_cinfo[CAI_DCACHE];
594 cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]);
595 cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]);
596 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]);
597 if (family == 6 && model == 9 && stepping == 8) {
598 /* Erratum: stepping 8 reports 4 when it should be 2 */
599 cai->cai_associativity = 2;
600 }
601
602 cai = &ci->ci_cinfo[CAI_ICACHE];
603 cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]);
604 cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]);
605 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]);
606 if (family == 6 && model == 9 && stepping == 8) {
607 /* Erratum: stepping 8 reports 4 when it should be 2 */
608 cai->cai_associativity = 2;
609 }
610
611 /*
612 * Determine L2 cache/TLB info.
613 */
614 if (lfunc < 0x80000006) {
615 /* No L2 cache info available. */
616 return;
617 }
618
619 x86_cpuid(0x80000006, descs);
620
621 cai = &ci->ci_cinfo[CAI_L2CACHE];
622 if (family > 6 || model >= 9) {
623 cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
624 cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);
625 cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]);
626 } else {
627 cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
628 cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
629 cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
630 }
631}
632
633static void
634cpu_probe_geode(struct cpu_info *ci)
635{
636
637 if (memcmp("Geode by NSC", ci->ci_vendor, 12) != 0 ||
638 CPUID_TO_FAMILY(ci->ci_signature) != 5)
639 return;
640
641 cpu_probe_cyrix_cmn(ci);
642 cpu_probe_amd_cache(ci);
643}
644
645static void
646cpu_probe_vortex86(struct cpu_info *ci)
647{
648#define PCI_MODE1_ADDRESS_REG 0x0cf8
649#define PCI_MODE1_DATA_REG 0x0cfc
650#define PCI_MODE1_ENABLE 0x80000000UL
651
652 uint32_t reg;
653
654 if (cpu_vendor != CPUVENDOR_VORTEX86)
655 return;
656 /*
657 * CPU model available from "Customer ID register" in
658 * North Bridge Function 0 PCI space
659 * we can't use pci_conf_read() because the PCI subsystem is not
660 * not initialised early enough
661 */
662
663 outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE | 0x90);
664 reg = inl(PCI_MODE1_DATA_REG);
665
666 switch(reg) {
667 case 0x31504d44:
668 strcpy(cpu_brand_string, "Vortex86SX");
669 break;
670 case 0x32504d44:
671 strcpy(cpu_brand_string, "Vortex86DX");
672 break;
673 case 0x33504d44:
674 strcpy(cpu_brand_string, "Vortex86MX");
675 break;
676 case 0x37504d44:
677 strcpy(cpu_brand_string, "Vortex86EX");
678 break;
679 default:
680 strcpy(cpu_brand_string, "Unknown Vortex86");
681 break;
682 }
683
684#undef PCI_MODE1_ENABLE
685#undef PCI_MODE1_ADDRESS_REG
686#undef PCI_MODE1_DATA_REG
687}
688
689#if !defined(__i386__) || defined(XEN)
690#define cpu_probe_old_fpu(ci)
691#else
692static void
693cpu_probe_old_fpu(struct cpu_info *ci)
694{
695 uint16_t control;
696
697 /* Check that there really is an fpu (496SX) */
698 clts();
699 fninit();
700 /* Read default control word */
701 fnstcw(&control);
702 if (control != __INITIAL_NPXCW__) {
703 /* Must be a 486SX, trap FP instructions */
704 lcr0((rcr0() & ~CR0_MP) | CR0_EM);
705 i386_fpu_present = 0;
706 return;
707 }
708
709 /* Check for 'FDIV' bug on the original Pentium */
710 if (npx586bug1(4195835, 3145727) != 0)
711 /* NB 120+MHz cpus are not affected */
712 i386_fpu_fdivbug = 1;
713
714 stts();
715}
716#endif
717
718static void
719cpu_probe_fpu(struct cpu_info *ci)
720{
721 u_int descs[4];
722
723#ifdef i386 /* amd64 always has fxsave, sse and sse2 */
724 /* If we have FXSAVE/FXRESTOR, use them. */
725 if ((ci->ci_feat_val[0] & CPUID_FXSR) == 0) {
726 i386_use_fxsave = 0;
727 /* Allow for no fpu even if cpuid is supported */
728 cpu_probe_old_fpu(ci);
729 return;
730 }
731
732 i386_use_fxsave = 1;
733 /*
734 * If we have SSE/SSE2, enable XMM exceptions, and
735 * notify userland.
736 */
737 if (ci->ci_feat_val[0] & CPUID_SSE)
738 i386_has_sse = 1;
739 if (ci->ci_feat_val[0] & CPUID_SSE2)
740 i386_has_sse2 = 1;
741#else
742 /*
743 * For amd64 i386_use_fxsave, i386_has_sse and i386_has_sse2 are
744 * #defined to 1.
745 */
746#endif /* i386 */
747
748 x86_fpu_save = FPU_SAVE_FXSAVE;
749
750 /* See if xsave (for AVX is supported) */
751 if ((ci->ci_feat_val[1] & CPUID2_XSAVE) == 0)
752 return;
753
754 x86_fpu_save = FPU_SAVE_XSAVE;
755
756 /* xsaveopt ought to be faster than xsave */
757 x86_cpuid2(0xd, 1, descs);
758 if (descs[0] & CPUID_PES1_XSAVEOPT)
759 x86_fpu_save = FPU_SAVE_XSAVEOPT;
760
761 /* Get features and maximum size of the save area */
762 x86_cpuid(0xd, descs);
763 /* XXX these probably ought to be per-cpu */
764 if (descs[2] > 512)
765 x86_fpu_save_size = descs[2];
766#ifndef XEN
767 x86_xsave_features = (uint64_t)descs[3] << 32 | descs[0];
768#endif
769}
770
771void
772cpu_probe(struct cpu_info *ci)
773{
774 u_int descs[4];
775 int i;
776 uint32_t miscbytes;
777 uint32_t brand[12];
778
779 cpu_vendor = i386_nocpuid_cpus[cputype << 1];
780 cpu_class = i386_nocpuid_cpus[(cputype << 1) + 1];
781
782 if (cpuid_level < 0) {
783 /* cpuid instruction not supported */
784 cpu_probe_old_fpu(ci);
785 return;
786 }
787
788 for (i = 0; i < __arraycount(ci->ci_feat_val); i++) {
789 ci->ci_feat_val[i] = 0;
790 }
791
792 x86_cpuid(0, descs);
793 cpuid_level = descs[0];
794 ci->ci_max_cpuid = descs[0];
795
796 ci->ci_vendor[0] = descs[1];
797 ci->ci_vendor[2] = descs[2];
798 ci->ci_vendor[1] = descs[3];
799 ci->ci_vendor[3] = 0;
800
801 if (memcmp(ci->ci_vendor, "GenuineIntel", 12) == 0)
802 cpu_vendor = CPUVENDOR_INTEL;
803 else if (memcmp(ci->ci_vendor, "AuthenticAMD", 12) == 0)
804 cpu_vendor = CPUVENDOR_AMD;
805 else if (memcmp(ci->ci_vendor, "CyrixInstead", 12) == 0)
806 cpu_vendor = CPUVENDOR_CYRIX;
807 else if (memcmp(ci->ci_vendor, "Geode by NSC", 12) == 0)
808 cpu_vendor = CPUVENDOR_CYRIX;
809 else if (memcmp(ci->ci_vendor, "CentaurHauls", 12) == 0)
810 cpu_vendor = CPUVENDOR_IDT;
811 else if (memcmp(ci->ci_vendor, "GenuineTMx86", 12) == 0)
812 cpu_vendor = CPUVENDOR_TRANSMETA;
813 else if (memcmp(ci->ci_vendor, "Vortex86 SoC", 12) == 0)
814 cpu_vendor = CPUVENDOR_VORTEX86;
815 else
816 cpu_vendor = CPUVENDOR_UNKNOWN;
817
818 if (cpuid_level >= 1) {
819 x86_cpuid(1, descs);
820 ci->ci_signature = descs[0];
821 miscbytes = descs[1];
822 ci->ci_feat_val[1] = descs[2];
823 ci->ci_feat_val[0] = descs[3];
824
825 /* Determine family + class. */
826 cpu_class = CPUID_TO_FAMILY(ci->ci_signature)
827 + (CPUCLASS_386 - 3);
828 if (cpu_class > CPUCLASS_686)
829 cpu_class = CPUCLASS_686;
830
831 /* CLFLUSH line size is next 8 bits */
832 if (ci->ci_feat_val[0] & CPUID_CFLUSH)
833 ci->ci_cflush_lsize = ((miscbytes >> 8) & 0xff) << 3;
834 ci->ci_initapicid = (miscbytes >> 24) & 0xff;
835 }
836
837 /*
838 * Get the basic information from the extended cpuid leafs.
839 * These were first implemented by amd, but most of the values
840 * match with those generated by modern intel cpus.
841 */
842 x86_cpuid(0x80000000, descs);
843 if (descs[0] >= 0x80000000)
844 ci->ci_max_ext_cpuid = descs[0];
845 else
846 ci->ci_max_ext_cpuid = 0;
847
848 if (ci->ci_max_ext_cpuid >= 0x80000001) {
849 /* Determine the extended feature flags. */
850 x86_cpuid(0x80000001, descs);
851 ci->ci_feat_val[3] = descs[2]; /* %ecx */
852 ci->ci_feat_val[2] = descs[3]; /* %edx */
853 }
854
855 if (ci->ci_max_ext_cpuid >= 0x80000004) {
856 x86_cpuid(0x80000002, brand);
857 x86_cpuid(0x80000003, brand + 4);
858 x86_cpuid(0x80000004, brand + 8);
859 /* Skip leading spaces on brand */
860 for (i = 0; i < 48; i++) {
861 if (((char *) brand)[i] != ' ')
862 break;
863 }
864 memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
865 }
866
867 /*
868 * Get the structured extended features.
869 */
870 if (cpuid_level >= 7) {
871 x86_cpuid(7, descs);
872 ci->ci_feat_val[5] = descs[1]; /* %ebx */
873 ci->ci_feat_val[6] = descs[2]; /* %ecx */
874 }
875
876 cpu_probe_intel(ci);
877 cpu_probe_k5(ci);
878 cpu_probe_k678(ci);
879 cpu_probe_cyrix(ci);
880 cpu_probe_winchip(ci);
881 cpu_probe_c3(ci);
882 cpu_probe_geode(ci);
883 cpu_probe_vortex86(ci);
884
885 cpu_probe_fpu(ci);
886
887 x86_cpu_topology(ci);
888
889 if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) &&
890 (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) {
891 /* Enable thermal monitor 1. */
892 wrmsr(MSR_MISC_ENABLE, rdmsr(MSR_MISC_ENABLE) | (1<<3));
893 }
894
895 ci->ci_feat_val[0] &= ~CPUID_FEAT_BLACKLIST;
896 if (ci == &cpu_info_primary) {
897 /* If first. Boot Processor is the cpu_feature reference. */
898 for (i = 0; i < __arraycount(cpu_feature); i++) {
899 cpu_feature[i] = ci->ci_feat_val[i];
900 }
901#ifndef XEN
902 /* Early patch of text segment. */
903 x86_patch(true);
904#endif
905 } else {
906 /*
907 * If not first. Warn about cpu_feature mismatch for
908 * secondary CPUs.
909 */
910 for (i = 0; i < __arraycount(cpu_feature); i++) {
911 if (cpu_feature[i] != ci->ci_feat_val[i])
912 aprint_error_dev(ci->ci_dev,
913 "feature mismatch: cpu_feature[%d] is "
914 "%#x, but CPU reported %#x\n",
915 i, cpu_feature[i], ci->ci_feat_val[i]);
916 }
917 }
918}
919
920/* Write what we know about the cpu to the console... */
921void
922cpu_identify(struct cpu_info *ci)
923{
924
925 cpu_setmodel("%s %d86-class",
926 cpu_vendor_names[cpu_vendor], cpu_class + 3);
927 if (cpu_brand_string[0] != '\0') {
928 aprint_normal_dev(ci->ci_dev, "%s", cpu_brand_string);
929 } else {
930 aprint_normal_dev(ci->ci_dev, "%s", cpu_getmodel());
931 if (ci->ci_data.cpu_cc_freq != 0)
932 aprint_normal(", %dMHz",
933 (int)(ci->ci_data.cpu_cc_freq / 1000000));
934 }
935 if (ci->ci_signature != 0)
936 aprint_normal(", id 0x%x", ci->ci_signature);
937 aprint_normal("\n");
938
939 if (cpu_brand_string[0] == '\0') {
940 strlcpy(cpu_brand_string, cpu_getmodel(),
941 sizeof(cpu_brand_string));
942 }
943 if (cpu_class == CPUCLASS_386) {
944 panic("NetBSD requires an 80486DX or later processor");
945 }
946 if (cputype == CPU_486DLC) {
947 aprint_error("WARNING: BUGGY CYRIX CACHE\n");
948 }
949
950#if !defined(XEN) || defined(DOM0OPS) /* on Xen rdmsr is for Dom0 only */
951 if (cpu_vendor == CPUVENDOR_AMD /* check enablement of an */
952 && device_unit(ci->ci_dev) == 0 /* AMD feature only once */
953 && ((cpu_feature[3] & CPUID_SVM) == CPUID_SVM)) {
954 uint64_t val;
955
956 val = rdmsr(MSR_VMCR);
957 if (((val & VMCR_SVMED) == VMCR_SVMED)
958 && ((val & VMCR_LOCK) == VMCR_LOCK)) {
959 aprint_normal_dev(ci->ci_dev,
960 "SVM disabled by the BIOS\n");
961 }
962 }
963#endif
964
965#ifdef i386
966 if (i386_fpu_present == 0)
967 aprint_normal_dev(ci->ci_dev, "no fpu\n");
968
969 if (i386_fpu_fdivbug == 1)
970 aprint_normal_dev(ci->ci_dev,
971 "WARNING: Pentium FDIV bug detected!\n");
972
973 if (cpu_vendor == CPUVENDOR_TRANSMETA) {
974 u_int descs[4];
975 x86_cpuid(0x80860000, descs);
976 if (descs[0] >= 0x80860007)
977 /* Create longrun sysctls */
978 tmx86_init_longrun();
979 }
980#endif /* i386 */
981
982}
983