Sat Feb 22 17:48:08 2014 UTC ()
Re-use the unused ci_cpu_serial[3] to save the highest cpuid values
  for the normal and extended leafs.
(The 'normal' one might be luring in the global cpulevel.)
Read the 'extended feature' from cpuid.80000001.%ecx/edx into
    ci_feat_val[3/2] just after saving cpuid.1.%ecx/dx in ci_feat_val[1/0]
    instead of doing it separately for amd k678 and via c3 processors
    in their probe functions and repeating it for all cpus a few instructions
    later when x86_cpu_topology() is called.
x86_cpu_topology() is only called from cpu_probe() and really doesn't
  deserve its own source file. Chasing the setup code is bad enough anyway.


(dsl)
diff -r1.63 -r1.64 src/sys/arch/x86/include/cpu.h
diff -r1.8 -r1.9 src/sys/arch/x86/x86/cpu_topology.c
diff -r1.39 -r1.40 src/sys/arch/x86/x86/identcpu.c

cvs diff -r1.63 -r1.64 src/sys/arch/x86/include/cpu.h (expand / switch to unified diff)

--- src/sys/arch/x86/include/cpu.h 2014/02/20 18:14:11 1.63
+++ src/sys/arch/x86/include/cpu.h 2014/02/22 17:48:08 1.64
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.h,v 1.63 2014/02/20 18:14:11 dsl Exp $ */ 1/* $NetBSD: cpu.h,v 1.64 2014/02/22 17:48:08 dsl Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1990 The Regents of the University of California. 4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * William Jolitz. 8 * William Jolitz.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -140,38 +140,40 @@ struct cpu_info { @@ -140,38 +140,40 @@ struct cpu_info {
140 } ci_istate __aligned(8); 140 } ci_istate __aligned(8);
141#define ci_ipending ci_istate.ipending 141#define ci_ipending ci_istate.ipending
142#define ci_ilevel ci_istate.ilevel 142#define ci_ilevel ci_istate.ilevel
143 143
144 int ci_idepth; 144 int ci_idepth;
145 void * ci_intrstack; 145 void * ci_intrstack;
146 uint32_t ci_imask[NIPL]; 146 uint32_t ci_imask[NIPL];
147 uint32_t ci_iunmask[NIPL]; 147 uint32_t ci_iunmask[NIPL];
148 148
149 uint32_t ci_flags; /* flags; see below */ 149 uint32_t ci_flags; /* flags; see below */
150 uint32_t ci_ipis; /* interprocessor interrupts pending */ 150 uint32_t ci_ipis; /* interprocessor interrupts pending */
151 uint32_t sc_apic_version; /* local APIC version */ 151 uint32_t sc_apic_version; /* local APIC version */
152 152
153 uint32_t ci_signature; /* X86 cpuid type */ 153 uint32_t ci_signature; /* X86 cpuid type (cpuid.1.%eax) */
154 uint32_t ci_vendor[4]; /* vendor string */ 154 uint32_t ci_vendor[4]; /* vendor string */
155 uint32_t ci_cpu_serial[3]; /* PIII serial number */ 155 uint32_t _unused2;
 156 uint32_t ci_max_cpuid; /* cpuid.0:%eax */
 157 uint32_t ci_max_ext_cpuid; /* cpuid.80000000:%eax */
156 volatile uint32_t ci_lapic_counter; 158 volatile uint32_t ci_lapic_counter;
157 159
158 uint32_t ci_feat_val[5]; /* X86 CPUID feature bits 160 uint32_t ci_feat_val[5]; /* X86 CPUID feature bits */
159 * [0] basic features %edx 161 /* [0] basic features cpuid.1:%edx
160 * [1] basic features %ecx 162 * [1] basic features cpuid.1:%ecx (CPUID2_xxx bits)
161 * [2] extended features %edx 163 * [2] extended features cpuid:80000001:%edx
162 * [3] extended features %ecx 164 * [3] extended features cpuid:80000001:%ecx
163 * [4] VIA padlock features 165 * [4] VIA padlock features
164 */ 166 */
165  167
166 const struct cpu_functions *ci_func; /* start/stop functions */ 168 const struct cpu_functions *ci_func; /* start/stop functions */
167 struct trapframe *ci_ddb_regs; 169 struct trapframe *ci_ddb_regs;
168 170
169 u_int ci_cflush_lsize; /* CFLUSH insn line size */ 171 u_int ci_cflush_lsize; /* CFLUSH insn line size */
170 struct x86_cache_info ci_cinfo[CAI_COUNT]; 172 struct x86_cache_info ci_cinfo[CAI_COUNT];
171 173
172 union descriptor *ci_gdt; 174 union descriptor *ci_gdt;
173 175
174#ifdef i386 176#ifdef i386
175 struct i386tss ci_doubleflt_tss; 177 struct i386tss ci_doubleflt_tss;
176 struct i386tss ci_ddbipi_tss; 178 struct i386tss ci_ddbipi_tss;
177#endif 179#endif

cvs diff -r1.8 -r1.9 src/sys/arch/x86/x86/cpu_topology.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/cpu_topology.c 2013/11/15 08:47:55 1.8
+++ src/sys/arch/x86/x86/cpu_topology.c 2014/02/22 17:48:08 1.9
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu_topology.c,v 1.8 2013/11/15 08:47:55 msaitoh Exp $ */ 1/* $NetBSD: cpu_topology.c,v 1.9 2014/02/22 17:48:08 dsl Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009 Mindaugas Rasiukevicius <rmind at NetBSD org>, 4 * Copyright (c) 2009 Mindaugas Rasiukevicius <rmind at NetBSD org>,
5 * Copyright (c) 2008 YAMAMOTO Takashi, 5 * Copyright (c) 2008 YAMAMOTO Takashi,
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -26,105 +26,95 @@ @@ -26,105 +26,95 @@
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30/* 30/*
31 * x86 CPU topology detection. 31 * x86 CPU topology detection.
32 * 32 *
33 * References: 33 * References:
34 * - 53668.pdf (7.10.2), 276613.pdf 34 * - 53668.pdf (7.10.2), 276613.pdf
35 * - 31116.pdf, 41256.pdf, 25481.pdf 35 * - 31116.pdf, 41256.pdf, 25481.pdf
36 */ 36 */
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.8 2013/11/15 08:47:55 msaitoh Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.9 2014/02/22 17:48:08 dsl Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/bitops.h> 42#include <sys/bitops.h>
43 43
44#include <machine/specialreg.h> 44#include <machine/specialreg.h>
45#include <machine/cpu.h> 45#include <machine/cpu.h>
46 46
47#include <x86/cpufunc.h> 47#include <x86/cpufunc.h>
48#include <x86/cputypes.h> 48#include <x86/cputypes.h>
49#include <x86/cpuvar.h> 49#include <x86/cpuvar.h>
50 50
51void 51void
52x86_cpu_topology(struct cpu_info *ci) 52x86_cpu_topology(struct cpu_info *ci)
53{ 53{
54 u_int lp_max; /* Logical processors per package (node) */ 54 u_int lp_max; /* Logical processors per package (node) */
55 u_int core_max; /* Core per package */ 55 u_int core_max; /* Core per package */
56 int n, cpu_family, apic_id, smt_bits, core_bits = 0; 56 int n, cpu_family, apic_id, smt_bits, core_bits = 0;
57 uint32_t descs[4], lextmode; 57 uint32_t descs[4];
58 58
59 apic_id = ci->ci_initapicid; 59 apic_id = ci->ci_initapicid;
60 cpu_family = CPUID_TO_FAMILY(ci->ci_signature); 60 cpu_family = CPUID_TO_FAMILY(ci->ci_signature);
61 61
62 /* Initial values. */ 62 /* Initial values. */
63 ci->ci_package_id = apic_id; 63 ci->ci_package_id = apic_id;
64 ci->ci_core_id = 0; 64 ci->ci_core_id = 0;
65 ci->ci_smt_id = 0; 65 ci->ci_smt_id = 0;
66 66
67 switch (cpu_vendor) { 67 switch (cpu_vendor) {
68 case CPUVENDOR_INTEL: 68 case CPUVENDOR_INTEL:
69 if (cpu_family < 6) 69 if (cpu_family < 6)
70 return; 70 return;
71 break; 71 break;
72 case CPUVENDOR_AMD: 72 case CPUVENDOR_AMD:
73 if (cpu_family < 0xf) 73 if (cpu_family < 0xf)
74 return; 74 return;
75 break; 75 break;
76 default: 76 default:
77 return; 77 return;
78 } 78 }
79 79
80 /* Determine the extended feature flags. */ 
81 x86_cpuid(0x80000000, descs); 
82 lextmode = descs[0]; 
83 if (lextmode >= 0x80000001) { 
84 x86_cpuid(0x80000001, descs); 
85 ci->ci_feat_val[2] = descs[3]; /* edx */ 
86 ci->ci_feat_val[3] = descs[2]; /* ecx */ 
87 } 
88 
89 /* Check for HTT support. See notes below regarding AMD. */ 80 /* Check for HTT support. See notes below regarding AMD. */
90 if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) { 81 if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
91 /* Maximum number of LPs sharing a cache (ebx[23:16]). */ 82 /* Maximum number of LPs sharing a cache (ebx[23:16]). */
92 x86_cpuid(1, descs); 83 x86_cpuid(1, descs);
93 lp_max = (descs[1] >> 16) & 0xff; 84 lp_max = (descs[1] >> 16) & 0xff;
94 } else { 85 } else {
95 lp_max = 1; 86 lp_max = 1;
96 } 87 }
97 88
98 switch (cpu_vendor) { 89 switch (cpu_vendor) {
99 case CPUVENDOR_INTEL: 90 case CPUVENDOR_INTEL:
100 /* Check for leaf 4 support. */ 91 /* Check for leaf 4 support. */
101 x86_cpuid(0, descs); 92 if (ci->ci_max_cpuid >= 4) {
102 if (descs[0] >= 4) { 
103 /* Maximum number of Cores per package (eax[31:26]). */ 93 /* Maximum number of Cores per package (eax[31:26]). */
104 x86_cpuid2(4, 0, descs); 94 x86_cpuid2(4, 0, descs);
105 core_max = (descs[0] >> 26) + 1; 95 core_max = (descs[0] >> 26) + 1;
106 } else { 96 } else {
107 core_max = 1; 97 core_max = 1;
108 } 98 }
109 break; 99 break;
110 case CPUVENDOR_AMD: 100 case CPUVENDOR_AMD:
111 /* In a case of AMD, HTT flag means CMP support. */ 101 /* In a case of AMD, HTT flag means CMP support. */
112 if ((ci->ci_feat_val[0] & CPUID_HTT) == 0) { 102 if ((ci->ci_feat_val[0] & CPUID_HTT) == 0) {
113 core_max = 1; 103 core_max = 1;
114 break; 104 break;
115 } 105 }
116 /* Legacy Method, LPs represent Cores. */ 106 /* Legacy Method, LPs represent Cores. */
117 if (cpu_family < 0x10 || lextmode < 0x80000008) { 107 if (cpu_family < 0x10 || ci->ci_max_ext_cpuid < 0x80000008) {
118 core_max = lp_max; 108 core_max = lp_max;
119 break; 109 break;
120 } 110 }
121 /* Number of Cores (NC) per package (ecx[7:0]). */ 111 /* Number of Cores (NC) per package (ecx[7:0]). */
122 x86_cpuid(0x80000008, descs); 112 x86_cpuid(0x80000008, descs);
123 core_max = (descs[2] & 0xff) + 1; 113 core_max = (descs[2] & 0xff) + 1;
124 /* Amount of bits representing Core ID (ecx[15:12]). */ 114 /* Amount of bits representing Core ID (ecx[15:12]). */
125 n = (descs[2] >> 12) & 0x0f; 115 n = (descs[2] >> 12) & 0x0f;
126 if (n != 0) { 116 if (n != 0) {
127 /* 117 /*
128 * Extended Method. 118 * Extended Method.
129 * core_bits = 2 ^ n (power of two) 119 * core_bits = 2 ^ n (power of two)
130 */ 120 */

cvs diff -r1.39 -r1.40 src/sys/arch/x86/x86/identcpu.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/identcpu.c 2013/12/23 11:40:57 1.39
+++ src/sys/arch/x86/x86/identcpu.c 2014/02/22 17:48:08 1.40
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: identcpu.c,v 1.39 2013/12/23 11:40:57 msaitoh Exp $ */ 1/* $NetBSD: identcpu.c,v 1.40 2014/02/22 17:48:08 dsl Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden, and by Jason R. Thorpe. 8 * by Frank van der Linden, and by Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 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 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.39 2013/12/23 11:40:57 msaitoh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.40 2014/02/22 17:48:08 dsl Exp $");
34 34
35#include "opt_xen.h" 35#include "opt_xen.h"
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/device.h> 39#include <sys/device.h>
40 40
41#include <uvm/uvm_extern.h> 41#include <uvm/uvm_extern.h>
42 42
43#include <machine/specialreg.h> 43#include <machine/specialreg.h>
44#include <machine/pio.h> 44#include <machine/pio.h>
45#include <machine/cpu.h> 45#include <machine/cpu.h>
46 46
@@ -125,27 +125,27 @@ cpu_probe_intel_cache(struct cpu_info *c @@ -125,27 +125,27 @@ cpu_probe_intel_cache(struct cpu_info *c
125 ci->ci_cinfo[cai->cai_index] = 125 ci->ci_cinfo[cai->cai_index] =
126 *cai; 126 *cai;
127 } 127 }
128 } 128 }
129 } 129 }
130 } 130 }
131 } 131 }
132 132
133 if (cpuid_level >= 4) { 133 if (cpuid_level >= 4) {
134 int type, level; 134 int type, level;
135 int ways, partitions, linesize, sets; 135 int ways, partitions, linesize, sets;
136 int caitype = -1; 136 int caitype = -1;
137 int totalsize; 137 int totalsize;
138  138
139 /* Parse the cache info from `cpuid leaf 4', if we have it. */ 139 /* Parse the cache info from `cpuid leaf 4', if we have it. */
140 for (i = 0; ; i++) { 140 for (i = 0; ; i++) {
141 x86_cpuid2(4, i, descs); 141 x86_cpuid2(4, i, descs);
142 type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE); 142 type = __SHIFTOUT(descs[0], CPUID_DCP_CACHETYPE);
143 if (type == CPUID_DCP_CACHETYPE_N) 143 if (type == CPUID_DCP_CACHETYPE_N)
144 break; 144 break;
145 level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL); 145 level = __SHIFTOUT(descs[0], CPUID_DCP_CACHELEVEL);
146 switch (level) { 146 switch (level) {
147 case 1: 147 case 1:
148 if (type == CPUID_DCP_CACHETYPE_I) 148 if (type == CPUID_DCP_CACHETYPE_I)
149 caitype = CAI_ICACHE; 149 caitype = CAI_ICACHE;
150 else if (type == CPUID_DCP_CACHETYPE_D) 150 else if (type == CPUID_DCP_CACHETYPE_D)
151 caitype = CAI_DCACHE; 151 caitype = CAI_DCACHE;
@@ -349,40 +349,31 @@ cpu_probe_k5(struct cpu_info *ci) @@ -349,40 +349,31 @@ cpu_probe_k5(struct cpu_info *ci)
349 */ 349 */
350 flag = ci->ci_feat_val[0]; 350 flag = ci->ci_feat_val[0];
351 if ((flag & CPUID_APIC) != 0) 351 if ((flag & CPUID_APIC) != 0)
352 flag = (flag & ~CPUID_APIC) | CPUID_PGE; 352 flag = (flag & ~CPUID_APIC) | CPUID_PGE;
353 ci->ci_feat_val[0] = flag; 353 ci->ci_feat_val[0] = flag;
354 } 354 }
355 355
356 cpu_probe_amd_cache(ci); 356 cpu_probe_amd_cache(ci);
357} 357}
358 358
359static void 359static void
360cpu_probe_k678(struct cpu_info *ci) 360cpu_probe_k678(struct cpu_info *ci)
361{ 361{
362 uint32_t descs[4]; 
363 362
364 if (cpu_vendor != CPUVENDOR_AMD || 363 if (cpu_vendor != CPUVENDOR_AMD ||
365 CPUID_TO_FAMILY(ci->ci_signature) < 6) 364 CPUID_TO_FAMILY(ci->ci_signature) < 6)
366 return; 365 return;
367 366
368 /* Determine the extended feature flags. */ 
369 x86_cpuid(0x80000000, descs); 
370 if (descs[0] >= 0x80000001) { 
371 x86_cpuid(0x80000001, descs); 
372 ci->ci_feat_val[3] = descs[2]; /* %ecx */ 
373 ci->ci_feat_val[2] = descs[3]; /* %edx */ 
374 } 
375 
376 cpu_probe_amd_cache(ci); 367 cpu_probe_amd_cache(ci);
377} 368}
378 369
379static inline uint8_t 370static inline uint8_t
380cyrix_read_reg(uint8_t reg) 371cyrix_read_reg(uint8_t reg)
381{ 372{
382 373
383 outb(0x22, reg); 374 outb(0x22, reg);
384 return inb(0x23); 375 return inb(0x23);
385} 376}
386 377
387static inline void 378static inline void
388cyrix_write_reg(uint8_t reg, uint8_t data) 379cyrix_write_reg(uint8_t reg, uint8_t data)
@@ -505,32 +496,26 @@ cpu_probe_c3(struct cpu_info *ci) @@ -505,32 +496,26 @@ cpu_probe_c3(struct cpu_info *ci)
505 496
506 if (cpu_vendor != CPUVENDOR_IDT || 497 if (cpu_vendor != CPUVENDOR_IDT ||
507 CPUID_TO_FAMILY(ci->ci_signature) < 6) 498 CPUID_TO_FAMILY(ci->ci_signature) < 6)
508 return; 499 return;
509 500
510 family = CPUID_TO_FAMILY(ci->ci_signature); 501 family = CPUID_TO_FAMILY(ci->ci_signature);
511 model = CPUID_TO_MODEL(ci->ci_signature); 502 model = CPUID_TO_MODEL(ci->ci_signature);
512 stepping = CPUID_TO_STEPPING(ci->ci_signature); 503 stepping = CPUID_TO_STEPPING(ci->ci_signature);
513 504
514 /* Determine the largest extended function value. */ 505 /* Determine the largest extended function value. */
515 x86_cpuid(0x80000000, descs); 506 x86_cpuid(0x80000000, descs);
516 lfunc = descs[0]; 507 lfunc = descs[0];
517 508
518 /* Determine the extended feature flags. */ 
519 if (lfunc >= 0x80000001) { 
520 x86_cpuid(0x80000001, descs); 
521 ci->ci_feat_val[2] = descs[3]; 
522 } 
523 
524 if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) { 509 if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) {
525 /* Nehemiah or Esther */ 510 /* Nehemiah or Esther */
526 x86_cpuid(0xc0000000, descs); 511 x86_cpuid(0xc0000000, descs);
527 lfunc = descs[0]; 512 lfunc = descs[0];
528 if (lfunc >= 0xc0000001) { /* has ACE, RNG */ 513 if (lfunc >= 0xc0000001) { /* has ACE, RNG */
529 int rng_enable = 0, ace_enable = 0; 514 int rng_enable = 0, ace_enable = 0;
530 x86_cpuid(0xc0000001, descs); 515 x86_cpuid(0xc0000001, descs);
531 lfunc = descs[3]; 516 lfunc = descs[3];
532 ci->ci_feat_val[4] = lfunc; 517 ci->ci_feat_val[4] = lfunc;
533 /* Check for and enable RNG */ 518 /* Check for and enable RNG */
534 if (lfunc & CPUID_VIA_HAS_RNG) { 519 if (lfunc & CPUID_VIA_HAS_RNG) {
535 if (!(lfunc & CPUID_VIA_DO_RNG)) { 520 if (!(lfunc & CPUID_VIA_DO_RNG)) {
536 rng_enable++; 521 rng_enable++;
@@ -565,27 +550,27 @@ cpu_probe_c3(struct cpu_info *ci) @@ -565,27 +550,27 @@ cpu_probe_c3(struct cpu_info *ci)
565 ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM; 550 ci->ci_feat_val[4] |= CPUID_VIA_DO_PMM;
566 } 551 }
567 } 552 }
568 553
569 /* Actually do the enables. */ 554 /* Actually do the enables. */
570 if (rng_enable) { 555 if (rng_enable) {
571 msr = rdmsr(MSR_VIA_RNG); 556 msr = rdmsr(MSR_VIA_RNG);
572 wrmsr(MSR_VIA_RNG, msr | MSR_VIA_RNG_ENABLE); 557 wrmsr(MSR_VIA_RNG, msr | MSR_VIA_RNG_ENABLE);
573 } 558 }
574 if (ace_enable) { 559 if (ace_enable) {
575 msr = rdmsr(MSR_VIA_ACE); 560 msr = rdmsr(MSR_VIA_ACE);
576 wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE); 561 wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE);
577 } 562 }
578  563
579 } 564 }
580 } 565 }
581 566
582 /* 567 /*
583 * Determine L1 cache/TLB info. 568 * Determine L1 cache/TLB info.
584 */ 569 */
585 if (lfunc < 0x80000005) { 570 if (lfunc < 0x80000005) {
586 /* No L1 cache info available. */ 571 /* No L1 cache info available. */
587 return; 572 return;
588 } 573 }
589 574
590 x86_cpuid(0x80000005, descs); 575 x86_cpuid(0x80000005, descs);
591 576
@@ -606,27 +591,27 @@ cpu_probe_c3(struct cpu_info *ci) @@ -606,27 +591,27 @@ cpu_probe_c3(struct cpu_info *ci)
606 if (family == 6 && model == 9 && stepping == 8) { 591 if (family == 6 && model == 9 && stepping == 8) {
607 /* Erratum: stepping 8 reports 4 when it should be 2 */ 592 /* Erratum: stepping 8 reports 4 when it should be 2 */
608 cai->cai_associativity = 2; 593 cai->cai_associativity = 2;
609 } 594 }
610 595
611 cai = &ci->ci_cinfo[CAI_ICACHE]; 596 cai = &ci->ci_cinfo[CAI_ICACHE];
612 cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]); 597 cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]);
613 cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]); 598 cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]);
614 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]); 599 cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]);
615 if (family == 6 && model == 9 && stepping == 8) { 600 if (family == 6 && model == 9 && stepping == 8) {
616 /* Erratum: stepping 8 reports 4 when it should be 2 */ 601 /* Erratum: stepping 8 reports 4 when it should be 2 */
617 cai->cai_associativity = 2; 602 cai->cai_associativity = 2;
618 } 603 }
619  604
620 /* 605 /*
621 * Determine L2 cache/TLB info. 606 * Determine L2 cache/TLB info.
622 */ 607 */
623 if (lfunc < 0x80000006) { 608 if (lfunc < 0x80000006) {
624 /* No L2 cache info available. */ 609 /* No L2 cache info available. */
625 return; 610 return;
626 } 611 }
627 612
628 x86_cpuid(0x80000006, descs); 613 x86_cpuid(0x80000006, descs);
629 614
630 cai = &ci->ci_cinfo[CAI_L2CACHE]; 615 cai = &ci->ci_cinfo[CAI_L2CACHE];
631 if (family > 6 || model >= 9) { 616 if (family > 6 || model >= 9) {
632 cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]); 617 cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
@@ -702,79 +687,99 @@ cpu_probe(struct cpu_info *ci) @@ -702,79 +687,99 @@ cpu_probe(struct cpu_info *ci)
702 687
703 cpu_vendor = i386_nocpuid_cpus[cputype << 1]; 688 cpu_vendor = i386_nocpuid_cpus[cputype << 1];
704 cpu_class = i386_nocpuid_cpus[(cputype << 1) + 1]; 689 cpu_class = i386_nocpuid_cpus[(cputype << 1) + 1];
705 690
706 if (cpuid_level < 0) 691 if (cpuid_level < 0)
707 return; 692 return;
708 693
709 for (i = 0; i < __arraycount(ci->ci_feat_val); i++) { 694 for (i = 0; i < __arraycount(ci->ci_feat_val); i++) {
710 ci->ci_feat_val[i] = 0; 695 ci->ci_feat_val[i] = 0;
711 } 696 }
712 697
713 x86_cpuid(0, descs); 698 x86_cpuid(0, descs);
714 cpuid_level = descs[0]; 699 cpuid_level = descs[0];
 700 ci->ci_max_cpuid = descs[0];
 701
715 ci->ci_vendor[0] = descs[1]; 702 ci->ci_vendor[0] = descs[1];
716 ci->ci_vendor[2] = descs[2]; 703 ci->ci_vendor[2] = descs[2];
717 ci->ci_vendor[1] = descs[3]; 704 ci->ci_vendor[1] = descs[3];
718 ci->ci_vendor[3] = 0; 705 ci->ci_vendor[3] = 0;
719 706
720 if (memcmp(ci->ci_vendor, "GenuineIntel", 12) == 0) 707 if (memcmp(ci->ci_vendor, "GenuineIntel", 12) == 0)
721 cpu_vendor = CPUVENDOR_INTEL; 708 cpu_vendor = CPUVENDOR_INTEL;
722 else if (memcmp(ci->ci_vendor, "AuthenticAMD", 12) == 0) 709 else if (memcmp(ci->ci_vendor, "AuthenticAMD", 12) == 0)
723 cpu_vendor = CPUVENDOR_AMD; 710 cpu_vendor = CPUVENDOR_AMD;
724 else if (memcmp(ci->ci_vendor, "CyrixInstead", 12) == 0) 711 else if (memcmp(ci->ci_vendor, "CyrixInstead", 12) == 0)
725 cpu_vendor = CPUVENDOR_CYRIX; 712 cpu_vendor = CPUVENDOR_CYRIX;
726 else if (memcmp(ci->ci_vendor, "Geode by NSC", 12) == 0) 713 else if (memcmp(ci->ci_vendor, "Geode by NSC", 12) == 0)
727 cpu_vendor = CPUVENDOR_CYRIX; 714 cpu_vendor = CPUVENDOR_CYRIX;
728 else if (memcmp(ci->ci_vendor, "CentaurHauls", 12) == 0) 715 else if (memcmp(ci->ci_vendor, "CentaurHauls", 12) == 0)
729 cpu_vendor = CPUVENDOR_IDT; 716 cpu_vendor = CPUVENDOR_IDT;
730 else if (memcmp(ci->ci_vendor, "GenuineTMx86", 12) == 0) 717 else if (memcmp(ci->ci_vendor, "GenuineTMx86", 12) == 0)
731 cpu_vendor = CPUVENDOR_TRANSMETA; 718 cpu_vendor = CPUVENDOR_TRANSMETA;
732 else if (memcmp(ci->ci_vendor, "Vortex86 SoC", 12) == 0) 719 else if (memcmp(ci->ci_vendor, "Vortex86 SoC", 12) == 0)
733 cpu_vendor = CPUVENDOR_VORTEX86; 720 cpu_vendor = CPUVENDOR_VORTEX86;
734 else 721 else
735 cpu_vendor = CPUVENDOR_UNKNOWN; 722 cpu_vendor = CPUVENDOR_UNKNOWN;
736 723
737 x86_cpuid(0x80000000, brand); 
738 if (brand[0] >= 0x80000004) { 
739 x86_cpuid(0x80000002, brand); 
740 x86_cpuid(0x80000003, brand + 4); 
741 x86_cpuid(0x80000004, brand + 8); 
742 for (i = 0; i < 48; i++) { 
743 if (((char *) brand)[i] != ' ') 
744 break; 
745 } 
746 memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i); 
747 } 
748 
749 if (cpuid_level >= 1) { 724 if (cpuid_level >= 1) {
750 x86_cpuid(1, descs); 725 x86_cpuid(1, descs);
751 ci->ci_signature = descs[0]; 726 ci->ci_signature = descs[0];
752 miscbytes = descs[1]; 727 miscbytes = descs[1];
753 ci->ci_feat_val[1] = descs[2]; 728 ci->ci_feat_val[1] = descs[2];
754 ci->ci_feat_val[0] = descs[3]; 729 ci->ci_feat_val[0] = descs[3];
755 730
756 /* Determine family + class. */ 731 /* Determine family + class. */
757 cpu_class = CPUID_TO_FAMILY(ci->ci_signature) 732 cpu_class = CPUID_TO_FAMILY(ci->ci_signature)
758 + (CPUCLASS_386 - 3); 733 + (CPUCLASS_386 - 3);
759 if (cpu_class > CPUCLASS_686) 734 if (cpu_class > CPUCLASS_686)
760 cpu_class = CPUCLASS_686; 735 cpu_class = CPUCLASS_686;
761 736
762 /* CLFLUSH line size is next 8 bits */ 737 /* CLFLUSH line size is next 8 bits */
763 if (ci->ci_feat_val[0] & CPUID_CFLUSH) 738 if (ci->ci_feat_val[0] & CPUID_CFLUSH)
764 ci->ci_cflush_lsize = ((miscbytes >> 8) & 0xff) << 3; 739 ci->ci_cflush_lsize = ((miscbytes >> 8) & 0xff) << 3;
765 ci->ci_initapicid = (miscbytes >> 24) & 0xff; 740 ci->ci_initapicid = (miscbytes >> 24) & 0xff;
766 } 741 }
767 742
 743 /*
 744 * Get the basic information from the extended cpuid leafs.
 745 * These were first implemented by amd, but most of the values
 746 * match with those generated by modern intel cpus.
 747 */
 748 x86_cpuid(0x80000000, descs);
 749 if (descs[0] == 0x80000000)
 750 ci->ci_max_ext_cpuid = descs[0];
 751 else
 752 ci->ci_max_ext_cpuid = 0;
 753
 754 if (ci->ci_max_ext_cpuid >= 0x80000001) {
 755 /* Determine the extended feature flags. */
 756 x86_cpuid(0x80000001, descs);
 757 ci->ci_feat_val[3] = descs[2]; /* %ecx */
 758 ci->ci_feat_val[2] = descs[3]; /* %edx */
 759 }
 760
 761 if (ci->ci_max_ext_cpuid >= 0x80000004) {
 762 x86_cpuid(0x80000002, brand);
 763 x86_cpuid(0x80000003, brand + 4);
 764 x86_cpuid(0x80000004, brand + 8);
 765 /* Skip leading spaces on brand */
 766 for (i = 0; i < 48; i++) {
 767 if (((char *) brand)[i] != ' ')
 768 break;
 769 }
 770 memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
 771 }
 772
768 cpu_probe_intel(ci); 773 cpu_probe_intel(ci);
769 cpu_probe_k5(ci); 774 cpu_probe_k5(ci);
770 cpu_probe_k678(ci); 775 cpu_probe_k678(ci);
771 cpu_probe_cyrix(ci); 776 cpu_probe_cyrix(ci);
772 cpu_probe_winchip(ci); 777 cpu_probe_winchip(ci);
773 cpu_probe_c3(ci); 778 cpu_probe_c3(ci);
774 cpu_probe_geode(ci); 779 cpu_probe_geode(ci);
775 cpu_probe_vortex86(ci); 780 cpu_probe_vortex86(ci);
776 781
777 x86_cpu_topology(ci); 782 x86_cpu_topology(ci);
778 783
779 if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) && 784 if (cpu_vendor != CPUVENDOR_AMD && (ci->ci_feat_val[0] & CPUID_TM) &&
780 (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) { 785 (rdmsr(MSR_MISC_ENABLE) & (1 << 3)) == 0) {
@@ -863,17 +868,23 @@ cpu_identify(struct cpu_info *ci) @@ -863,17 +868,23 @@ cpu_identify(struct cpu_info *ci)
863 } 868 }
864 869
865 /* If we have FXSAVE/FXRESTOR, use them. */ 870 /* If we have FXSAVE/FXRESTOR, use them. */
866 if (cpu_feature[0] & CPUID_FXSR) { 871 if (cpu_feature[0] & CPUID_FXSR) {
867 i386_use_fxsave = 1; 872 i386_use_fxsave = 1;
868 /* 873 /*
869 * If we have SSE/SSE2, enable XMM exceptions, and 874 * If we have SSE/SSE2, enable XMM exceptions, and
870 * notify userland. 875 * notify userland.
871 */ 876 */
872 if (cpu_feature[0] & CPUID_SSE) 877 if (cpu_feature[0] & CPUID_SSE)
873 i386_has_sse = 1; 878 i386_has_sse = 1;
874 if (cpu_feature[0] & CPUID_SSE2) 879 if (cpu_feature[0] & CPUID_SSE2)
875 i386_has_sse2 = 1; 880 i386_has_sse2 = 1;
876 } else 881 } else {
877 i386_use_fxsave = 0; 882 i386_use_fxsave = 0;
 883 }
 884#else
 885 /*
 886 * i386_use_fxsave, i386_has_sse and i386_has_sse2 are
 887 * #defined to 1.
 888 */
878#endif /* i386 */ 889#endif /* i386 */
879} 890}